Exemple #1
0
 function verify_token()
 {
     Keyring_Util::debug('Keyring_Service_OAuth2::verify_token()');
     if (!isset($_REQUEST['nonce']) || !wp_verify_nonce($_REQUEST['nonce'], 'keyring-verify-' . $this->get_name())) {
         Keyring::error(__('Invalid/missing verification nonce.', 'keyring'));
         exit;
     }
     if (!isset($_GET['code']) || !isset($_GET['state'])) {
         Keyring::error(sprintf(__('There was a problem authorizing with %s. Please try again in a moment.', 'keyring'), $this->get_label()));
         return false;
     }
     // Load up the request token that got us here and globalize it
     global $keyring_request_token;
     $state = preg_replace('/[^\\x20-\\x7E]/', '', $_GET['state']);
     $keyring_request_token = $this->store->get_token(array('id' => $state, 'type' => 'request'));
     Keyring_Util::debug('OAuth2 Loaded Request Token ' . $state);
     Keyring_Util::debug($keyring_request_token);
     if (!$keyring_request_token) {
         Keyring::error(sprintf(__('Failed to load your request token while connecting to %s. Please try again in a moment.', 'keyring'), $this->get_label()));
         return false;
     }
     $error_debug_info = array();
     if (!empty($keyring_request_token->meta['blog_id']) && !empty($keyring_request_token->meta['user_id'])) {
         $error_debug_info = array('blog_id' => $keyring_request_token->meta['blog_id'], 'user_id' => $keyring_request_token->meta['user_id']);
     }
     // Remove request token, don't need it any more.
     $this->store->delete(array('id' => $state, 'type' => 'request'));
     $url = $this->access_token_url;
     if (!stristr($url, '?')) {
         $url .= '?';
     }
     $params = array('client_id' => $this->key, 'client_secret' => $this->secret, 'grant_type' => 'authorization_code', 'redirect_uri' => $this->callback_url, 'code' => $_GET['code']);
     $params = apply_filters('keyring_' . $this->get_name() . '_verify_token_params', $params);
     Keyring_Util::debug('OAuth2 Access Token URL: ' . $url . http_build_query($params));
     switch (strtoupper($this->access_token_method)) {
         case 'GET':
             $res = wp_remote_get($url . http_build_query($params));
             break;
         case 'POST':
             $res = wp_remote_post($url, apply_filters('keyring_' . $this->get_name() . '_verify_token_post_params', array('body' => $params)));
             break;
     }
     Keyring_Util::debug('OAuth2 Response');
     Keyring_Util::debug($res);
     if (200 == wp_remote_retrieve_response_code($res)) {
         $token = wp_remote_retrieve_body($res);
         Keyring_Util::debug($token);
         $token = $this->parse_access_token($token);
         $access_token = new Keyring_Access_Token($this->get_name(), $token['access_token'], $this->build_token_meta($token));
         $access_token = apply_filters('keyring_access_token', $access_token, $token);
         Keyring_Util::debug('OAuth2 Access Token for storage');
         Keyring_Util::debug($access_token);
         $id = $this->store_token($access_token);
         $this->verified($id, $keyring_request_token);
         exit;
     }
     Keyring::error(sprintf(__('There was a problem authorizing with %s. Please try again in a moment.', 'keyring'), $this->get_label()), $error_debug_info);
     return false;
 }
