This commit is contained in:
Justin Foell
2019-04-01 14:50:36 -05:00
parent 823fff522b
commit 3ce9d26e88
6 changed files with 280 additions and 93 deletions
+9 -1
View File
@@ -16,6 +16,12 @@ class WPStrava {
*/
private $settings = null;
/**
* Authorization object.
* @var WPStrava_Auth
*/
private $auth = null;
/**
* Array of WPStrava_API objects (one for each athlete).
*
@@ -40,9 +46,11 @@ class WPStrava {
*/
private function __construct() {
$this->settings = new WPStrava_Settings();
$this->auth = WPStrava_Auth::get_auth( 'forever' );
if ( is_admin() ) {
$this->settings->hook();
$this->auth->hook();
} else {
add_action( 'init', array( $this, 'register_shortcodes' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
@@ -90,7 +98,7 @@ class WPStrava {
}
/**
* Get an API object for the given athelete token.
* Get an API object for the given athlete token.
*
* @param string $token Athlete token.
* @return WPStrava_API
+119
View File
@@ -0,0 +1,119 @@
<?php
abstract class WPStrava_Auth {
protected $auth_url = 'https://www.strava.com/oauth/authorize?response_type=code';
private $feedback;
/**
* Factory method to get the correct Auth class based on specified string
* or by the options setting.
*
* @param string $auth 'refresh' or 'forever' (default 'refresh').
* @return WPStrava_Auth Instance of Auth
* @author Justin Foell <justin@foell.org>
*/
public static function get_auth( $auth = 'refresh' ) {
if ( 'forever' === $auth ) {
return new WPStrava_AuthForever();
}
// Default to refresh.
return new WPStrava_AuthRefresh();
}
abstract protected function get_authorize_url( $client_id );
public function hook() {
add_filter( 'pre_set_transient_settings_errors', array( $this, 'maybe_oauth' ) );
add_action( 'admin_init', array( $this, 'init' ) );
}
/**
* This runs after options are saved
*/
public function maybe_oauth( $value ) {
$settings = WPStrava::get_instance()->settings;
// User is clearing to start-over, don't oauth, ignore other errors.
if ( isset( $_POST['strava_token'] ) && $settings->tokens_empty( $_POST['strava_token'] ) ) {
return array();
}
// Redirect only if all the right options are in place.
if ( $settings->is_settings_updated( $value ) && $settings->is_option_page() ) {
// Only re-auth if client ID and secret were saved.
if ( ! empty( $_POST['strava_client_id'] ) && ! empty( $_POST['strava_client_secret'] ) ) {
wp_redirect( $this->get_authorize_url( $_POST['strava_client_id'] ) );
exit();
}
}
return $value;
}
public function init() {
$settings = WPStrava::get_instance()->settings;
//only update when redirected back from strava
if ( ! isset( $_GET['settings-updated'] ) && $settings->is_settings_page() ) {
if ( isset( $_GET['code'] ) ) {
$info = $this->token_exchange_initial( $_GET['code'] );
if ( isset( $info->access_token ) ) {
// Translators: New strava token
add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'New Strava token retrieved. %s', 'wp-strava' ), $this->feedback ), 'updated' );
$settings->add_token( $info->access_token );
$settings->update_token();
} else {
// throw new WPStrava_Exception( '' );
add_settings_error( 'strava_token', 'strava_token', $this->feedback );
}
} elseif ( isset( $_GET['error'] ) ) {
// Translators: authentication error mess
add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'Error authenticating at Strava: %s', 'wp-strava' ), str_replace( '_', ' ', $_GET['error'] ) ) );
}
}
}
protected function get_redirect_param() {
$page_name = WPStrava::get_instance()->settings->get_page_name();
return rawurlencode( admin_url( "options-general.php?page={$page_name}" ) );
}
// was fetch_token();
private function token_exchange_initial( $code ) {
$settings = WPStrava::get_instance()->settings;
$client_id = $settings->client_id;
$client_secret = $settings->client_secret;
$settings->delete_id_secret();
if ( $client_id && $client_secret ) {
$data = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'code' => $code,
);
$strava_info = $this->token_request( $data );
if ( isset( $strava_info->access_token ) ) {
$this->feedback .= __( 'Successfully authenticated.', 'wp-strava' );
return $strava_info;
}
// Translators: error message from Strava
$this->feedback .= sprintf( __( 'There was an error receiving data from Strava: <pre>%s</pre>', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
return false;
}
$this->feedback .= __( 'Missing Client ID or Client Secret.', 'wp-strava' );
return false;
}
protected function token_request( $data ) {
$api = new WPStrava_API();
return $api->post( 'oauth/token', $data );
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
/**
* This functionality is deprecated and will be shut down on October 15, 2019
*
* @see https://developers.strava.com/docs/oauth-updates/#migration-instructions
*/
/**
* AuthForever Class
*
* @since 2.0.0
*/
class WPStrava_AuthForever extends WPStrava_Auth {
protected function get_authorize_url( $client_id ) {
return add_query_arg(
array(
'client_id' => $client_id,
'redirect_uri' => $this->get_redirect_param(),
'approval_prompt' => 'force',
),
$this->auth_url
);
}
}
+47
View File
@@ -0,0 +1,47 @@
<?php
/**
* AuthRefresh class
*
* @since 2.0.0
*/
class WPStrava_AuthRefresh extends WPStrava_Auth {
public function hook() {
parent::hook();
// @TODO Need cronjob.
}
protected function get_authorize_url( $client_id ) {
return add_query_arg(
array(
'client_id' => $client_id,
'redirect_uri' => $this->get_redirect_param(),
'approval_prompt' => 'auto',
'scope' => 'read,activity:read',
),
$this->auth_url
);
}
protected function token_exchange_refresh() {
$data = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'refresh_token' => $refresh_token,
'grant_type' => 'refresh_token',
);
$strava_info = $this->token_request( $data );
if ( isset( $strava_info->access_token ) ) {
$this->feedback .= __( 'Successfully re-authenticated.', 'wp-strava' );
return $strava_info;
}
$this->feedback .= sprintf( __( 'There was an error receiving data from Strava: <pre>%s</pre>', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
return false;
}
}
+76 -92
View File
@@ -11,7 +11,6 @@
class WPStrava_Settings {
private $feedback;
private $tokens = array();
private $page_name = 'wp-strava-options';
private $option_page = 'wp-strava-settings-group';
@@ -19,40 +18,11 @@ class WPStrava_Settings {
//register admin menus
public function hook() {
add_action( 'admin_init', array( $this, 'register_strava_settings' ) );
add_action( 'admin_init', array( $this, 'register_strava_settings' ), 20 );
add_action( 'admin_menu', array( $this, 'add_strava_menu' ) );
add_filter( 'pre_set_transient_settings_errors', array( $this, 'maybe_oauth' ) );
add_filter( 'plugin_action_links_' . WPSTRAVA_PLUGIN_NAME, array( $this, 'settings_link' ) );
}
/**
* This runs after options are saved
*/
public function maybe_oauth( $value ) {
// User is clearing to start-over, don't oauth, ignore other errors.
if ( isset( $_POST['strava_token'] ) && $this->tokens_empty( $_POST['strava_token'] ) ) {
return array();
}
// Redirect only if all the right options are in place.
if ( isset( $value[0]['type'] ) && 'updated' === $value[0]['type'] ) { // Make sure there were no settings errors.
if ( isset( $_POST['option_page'] ) && $_POST['option_page'] === $this->option_page ) { // Make sure we're on our settings page.
// Only re-auth if client ID and secret were saved.
if ( ! empty( $_POST['strava_client_id'] ) && ! empty( $_POST['strava_client_secret'] ) ) {
$client_id = $_POST['strava_client_id'];
$client_secret = $_POST['strava_client_secret'];
$redirect = rawurlencode( admin_url( "options-general.php?page={$this->page_name}" ) );
$url = "https://www.strava.com/oauth/authorize?client_id={$client_id}&response_type=code&redirect_uri={$redirect}&approval_prompt=force";
wp_redirect( $url );
exit();
}
}
}
return $value;
}
public function add_strava_menu() {
add_options_page(
__( 'Strava Settings', 'wp-strava' ),
@@ -63,36 +33,12 @@ class WPStrava_Settings {
);
}
public function init() {
$this->tokens = $this->get_tokens();
// Only validate additional athlete information if all fields are present.
$this->adding_athlete = ! ( empty( $_POST['strava_client_id'] ) && empty( $_POST['strava_client_secret'] ) );
//only update when redirected back from strava
if ( ! isset( $_GET['settings-updated'] ) && isset( $_GET['page'] ) && $_GET['page'] === $this->page_name ) {
if ( isset( $_GET['code'] ) ) {
$token = $this->fetch_token( $_GET['code'] );
if ( $token ) {
// Translators: strava token
add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'New Strava token retrieved. %s', 'wp-strava' ), $this->feedback ), 'updated' );
$this->add_token( $token );
update_option( 'strava_token', $this->tokens );
} else {
add_settings_error( 'strava_token', 'strava_token', $this->feedback );
}
} elseif ( isset( $_GET['error'] ) ) {
// Translators: authentication error mess
add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'Error authenticating at Strava: %s', 'wp-strava' ), str_replace( '_', ' ', $_GET['error'] ) ) );
}
}
}
public function register_strava_settings() {
$this->init();
add_settings_section( 'strava_api', __( 'Strava API', 'wp-strava' ), array( $this, 'print_api_instructions' ), 'wp-strava' );
$this->adding_athlete = $this->is_adding_athlete();
$this->tokens = $this->get_tokens();
if ( $this->tokens_empty( $this->tokens ) ) {
register_setting( $this->option_page, 'strava_client_id', array( $this, 'sanitize_client_id' ) );
register_setting( $this->option_page, 'strava_client_secret', array( $this, 'sanitize_client_secret' ) );
@@ -136,7 +82,6 @@ class WPStrava_Settings {
}
public function print_api_instructions() {
$signup_url = 'http://www.strava.com/developers';
$settings_url = 'https://www.strava.com/settings/api';
$icon_url = 'https://plugins.svn.wordpress.org/wp-strava/assets/icon-128x128.png';
$blog_name = get_bloginfo( 'name' );
@@ -180,7 +125,6 @@ class WPStrava_Settings {
<li>To use Google map images, you must create a Static Maps API Key. Create a free key by going here: <a href='%1\$s'>%2\$s</a> and clicking <strong>Get a Key</strong></li>
<li>Once you've created your Google Static Maps API Key, enter the key below.
</ol>", 'wp-strava' ), $maps_url, $maps_url );
}
public function print_strava_options() {
@@ -285,38 +229,6 @@ class WPStrava_Settings {
return $token;
}
private function fetch_token( $code ) {
$client_id = $this->client_id;
$client_secret = $this->client_secret;
delete_option( 'strava_client_id' );
delete_option( 'strava_client_secret' );
if ( $client_id && $client_secret ) {
$api = new WPStrava_API();
$data = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'code' => $code,
);
$strava_info = $api->post( 'oauth/token', $data );
if ( isset( $strava_info->access_token ) ) {
$this->feedback .= __( 'Successfully authenticated.', 'wp-strava' );
return $strava_info->access_token;
}
// Translators: error message from Strava
$this->feedback .= sprintf( __( 'There was an error receiving data from Strava: <pre>%s</pre>', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
return false;
}
$this->feedback .= __( 'Missing Client ID or Client Secret.', 'wp-strava' );
return false;
}
public function print_gmaps_key_input() {
?>
<input type="text" id="strava_gmaps_key" name="strava_gmaps_key" value="<?php echo $this->gmaps_key; ?>" />
@@ -494,6 +406,78 @@ class WPStrava_Settings {
}
}
/**
* Undocumented function
*
* @param array $token
* @author Justin Foell <justin@foell.org>
* @since 2.0.0
*/
public function update_token() {
update_option( 'strava_token', $this->tokens );
}
/**
* Undocumented function
*
* @return void
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
public function delete_id_secret() {
delete_option( 'strava_client_id' );
delete_option( 'strava_client_secret' );
}
/**
* Undocumented function
*
* @param [type] $value
* @return boolean
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
public function is_settings_updated( $value ) {
return isset( $value[0]['type'] ) && 'updated' === $value[0]['type'];
}
/**
* Undocumented function
*
* @return boolean
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
public function is_option_page() {
return isset( $_POST['option_page'] ) && $_POST['option_page'] === $this->option_page;
}
/**
* Undocumented function
*
* @return boolean
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
public function is_settings_page() {
return isset( $_GET['page'] ) && $_GET['page'] === $this->page_name;
}
public function get_page_name() {
return $this->page_name;
}
/**
* Undocumented function
*
* @return boolean
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
private function is_adding_athlete() {
return ! ( empty( $_POST['strava_client_id'] ) && empty( $_POST['strava_client_secret'] ) );
}
public function __get( $name ) {
if ( ! strpos( 'strava_', $name ) ) {
$name = "strava_{$name}";
Regular → Executable
+4
View File
@@ -79,6 +79,10 @@ WP-Strava caches activity for one hour so your site doesn't hit the Strava API o
== Changelog ==
= 2.0.0 =
Added new Strava "refresh tokens" ala https://developers.strava.com/docs/oauth-updates/#migration-instructions
= 1.7.1 =
Added PHPUnit tests for all System of Measure calculations.