Plugin Directory

Changeset 2106748

Timestamp:
06/15/2019 09:01:16 PM (5 years ago)
Author:
beaulebens
Message:

Tagging v2.0

Location:
keyring
Files:
10 added
18 edited
1 copied

Legend:

Unmodified
Added
Removed
  • keyring/tags/2.0/includes/services/extended/google-analytics.php

    r1824012 r2106748  
    99 */
    1010
    11 class Keyring_Service_GoogleAnalytics extends Keyring_Service_OAuth2 {
     11class Keyring_Service_GoogleAnalytics extends Keyring_Service_ {
    1212    const NAME        = 'google-analytics';
    1313    const LABEL       = 'Google Analytics';
     
    1717    function __construct() {
    1818        parent::__construct();
    19 
    20         // Enable "basic" UI for entering key/secret
    21         if ( ! KEYRING__HEADLESS_MODE ) {
    22             add_action( 'keyring_google-analytics_manage_ui', array( $this, 'basic_ui' ) );
    23             add_filter( 'keyring_google-analytics_basic_ui_intro', array( $this, 'basic_ui_intro' ) );
    24         }
    25 
    26         $this->set_endpoint( 'authorize',    'https://accounts.google.com/o/oauth2/v2/auth',  'GET'  );
    27         $this->set_endpoint( 'access_token', 'https://www.googleapis.com/oauth2/v4/token',    'POST' );
    28         $this->set_endpoint( 'refresh',      'https://www.googleapis.com/oauth2/v4/token',    'POST' );
    29         $this->set_endpoint( 'userinfo',     'https://www.googleapis.com/oauth2/v3/userinfo', 'GET'  );
    30 
    31         $creds = $this->get_credentials();
    32         $this->redirect_uri = $creds['redirect_uri'];
    33         $this->key          = $creds['key'];
    34         $this->secret       = $creds['secret'];
    35 
    36         $this->authorization_header    = 'Bearer';
    37         $this->authorization_parameter = false;
    38 
    39         // Need to reset the callback because Google is very strict about where it sends people
    40         if ( !empty( $creds['redirect_uri'] ) ) {
    41             $this->callback_url = $creds['redirect_uri']; // Allow user to manually enter a redirect URI
    42         } else {
    43             $this->callback_url = remove_query_arg( array( 'nonce', 'kr_nonce' ), $this->callback_url ); // At least strip nonces, since you can't save them in your app config
    44         }
    45 
    46         add_filter( 'keyring_google-analytics_request_token_params', array( $this, 'request_token_params' ) );
    47         add_action( 'pre_keyring_google-analytics_verify', array( $this, 'redirect_incoming_verify' ) );
    48     }
    49 
    50     function basic_ui_intro() {
    51         echo '<p>' . sprintf( __( "Google controls access to all of their APIs through their API Console. <a href='%s'>Go to the Library page in the console</a> and click the <strong>Select a project</strong> dropdown next to the logo in the upper left of the screen. Click the <strong>plus icon</strong> to create a new project. Enter a name and then click <strong>Create</strong>.", 'keyring' ), 'https://console.developers.google.com/apis/library' ) . '</p>';
    52         echo '<p>' . __( "Now you need to enable the Analytics API and setup your OAuth credentials.", 'keyring' );
    53         echo '<ol>';
    54         echo '<li>' . __( "Select your project from the project dropdown.", 'keyring' ) . '</li>';
    55         echo '<li>' . __( "Click <strong>Library</strong> in the menu on the left.", 'keyring' ) . '</li>';
    56         echo '<li>' . __( "Find and click <strong>Analytics API</strong>.", 'keyring' ) . '</li>';
    57         echo '<li>' . __( "Next to the heading, click <strong>Enable</strong>.", 'keyring' ) . '</li>';
    58         echo '<li>' . __( "Click the blue button labelled <strong>Create credentials</strong>.", 'keyring' ) . '</li>';
    59         echo '<li>' . __( "Click <strong>Credential</strong> in the menu on the left.", 'keyring' ) . '</li>';
    60         echo '<li>' . __( "Click the <strong>OAuth consent screen</strong> menu item.", 'keyring' ) . '</li>';
    61         echo '<li>' . __( "You must enter a <strong>Product name</strong>, but you can skip the logo and home page URL.", 'keyring' ) . '</li>';
    62         echo '<li>' . __( "Click Save.", 'keyring' ) . '</li>';
    63         echo '<li>' . __( "Click the <strong>Create credentials</strong> button and select <strong>OAuth client ID</strong>.", 'keyring' ) . '</li>';
    64         echo '<li>' . __( "Select <strong>Web application</strong> and enter a relevant name or just use the default.", 'keyring' ) . '</li>';
    65         echo '<li>' . sprintf( __( "For the <strong>Authorized JavaScript Origins</strong>, enter the URL of your domain, e.g. <code>http://%s</code>.", 'keyring' ), $_SERVER['HTTP_HOST'] ) . '</li>';
    66         echo '<li>' . sprintf( __( "In the <strong>Authorized Redirect URIs</strong> box, enter the URL <code>%s</code>.", 'keyring' ), Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) ) ) . '</li>';
    67         echo '<li>' . __( "Click <strong>Create</strong> when you're done.", 'keyring' ) . '</li>';
    68         echo '</ol>';
    69         echo '<p>' . __( "Once you've saved your details, copy the <strong>Client ID</strong> into the <strong>Client ID</strong> field below, and the <strong>Client secret</strong> value into <strong>Client Secret</strong>. The Redirect URI box should fill itself out for you.", 'keyring' ) . '</p>';
    70 
    7119    }
    7220
     
    8634        }
    8735    }
    88 
    89     function request_token_params( $params ) {
    90         $params['scope'] = self::SCOPE;
    91         $params['access_type'] = self::ACCESS_TYPE;
    92         return $params;
    93     }
    94 
    95     function redirect_incoming_verify( $request ) {
    96         if ( ! isset( $request['kr_nonce'] ) ) {
    97             $kr_nonce = wp_create_nonce( 'keyring-verify' );
    98             $nonce    = wp_create_nonce( 'keyring-verify-' . $this->get_name() );
    99             wp_safe_redirect(
    100                 Keyring_Util::admin_url(
    101                     $this->get_name(),
    102                     array(
    103                         'action'   => 'verify',
    104                         'kr_nonce' => $kr_nonce,
    105                         'nonce'    => $nonce,
    106                         'state'    => $request['state'],
    107                         'code'     => $request['code'], // Auth code from successful response (maybe)
    108                     )
    109                 )
    110             );
    111             exit;
    112         }
    113     }
    114 
    115     function build_token_meta( $token ) {
    116         $meta = array(
    117             'refresh_token' => $token['refresh_token'],
    118             'expires'       => time() + $token['expires_in'],
    119         );
    120 
    121         $this->set_token(
    122             new Keyring_Access_Token(
    123                 $this->get_name(),
    124                 $token['access_token'],
    125                 array()
    126             )
    127         );
    128         $response = $this->request( $this->userinfo_url, array( 'method' => $this->userinfo_method ) );
    129         if ( ! Keyring_Util::is_error( $response ) ) {
    130             $meta['user_id'] = $response->sub;
    131             $meta['name']    = $response->name;
    132             $meta['picture'] = $response->picture;
    133         }
    134 
    135         return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, array(), $this );
    136     }
    137 
    138     function get_display( Keyring_Access_Token $token ) {
    139         return $token->get_meta( 'name' );
    140     }
    141 
    142     function maybe_refresh_token() {
    143         // Request a new token, using the refresh_token
    144         $token = $this->get_token();
    145         $meta  = $token->get_meta();
    146         if ( empty( $meta['refresh_token'] ) ) {
    147             return false;
    148         }
    149 
    150         // Don't refresh if token is valid
    151         if ( ! $token->is_expired( 20 ) ) {
    152             return;
    153         }
    154 
    155         $response = wp_remote_post( $this->refresh_url, array(
    156             'method' => $this->refresh_method,
    157             'body'   => array(
    158                 'client_id'     => $this->key,
    159                 'client_secret' => $this->secret,
    160                 'refresh_token' => $meta['refresh_token'],
    161                 'grant_type'    => 'refresh_token',
    162             ),
    163         ) );
    164 
    165         if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
    166             return false;
    167         }
    168 
    169         $return = json_decode( wp_remote_retrieve_body( $response ) );
    170         $meta['expires'] = time() + $return->expires_in;
    171 
    172         // Build access token
    173         $access_token = new Keyring_Access_Token(
    174             $this->get_name(),
    175             $return->access_token,
    176             $meta,
    177             $this->token->unique_id
    178         );
    179 
    180         // Store the updated access token
    181         $access_token = apply_filters( 'keyring_access_token', $access_token, $token );
    182         $id = $this->store->update( $access_token );
    183 
    184         // And switch to using it
    185         $this->set_token( $access_token );
    186     }
    187 
    188     // Need to potentially refresh token before each request
    189     function request( $url, array $params = array() ) {
    190         $this->maybe_refresh_token();
    191         return parent::request( $url, $params );
    192     }
    193 
    194     // Minor modifications from Keyring_Service::basic_ui
    195     function basic_ui() {
    196         if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'keyring-manage-' . $this->get_name() ) ) {
    197             Keyring::error( __( 'Invalid/missing management nonce.', 'keyring' ) );
    198             exit;
    199         }
    200 
    201         // Common Header
    202         echo '<div class="wrap">';
    203         echo '<h2>' . __( 'Keyring Service Management', 'keyring' ) . '</h2>';
    204         echo '<p><a href="' . Keyring_Util::admin_url( false, array( 'action' => 'services' ) ) . '">' . __( '&larr; Back', 'keyring' ) . '</a></p>';
    205         echo '<h3>' . sprintf( __( '%s API Credentials', 'keyring' ), esc_html( $this->get_label() ) ) . '</h3>';
    206 
    207         // Handle actually saving credentials
    208         if ( isset( $_POST['api_key'] ) && isset( $_POST['api_secret'] ) ) {
    209             // Store credentials against this service
    210             $this->update_credentials( array(
    211                 'key'          => stripslashes( $_POST['api_key'] ),
    212                 'secret'       => stripslashes( $_POST['api_secret'] ),
    213                 'redirect_uri' => stripslashes( $_POST['redirect_uri'] ),
    214             ) );
    215             echo '<div class="updated"><p>' . __( 'Credentials saved.', 'keyring' ) . '</p></div>';
    216         }
    217 
    218         $api_key = $api_secret = $redirect_uri = '';
    219         if ( $creds = $this->get_credentials() ) {
    220             $api_key      = $creds['key'];
    221             $api_secret   = $creds['secret'];
    222             $redirect_uri = $creds['redirect_uri'];
    223         }
    224 
    225         echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_intro', '' );
    226 
    227         if ( ! $redirect_uri ) {
    228             $redirect_uri = Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) );
    229         }
    230 
    231         // Output basic form for collecting key/secret
    232         echo '<form method="post" action="">';
    233         echo '<input type="hidden" name="service" value="' . esc_attr( $this->get_name() ) . '" />';
    234         echo '<input type="hidden" name="action" value="manage" />';
    235         wp_nonce_field( 'keyring-manage', 'kr_nonce', false );
    236         wp_nonce_field( 'keyring-manage-' . $this->get_name(), 'nonce', false );
    237         echo '<table class="form-table">';
    238         echo '<tr><th scope="row">' . __( 'Client ID', 'keyring' ) . '</th>';
    239         echo '<td><input type="text" name="api_key" value="' . esc_attr( $api_key ) . '" id="api_key" class="regular-text"></td></tr>';
    240         echo '<tr><th scope="row">' . __( 'Client Secret', 'keyring' ) . '</th>';
    241         echo '<td><input type="text" name="api_secret" value="' . esc_attr( $api_secret ) . '" id="api_secret" class="regular-text"></td></tr>';
    242         echo '<tr><th scope="row">' . __( 'Redirect URI', 'keyring' ) . '</th>';
    243         echo '<td><input type="text" name="redirect_uri" value="' . esc_attr( $redirect_uri ) . '" id="redirect_uri" class="regular-text"></td></tr>';
    244         echo '</table>';
    245         echo '<p class="submitbox">';
    246         echo '<input type="submit" name="submit" value="' . __( 'Save Changes', 'keyring' ) . '" id="submit" class="button-primary">';
    247         echo '<a href="' . esc_url( $_SERVER['HTTP_REFERER'] ) . '" class="submitdelete" style="margin-left:2em;">' . __( 'Cancel', 'keyring' ) . '</a>';
    248         echo '</p>';
    249         echo '</form>';
    250         echo '</div>';
    251     }
    252 
    253     function test_connection() {
    254         $res = $this->request( $this->userinfo_url, array( 'method' => $this->userinfo_method ) );
    255         if ( ! Keyring_Util::is_error( $res ) ) {
    256             return true;
    257         }
    258 
    259         return $res;
    260     }
    26136}
    26237
  • keyring/tags/2.0/includes/services/extended/google-contacts.php

    r1824012 r2106748  
    33/**
    44 * Google (Contacts) service definition for Keyring.
     5
    56 * Contacts API: https://developers.google.com/google-apps/contacts/v3/
    67 * OAuth implementation: https://developers.google.com/accounts/docs/OAuth2WebServer
     
    89 */
    910
    10 class Keyring_Service_GoogleContacts extends Keyring_Service_OAuth2 {
     11class Keyring_Service_GoogleContacts extends Keyring_Service_ {
    1112    const NAME        = 'google-contacts';
    1213    const LABEL       = 'Google Contacts';
     
    1415    const API_VERSION = '3.0';
    1516
    16     var $self_url     = '';
    17     var $self_method  = '';
    18 
    1917    function __construct() {
    2018        parent::__construct();
    21 
    22         // Enable "basic" UI for entering key/secret
    23         if ( ! KEYRING__HEADLESS_MODE ) {
    24             add_action( 'keyring_google-contacts_manage_ui', array( $this, 'basic_ui' ) );
    25             add_filter( 'keyring_google-contacts_basic_ui_intro', array( $this, 'basic_ui_intro' ) );
    26         }
    27 
    28         // Set scope
    29         add_filter( 'keyring_google-contacts_request_token_params', array( $this, 'request_token_params' ) );
    30 
    31         // Handle Google's annoying limitation of not allowing us to redirect to a dynamic URL
    32         add_action( 'pre_keyring_google-contacts_verify', array( $this, 'redirect_incoming_verify' ) );
    33 
    34         $this->set_endpoint( 'authorize',    'https://accounts.google.com/o/oauth2/auth',     'GET'  );
    35         $this->set_endpoint( 'access_token', 'https://accounts.google.com/o/oauth2/token',    'POST' );
    36         $this->set_endpoint( 'self',         'https://www.googleapis.com/oauth2/v1/userinfo', 'GET'  );
    37 
    38         $creds = $this->get_credentials();
    39         $this->redirect_uri = $creds['redirect_uri'];
    40         $this->key          = $creds['key'];
    41         $this->secret       = $creds['secret'];
    42 
    43         $this->authorization_header    = 'Bearer'; // Oh, you
    44         $this->authorization_parameter = false;
    45 
    46         // Need to reset the callback because Google is very strict about where it sends people
    47         if ( !empty( $creds['redirect_uri'] ) ) {
    48             $this->callback_url = $creds['redirect_uri']; // Allow user to manually enter a redirect URI
    49         } else {
    50             $this->callback_url = remove_query_arg( array( 'nonce', 'kr_nonce' ), $this->callback_url ); // At least strip nonces, since you can't save them in your app config
    51         }
    52     }
    53 
    54     function basic_ui_intro() {
    55         echo '<p>' . sprintf( __( "Google controls access to all of their APIs through their API Console. <a href='%s'>Go to the console</a> and click the project dropdown just under the logo in the upper left of the screen. Click <strong>Create&hellip;</strong> to create a new project. Enter a name and then click <strong>Create project</strong>. You don't technically need access to any of the additional APIs, but if you want to, then feel free to enable them", 'keyring' ), 'https://code.google.com/apis/console' ) . '</p>';
    56         echo '<p>' . __( "Now you need to set up an OAuth Client ID.", 'keyring' ) . '</p>';
    57         echo '<ol>';
    58         echo '<li>' . __( "Click <strong>API Access</strong> in the menu on the left.", 'keyring' ) . '</li>';
    59         echo '<li>' . __( "Click the big blue button labelled <strong>Create an OAuth 2.0 client ID&hellip;</strong>", 'keyring' ) . '</li>';
    60         echo '<li>' . __( "You must enter a <strong>Product name</strong>, but you can skip the logo and home page URL", 'keyring' ) . '</li>';
    61         echo '<li>' . __( "Leave the Application type set to <strong>Web application</strong>", 'keyring' ) . '</li>';
    62         echo '<li>' . __( "Next to <strong>Your site or hostname</strong>, click <strong>(more options)</strong>", 'keyring' ) . '</li>';
    63         echo '<li>' . sprintf( __( "In the <strong>Authorized Redirect URIs</strong> box, enter the URL <code>%s</code>", 'keyring' ), Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) ) ) . '</li>';
    64         echo '<li>' . sprintf( __( "For the <strong>Authorized JavaScript Origins</strong>, enter the URL of your domain, e.g. <code>http://%s</code>", 'keyring' ), $_SERVER['HTTP_HOST'] ) . '</li>';
    65         echo '<li>' . __( "Click <strong>Create client ID</strong> when you're done", 'keyring' ) . '</li>';
    66         echo '</ol>';
    67         echo '<p>' . __( "Once you've saved your details, copy the <strong>Client ID</strong> into the <strong>Client ID</strong> field below, and the <strong>Client secret</strong> value into <strong>Client Secret</strong>. The Redirect URI box should fill itself out for you.", 'keyring' ) . '</p>';
    6819    }
    6920
     
    8940    }
    9041
    91     function redirect_incoming_verify( $request ) {
    92         if ( !isset( $request['kr_nonce'] ) ) {
    93             // First request, from Google. Nonce it and move on.
    94             $kr_nonce = wp_create_nonce( 'keyring-verify' );
    95             $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() );
    96             wp_safe_redirect(
    97                 Keyring_Util::admin_url(
    98                     $this->get_name(),
    99                     array(
    100                         'action'   => 'verify',
    101                         'kr_nonce' => $kr_nonce,
    102                         'nonce'    => $nonce,
    103                         'state'    => $request['state'],
    104                         'code'     => $request['code'], // Auth code from successful response (maybe)
    105                     )
    106                 )
    107             );
    108             exit;
    109         }
    110     }
    111 
    112     function build_token_meta( $token ) {
    113         $meta = array();
    114         if ( !$token ) {
    115             return $meta;
    116         }
    117 
    118         $token = new Keyring_Access_Token( $this->get_name(), new OAuthToken( $token['access_token'], '' ), array() );
    119         $this->set_token( $token );
    120         $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) );
    121         if ( ! Keyring_Util::is_error( $response ) ) {
    122             $meta = array(
    123                 'user_id'   => $response->id,
    124                 'name'      => $response->name,
    125                 'profile'   => $response->link,
    126                 'picture'   => $response->picture,
    127             );
    128         }
    129 
    130         return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this );
    131     }
    132 
    133     function get_display( Keyring_Access_Token $token ) {
    134         return $token->get_meta( 'name' );
    135     }
    136 
    13742    function request( $url, array $params = array() ) {
    13843        // add header (version), required for all requests
    13944        $params['headers']['GData-Version'] = self::API_VERSION;
    140 
    14145        return parent::request( $url, $params );
    142     }
    143 
    144     // Minor modifications from Keyring_Service::basic_ui
    145     function basic_ui() {
    146         if ( !isset( $_REQUEST['nonce'] ) || !wp_verify_nonce( $_REQUEST['nonce'], 'keyring-manage-' . $this->get_name() ) ) {
    147             Keyring::error( __( 'Invalid/missing management nonce.', 'keyring' ) );
    148             exit;
    149         }
    150 
    151         // Common Header
    152         echo '<div class="wrap">';
    153         echo '<h2>' . __( 'Keyring Service Management', 'keyring' ) . '</h2>';
    154         echo '<p><a href="' . Keyring_Util::admin_url( false, array( 'action' => 'services' ) ) . '">' . __( '&larr; Back', 'keyring' ) . '</a></p>';
    155         echo '<h3>' . sprintf( __( '%s API Credentials', 'keyring' ), esc_html( $this->get_label() ) ) . '</h3>';
    156 
    157         // Handle actually saving credentials
    158         if ( isset( $_POST['api_key'] ) && isset( $_POST['api_secret'] ) ) {
    159             // Store credentials against this service
    160             $this->update_credentials( array(
    161                 'key'          => stripslashes( $_POST['api_key'] ),
    162                 'secret'       => stripslashes( $_POST['api_secret'] ),
    163                 'redirect_uri' => stripslashes( $_POST['redirect_uri'] ),
    164             ) );
    165             echo '<div class="updated"><p>' . __( 'Credentials saved.', 'keyring' ) . '</p></div>';
    166         }
    167 
    168         $api_key = $api_secret = $redirect_uri = '';
    169         if ( $creds = $this->get_credentials() ) {
    170             $api_key      = $creds['key'];
    171             $api_secret   = $creds['secret'];
    172             $redirect_uri = $creds['redirect_uri'];
    173         }
    174 
    175         echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_intro', '' );
    176 
    177         if ( ! $redirect_uri ) {
    178             $redirect_uri = Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) );
    179         }
    180 
    181         // Output basic form for collecting key/secret
    182         echo '<form method="post" action="">';
    183         echo '<input type="hidden" name="service" value="' . esc_attr( $this->get_name() ) . '" />';
    184         echo '<input type="hidden" name="action" value="manage" />';
    185         wp_nonce_field( 'keyring-manage', 'kr_nonce', false );
    186         wp_nonce_field( 'keyring-manage-' . $this->get_name(), 'nonce', false );
    187         echo '<table class="form-table">';
    188         echo '<tr><th scope="row">' . __( 'Client ID', 'keyring' ) . '</th>';
    189         echo '<td><input type="text" name="api_key" value="' . esc_attr( $api_key ) . '" id="api_key" class="regular-text"></td></tr>';
    190         echo '<tr><th scope="row">' . __( 'Client Secret', 'keyring' ) . '</th>';
    191         echo '<td><input type="text" name="api_secret" value="' . esc_attr( $api_secret ) . '" id="api_secret" class="regular-text"></td></tr>';
    192         echo '<tr><th scope="row">' . __( 'Redirect URI', 'keyring' ) . '</th>';
    193         echo '<td><input type="text" name="redirect_uri" value="' . esc_attr( $redirect_uri ) . '" id="redirect_uri" class="regular-text"></td></tr>';
    194         echo '</table>';
    195         echo '<p class="submitbox">';
    196         echo '<input type="submit" name="submit" value="' . __( 'Save Changes', 'keyring' ) . '" id="submit" class="button-primary">';
    197         echo '<a href="' . esc_url( $_SERVER['HTTP_REFERER'] ) . '" class="submitdelete" style="margin-left:2em;">' . __( 'Cancel', 'keyring' ) . '</a>';
    198         echo '</p>';
    199         echo '</form>';
    200         echo '</div>';
    201     }
    202 
    203     function test_connection() {
    204         $res = $this->request( $this->self_url, array( 'method' => $this->self_method ) );
    205         if ( ! Keyring_Util::is_error( $res ) ) {
    206             return true;
    207         }
    208 
    209         return $res;
    21046    }
    21147}
  • keyring/tags/2.0/includes/services/extended/nest.php

    r1638335 r2106748  
    2121        $this->set_endpoint( 'authorize',    'https://home.nest.com/login/oauth2',            'GET'  );
    2222        $this->set_endpoint( 'access_token', 'https://api.home.nest.com/oauth2/access_token', 'POST' );
    23         $this->set_endpoint( 'self',         'https://developer-api.nest.com/',                'GET'  );
     23        $this->set_endpoint( 'self',         'https://developer-api.nest.com/',               'GET'  );
    2424
    2525        $creds = $this->get_credentials();
     
    3030        $this->authorization_header = 'Bearer';
    3131
     32
     33
     34
     35
    3236        // Nest ignores our redirect_uri, and just redirects back to a static URI
    3337        add_action( 'pre_keyring_nest_verify', array( $this, 'redirect_incoming_verify' ) );
     
    3640    function redirect_incoming_verify( $request ) {
    3741        if ( ! isset( $request['kr_nonce'] ) ) {
    38             // First request, from Pinterest. Nonce it and move on.
     42            // First request, from est. Nonce it and move on.
    3943            $kr_nonce = wp_create_nonce( 'keyring-verify' );
    4044            $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() );
  • keyring/tags/2.0/includes/services/extended/strava.php

    r1824012 r2106748  
    5656
    5757            if ( ! Keyring_Util::is_error( $profile ) ) {
    58                 $meta['firstname']  = $profile->firstname;
    59                 $meta['lastname']   = $profile->lastname;
    60                 $meta['picture']    = $profile->profile;
    61                 $meta['first_date'] = $profile->created_at; // Capture the athlete's profile creation date for later use, eg: in keyring-social-importers
     58                // Somehow "username" can be "null" in the Strava data model, so then we use a concat of first_name + last_name
     59                $meta['name'] = '';
     60                if ( empty( $profile->username ) ) {
     61                    if ( ! empty( $profile->firstname ) ) {
     62                        $meta['name'] .= $profile->firstname;
     63                    }
     64                    if ( ! empty( $profile->lastname ) ) {
     65                        $meta['name'] .= ' ' . $profile->lastname;
     66                    }
     67                    $meta['name'] = trim( $meta['name'] );
     68                } else {
     69                    $meta['name'] = $profile->username;
     70                }
     71                $meta['first_name']  = $profile->firstname;
     72                $meta['last_name']   = $profile->lastname;
     73                $meta['picture']     = $profile->profile;
     74                $meta['first_date']  = $profile->created_at; // Capture the athlete's profile creation date for later use, eg: in keyring-social-importers
    6275            }
    6376
  • keyring/tags/2.0/includes/services/extended/twitter.php

    r1638335 r2106748  
    3838
    3939    function basic_ui_intro() {
    40         echo '<p>' . sprintf( __( 'If you haven\'t already, you\'ll need to <a href="%1$s">create an app on Twitter</a> (log in using your normal Twitter account). Make sure you enter something for the <strong>Callback URL</strong>, even though Keyring will override it with the correct value. Just enter your homepage, e.g. <code>%2$s</code>.', 'keyring' ), 'https://apps.twitter.com/app/new', get_bloginfo( 'url' ) ) . '</p>';
     40' ) ) . '</p>';
    4141        echo '<p>' . __( "Once you've created an app, copy and paste your <strong>Consumer key</strong> and <strong>Consumer secret</strong> (from under the <strong>OAuth settings</strong> section of your app's details) into the boxes below. You don't need an App ID for Twitter.", 'keyring' ) . '</p>';
    4242    }
  • keyring/tags/2.0/keyring.php

    r1824012 r2106748  
    44Plugin URI: http://dentedreality.com.au/projects/wp-keyring/
    55Description: Keyring helps you manage your keys. It provides a generic, very hookable framework for connecting to remote systems and managing your access tokens, username/password combos etc for those services. On its own it doesn't do much, but it enables other plugins to do things that require authorization to act on your behalf.
    6 Version: 1.9
     6Version:
    77Author: Beau Lebens
    88Author URI: http://dentedreality.com.au
     
    2727
    2828// Indicates Keyring is installed/active so that other plugins can detect it
    29 define( 'KEYRING__VERSION', '1.9' );
     29define( 'KEYRING__VERSION', '' );
    3030
    3131/**
     
    198198        $keyring = Keyring::init();
    199199        $keyring->errors[] = $str;
    200         do_action( 'keyring_error', $str, $info, isset( $this ) ? $this : null );
     200        do_action( 'keyring_error', $str, $info );
    201201        if ( $die ) {
    202202            wp_die( $str, __( 'Keyring Error', 'keyring' ) );
  • keyring/tags/2.0/readme.txt

    r1824012 r2106748  
    44Tags: authentication, security, oauth, http basic, authorization, facebook, foursquare, instagram, twitter, google
    55Requires at least: 4.0
    6 Tested up to: 4.9.4
    7 Stable Tag: 1.9
     6Tested up to:
     7Stable Tag:
    88
    99An authentication framework that handles authorization/communication with most popular web services.
     
    3030* [Flickr](https://flickr.com/)
    3131* [Foursquare](https://foursquare.com/)
    32 * [Google Analytics](https://developers.google.com/analytics/devguides/reporting/core/v4/)
    33 * [Google Contacts](https://developers.google.com/google-apps/contacts/v3/)
     32* [Google Analytics](https://www.google.com/analytics/)
     33* [Google Contacts](https://www.google.com/contacts/)
     34* [Google Mail](https://www.google.com/mail/)
    3435* [Instagram](https://instagram.com/)
    3536* [Instapaper](https://instapaper.com/)
     
    4546* [Twitter](https://twitter.com/)
    4647* [Yahoo! Updates](https://yahoo.com/)
     48
    4749
    4850You can very easily write your own Service definitions and then use all the power of Keyring to hook into that authentication flow. See the [Keyring Developer's Guide](http://dentedreality.com.au/projects/wp-keyring/) for more details.
     
    103105
    104106== Changelog ==
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
    105118
    106119= 1.9 =
  • keyring/tags/2.0/service.php

    r1824012 r2106748  
    326326$keyring_services = apply_filters( 'keyring_services', $keyring_services );
    327327foreach ( $keyring_services as $keyring_service )
    328     require $keyring_service;
     328    require $keyring_service;
    329329unset( $keyring_services, $keyring_service );
  • keyring/tags/2.0/token.php

    r634448 r2106748  
    9595    **/
    9696    function is_expired( $window = 0 ) {
    97         if ( !$expires = $this->get_meta( 'expires' ) )
     97        if ( !
    9898            return false; // No expires value, assume it's a permanent token
     99
    99100
    100         if ( '0000-00-00 00:00:00' == $expires )
     101        if ( '0000-00-00 00:00:00' == $expires )
    101102            return false; // Doesn't expire
     103
    102104
    103         if ( ( time() + $window ) > strtotime( $expires ) )
     105        if ( (
    104106            return true; // Token's expiry time has passed, or will pass before $window
     107
    105108
    106109        // Not expired
  • keyring/trunk/includes/services/extended/google-analytics.php

    r1824012 r2106748  
    99 */
    1010
    11 class Keyring_Service_GoogleAnalytics extends Keyring_Service_OAuth2 {
     11class Keyring_Service_GoogleAnalytics extends Keyring_Service_ {
    1212    const NAME        = 'google-analytics';
    1313    const LABEL       = 'Google Analytics';
     
    1717    function __construct() {
    1818        parent::__construct();
    19 
    20         // Enable "basic" UI for entering key/secret
    21         if ( ! KEYRING__HEADLESS_MODE ) {
    22             add_action( 'keyring_google-analytics_manage_ui', array( $this, 'basic_ui' ) );
    23             add_filter( 'keyring_google-analytics_basic_ui_intro', array( $this, 'basic_ui_intro' ) );
    24         }
    25 
    26         $this->set_endpoint( 'authorize',    'https://accounts.google.com/o/oauth2/v2/auth',  'GET'  );
    27         $this->set_endpoint( 'access_token', 'https://www.googleapis.com/oauth2/v4/token',    'POST' );
    28         $this->set_endpoint( 'refresh',      'https://www.googleapis.com/oauth2/v4/token',    'POST' );
    29         $this->set_endpoint( 'userinfo',     'https://www.googleapis.com/oauth2/v3/userinfo', 'GET'  );
    30 
    31         $creds = $this->get_credentials();
    32         $this->redirect_uri = $creds['redirect_uri'];
    33         $this->key          = $creds['key'];
    34         $this->secret       = $creds['secret'];
    35 
    36         $this->authorization_header    = 'Bearer';
    37         $this->authorization_parameter = false;
    38 
    39         // Need to reset the callback because Google is very strict about where it sends people
    40         if ( !empty( $creds['redirect_uri'] ) ) {
    41             $this->callback_url = $creds['redirect_uri']; // Allow user to manually enter a redirect URI
    42         } else {
    43             $this->callback_url = remove_query_arg( array( 'nonce', 'kr_nonce' ), $this->callback_url ); // At least strip nonces, since you can't save them in your app config
    44         }
    45 
    46         add_filter( 'keyring_google-analytics_request_token_params', array( $this, 'request_token_params' ) );
    47         add_action( 'pre_keyring_google-analytics_verify', array( $this, 'redirect_incoming_verify' ) );
    48     }
    49 
    50     function basic_ui_intro() {
    51         echo '<p>' . sprintf( __( "Google controls access to all of their APIs through their API Console. <a href='%s'>Go to the Library page in the console</a> and click the <strong>Select a project</strong> dropdown next to the logo in the upper left of the screen. Click the <strong>plus icon</strong> to create a new project. Enter a name and then click <strong>Create</strong>.", 'keyring' ), 'https://console.developers.google.com/apis/library' ) . '</p>';
    52         echo '<p>' . __( "Now you need to enable the Analytics API and setup your OAuth credentials.", 'keyring' );
    53         echo '<ol>';
    54         echo '<li>' . __( "Select your project from the project dropdown.", 'keyring' ) . '</li>';
    55         echo '<li>' . __( "Click <strong>Library</strong> in the menu on the left.", 'keyring' ) . '</li>';
    56         echo '<li>' . __( "Find and click <strong>Analytics API</strong>.", 'keyring' ) . '</li>';
    57         echo '<li>' . __( "Next to the heading, click <strong>Enable</strong>.", 'keyring' ) . '</li>';
    58         echo '<li>' . __( "Click the blue button labelled <strong>Create credentials</strong>.", 'keyring' ) . '</li>';
    59         echo '<li>' . __( "Click <strong>Credential</strong> in the menu on the left.", 'keyring' ) . '</li>';
    60         echo '<li>' . __( "Click the <strong>OAuth consent screen</strong> menu item.", 'keyring' ) . '</li>';
    61         echo '<li>' . __( "You must enter a <strong>Product name</strong>, but you can skip the logo and home page URL.", 'keyring' ) . '</li>';
    62         echo '<li>' . __( "Click Save.", 'keyring' ) . '</li>';
    63         echo '<li>' . __( "Click the <strong>Create credentials</strong> button and select <strong>OAuth client ID</strong>.", 'keyring' ) . '</li>';
    64         echo '<li>' . __( "Select <strong>Web application</strong> and enter a relevant name or just use the default.", 'keyring' ) . '</li>';
    65         echo '<li>' . sprintf( __( "For the <strong>Authorized JavaScript Origins</strong>, enter the URL of your domain, e.g. <code>http://%s</code>.", 'keyring' ), $_SERVER['HTTP_HOST'] ) . '</li>';
    66         echo '<li>' . sprintf( __( "In the <strong>Authorized Redirect URIs</strong> box, enter the URL <code>%s</code>.", 'keyring' ), Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) ) ) . '</li>';
    67         echo '<li>' . __( "Click <strong>Create</strong> when you're done.", 'keyring' ) . '</li>';
    68         echo '</ol>';
    69         echo '<p>' . __( "Once you've saved your details, copy the <strong>Client ID</strong> into the <strong>Client ID</strong> field below, and the <strong>Client secret</strong> value into <strong>Client Secret</strong>. The Redirect URI box should fill itself out for you.", 'keyring' ) . '</p>';
    70 
    7119    }
    7220
     
    8634        }
    8735    }
    88 
    89     function request_token_params( $params ) {
    90         $params['scope'] = self::SCOPE;
    91         $params['access_type'] = self::ACCESS_TYPE;
    92         return $params;
    93     }
    94 
    95     function redirect_incoming_verify( $request ) {
    96         if ( ! isset( $request['kr_nonce'] ) ) {
    97             $kr_nonce = wp_create_nonce( 'keyring-verify' );
    98             $nonce    = wp_create_nonce( 'keyring-verify-' . $this->get_name() );
    99             wp_safe_redirect(
    100                 Keyring_Util::admin_url(
    101                     $this->get_name(),
    102                     array(
    103                         'action'   => 'verify',
    104                         'kr_nonce' => $kr_nonce,
    105                         'nonce'    => $nonce,
    106                         'state'    => $request['state'],
    107                         'code'     => $request['code'], // Auth code from successful response (maybe)
    108                     )
    109                 )
    110             );
    111             exit;
    112         }
    113     }
    114 
    115     function build_token_meta( $token ) {
    116         $meta = array(
    117             'refresh_token' => $token['refresh_token'],
    118             'expires'       => time() + $token['expires_in'],
    119         );
    120 
    121         $this->set_token(
    122             new Keyring_Access_Token(
    123                 $this->get_name(),
    124                 $token['access_token'],
    125                 array()
    126             )
    127         );
    128         $response = $this->request( $this->userinfo_url, array( 'method' => $this->userinfo_method ) );
    129         if ( ! Keyring_Util::is_error( $response ) ) {
    130             $meta['user_id'] = $response->sub;
    131             $meta['name']    = $response->name;
    132             $meta['picture'] = $response->picture;
    133         }
    134 
    135         return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, array(), $this );
    136     }
    137 
    138     function get_display( Keyring_Access_Token $token ) {
    139         return $token->get_meta( 'name' );
    140     }
    141 
    142     function maybe_refresh_token() {
    143         // Request a new token, using the refresh_token
    144         $token = $this->get_token();
    145         $meta  = $token->get_meta();
    146         if ( empty( $meta['refresh_token'] ) ) {
    147             return false;
    148         }
    149 
    150         // Don't refresh if token is valid
    151         if ( ! $token->is_expired( 20 ) ) {
    152             return;
    153         }
    154 
    155         $response = wp_remote_post( $this->refresh_url, array(
    156             'method' => $this->refresh_method,
    157             'body'   => array(
    158                 'client_id'     => $this->key,
    159                 'client_secret' => $this->secret,
    160                 'refresh_token' => $meta['refresh_token'],
    161                 'grant_type'    => 'refresh_token',
    162             ),
    163         ) );
    164 
    165         if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
    166             return false;
    167         }
    168 
    169         $return = json_decode( wp_remote_retrieve_body( $response ) );
    170         $meta['expires'] = time() + $return->expires_in;
    171 
    172         // Build access token
    173         $access_token = new Keyring_Access_Token(
    174             $this->get_name(),
    175             $return->access_token,
    176             $meta,
    177             $this->token->unique_id
    178         );
    179 
    180         // Store the updated access token
    181         $access_token = apply_filters( 'keyring_access_token', $access_token, $token );
    182         $id = $this->store->update( $access_token );
    183 
    184         // And switch to using it
    185         $this->set_token( $access_token );
    186     }
    187 
    188     // Need to potentially refresh token before each request
    189     function request( $url, array $params = array() ) {
    190         $this->maybe_refresh_token();
    191         return parent::request( $url, $params );
    192     }
    193 
    194     // Minor modifications from Keyring_Service::basic_ui
    195     function basic_ui() {
    196         if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'keyring-manage-' . $this->get_name() ) ) {
    197             Keyring::error( __( 'Invalid/missing management nonce.', 'keyring' ) );
    198             exit;
    199         }
    200 
    201         // Common Header
    202         echo '<div class="wrap">';
    203         echo '<h2>' . __( 'Keyring Service Management', 'keyring' ) . '</h2>';
    204         echo '<p><a href="' . Keyring_Util::admin_url( false, array( 'action' => 'services' ) ) . '">' . __( '&larr; Back', 'keyring' ) . '</a></p>';
    205         echo '<h3>' . sprintf( __( '%s API Credentials', 'keyring' ), esc_html( $this->get_label() ) ) . '</h3>';
    206 
    207         // Handle actually saving credentials
    208         if ( isset( $_POST['api_key'] ) && isset( $_POST['api_secret'] ) ) {
    209             // Store credentials against this service
    210             $this->update_credentials( array(
    211                 'key'          => stripslashes( $_POST['api_key'] ),
    212                 'secret'       => stripslashes( $_POST['api_secret'] ),
    213                 'redirect_uri' => stripslashes( $_POST['redirect_uri'] ),
    214             ) );
    215             echo '<div class="updated"><p>' . __( 'Credentials saved.', 'keyring' ) . '</p></div>';
    216         }
    217 
    218         $api_key = $api_secret = $redirect_uri = '';
    219         if ( $creds = $this->get_credentials() ) {
    220             $api_key      = $creds['key'];
    221             $api_secret   = $creds['secret'];
    222             $redirect_uri = $creds['redirect_uri'];
    223         }
    224 
    225         echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_intro', '' );
    226 
    227         if ( ! $redirect_uri ) {
    228             $redirect_uri = Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) );
    229         }
    230 
    231         // Output basic form for collecting key/secret
    232         echo '<form method="post" action="">';
    233         echo '<input type="hidden" name="service" value="' . esc_attr( $this->get_name() ) . '" />';
    234         echo '<input type="hidden" name="action" value="manage" />';
    235         wp_nonce_field( 'keyring-manage', 'kr_nonce', false );
    236         wp_nonce_field( 'keyring-manage-' . $this->get_name(), 'nonce', false );
    237         echo '<table class="form-table">';
    238         echo '<tr><th scope="row">' . __( 'Client ID', 'keyring' ) . '</th>';
    239         echo '<td><input type="text" name="api_key" value="' . esc_attr( $api_key ) . '" id="api_key" class="regular-text"></td></tr>';
    240         echo '<tr><th scope="row">' . __( 'Client Secret', 'keyring' ) . '</th>';
    241         echo '<td><input type="text" name="api_secret" value="' . esc_attr( $api_secret ) . '" id="api_secret" class="regular-text"></td></tr>';
    242         echo '<tr><th scope="row">' . __( 'Redirect URI', 'keyring' ) . '</th>';
    243         echo '<td><input type="text" name="redirect_uri" value="' . esc_attr( $redirect_uri ) . '" id="redirect_uri" class="regular-text"></td></tr>';
    244         echo '</table>';
    245         echo '<p class="submitbox">';
    246         echo '<input type="submit" name="submit" value="' . __( 'Save Changes', 'keyring' ) . '" id="submit" class="button-primary">';
    247         echo '<a href="' . esc_url( $_SERVER['HTTP_REFERER'] ) . '" class="submitdelete" style="margin-left:2em;">' . __( 'Cancel', 'keyring' ) . '</a>';
    248         echo '</p>';
    249         echo '</form>';
    250         echo '</div>';
    251     }
    252 
    253     function test_connection() {
    254         $res = $this->request( $this->userinfo_url, array( 'method' => $this->userinfo_method ) );
    255         if ( ! Keyring_Util::is_error( $res ) ) {
    256             return true;
    257         }
    258 
    259         return $res;
    260     }
    26136}
    26237
  • keyring/trunk/includes/services/extended/google-contacts.php

    r1824012 r2106748  
    33/**
    44 * Google (Contacts) service definition for Keyring.
     5
    56 * Contacts API: https://developers.google.com/google-apps/contacts/v3/
    67 * OAuth implementation: https://developers.google.com/accounts/docs/OAuth2WebServer
     
    89 */
    910
    10 class Keyring_Service_GoogleContacts extends Keyring_Service_OAuth2 {
     11class Keyring_Service_GoogleContacts extends Keyring_Service_ {
    1112    const NAME        = 'google-contacts';
    1213    const LABEL       = 'Google Contacts';
     
    1415    const API_VERSION = '3.0';
    1516
    16     var $self_url     = '';
    17     var $self_method  = '';
    18 
    1917    function __construct() {
    2018        parent::__construct();
    21 
    22         // Enable "basic" UI for entering key/secret
    23         if ( ! KEYRING__HEADLESS_MODE ) {
    24             add_action( 'keyring_google-contacts_manage_ui', array( $this, 'basic_ui' ) );
    25             add_filter( 'keyring_google-contacts_basic_ui_intro', array( $this, 'basic_ui_intro' ) );
    26         }
    27 
    28         // Set scope
    29         add_filter( 'keyring_google-contacts_request_token_params', array( $this, 'request_token_params' ) );
    30 
    31         // Handle Google's annoying limitation of not allowing us to redirect to a dynamic URL
    32         add_action( 'pre_keyring_google-contacts_verify', array( $this, 'redirect_incoming_verify' ) );
    33 
    34         $this->set_endpoint( 'authorize',    'https://accounts.google.com/o/oauth2/auth',     'GET'  );
    35         $this->set_endpoint( 'access_token', 'https://accounts.google.com/o/oauth2/token',    'POST' );
    36         $this->set_endpoint( 'self',         'https://www.googleapis.com/oauth2/v1/userinfo', 'GET'  );
    37 
    38         $creds = $this->get_credentials();
    39         $this->redirect_uri = $creds['redirect_uri'];
    40         $this->key          = $creds['key'];
    41         $this->secret       = $creds['secret'];
    42 
    43         $this->authorization_header    = 'Bearer'; // Oh, you
    44         $this->authorization_parameter = false;
    45 
    46         // Need to reset the callback because Google is very strict about where it sends people
    47         if ( !empty( $creds['redirect_uri'] ) ) {
    48             $this->callback_url = $creds['redirect_uri']; // Allow user to manually enter a redirect URI
    49         } else {
    50             $this->callback_url = remove_query_arg( array( 'nonce', 'kr_nonce' ), $this->callback_url ); // At least strip nonces, since you can't save them in your app config
    51         }
    52     }
    53 
    54     function basic_ui_intro() {
    55         echo '<p>' . sprintf( __( "Google controls access to all of their APIs through their API Console. <a href='%s'>Go to the console</a> and click the project dropdown just under the logo in the upper left of the screen. Click <strong>Create&hellip;</strong> to create a new project. Enter a name and then click <strong>Create project</strong>. You don't technically need access to any of the additional APIs, but if you want to, then feel free to enable them", 'keyring' ), 'https://code.google.com/apis/console' ) . '</p>';
    56         echo '<p>' . __( "Now you need to set up an OAuth Client ID.", 'keyring' ) . '</p>';
    57         echo '<ol>';
    58         echo '<li>' . __( "Click <strong>API Access</strong> in the menu on the left.", 'keyring' ) . '</li>';
    59         echo '<li>' . __( "Click the big blue button labelled <strong>Create an OAuth 2.0 client ID&hellip;</strong>", 'keyring' ) . '</li>';
    60         echo '<li>' . __( "You must enter a <strong>Product name</strong>, but you can skip the logo and home page URL", 'keyring' ) . '</li>';
    61         echo '<li>' . __( "Leave the Application type set to <strong>Web application</strong>", 'keyring' ) . '</li>';
    62         echo '<li>' . __( "Next to <strong>Your site or hostname</strong>, click <strong>(more options)</strong>", 'keyring' ) . '</li>';
    63         echo '<li>' . sprintf( __( "In the <strong>Authorized Redirect URIs</strong> box, enter the URL <code>%s</code>", 'keyring' ), Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) ) ) . '</li>';
    64         echo '<li>' . sprintf( __( "For the <strong>Authorized JavaScript Origins</strong>, enter the URL of your domain, e.g. <code>http://%s</code>", 'keyring' ), $_SERVER['HTTP_HOST'] ) . '</li>';
    65         echo '<li>' . __( "Click <strong>Create client ID</strong> when you're done", 'keyring' ) . '</li>';
    66         echo '</ol>';
    67         echo '<p>' . __( "Once you've saved your details, copy the <strong>Client ID</strong> into the <strong>Client ID</strong> field below, and the <strong>Client secret</strong> value into <strong>Client Secret</strong>. The Redirect URI box should fill itself out for you.", 'keyring' ) . '</p>';
    6819    }
    6920
     
    8940    }
    9041
    91     function redirect_incoming_verify( $request ) {
    92         if ( !isset( $request['kr_nonce'] ) ) {
    93             // First request, from Google. Nonce it and move on.
    94             $kr_nonce = wp_create_nonce( 'keyring-verify' );
    95             $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() );
    96             wp_safe_redirect(
    97                 Keyring_Util::admin_url(
    98                     $this->get_name(),
    99                     array(
    100                         'action'   => 'verify',
    101                         'kr_nonce' => $kr_nonce,
    102                         'nonce'    => $nonce,
    103                         'state'    => $request['state'],
    104                         'code'     => $request['code'], // Auth code from successful response (maybe)
    105                     )
    106                 )
    107             );
    108             exit;
    109         }
    110     }
    111 
    112     function build_token_meta( $token ) {
    113         $meta = array();
    114         if ( !$token ) {
    115             return $meta;
    116         }
    117 
    118         $token = new Keyring_Access_Token( $this->get_name(), new OAuthToken( $token['access_token'], '' ), array() );
    119         $this->set_token( $token );
    120         $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) );
    121         if ( ! Keyring_Util::is_error( $response ) ) {
    122             $meta = array(
    123                 'user_id'   => $response->id,
    124                 'name'      => $response->name,
    125                 'profile'   => $response->link,
    126                 'picture'   => $response->picture,
    127             );
    128         }
    129 
    130         return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this );
    131     }
    132 
    133     function get_display( Keyring_Access_Token $token ) {
    134         return $token->get_meta( 'name' );
    135     }
    136 
    13742    function request( $url, array $params = array() ) {
    13843        // add header (version), required for all requests
    13944        $params['headers']['GData-Version'] = self::API_VERSION;
    140 
    14145        return parent::request( $url, $params );
    142     }
    143 
    144     // Minor modifications from Keyring_Service::basic_ui
    145     function basic_ui() {
    146         if ( !isset( $_REQUEST['nonce'] ) || !wp_verify_nonce( $_REQUEST['nonce'], 'keyring-manage-' . $this->get_name() ) ) {
    147             Keyring::error( __( 'Invalid/missing management nonce.', 'keyring' ) );
    148             exit;
    149         }
    150 
    151         // Common Header
    152         echo '<div class="wrap">';
    153         echo '<h2>' . __( 'Keyring Service Management', 'keyring' ) . '</h2>';
    154         echo '<p><a href="' . Keyring_Util::admin_url( false, array( 'action' => 'services' ) ) . '">' . __( '&larr; Back', 'keyring' ) . '</a></p>';
    155         echo '<h3>' . sprintf( __( '%s API Credentials', 'keyring' ), esc_html( $this->get_label() ) ) . '</h3>';
    156 
    157         // Handle actually saving credentials
    158         if ( isset( $_POST['api_key'] ) && isset( $_POST['api_secret'] ) ) {
    159             // Store credentials against this service
    160             $this->update_credentials( array(
    161                 'key'          => stripslashes( $_POST['api_key'] ),
    162                 'secret'       => stripslashes( $_POST['api_secret'] ),
    163                 'redirect_uri' => stripslashes( $_POST['redirect_uri'] ),
    164             ) );
    165             echo '<div class="updated"><p>' . __( 'Credentials saved.', 'keyring' ) . '</p></div>';
    166         }
    167 
    168         $api_key = $api_secret = $redirect_uri = '';
    169         if ( $creds = $this->get_credentials() ) {
    170             $api_key      = $creds['key'];
    171             $api_secret   = $creds['secret'];
    172             $redirect_uri = $creds['redirect_uri'];
    173         }
    174 
    175         echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_intro', '' );
    176 
    177         if ( ! $redirect_uri ) {
    178             $redirect_uri = Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) );
    179         }
    180 
    181         // Output basic form for collecting key/secret
    182         echo '<form method="post" action="">';
    183         echo '<input type="hidden" name="service" value="' . esc_attr( $this->get_name() ) . '" />';
    184         echo '<input type="hidden" name="action" value="manage" />';
    185         wp_nonce_field( 'keyring-manage', 'kr_nonce', false );
    186         wp_nonce_field( 'keyring-manage-' . $this->get_name(), 'nonce', false );
    187         echo '<table class="form-table">';
    188         echo '<tr><th scope="row">' . __( 'Client ID', 'keyring' ) . '</th>';
    189         echo '<td><input type="text" name="api_key" value="' . esc_attr( $api_key ) . '" id="api_key" class="regular-text"></td></tr>';
    190         echo '<tr><th scope="row">' . __( 'Client Secret', 'keyring' ) . '</th>';
    191         echo '<td><input type="text" name="api_secret" value="' . esc_attr( $api_secret ) . '" id="api_secret" class="regular-text"></td></tr>';
    192         echo '<tr><th scope="row">' . __( 'Redirect URI', 'keyring' ) . '</th>';
    193         echo '<td><input type="text" name="redirect_uri" value="' . esc_attr( $redirect_uri ) . '" id="redirect_uri" class="regular-text"></td></tr>';
    194         echo '</table>';
    195         echo '<p class="submitbox">';
    196         echo '<input type="submit" name="submit" value="' . __( 'Save Changes', 'keyring' ) . '" id="submit" class="button-primary">';
    197         echo '<a href="' . esc_url( $_SERVER['HTTP_REFERER'] ) . '" class="submitdelete" style="margin-left:2em;">' . __( 'Cancel', 'keyring' ) . '</a>';
    198         echo '</p>';
    199         echo '</form>';
    200         echo '</div>';
    201     }
    202 
    203     function test_connection() {
    204         $res = $this->request( $this->self_url, array( 'method' => $this->self_method ) );
    205         if ( ! Keyring_Util::is_error( $res ) ) {
    206             return true;
    207         }
    208 
    209         return $res;
    21046    }
    21147}
  • keyring/trunk/includes/services/extended/nest.php

    r1638335 r2106748  
    2121        $this->set_endpoint( 'authorize',    'https://home.nest.com/login/oauth2',            'GET'  );
    2222        $this->set_endpoint( 'access_token', 'https://api.home.nest.com/oauth2/access_token', 'POST' );
    23         $this->set_endpoint( 'self',         'https://developer-api.nest.com/',                'GET'  );
     23        $this->set_endpoint( 'self',         'https://developer-api.nest.com/',               'GET'  );
    2424
    2525        $creds = $this->get_credentials();
     
    3030        $this->authorization_header = 'Bearer';
    3131
     32
     33
     34
     35
    3236        // Nest ignores our redirect_uri, and just redirects back to a static URI
    3337        add_action( 'pre_keyring_nest_verify', array( $this, 'redirect_incoming_verify' ) );
     
    3640    function redirect_incoming_verify( $request ) {
    3741        if ( ! isset( $request['kr_nonce'] ) ) {
    38             // First request, from Pinterest. Nonce it and move on.
     42            // First request, from est. Nonce it and move on.
    3943            $kr_nonce = wp_create_nonce( 'keyring-verify' );
    4044            $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() );
  • keyring/trunk/includes/services/extended/strava.php

    r1824012 r2106748  
    5656
    5757            if ( ! Keyring_Util::is_error( $profile ) ) {
    58                 $meta['firstname']  = $profile->firstname;
    59                 $meta['lastname']   = $profile->lastname;
    60                 $meta['picture']    = $profile->profile;
    61                 $meta['first_date'] = $profile->created_at; // Capture the athlete's profile creation date for later use, eg: in keyring-social-importers
     58                // Somehow "username" can be "null" in the Strava data model, so then we use a concat of first_name + last_name
     59                $meta['name'] = '';
     60                if ( empty( $profile->username ) ) {
     61                    if ( ! empty( $profile->firstname ) ) {
     62                        $meta['name'] .= $profile->firstname;
     63                    }
     64                    if ( ! empty( $profile->lastname ) ) {
     65                        $meta['name'] .= ' ' . $profile->lastname;
     66                    }
     67                    $meta['name'] = trim( $meta['name'] );
     68                } else {
     69                    $meta['name'] = $profile->username;
     70                }
     71                $meta['first_name']  = $profile->firstname;
     72                $meta['last_name']   = $profile->lastname;
     73                $meta['picture']     = $profile->profile;
     74                $meta['first_date']  = $profile->created_at; // Capture the athlete's profile creation date for later use, eg: in keyring-social-importers
    6275            }
    6376
  • keyring/trunk/includes/services/extended/twitter.php

    r1638335 r2106748  
    3838
    3939    function basic_ui_intro() {
    40         echo '<p>' . sprintf( __( 'If you haven\'t already, you\'ll need to <a href="%1$s">create an app on Twitter</a> (log in using your normal Twitter account). Make sure you enter something for the <strong>Callback URL</strong>, even though Keyring will override it with the correct value. Just enter your homepage, e.g. <code>%2$s</code>.', 'keyring' ), 'https://apps.twitter.com/app/new', get_bloginfo( 'url' ) ) . '</p>';
     40' ) ) . '</p>';
    4141        echo '<p>' . __( "Once you've created an app, copy and paste your <strong>Consumer key</strong> and <strong>Consumer secret</strong> (from under the <strong>OAuth settings</strong> section of your app's details) into the boxes below. You don't need an App ID for Twitter.", 'keyring' ) . '</p>';
    4242    }
  • keyring/trunk/keyring.php

    r1824012 r2106748  
    44Plugin URI: http://dentedreality.com.au/projects/wp-keyring/
    55Description: Keyring helps you manage your keys. It provides a generic, very hookable framework for connecting to remote systems and managing your access tokens, username/password combos etc for those services. On its own it doesn't do much, but it enables other plugins to do things that require authorization to act on your behalf.
    6 Version: 1.9
     6Version:
    77Author: Beau Lebens
    88Author URI: http://dentedreality.com.au
     
    2727
    2828// Indicates Keyring is installed/active so that other plugins can detect it
    29 define( 'KEYRING__VERSION', '1.9' );
     29define( 'KEYRING__VERSION', '' );
    3030
    3131/**
     
    198198        $keyring = Keyring::init();
    199199        $keyring->errors[] = $str;
    200         do_action( 'keyring_error', $str, $info, isset( $this ) ? $this : null );
     200        do_action( 'keyring_error', $str, $info );
    201201        if ( $die ) {
    202202            wp_die( $str, __( 'Keyring Error', 'keyring' ) );
  • keyring/trunk/readme.txt

    r1824012 r2106748  
    44Tags: authentication, security, oauth, http basic, authorization, facebook, foursquare, instagram, twitter, google
    55Requires at least: 4.0
    6 Tested up to: 4.9.4
    7 Stable Tag: 1.9
     6Tested up to:
     7Stable Tag:
    88
    99An authentication framework that handles authorization/communication with most popular web services.
     
    3030* [Flickr](https://flickr.com/)
    3131* [Foursquare](https://foursquare.com/)
    32 * [Google Analytics](https://developers.google.com/analytics/devguides/reporting/core/v4/)
    33 * [Google Contacts](https://developers.google.com/google-apps/contacts/v3/)
     32* [Google Analytics](https://www.google.com/analytics/)
     33* [Google Contacts](https://www.google.com/contacts/)
     34* [Google Mail](https://www.google.com/mail/)
    3435* [Instagram](https://instagram.com/)
    3536* [Instapaper](https://instapaper.com/)
     
    4546* [Twitter](https://twitter.com/)
    4647* [Yahoo! Updates](https://yahoo.com/)
     48
    4749
    4850You can very easily write your own Service definitions and then use all the power of Keyring to hook into that authentication flow. See the [Keyring Developer's Guide](http://dentedreality.com.au/projects/wp-keyring/) for more details.
     
    103105
    104106== Changelog ==
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
    105118
    106119= 1.9 =
  • keyring/trunk/service.php

    r1824012 r2106748  
    326326$keyring_services = apply_filters( 'keyring_services', $keyring_services );
    327327foreach ( $keyring_services as $keyring_service )
    328     require $keyring_service;
     328    require $keyring_service;
    329329unset( $keyring_services, $keyring_service );
  • keyring/trunk/token.php

    r634448 r2106748  
    9595    **/
    9696    function is_expired( $window = 0 ) {
    97         if ( !$expires = $this->get_meta( 'expires' ) )
     97        if ( !
    9898            return false; // No expires value, assume it's a permanent token
     99
    99100
    100         if ( '0000-00-00 00:00:00' == $expires )
     101        if ( '0000-00-00 00:00:00' == $expires )
    101102            return false; // Doesn't expire
     103
    102104
    103         if ( ( time() + $window ) > strtotime( $expires ) )
     105        if ( (
    104106            return true; // Token's expiry time has passed, or will pass before $window
     107
    105108
    106109        // Not expired
Note: See TracChangeset for help on using the changeset viewer.