Exemple #2
0
 function verify_token()
 {
     if (!isset($_REQUEST['nonce']) || !wp_verify_nonce($_REQUEST['nonce'], 'keyring-verify-' . $this->get_name())) {
         Keyring::error(__('Invalid/missing verification nonce.', 'keyring'));
         exit;
     }
     // Load up the request token that got us here and globalize it
     if ($_REQUEST['state']) {
         global $keyring_request_token;
         $state = (int) $_REQUEST['state'];
         $keyring_request_token = $this->store->get_token(array('id' => $state, 'type' => 'request'));
         Keyring_Util::debug('xAuth/Instapaper Loaded Request Token ' . $_REQUEST['state']);
         Keyring_Util::debug($keyring_request_token);
         // Remove request token, don't need it any more.
         $this->store->delete(array('id' => $state, 'type' => 'request'));
     }
     if (!strlen($_POST['username'])) {
         $url = Keyring_Util::admin_url($this->get_name(), array('action' => 'request', 'error' => 'empty', 'kr_nonce' => wp_create_nonce('keyring-request')));
         Keyring_Util::debug($url);
         wp_safe_redirect($url);
         exit;
     }
     $body = array('x_auth_mode' => 'client_auth', 'x_auth_password' => $_POST['password'], 'x_auth_username' => $_POST['username']);
     ksort($body);
     $this->set_token(new Keyring_Access_Token($this->get_name(), null, array()));
     $res = $this->request($this->access_token_url, array('method' => $this->access_token_method, 'raw_response' => true, 'body' => $body));
     Keyring_Util::debug('OAuth1 Access Token Response');
     Keyring_Util::debug($res);
     // We will get a 401 if they entered an incorrect user/pass combo. ::request
     // will then return a Keyring_Error
     if (Keyring_Util::is_error($res)) {
         $url = Keyring_Util::admin_url($this->get_name(), array('action' => 'request', 'error' => '401', 'kr_nonce' => wp_create_nonce('keyring-request')));
         Keyring_Util::debug($url);
         wp_safe_redirect($url);
         exit;
     }
     parse_str($res, $token);
     $meta = array_merge(array('username' => $_POST['username']), $this->build_token_meta($token));
     $access_token = new Keyring_Access_Token($this->get_name(), new OAuthToken($token['oauth_token'], $token['oauth_token_secret']), $meta);
     $access_token = apply_filters('keyring_access_token', $access_token);
     // If we didn't get a 401, then we'll assume it's OK
     $id = $this->store_token($access_token);
     $this->verified($id, $keyring_request_token);
 }
Exemple #3
0
    function basic_ui()
    {
        if (!isset($_REQUEST['nonce']) || !wp_verify_nonce($_REQUEST['nonce'], 'keyring-manage-' . $this->get_name())) {
            Keyring::error(__('Invalid/missing management nonce.', 'keyring'));
            exit;
        }
        // Common Header
        echo '<div class="wrap">';
        screen_icon('ms-admin');
        echo '<h2>' . __('Keyring Service Management', 'keyring') . '</h2>';
        echo '<p><a href="' . Keyring_Util::admin_url(false, array('action' => 'services')) . '">' . __('&larr; Back', 'keyring') . '</a></p>';
        echo '<h3>' . sprintf(__('%s API Credentials', 'keyring'), esc_html($this->get_label())) . '</h3>';
        // Handle actually saving credentials
        if (isset($_POST['api_key']) && isset($_POST['api_secret'])) {
            // Store credentials against this service
            $this->update_credentials(array('app_id' => stripslashes($_POST['app_id']), 'key' => stripslashes($_POST['api_key']), 'secret' => stripslashes($_POST['api_secret'])));
            echo '<div class="updated"><p>' . __('Credentials saved.', 'keyring') . '</p></div>';
        }
        $app_id = $api_key = $api_secret = '';
        if ($creds = $this->get_credentials()) {
            $app_id = $creds['app_id'];
            $api_key = $creds['key'];
            $api_secret = $creds['secret'];
        }
        echo apply_filters('keyring_' . $this->get_name() . '_basic_ui_intro', '');
        // Output basic form for collecting key/secret
        echo '<form method="post" action="">';
        echo '<input type="hidden" name="service" value="' . esc_attr($this->get_name()) . '" />';
        echo '<input type="hidden" name="action" value="manage" />';
        wp_nonce_field('keyring-manage', 'kr_nonce', false);
        wp_nonce_field('keyring-manage-' . $this->get_name(), 'nonce', false);
        echo '<table class="form-table">';
        echo '<tr><th scope="row">' . __('App ID', 'keyring') . '</th>';
        echo '<td><input type="text" name="app_id" value="' . esc_attr($app_id) . '" id="app_id" class="regular-text"></td></tr>';
        echo '<tr><th scope="row">' . __('API Key', 'keyring') . '</th>';
        echo '<td><input type="text" name="api_key" value="' . esc_attr($api_key) . '" id="api_key" class="regular-text"></td></tr>';
        echo '<tr><th scope="row">' . __('API Secret', 'keyring') . '</th>';
        echo '<td><input type="text" name="api_secret" value="' . esc_attr($api_secret) . '" id="api_secret" class="regular-text"></td></tr>';
        echo '</table>';
        echo '<p class="submitbox">';
        echo '<input type="submit" name="submit" value="' . __('Save Changes', 'keyring') . '" id="submit" class="button-primary">';
        echo '<a href="' . esc_url($_SERVER['HTTP_REFERER']) . '" class="submitdelete" style="margin-left:2em;">' . __('Cancel', 'keyring') . '</a>';
        echo '</p>';
        echo '</form>';
        ?>
<script type="text/javascript" charset="utf-8">
			jQuery( document ).ready( function() {
				jQuery( '#app_id' ).focus();
			} );
		</script><?php 
        echo '</div>';
    }
