Skip to content

Commit

Permalink
Prompt to reset the Meetup API authentication tokens, as we can't do …
Browse files Browse the repository at this point in the history
…it automatically. (#317)

* Prompt to reset the Meetup API authentication tokens, as we can't do it automatically.
  • Loading branch information
dd32 authored Oct 21, 2024
1 parent 3269f6d commit c5f9061
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 39 deletions.
18 changes: 15 additions & 3 deletions mu-plugins/utilities/class-meetup-client.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class Meetup_Client extends API_Client {
* }
*/
public function __construct( array $settings = array() ) {
// Define the OAuth client first, such that it can be used in the parent constructor callbacks.
$this->oauth_client = new Meetup_OAuth2_Client;

parent::__construct( array(
/*
* Response codes that should break the request loop.
Expand Down Expand Up @@ -86,13 +89,12 @@ public function __construct( array $settings = array() ) {
self::cli_message( 'Meetup Client debug is on. Results will be truncated.' );
}

$this->oauth_client = new Meetup_OAuth2_Client();
add_action( 'api_client_tenacious_remote_request_attempt', array( $this, 'maybe_reset_oauth_token' ) );
add_action( 'api_client_handle_error_response', array( $this, 'maybe_reset_oauth_token' ) );

if ( ! empty( $this->oauth_client->error->get_error_messages() ) ) {
$this->error = $this->merge_errors( $this->error, $this->oauth_client->error );
}

add_action( 'api_client_tenacious_remote_request_attempt', array( $this, 'maybe_reset_oauth_token' ) );
}

/**
Expand All @@ -106,6 +108,12 @@ public function __construct( array $settings = array() ) {
* @return void
*/
public function maybe_reset_oauth_token( $response ) {
static $resetting = false;
// Avoid recursive calls.
if ( $resetting ) {
return;
}

$code = wp_remote_retrieve_response_code( $response );
$body = json_decode( wp_remote_retrieve_body( $response ), true );

Expand All @@ -115,6 +123,8 @@ public function maybe_reset_oauth_token( $response ) {
( 400 === $code && $parsed_error->get_error_message( 'invalid_grant' ) )
|| ( 401 === $code && $parsed_error->get_error_message( 'auth_fail' ) )
) {
$resetting = true;

$this->oauth_client->reset_oauth_token();

if ( ! empty( $this->oauth_client->error->get_error_messages() ) ) {
Expand All @@ -123,6 +133,8 @@ public function maybe_reset_oauth_token( $response ) {

// Reset the request headers, so that they include the new oauth token.
$this->current_request_args = $this->get_request_args();

$resetting = false;
}
}

Expand Down
73 changes: 37 additions & 36 deletions mu-plugins/utilities/class-meetup-oauth2-client.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function __construct() {
* See API_Client::tenacious_remote_request.
*/
'breaking_response_codes' => array(
400, // Bad request.
400, // Bad request. This happens for invalid_grant during refresh
401, // Unauthorized (invalid key).
429, // Too many requests (rate-limited).
404, // Unable to find group
Expand Down Expand Up @@ -219,48 +219,49 @@ public function get_oauth_token() {
return $this->oauth_token['access_token'];
}

// Get cached access token
$token = get_site_option( self::SITE_OPTION_KEY_OAUTH, array() );
$valid = $this->is_valid_token( $token, 'access_token' );

if ( ! $this->is_valid_token( $token, 'access_token' ) ) {

// At this point, we need to get a new oAuth done.
if ( empty( $_GET['code'] ) ) {
$_GET['code'] = get_site_option( self::SITE_OPTION_KEY_AUTHORIZATION, false );

if ( ! $_GET['code'] ) {
$message = sprintf(
"Meetup.com oAuth expired. Please access the following url while logged into the %s meetup.com account: \n\n%s\n\n" .
"For sites other than WordCamp Central, the ?code=... parameter will need to be stored on this site via wp-cli and this task run again: `wp --url=%s site option update '%s' '...'`",
self::EMAIL,
sprintf(
'https://secure.meetup.com/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=%s&state=meetup-oauth',
self::CONSUMER_KEY,
self::REDIRECT_URI
),
network_site_url('/'),
self::SITE_OPTION_KEY_AUTHORIZATION
);

if ( admin_url( '/' ) === self::REDIRECT_URI ) {
printf( '<div class="notice notice-error"><p>%s</p></div>', nl2br( make_clickable( $message ) ) );
}

trigger_error( $message, E_USER_WARNING );

return false;
// If it's a valid token, but expired, refresh it.
if ( $valid && $this->is_expired_token( $token ) ) {
$token = $this->request_token( 'refresh_token', $token );
$valid = $this->is_valid_token( $token, 'access_token' );
}

// If it's not a valid token, or the refresh token wasn't valid, check to see if we're able to fetch a new one.
if ( ! $valid ) {
$auth_code = $_GET['code'] ?? get_site_option( self::SITE_OPTION_KEY_AUTHORIZATION, false );

if ( $auth_code ) {
$token = $this->request_token( 'access_token', array( 'code' => $auth_code ) );
$valid = $this->is_valid_token( $token, 'access_token' );
if ( $valid ) {
delete_site_option( self::SITE_OPTION_KEY_AUTHORIZATION, false );
}
}
}

$token = $this->request_token( 'access_token', array( 'code' => $_GET['code'] ) );
// If we're unable to find a valid token, and we're not mid-refresh, throw a Warning & Notice.
if ( ! $valid ) {
$message = sprintf(
"Meetup.com oAuth expired. Please access the following url while logged into the %s meetup.com account: \n\n%s\n\n" .
"For sites other than WordCamp Central, the ?code=... parameter will need to be stored on this site via wp-cli and this task run again: `wp --url=%s site option update '%s' '...'`",
self::EMAIL,
sprintf(
'https://secure.meetup.com/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=%s&state=meetup-oauth',
self::CONSUMER_KEY,
self::REDIRECT_URI
),
network_site_url('/'),
self::SITE_OPTION_KEY_AUTHORIZATION
);

if ( $this->is_valid_token( $token, 'access_token' ) ) {
delete_site_option( self::SITE_OPTION_KEY_AUTHORIZATION, false );
if ( admin_url( '/' ) === self::REDIRECT_URI ) {
printf( '<div class="notice notice-error"><p>%s</p></div>', nl2br( make_clickable( $message ) ) );
}
} elseif ( $this->is_expired_token( $token ) ) {
$token = $this->request_token( 'refresh_token', $token );
}
trigger_error( $message, E_USER_WARNING );

if ( ! $this->is_valid_token( $token, 'access_token' ) ) {
return false;
}

Expand All @@ -283,7 +284,7 @@ public function get_oauth_token() {
public function reset_oauth_token() {
// NO. JUST NO. Do not delete the oAuth token.
// This is temporarily disabled while Meetup.com server-to-server authentication is unavailable.
// delete_site_option( self::SITE_OPTION_KEY_OAUTH );
delete_site_option( self::SITE_OPTION_KEY_OAUTH );

$this->oauth_token = array();
$this->error = new WP_Error();
Expand Down

0 comments on commit c5f9061

Please sign in to comment.