function mexp_instagram_user_credentials_callback($credentials) { if (!class_exists('Keyring')) { return $credentials; } // Check that the instagram service is setup $keyring = Keyring::init()->get_service_by_name('instagram'); if (is_null($keyring)) { return $credentials; } $keyring_store = Keyring::init()->get_token_store(); // Hacky time, Keyring is designed to handle requests, but we're just stealing its access_token. if (method_exists($keyring_store, 'get_tokens_by_user')) { // The wpcom version uses the get_tokens_by_user method $users_tokens = $keyring_store->get_tokens_by_user(get_current_user_id()); if (in_array('instagram', $users_tokens)) { $credentials['access_token'] = $users_tokens['instagram'][0]->token; } } elseif (method_exists($keyring_store, 'get_tokens')) { // The released version uses the get_tokens method $users_tokens = $keyring_store->get_tokens(array('service' => 'instagram', 'user_id' => get_current_user_id())); if (count($users_tokens) > 0) { $credentials['access_token'] = $users_tokens[0]->token; } } return $credentials; }
/** * Get the user's API token. * * @access public * * @return string The user's token */ public function get_token() { $token = get_option('eventbrite_api_token'); if (empty($token)) { return false; } $this->set_token(Keyring::init()->get_token_store()->get_token(array('type' => 'access', 'id' => $token))); $this->eventbrite_external_id = defined('IS_WPCOM') && IS_WPCOM ? $this->token->get_meta('external_id') : $this->token->get_meta('user_id'); return $this->token; }
function get_service() { if (!$this->service) { $class = $this->get_meta('_classname', true); if ($class && class_exists($class)) { $this->service = call_user_func(array($class, 'init')); } else { $this->service = Keyring::get_service_by_name($this->get_name()); } } return $this->service; }
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); }
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; }
<?php // Check if the author of this post is connected to the Twitter importer, // if so load their Twitter avatar, if not use their Gravatar $icon_size = 35; // In px, how big (square) should the avatar/icon be? // I'm being a horrible person and accessing options directly to avoid re-loading all the importer code if (class_exists('Keyring')) { if ($importer = get_option('keyring_twitter_importer')) { if ($token = $importer['token']) { $token = Keyring::get_token_store()->get_token(array('id' => $token, 'type' => 'access')); $url = $token->get_meta('picture'); if ($url) { // Use Photon (if available) to resize their icon properly if (function_exists('jetpack_photon_url')) { $url = jetpack_photon_url($url, array('resize' => "{$icon_size},{$icon_size}", 'filter' => 'grayscale')); } // Output that sucka echo '<a href="' . get_author_posts_url(false, get_the_author_meta('ID')) . '">'; echo '<img src="' . esc_url($url) . '" class="format-icon" width="' . esc_attr($icon_size) . '" height="' . esc_attr($icon_size) . '" alt="" />'; echo '</a>'; return; // Avoid doing the Gravatar, below } } } } // No Twitter connection, try to use their Gravatar instead $gravatar = get_avatar(get_the_author_meta('ID'), $icon_size); $gravatar = str_replace("class='", "class='format-icon ", $gravatar); echo '<a href="' . get_author_posts_url(false, get_the_author_meta('ID')) . '">';
function is_connected() { $c = get_called_class(); return Keyring::get_token_store()->count(array('service' => $c::NAME)); }
/** * Generic error handler/trigger. * @param String $str Informational message (user-readable) * @param array $info Additional information relating to the error. * @param boolean $die If we should immediately die (default) or continue */ static function error($str, $info = array(), $die = true) { $keyring = Keyring::init(); $keyring->errors[] = $str; do_action('keyring_error', $str, $info, isset($this) ? $this : null); if ($die) { wp_die($str, __('Keyring Error', 'keyring')); exit; } }
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')) . '">' . __('← 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('key' => stripslashes($_POST['api_key']), 'secret' => stripslashes($_POST['api_secret']), 'redirect_uri' => stripslashes($_POST['redirect_uri']))); echo '<div class="updated"><p>' . __('Credentials saved.', 'keyring') . '</p></div>'; } $api_key = $api_secret = $redirect_uri = ''; if ($creds = $this->get_credentials()) { $api_key = $creds['key']; $api_secret = $creds['secret']; $redirect_uri = $creds['redirect_uri']; } echo apply_filters('keyring_' . $this->get_name() . '_basic_ui_intro', ''); if (!$redirect_uri) { $redirect_uri = Keyring_Util::admin_url($this->get_name(), array('action' => 'verify')); } // 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">' . __('Client ID', '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">' . __('Client 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 '<tr><th scope="row">' . __('Redirect URI', 'keyring') . '</th>'; echo '<td><input type="text" name="redirect_uri" value="' . esc_attr($redirect_uri) . '" id="redirect_uri" 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>'; echo '</div>'; }
function __construct() { $this->keyring = Keyring::init(); parent::__construct(array('singular' => 'connection', 'plural' => 'connections', 'screen' => $this->keyring->admin_page)); $this->items = Keyring::get_token_store()->get_tokens(); }
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); } }
/** * See __construct() for details on how this is hooked in to handle the UI for * during the verify process. */ function verify_ui() { Keyring::admin_page_header(); echo '<p>As an example, we just randomly generated a token and saved it in the token store. When you go back to your Connections listing, you should see it listed there under "Example Service".</p>'; echo '<p><a href="' . esc_url(Keyring_Util::admin_url()) . '" class="button-primary">' . __('Done', 'keyring') . '</a>'; Keyring::admin_page_footer(); }
/** * The first screen the user sees in the import process. Summarizes the process and allows * them to either select an existing Keyring token or start the process of creating a new one. * Also makes sure they have the correct service available, and that it's configured correctly. */ function greet() { if (method_exists($this, 'full_custom_greet')) { $this->full_custom_greet(); return; } $this->header(); // If this service is not configured, then we can't continue if (!($service = Keyring::get_service_by_name(static::SLUG))) { ?> <p class="error"><?php echo esc_html(sprintf(__("It looks like you don't have the %s service for Keyring installed.", 'keyring'), static::LABEL)); ?> </p> <?php $this->footer(); return; ?> <?php } elseif (!$service->is_configured()) { ?> <p class="error"><?php echo esc_html(sprintf(__("Before you can use this importer, you need to configure the %s service within Keyring.", 'keyring'), static::LABEL)); ?> </p> <?php if (current_user_can('read') && !KEYRING__HEADLESS_MODE && has_action('keyring_' . static::SLUG . '_manage_ui')) { $manage_kr_nonce = wp_create_nonce('keyring-manage'); $manage_nonce = wp_create_nonce('keyring-manage-' . static::SLUG); echo '<p><a href="' . esc_url(Keyring_Util::admin_url(static::SLUG, array('action' => 'manage', 'kr_nonce' => $manage_kr_nonce, 'nonce' => $manage_nonce))) . '" class="button-primary">' . sprintf(__('Configure %s Service', 'keyring'), static::LABEL) . '</a></p>'; } $this->footer(); return; ?> <?php } ?> <div class="narrow"> <form action="admin.php?import=<?php echo static::SLUG; ?> &step=greet" method="post"> <p><?php printf(__("Howdy! This importer requires you to connect to %s before you can continue.", 'keyring'), static::LABEL); ?> </p> <?php do_action('keyring_importer_' . static::SLUG . '_greet'); ?> <?php if ($service->is_connected()) { ?> <p><?php echo sprintf(esc_html(__('It looks like you\'re already connected to %1$s via %2$s. You may use an existing connection, or create a new one:', 'keyring')), static::LABEL, '<a href="' . esc_attr(Keyring_Util::admin_url()) . '">Keyring</a>'); ?> </p> <?php $service->token_select_box(static::SLUG . '_token', true); ?> <input type="submit" name="connect_existing" value="<?php echo esc_attr(__('Continue…', 'keyring')); ?> " id="connect_existing" class="button-primary" /> <?php } else { ?> <p><?php echo esc_html(sprintf(__("To get started, we'll need to connect to your %s account so that we can access your content.", 'keyring'), static::LABEL)); ?> </p> <input type="submit" name="create_new" value="<?php echo esc_attr(sprintf(__('Connect to %s…', 'keyring'), static::LABEL)); ?> " id="create_new" class="button-primary" /> <?php } ?> </form> </div> <?php $this->footer(); }
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); } }