Exemple #4
0
 /**
  * Core request handler which is the crux of everything. An action is called
  * here for almost everything Keyring does, so you can use it to intercept
  * almost everything. Based entirely on $_REQUEST[page|action|service]
  */
 static function request_handlers()
 {
     global $current_user;
     if (defined('KEYRING__FORCE_USER') && KEYRING__FORCE_USER && in_array($_REQUEST['action'], array('request', 'verify'))) {
         global $current_user;
         $real_user = $current_user->ID;
         wp_set_current_user(KEYRING__FORCE_USER);
     }
     if (!empty($_REQUEST['action']) && in_array($_REQUEST['action'], apply_filters('keyring_core_actions', array('request', 'verify', 'created', 'delete', 'manage'))) && !empty($_REQUEST['service']) && in_array($_REQUEST['service'], array_keys(Keyring::get_registered_services()))) {
         // We have an action here to allow us to do things pre-authorization, just in case
         do_action("pre_keyring_{$_REQUEST['service']}_{$_REQUEST['action']}", $_REQUEST);
         // Core nonce check required for everything. "keyring-ACTION" is the kr_nonce format
         if (!isset($_REQUEST['kr_nonce']) || !wp_verify_nonce($_REQUEST['kr_nonce'], 'keyring-' . $_REQUEST['action'])) {
             Keyring::error(__('Invalid/missing Keyring core nonce. All core actions require a valid nonce.', 'keyring'));
             exit;
         }
         Keyring_Util::debug("keyring_{$_REQUEST['service']}_{$_REQUEST['action']}");
         Keyring_Util::debug($_GET);
         do_action("keyring_{$_REQUEST['service']}_{$_REQUEST['action']}", $_REQUEST);
         if ('delete' == $_REQUEST['action']) {
             do_action("keyring_connection_deleted", $_REQUEST['service'], $_REQUEST);
         }
     }
     if (defined('KEYRING__FORCE_USER') && KEYRING__FORCE_USER && in_array($_REQUEST['action'], array('request', 'verify'))) {
         wp_set_current_user($real_user);
     }
 }
Exemple #5
0
 function admin_page()
 {
     // Handle delete request. Will default back to "tokens" later
     if (isset($_REQUEST['action']) && 'delete' == $_REQUEST['action']) {
         if (!isset($_REQUEST['nonce']) || !wp_verify_nonce($_REQUEST['nonce'], 'keyring-delete-' . $_REQUEST['service'] . '-' . $_REQUEST['token'])) {
             Keyring::error(__('Invalid/missing delete nonce.', 'keyring'));
             exit;
         }
         if ($this->keyring->get_token_store()->delete(array('id' => (int) $_REQUEST['token'], 'type' => 'access'))) {
             Keyring::message(__('That connection has been deleted.', 'keyring'));
         } else {
             Keyring::message(__('Could not delete that connection!', 'keyring'));
         }
     }
     // Handle test request. Will default back to "tokens" later
     if (isset($_REQUEST['action']) && 'test' == $_REQUEST['action']) {
         if (!isset($_REQUEST['nonce']) || !wp_verify_nonce($_REQUEST['nonce'], 'keyring-test-' . $_REQUEST['service'] . '-' . $_REQUEST['token'])) {
             Keyring::error(__('Invalid/missing testing nonce.', 'keyring'));
             exit;
         }
         // If the test_connection() method exists, call it for this service/connection
         $service = $this->keyring->get_service_by_name($_REQUEST['service']);
         if (method_exists($service, 'test_connection')) {
             $service->set_token($this->keyring->get_token_store()->get_token(array('id' => $_REQUEST['token'], 'type' => 'request')));
             if ($service->test_connection()) {
                 Keyring::message(__('This connection is working correctly.', 'keyring'));
             } else {
                 Keyring::message(__('This connection is <strong>NOT</strong> working correctly.', 'keyring'));
             }
         } else {
             Keyring::message(__('This service does not currently support connection testing.', 'keyring'));
         }
     }
     // Set up our defaults
     $service = '';
     if (!empty($_REQUEST['service'])) {
         $service = $_REQUEST['service'];
     }
     $action = 'tokens';
     if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], array('tokens', 'services', 'request', 'verify', 'manage'))) {
         $action = $_REQUEST['action'];
     }
     // Custom UI optionally hooked in to handle this service/action. Trigger action
     // and assume it handles everything, so bail out after that.
     if (Keyring_Util::has_custom_ui($service, $action)) {
         do_action("keyring_{$service}_{$action}_ui");
         return;
     }
     // Nothing else has bailed, so it must be one of our default/core screens.
     switch ($action) {
         case 'tokens':
             $this->admin_page_header('tokens');
             $list_table = new Keyring_Connections_List_Table();
             $list_table->display();
             $this->admin_page_footer();
             break;
         case 'services':
             $this->admin_page_header('services');
             $services = $this->keyring->get_registered_services();
             if (count($services)) {
                 $configured = $not_configured = array();
                 foreach ($services as $service) {
                     if ($service->is_configured()) {
                         $configured[] = $service;
                     } else {
                         $not_configured[] = $service;
                     }
                 }
                 if (count($configured)) {
                     echo '<p><strong>' . __('Click a service to create a new connection:', 'keyring') . '</strong></p>';
                     echo '<ul>';
                     foreach ($configured as $service) {
                         $request_kr_nonce = wp_create_nonce('keyring-request');
                         $request_nonce = wp_create_nonce('keyring-request-' . $service->get_name());
                         echo '<li><a href="' . esc_url(Keyring_Util::admin_url($service->get_name(), array('action' => 'request', 'kr_nonce' => $request_kr_nonce, 'nonce' => $request_nonce))) . '">' . esc_html($service->get_label()) . '</a>';
                         if (has_action('keyring_' . $service->get_name() . '_manage_ui')) {
                             $manage_kr_nonce = wp_create_nonce('keyring-manage');
                             $manage_nonce = wp_create_nonce('keyring-manage-' . $service->get_name());
                             echo ' (<a href="' . esc_url(Keyring_Util::admin_url($service->get_name(), array('action' => 'manage', 'kr_nonce' => $manage_kr_nonce, 'nonce' => $manage_nonce))) . '">' . esc_html(__('Manage', 'keyring')) . '</a>)';
                         }
                         echo '</li>';
                     }
                     echo '</ul><br /><br />';
                 } else {
                     echo '<p>' . __('There are no fully-configured services available to connect to.', 'keyring') . '</p>';
                 }
                 if (count($not_configured)) {
                     echo '<p>' . __('The following services need to be configured correctly before you can connect to them.', 'keyring') . '</p>';
                     echo '<ul>';
                     foreach ($not_configured as $service) {
                         if (!has_action('keyring_' . $service->get_name() . '_manage_ui')) {
                             continue;
                         }
                         $manage_kr_nonce = wp_create_nonce('keyring-manage');
                         $manage_nonce = wp_create_nonce('keyring-manage-' . $service->get_name());
                         echo '<li><a href="' . esc_url(Keyring_Util::admin_url($service->get_name(), array('action' => 'manage', 'kr_nonce' => $manage_kr_nonce, 'nonce' => $manage_nonce))) . '">' . esc_html($service->get_label()) . '</a></li>';
                     }
                     echo '</ul>';
                 }
             }
             $this->admin_page_footer();
             break;
     }
 }
Exemple #6
0
 function request($url, array $params = array())
 {
     if ($this->requires_token() && empty($this->token)) {
         return new Keyring_Error('keyring-request-error', __('No token', 'keyring'));
     }
     $raw_response = false;
     if (isset($params['raw_response'])) {
         $raw_response = (bool) $params['raw_response'];
         unset($params['raw_response']);
     }
     $method = 'GET';
     if (isset($params['method'])) {
         $method = strtoupper($params['method']);
         unset($params['method']);
     }
     $sign_parameters = true;
     if (isset($params['sign_parameters'])) {
         $sign_parameters = (bool) $params['sign_parameters'];
         unset($params['sign_parameters']);
     }
     // Should be an OAuthToken object
     $token = $this->token->token ? $this->token->token : null;
     Keyring_Util::debug($token);
     $sign_vars = false;
     if (isset($params['body']) && $sign_parameters) {
         if (is_string($params['body'])) {
             wp_parse_str($params['body'], $sign_vars);
         } else {
             if (is_array($params['body'])) {
                 $sign_vars = $params['body'];
             }
         }
     }
     $req = $this->prepare_request($token, $method, $url, $sign_vars);
     $request_url = (string) $req;
     if ($this->token && $this->authorization_header) {
         $header = $req->to_header($this->authorization_realm);
         // Gives a complete header string, not just the second half
         $bits = explode(': ', $header, 2);
         $params['headers']['Authorization'] = $bits[1];
         // This hack was introduced for Instapaper (http://stackoverflow.com/a/9645033/1507683), which is overly strict on
         // header formatting, but it doesn't seem to cause problems anywhere else.
         $params['headers']['Authorization'] = str_replace('",', '", ', $params['headers']['Authorization']);
         Keyring_Util::debug('OAuth1 Authorization Header');
         Keyring_Util::debug($params['headers']['Authorization']);
         // oauth_verifier was probably added directly to the URL, need to manually remove it
         $request_url = remove_query_arg('oauth_verifier', $url);
     }
     $query = '';
     $parsed = parse_url($request_url);
     if (!empty($parsed['query']) && 'POST' == $method) {
         $request_url = str_replace('?' . $parsed['query'], '', $request_url);
         $query = $parsed['query'];
     }
     Keyring_Util::debug("OAuth1 Request URL: {$request_url}");
     switch ($method) {
         case 'GET':
             Keyring_Util::debug('OAuth1 GET ' . $request_url);
             $res = wp_remote_get($request_url, $params);
             break;
         case 'POST':
             $params = array_merge(array('body' => $query, 'sslverify' => false), $params);
             Keyring_Util::debug('OAuth1 POST ' . $request_url);
             Keyring_Util::debug($params);
             $res = wp_remote_post($request_url, $params);
             break;
         case 'PUT':
             $params = array_merge(array('method' => 'PUT'), $params);
             $res = wp_remote_request($request_url, $params);
             break;
         default:
             Keyring::error(__('Unsupported method specified.', 'keyring'));
             exit;
     }
     Keyring_Util::debug($res);
     $this->set_request_response_code(wp_remote_retrieve_response_code($res));
     if (200 == wp_remote_retrieve_response_code($res) || 201 == wp_remote_retrieve_response_code($res)) {
         if ($raw_response) {
             return wp_remote_retrieve_body($res);
         } else {
             return $this->parse_response(wp_remote_retrieve_body($res));
         }
     } else {
         return new Keyring_Error('keyring-request-error', $res);
     }
 }
Exemple #7
0
 function request($url, array $params = array())
 {
     if ($this->requires_token() && empty($this->token)) {
         return new Keyring_Error('keyring-request-error', __('No token'));
     }
     if ($this->requires_token()) {
         $params['headers'] = array('Authorization' => 'Basic ' . $this->token);
     }
     $method = 'GET';
     if (isset($params['method'])) {
         $method = strtoupper($params['method']);
         unset($params['method']);
     }
     $raw_response = false;
     if (isset($params['raw_response'])) {
         $raw_response = (bool) $params['raw_response'];
         unset($params['raw_response']);
     }
     Keyring_Util::debug("HTTP Basic {$method} {$url}");
     Keyring_Util::debug($params);
     switch (strtoupper($method)) {
         case 'GET':
             $res = wp_remote_get($url, $params);
             break;
         case 'POST':
             $res = wp_remote_post($url, $params);
             break;
         default:
             Keyring::error(__('Unsupported method specified for verify_token.', 'keyring'));
             exit;
     }
     Keyring_Util::debug($res);
     $this->set_request_response_code(wp_remote_retrieve_response_code($res));
     if (200 == wp_remote_retrieve_response_code($res) || 201 == wp_remote_retrieve_response_code($res)) {
         if ($raw_response) {
             return wp_remote_retrieve_body($res);
         } else {
             return $this->parse_response(wp_remote_retrieve_body($res));
         }
     } else {
         return new Keyring_Error('keyring-request-error', $res);
     }
 }