├── README.md ├── composer.json ├── publishiza.php ├── publishiza ├── assets │ ├── css │ │ └── publishiza.css │ └── js │ │ └── publishiza.js ├── includes │ ├── admin.php │ ├── capabilities.php │ ├── hooks.php │ ├── keyring.php │ ├── service.php │ └── twitter.php └── keyring │ ├── admin-ui.php │ ├── includes │ ├── oauth-php │ │ ├── CHANGELOG.txt │ │ ├── LICENSE.txt │ │ ├── OAuth.php │ │ ├── OAuthTests.xml │ │ ├── OAuth_TestServer.php │ │ ├── doc │ │ │ └── design.txt │ │ └── tests │ │ │ ├── Mock_OAuthBaseStringRequest.php │ │ │ ├── Mock_OAuthDataStore.php │ │ │ ├── Mock_OAuthSignatureMethod_RSA_SHA1.php │ │ │ ├── OAuthConsumerTest.php │ │ │ ├── OAuthRequestTest.php │ │ │ ├── OAuthServerTest.php │ │ │ ├── OAuthSignatureMethodHmacSha1Test.php │ │ │ ├── OAuthSignatureMethodPlaintextTest.php │ │ │ ├── OAuthSignatureMethodRsaSha1Test.php │ │ │ ├── OAuthTokenTest.php │ │ │ ├── OAuthUtilTest.php │ │ │ └── common.php │ ├── services │ │ ├── core │ │ │ ├── http-basic.php │ │ │ ├── oauth1.php │ │ │ └── oauth2.php │ │ └── extended │ │ │ ├── 500px.php │ │ │ ├── delicious.php │ │ │ ├── eventbrite.php │ │ │ ├── facebook.php │ │ │ ├── fitbit.php │ │ │ ├── flickr.php │ │ │ ├── foursquare.php │ │ │ ├── google-contacts.php │ │ │ ├── instagram.php │ │ │ ├── instapaper.php │ │ │ ├── linkedin.php │ │ │ ├── moves.php │ │ │ ├── nest.php │ │ │ ├── pinterest.php │ │ │ ├── runkeeper.php │ │ │ ├── tripit.php │ │ │ ├── tumblr.php │ │ │ ├── twitter.php │ │ │ └── yahoo.php │ └── stores │ │ └── singlestore.php │ ├── keyring.php │ ├── languages │ └── keyring.po │ ├── readme.txt │ ├── service.php │ ├── store.php │ └── token.php └── readme.txt /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Publishiza 3 | 4 | Compose and publish a Tweetstorm, all from inside your WordPress. 5 | 6 | * Seamlessly integrates into your WordPress dashboard interface 7 | * Safe, secure, & efficient 8 | 9 | Publishiza includes Keyring, a great foundation by my pal Beau Lebens. 10 | 11 | # Installation 12 | 13 | * Download and install using the built in WordPress plugin installer. 14 | * Activate in the "Plugins" area of your admin by clicking the "Activate" link. 15 | * Visit: Tools > Keyring 16 | * Add a New Service 17 | * Authorize Publishiza 18 | 19 | # FAQ 20 | 21 | ### Does this create new database tables? 22 | 23 | No. It uses WordPress's custom post-type, custom taxonomy, and metadata APIs. 24 | 25 | ### Does this modify existing database tables? 26 | 27 | No. All of WordPress's core database tables remain untouched. 28 | 29 | ### Where can I get support? 30 | 31 | * Here on GitHub: https://github.com/JJJ/publishiza/ 32 | 33 | ### Can I contribute? 34 | 35 | Yes, please! 36 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jjj/publishiza", 3 | "description": "Compose and publish a Tweetstorm, all from inside your WordPress.", 4 | "homepage": "https://github.com/jjj/publishiza", 5 | "type": "wordpress-plugin", 6 | "require": { 7 | "php": ">=5.2", 8 | "composer/installers": "^1.0" 9 | }, 10 | "license": "GPLv2 or later", 11 | "authors": [ 12 | { 13 | "name": "John James Jacoby", 14 | "email": "johnjamesjacoby@me.com" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /publishiza.php: -------------------------------------------------------------------------------- 1 | 'keyring', 'action' => 'services' ), admin_url( 'tools.php' ) ); 114 | wp_safe_redirect( $redirect_to ); 115 | exit; 116 | } 117 | add_action( 'activated_plugin', 'publishiza_activation_redirect' ); 118 | -------------------------------------------------------------------------------- /publishiza/assets/css/publishiza.css: -------------------------------------------------------------------------------- 1 | #publishiza-action { 2 | margin: 10px; 3 | } 4 | 5 | #publishiza-select { 6 | line-height: 2.5em; 7 | margin-top: 3px; 8 | display: none; 9 | } 10 | #publishiza-select select#pts_post_type { 11 | margin-right: 2px; 12 | } 13 | #publishiza-select a#save-publishiza { 14 | vertical-align: middle; 15 | margin-right: 2px; 16 | } 17 | #publishiza-display { 18 | font-weight: bold; 19 | } 20 | #post-body .publishiza::before { 21 | content: '\f301'; 22 | font: 400 20px/1 dashicons; 23 | speak: none; 24 | display: inline-block; 25 | padding: 0 2px 0 0; 26 | top: 0; 27 | left: -1px; 28 | position: relative; 29 | vertical-align: top; 30 | -webkit-font-smoothing: antialiased; 31 | -moz-osx-font-smoothing: grayscale; 32 | text-decoration: none !important; 33 | color: #888; 34 | } 35 | -------------------------------------------------------------------------------- /publishiza/assets/js/publishiza.js: -------------------------------------------------------------------------------- 1 | jQuery( function( $ ) { 2 | var $publish_btn = $( '#publish' ), 3 | $edit = $( '#edit-publishiza' ), 4 | $save = $( '#save-publishiza' ), 5 | $cancel = $( '#cancel-publishiza' ), 6 | $select = $( '#publishiza-select' ), 7 | $display = $( '#publishiza-display' ), 8 | $publish_text = $publish_btn.val(); 9 | 10 | $( '.misc-pub-section.curtime.misc-pub-section-last' ).removeClass( 'misc-pub-section-last' ); 11 | 12 | $edit.on( 'click', function( e ) { 13 | $( this ).hide(); 14 | $select.slideDown(); 15 | e.preventDefault(); 16 | } ); 17 | 18 | $save.on( 'click', function( e ) { 19 | var $select_text = $( '#publishiza :selected' ).text(); 20 | 21 | $select.slideUp(); 22 | $edit.show(); 23 | $display.text( $select_text ); 24 | 25 | if ( 'on' === $select_text ) { 26 | $publish_btn.val( '\u{1F4A9}\u{1F329}' ); 27 | } else { 28 | $publish_btn.val( $publish_text ); 29 | } 30 | 31 | e.preventDefault(); 32 | } ); 33 | 34 | $cancel.on( 'click', function( e ) { 35 | $select.slideUp(); 36 | $edit.show(); 37 | e.preventDefault(); 38 | } ); 39 | } ); 40 | -------------------------------------------------------------------------------- /publishiza/includes/admin.php: -------------------------------------------------------------------------------- 1 | get_tokens( array( 29 | 'service' => 'publishiza', 30 | 'user_id' => $post->post_author 31 | ) ); 32 | 33 | // Not authed 34 | if ( ! empty( $tokens ) ) { 35 | $setup = true; 36 | } ?> 37 | 38 |
39 | 40 | post_status ); 44 | $meta = get_post_meta( $post->ID, 'publishiza', true ); 45 | $text = empty( $meta ) 46 | ? esc_html__( 'off', 'publishiza' ) 47 | : date( __( 'M j, Y @ H:i', 'publishiza' ), $meta['time'] ); ?> 48 | 49 | 50 | 51 | 52 | 53 | 54 |
55 | 59 | 60 | 61 |
'request', 'kr_nonce' => $request_kr_nonce, 'nonce' => $request_nonce ) ) ) . '">' . esc_html__( 'Connect', 'publishiza' ) . ''; 70 | endif; 71 | 72 | ?>
73 | 74 | set_endpoint( 'update', 'https://api.twitter.com/1.1/statuses/update.json', 'POST' ); 36 | 37 | parent::__construct(); 38 | } 39 | 40 | /** 41 | * Return Publishiza credentials 42 | * 43 | * @since 1.0.0 44 | * 45 | * @return array 46 | */ 47 | public function _get_credentials() { 48 | return array( 49 | 'app_id' => '', 50 | 'key' => $this->key, 51 | 'secret' => $this->secret, 52 | ); 53 | } 54 | 55 | /** 56 | * 57 | * @since 1.0.0 58 | */ 59 | function basic_ui() { 60 | 61 | // Bail if no nonce 62 | if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'keyring-manage-' . $this->get_name() ) ) { 63 | Keyring::error( __( 'Invalid/missing management nonce.', 'publishiza' ) ); 64 | exit; 65 | } 66 | 67 | // Common Header 68 | echo '
'; 69 | screen_icon( 'ms-admin' ); 70 | echo '

' . __( 'Service Management', 'publishiza' ) . '

'; 71 | echo '

' . __( '← Back', 'publishiza' ) . '

'; 72 | echo '

' . sprintf( __( '%s Connection', 'publishiza' ), esc_html( $this->get_label() ) ) . '

'; 73 | 74 | // Handle actually saving credentials 75 | if ( isset( $_POST['api_key'] ) && isset( $_POST['api_secret'] ) ) { 76 | // Store credentials against this service 77 | $this->update_credentials( array( 78 | 'app_id' => ( ! empty( $_POST['app_id'] ) ? stripslashes( $_POST['app_id'] ) : '' ), 79 | 'key' => ( ! empty( $_POST['api_key'] ) ? stripslashes( $_POST['api_key'] ) : '' ), 80 | 'secret' => ( ! empty( $_POST['api_secret'] ) ? stripslashes( $_POST['api_secret'] ) : '' ) 81 | ) ); 82 | echo '

' . __( 'Credentials saved.', 'publishiza' ) . '

'; 83 | } 84 | 85 | if ( $creds = $this->get_credentials() ) { 86 | $app_id = $creds['app_id']; 87 | $api_key = $creds['key']; 88 | $api_secret = $creds['secret']; 89 | } else { 90 | $app_id = $api_key = $api_secret = ''; 91 | } 92 | 93 | echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_intro', '' ); 94 | 95 | // Output basic form for collecting key/secret 96 | echo '
'; 97 | echo ''; 98 | echo ''; 99 | 100 | wp_nonce_field( 'keyring-manage', 'kr_nonce', false ); 101 | wp_nonce_field( 'keyring-manage-' . $this->get_name(), 'nonce', false ); 102 | 103 | $ui_app_id = ''; 104 | 105 | echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_app_id', $ui_app_id ); 106 | 107 | $ui_api_key = ''; 108 | 109 | echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_api_key', $ui_api_key ); 110 | 111 | $ui_api_secret = ''; 112 | 113 | echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_api_secret', $ui_api_secret ); 114 | 115 | echo '

'; 116 | echo ''; 117 | echo '' . __( 'Cancel', 'publishiza' ) . ''; 118 | echo '

'; 119 | echo '
'; 120 | ?>'; 126 | } 127 | 128 | public function basic_ui_intro() { 129 | echo '

' . __( 'In a separate browser tab, login to Twitter with the account you would like to connect to Publishiza, then click "Connect"', 'publishiza' ) . '

'; 130 | } 131 | } 132 | 133 | // 134 | remove_action( 'keyring_load_services', array( 'Keyring_Service_Twitter', 'init' ) ); 135 | add_action( 'keyring_load_services', array( 'Keyring_Service_Publishiza', 'init' ) ); 136 | -------------------------------------------------------------------------------- /publishiza/includes/twitter.php: -------------------------------------------------------------------------------- 1 | 'array', 14 | 'description' => esc_html__( 'Publishiza response information from Twitter', 'publishiza' ), 15 | 'single' => true, 16 | 'sanitize_callback' => 'publishiza_sanitize_post_meta', 17 | 'auth_callback' => 'publishiza_auth_post_meta', 18 | 'show_in_rest' => true 19 | ) ); 20 | } 21 | 22 | /** 23 | * Publishiza to Twitter 24 | * 25 | * @since 1.0.0 26 | * 27 | * @param int $post_id 28 | * @param WP_Post $post 29 | */ 30 | function publishiza_publish_post( $post_id = 0, $post = null ) { 31 | 32 | // Bail if not Publishiza'ing 33 | if ( empty( $_POST['publishiza'] ) ) { 34 | return; 35 | } 36 | 37 | // Bail if already Publishizaed 38 | if ( get_post_meta( $post_id, 'publishiza', true ) ) { 39 | return; 40 | } 41 | 42 | // Bail if nonce fails 43 | if ( ! wp_verify_nonce( 'publishiza-nonce', 'publishiza-select' ) ) { 44 | //return; 45 | } 46 | 47 | // Publishiza & get response 48 | $response = publishiza_maybe_post_to_twitter( $post ); 49 | 50 | // Save response to prevent 51 | add_post_meta( $post_id, 'publishiza', array( 52 | 'time' => time(), 53 | 'start' => $response 54 | ) ); 55 | } 56 | 57 | /** 58 | * Maybe Publishiza a WordPress post to Twitter 59 | * 60 | * Check for valid service/tokens/tweets – bail if there is a problem 61 | * 62 | * @since 1.0.0 63 | * 64 | * @param WP_Post $post 65 | */ 66 | function publishiza_maybe_post_to_twitter( $post = null ) { 67 | 68 | // Look for Publishiza connection 69 | $service = Keyring::get_service_by_name( 'publishiza' ); 70 | 71 | // Bail if no connection to Twitter 72 | if ( ! $service->is_connected() ) { 73 | return; 74 | } 75 | 76 | // Look for auth tokens 77 | $tokens = Keyring::get_token_store()->get_tokens( array( 78 | 'service' => 'publishiza', 79 | 'user_id' => $post->post_author 80 | ) ); 81 | 82 | // Bail if not authed 83 | if ( empty( $tokens ) ) { 84 | return false; 85 | } 86 | 87 | // Process post content into Tweets 88 | $tweets = publishiza_get_tweets_from_text( $post->post_content, $post ); 89 | 90 | // Bail if no tweets 91 | if ( empty( $tweets ) ) { 92 | return false; 93 | } 94 | 95 | // Try to post tweets to Twitter 96 | return publishiza_post_tweets_to_twitter( array( 97 | 'tweets' => $tweets, 98 | 'service' => $service, 99 | 'tokens' => $tokens 100 | ) ); 101 | } 102 | 103 | /** 104 | * Return array of strings for more predictable fitment into Twitter's current 105 | * 140 character restriction. 106 | * 107 | * @since 1.1.0 108 | * 109 | * @param string $text 110 | * @return array 111 | */ 112 | function publishiza_get_tweets_from_text( $text = '', $text_object = null ) { 113 | 114 | /** 115 | * Filter length of individual tweets 116 | * 117 | * @since 1.0.0 118 | * 119 | * @param int 119 Maximum length of each tweet 120 | * @return int 121 | */ 122 | $length = (int) apply_filters( 'publishiza_storm_length', 119 ); 123 | 124 | // Format text blob for word wrapping 125 | $decoded = html_entity_decode( $text, ENT_QUOTES, 'UTF-8' ); 126 | $stripped = wp_strip_all_tags( $decoded, true ); 127 | 128 | /** 129 | * Filter the plain-text, so it can be stormed 130 | * 131 | * @since 1.1.0 132 | * 133 | * @param string $stripped Stripped text 134 | * @param string $text Original text 135 | * @return string 136 | */ 137 | $filtered = (string) apply_filters( 'publishiza_storm_text', $stripped, $text, $text_object ); 138 | 139 | // Wrap text blob into a managable array 140 | $split = wordwrap( $filtered, $length, "\n", false ); 141 | $trimmed = array_map( 'trim', explode( "\n", $split ) ); 142 | $tweets = array_filter( $trimmed ); 143 | 144 | /** 145 | * Filter array of tweets, processed from $text 146 | * 147 | * @since 1.1.0 148 | * 149 | * @param array $tweets Array of all tweets 150 | * @param string $text The original text 151 | * @param int $length The maximum length of each tweet 152 | * @return array 153 | */ 154 | return (array) apply_filters( 'publishiza_format_post_content_for_twitter', $tweets, $text, $length ); 155 | } 156 | 157 | /** 158 | * Sends multiple POST requests to the Twitter API, one for each tweet in the 159 | * array of tweets passed 160 | * 161 | * @since 1.1.0 162 | * 163 | * @param array $tweets 164 | * @param Keyring_Service $service 165 | * 166 | * @return boolean 167 | */ 168 | function publishiza_post_tweets_to_twitter( $args = array() ) { 169 | 170 | // Parse args 171 | $r = wp_parse_args( $args, array( 172 | 'tweets' => array(), 173 | 'service' => null, 174 | 'tokens' => null 175 | ) ); 176 | 177 | // Bail if nothing to do 178 | if ( empty( $r['tweets'] ) || empty( $r['tokens'] ) || empty( $r['service'] ) ) { 179 | return false; 180 | } 181 | 182 | // Storm settings 183 | $sleep = apply_filters( 'publishiza_storm_sleep', 2 ); 184 | $control = apply_filters( 'publishiza_storm_control', html_entity_decode( '💩🌩 ', 0, 'UTF-8' ) ); 185 | $ndash = apply_filters( 'publishiza_storm_divider', html_entity_decode( '–', 0, 'UTF-8' ) ); 186 | $ellip = apply_filters( 'publishiza_storm_ellipsis', html_entity_decode( '…', 0, 'UTF-8' ) ); 187 | $count = count( $r['tweets'] ); 188 | $responses = array(); 189 | $first = false; 190 | 191 | // Loop through connections (multiple accounts can storm simultaneously) 192 | foreach ( $r['tokens'] as $token ) { 193 | 194 | // Set the token 195 | $r['service']->token = $token; 196 | $previous_status_id = false; 197 | 198 | // Storm 199 | foreach ( $r['tweets'] as $index => $tweet ) { 200 | 201 | // Build the prefix 202 | $position = (int) $index + 1; 203 | $prefix = apply_filters( 'publishiza_storm_prefix', "{$control}{$position}/{$count} {$ndash} " ); 204 | $text = "{$prefix}{$tweet}"; 205 | 206 | // Maybe append an ellipsis 207 | if ( ! empty( $ellip ) && ( $position !== $count ) ) { 208 | $text = "{$text}{$ellip}"; 209 | } 210 | 211 | // Get request body 212 | $body = array( 213 | 'status' => $text, 214 | 'trim_user' => 1 215 | ); 216 | 217 | // Maybe in response to the first ID 218 | if ( ( $position > 1 ) && ! empty( $previous_status_id ) ) { 219 | $body['in_reply_to_status_id'] = (int) $previous_status_id; 220 | } 221 | 222 | // Send update to Twitter 223 | $response = $r['service']->request( $r['service']->update_url, array( 224 | 'method' => $r['service']->update_method, 225 | 'body' => $body 226 | ) ); 227 | 228 | // Error! 229 | if ( is_a( $response, 'Keyring_Error' ) ) { 230 | return false; 231 | } 232 | 233 | // Setup storm 234 | if ( isset( $response->id ) ) { 235 | $previous_status_id = $response->id; 236 | 237 | // Set first response ID 238 | if ( empty( $first ) && ( 1 === $position ) ) { 239 | $first = $response->id; 240 | } 241 | } 242 | 243 | // Add response to responses array (@todo: save for debug?) 244 | $responses[] = $response; 245 | 246 | // Wait to avoid being throttled 247 | sleep( $sleep ); 248 | } 249 | } 250 | 251 | // Return ID of first tweet 252 | return $first; 253 | } 254 | 255 | /** 256 | * Maybe append the short-link to the end of the blog post content 257 | * 258 | * @since 1.1.0 259 | * 260 | * @param string $text 261 | * @param string $original 262 | * @param WP_Post $object 263 | * 264 | * @return string 265 | */ 266 | function publishiza_append_short_link( $text = '', $original = '', $object = null ) { 267 | 268 | // Bail if no text or not a post object 269 | if ( empty( $text ) || ! is_a( $object, 'WP_Post' ) ) { 270 | return $text; 271 | } 272 | 273 | // Bail if turned off 274 | if ( ! apply_filters( 'publishiza_append_short_link', false, $object ) ) { 275 | return $text; 276 | } 277 | 278 | // Get the short link 279 | $shorty = wp_get_shortlink( $post->ID, 'post', false ); 280 | 281 | // Return text, maybe with appended short-link 282 | return ! empty( $shorty ) 283 | ? "{$text} - {$shorty}" 284 | : $text; 285 | } 286 | -------------------------------------------------------------------------------- /publishiza/keyring/admin-ui.php: -------------------------------------------------------------------------------- 1 | Keyring) which includes: 5 | * - managing Service credentials 6 | * - creating connections 7 | * - deleting connections 8 | * - (coming soon) managing active/inactive Services 9 | * 10 | * Run Keyring with KEYRING__HEADLESS_MODE defined as true to disable all UI. 11 | * 12 | * @package Keyring 13 | */ 14 | class Keyring_Admin_UI { 15 | var $keyring = false; 16 | 17 | function __construct() { 18 | add_action( 'admin_menu', array( $this, 'admin_menu' ) ); 19 | } 20 | 21 | static function &init() { 22 | static $instance = false; 23 | 24 | if ( !$instance ) { 25 | $instance = new Keyring_Admin_UI; 26 | } 27 | 28 | return $instance; 29 | } 30 | 31 | function inline_css() { 32 | ?>keyring = Keyring::init(); 47 | add_action( 'admin_head', array( $this, 'inline_css' ) ); 48 | } 49 | 50 | function admin_page_header( $screen = false ) { 51 | // Output the actual heading + icon for the page 52 | echo '
'; 53 | screen_icon( 'ms-admin' ); 54 | switch ( $screen ) { 55 | case 'tokens' : 56 | echo '

' . __( 'Keyring: Service Connections', 'keyring' ) . ' ' . __( 'Add New', 'keyring' ) . '

'; 57 | break; 58 | case 'services' : 59 | echo '

' . __( 'Add New Connection', 'keyring' ) . '

'; 60 | echo '

' . __( '← Back', 'keyring' ) . '

'; 61 | break; 62 | case 'error' : 63 | echo '

' . __( 'Keyring Error!', 'keyring' ) . '

'; 64 | break; 65 | default : 66 | echo '

' . __( 'Keyring', 'keyring' ) . '

'; 67 | } 68 | 69 | // Output any errors if we have them, then stop, and link back to home. 70 | if ( $this->keyring->has_errors() ) { 71 | echo '
    '; 72 | foreach ( $this->keyring->get_errors() as $error ) { 73 | echo "
  • " . esc_html( $error ) . "
  • "; 74 | } 75 | echo '
'; 76 | return; 77 | } 78 | 79 | // Output any messages as part of the UI (don't abort). 80 | if ( $this->keyring->has_messages() ) { 81 | echo '
    '; 82 | foreach ( $this->keyring->get_messages() as $message ) { 83 | echo "
  • " . esc_html( $message ) . "
  • "; 84 | } 85 | echo '
'; 86 | } 87 | } 88 | 89 | static function admin_page_footer() { 90 | echo '
'; // class="wrap" 91 | } 92 | 93 | function admin_page() { 94 | // Handle delete request. Will default back to "tokens" later 95 | if ( isset( $_REQUEST['action'] ) && 'delete' == $_REQUEST['action'] ) { 96 | if ( !isset( $_REQUEST['nonce'] ) || !wp_verify_nonce( $_REQUEST['nonce'], 'keyring-delete-' . $_REQUEST['service'] . '-' . $_REQUEST['token'] ) ) { 97 | Keyring::error( __( 'Invalid/missing delete nonce.', 'keyring' ) ); 98 | exit; 99 | } 100 | 101 | if ( $this->keyring->get_token_store()->delete( array( 'id' => (int) $_REQUEST['token'], 'type' => 'access' ) ) ) 102 | Keyring::message( __( 'That connection has been deleted.', 'keyring' ) ); 103 | else 104 | Keyring::message( __( 'Could not delete that connection!', 'keyring' ) ); 105 | } 106 | 107 | // Handle test request. Will default back to "tokens" later 108 | if ( isset( $_REQUEST['action'] ) && 'test' == $_REQUEST['action'] ) { 109 | if ( !isset( $_REQUEST['nonce'] ) || !wp_verify_nonce( $_REQUEST['nonce'], 'keyring-test-' . $_REQUEST['service'] . '-' . $_REQUEST['token'] ) ) { 110 | Keyring::error( __( 'Invalid/missing testing nonce.', 'keyring' ) ); 111 | exit; 112 | } 113 | 114 | // If the test_connection() method exists, call it for this service/connection 115 | $service = $this->keyring->get_service_by_name( $_REQUEST['service'] ); 116 | if ( method_exists( $service, 'test_connection' ) ) { 117 | $service->set_token( $this->keyring->get_token_store()->get_token( array( 'id' => $_REQUEST['token'], 'type' => 'request' ) ) ); 118 | 119 | $test = $service->test_connection(); 120 | if ( true === $test ) { 121 | Keyring::message( __( 'This connection appears to be working.', 'keyring' ) ); 122 | } else { 123 | Keyring::error( __( 'This connection is NOT working correctly.', 'keyring' ), $test, false ); 124 | } 125 | } else { 126 | Keyring::message( __( 'This service does not currently support connection testing.', 'keyring' ) ); 127 | } 128 | 129 | } 130 | 131 | // Set up our defaults 132 | $service = ''; 133 | if ( !empty( $_REQUEST['service'] ) ) 134 | $service = $_REQUEST['service']; 135 | 136 | $action = 'tokens'; 137 | if ( isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], array( 'tokens', 'services', 'request', 'verify', 'manage' ) ) ) { 138 | $action = $_REQUEST['action']; 139 | } 140 | 141 | // Prevent non-admins from accessing any management UI 142 | if ( 'manage' == $action && ! current_user_can( 'manage_options' ) ) { 143 | $action = 'tokens'; 144 | } 145 | 146 | // Custom UI optionally hooked in to handle this service/action. Trigger action 147 | // and assume it handles everything, so bail out after that. 148 | if ( Keyring_Util::has_custom_ui( $service, $action ) ) { 149 | do_action( "keyring_{$service}_{$action}_ui" ); 150 | return; 151 | } 152 | 153 | // Nothing else has bailed, so it must be one of our default/core screens. 154 | switch ( $action ) { 155 | case 'tokens' : 156 | $this->admin_page_header( 'tokens' ); 157 | 158 | $list_table = new Keyring_Connections_List_Table(); 159 | $list_table->display(); 160 | 161 | $this->admin_page_footer(); 162 | break; 163 | 164 | case 'services' : 165 | $this->admin_page_header( 'services' ); 166 | 167 | $services = $this->keyring->get_registered_services(); 168 | if ( count( $services ) ) { 169 | $configured = $not_configured = array(); 170 | foreach ( $services as $service ) { 171 | if ( $service->is_configured() ) 172 | $configured[] = $service; 173 | else 174 | $not_configured[] = $service; 175 | } 176 | 177 | if ( count( $configured ) ) { 178 | echo '

' . __( 'Click a service to create a new connection:', 'keyring' ) . '

'; 179 | echo '

'; 194 | } else { 195 | echo '

' . __( 'There are no fully-configured services available to connect to.', 'keyring' ) . '

'; 196 | } 197 | 198 | if ( current_user_can( 'manage_options' ) && count( $not_configured ) ) { 199 | echo '

' . __( 'The following services need to be configured correctly before you can connect to them.', 'keyring' ) . '

'; 200 | echo ''; 210 | } 211 | } 212 | 213 | $this->admin_page_footer(); 214 | break; 215 | } 216 | } 217 | } 218 | 219 | /** WordPress List Table Administration API and base class */ 220 | require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; 221 | 222 | class Keyring_Connections_List_Table extends WP_List_Table { 223 | var $keyring = false; 224 | function __construct() { 225 | $this->keyring = Keyring::init(); 226 | 227 | parent::__construct( array( 228 | 'singular' => 'connection', 229 | 'plural' => 'connections', 230 | 'screen' => $this->keyring->admin_page, 231 | ) ); 232 | 233 | $this->items = Keyring::get_token_store()->get_tokens(); 234 | } 235 | 236 | function no_items() { 237 | echo '

' . sprintf( __( 'You haven\'t added any connections yet. Add a New Connection.', 'keyring' ), esc_url( Keyring_Util::admin_url( false, array( 'action' => 'services' ) ) ) ) . '

'; 238 | } 239 | 240 | function get_columns() { 241 | return array( 242 | 'service' => __( 'Service', 'keyring' ), 243 | 'avatar' => __( 'Avatar', 'keyring' ), 244 | 'id' => __( 'External ID', 'keyring' ), 245 | 'name' => __( 'Name', 'keyring' ), 246 | 'meta' => __( 'Meta', 'keyring' ), 247 | 'actions' => ' ' 248 | ); 249 | } 250 | 251 | function column_service( $row ) { 252 | echo $row->get_service()->get_label(); 253 | } 254 | 255 | function column_avatar( $row ) { 256 | $picture = set_url_scheme( $row->get_meta( 'picture' ) ); 257 | if ( $picture ) { 258 | echo '' . __( 'Avatar', 'keyring' ) . ''; 259 | } else { 260 | echo '-'; 261 | } 262 | } 263 | 264 | function column_id( $row ) { 265 | echo $row->get_meta( 'user_id' ); 266 | } 267 | 268 | function column_name( $row ) { 269 | // Make a few attempts to get something to display here 270 | $name = $row->get_meta( 'name' ); 271 | if ( !$name ) 272 | $name = $row->get_meta( 'username' ); 273 | if ( !$name ) 274 | $name = trim( $row->get_meta( 'first_name' ) . ' ' . $row->get_meta( 'last_name' ) ); 275 | 276 | if ( $name ) 277 | echo $name; 278 | else 279 | echo '-'; 280 | } 281 | 282 | function column_meta( $row ) { 283 | echo 'Show'; 284 | echo ''; 289 | } 290 | 291 | function column_actions( $row ) { 292 | $kr_delete_nonce = wp_create_nonce( 'keyring-delete' ); 293 | $delete_nonce = wp_create_nonce( 'keyring-delete-' . $row->get_service()->get_name() . '-' . $row->get_uniq_id() ); 294 | 295 | $kr_test_nonce = wp_create_nonce( 'keyring-test' ); 296 | $test_nonce = wp_create_nonce( 'keyring-test-' . $row->get_service()->get_name() . '-' . $row->get_uniq_id() ); 297 | 298 | echo ''; 299 | echo 'Delete'; 300 | echo ' | '; 301 | echo 'Test'; 302 | echo ''; 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/CHANGELOG.txt: -------------------------------------------------------------------------------- 1 | == 2008.08.04 == 2 | * Added LICENSE.txt file with MIT license, copyright owner is perhaps 3 | dubious however. 4 | == 2008.07.22 == 5 | * Change to encoding to fix last change to encoding of spaces 6 | == 2008.07.15 == 7 | * Another change to encoding per 8 | http://groups.google.com/group/oauth/browse_thread/thread/d39931d39b4af4bd 9 | * A change to port handling to better deal with https and the like per 10 | http://groups.google.com/group/oauth/browse_thread/thread/1b203a51d9590226 11 | * Fixed a small bug per 12 | http://code.google.com/p/oauth/issues/detail?id=26 13 | * Added missing base_string debug info when using RSA-SHA1 14 | * Increased size of example endpoint input field and added note about 15 | query strings 16 | == 2009-2011.03.28 == 17 | * Heaps of bug-fixes 18 | * Introduction of PHPUnit testcases (which aided in above mentioned bug-fixes) 19 | * Added support Revision A auth flows. 20 | * Possibly more, I've lost track.. 21 | == 2001.03.29 == 22 | * Fixed issue with hosts not being normalized correctly 23 | http://tools.ietf.org/html/rfc5849#section-3.4.1.2 24 | http://code.google.com/p/oauth/issues/detail?id=176 25 | http://code.google.com/p/oauth/issues/detail?id=187 26 | * Changed signature comparing to be timing insensitive 27 | http://code.google.com/p/oauth/issues/detail?id=178 28 | * Fixed issue with Host header on some servers on non-standard port includes the port-number 29 | http://code.google.com/p/oauth/issues/detail?id=170 30 | http://code.google.com/p/oauth/issues/detail?id=192 -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2007 Andy Smith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/OAuthTests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | tests 4 | 5 | 6 | 7 | tests 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/OAuth_TestServer.php: -------------------------------------------------------------------------------- 1 | signature_methods; 7 | } 8 | } 9 | 10 | class TestOAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod_RSA_SHA1 { 11 | public function fetch_private_cert(&$request) { 12 | $cert = <<consumer = new OAuthConsumer("key", "secret", NULL); 62 | $this->request_token = new OAuthToken("requestkey", "requestsecret", 1); 63 | $this->access_token = new OAuthToken("accesskey", "accesssecret", 1); 64 | $this->nonce = "nonce"; 65 | }/*}}}*/ 66 | 67 | function lookup_consumer($consumer_key) {/*{{{*/ 68 | if ($consumer_key == $this->consumer->key) return $this->consumer; 69 | return NULL; 70 | }/*}}}*/ 71 | 72 | function lookup_token($consumer, $token_type, $token) {/*{{{*/ 73 | $token_attrib = $token_type . "_token"; 74 | if ($consumer->key == $this->consumer->key 75 | && $token == $this->$token_attrib->key) { 76 | return $this->$token_attrib; 77 | } 78 | return NULL; 79 | }/*}}}*/ 80 | 81 | function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/ 82 | if ($consumer->key == $this->consumer->key 83 | && (($token && $token->key == $this->request_token->key) 84 | || ($token && $token->key == $this->access_token->key)) 85 | && $nonce == $this->nonce) { 86 | return $this->nonce; 87 | } 88 | return NULL; 89 | }/*}}}*/ 90 | 91 | function new_request_token($consumer) {/*{{{*/ 92 | if ($consumer->key == $this->consumer->key) { 93 | return $this->request_token; 94 | } 95 | return NULL; 96 | }/*}}}*/ 97 | 98 | function new_access_token($token, $consumer) {/*{{{*/ 99 | if ($consumer->key == $this->consumer->key 100 | && $token->key == $this->request_token->key) { 101 | return $this->access_token; 102 | } 103 | return NULL; 104 | }/*}}}*/ 105 | }/*}}}*/ 106 | ?> 107 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/doc/design.txt: -------------------------------------------------------------------------------- 1 | Interfaces: 2 | 3 | # OAuthConsumer is a data type that represents the identity of the Consumer 4 | # via its shared secret with the Service Provider. 5 | OAuthConsumer 6 | - key : str 7 | - secret : str 8 | 9 | # OAuthToken is a data type that represents an End User via either an access 10 | # or request token 11 | OAuthToken 12 | - token : str 13 | - secret : str 14 | - to_string() -> str 15 | - (static) from_string() -> OAuthToken 16 | 17 | # OAuthSignatureMethod is a strategy class that implements a signature method 18 | OAuthSignatureMethod 19 | - get_name() -> str 20 | - build_signature (OAuthRequest, OAuthConsumer, OAuthToken) -> str 21 | 22 | # OAuthRequest represents the request and can be seriali 23 | OAuthRequest: 24 | - OAuthRequest(str http_method, str http_url, [dict parameters]) -> constructor 25 | - set_parameter(str parameter, str value) -> void 26 | - example parameters: oauth_consumer_key, foo 27 | - get_parameter(str parameter) -> str 28 | - get_parameters() -> dict 29 | 30 | - get_normalized_http_method() -> str 31 | - get_normalized_http_url() -> str 32 | - get_signable_params() -> dict 33 | 34 | - to_header () -> str # serialize as a header for an HTTPAuth request 35 | - to_postdata () -> str # serialize as post data for a POST request 36 | - to_url () -> str # serialize as a url for a GET request 37 | - sign_request(OAuthSignatureMethod, OAuthConsumer, OAuthToken) -> void 38 | - build_signature(OAuthSignatureMethod, OAuthConsumer, OAuthToken) -> str 39 | - (static) from_request([str http_method, str http_url, dict parameters]) 40 | - (static) from_consumer_and_token(OAuthConsumer, OAuthToken, str http_method, str http_url, [dict parameters]) -> OAuthRequest 41 | 42 | 43 | # OAuthServer is a worker to check a requests validity against a data store 44 | OAuthServer: 45 | - OAuthServer(OAuthDataStore) -> constructor 46 | - set_data_store(OAuthDataStore) -> void 47 | - get_data_store() -> OAuthDataStore 48 | 49 | - fetch_request_token (OAuthRequest) -> OAuthToken 50 | - fetch_access_token (OAuthRequest) -> OAuthToken 51 | - verify_request (OAuthRequest) -> OAuthToken 52 | 53 | # OAuthClient is a worker to attempt to execute a request 54 | OAuthClient: 55 | - OAuthClient(OAuthConsumer, OAuthToken) -> constructor 56 | - get_consumer() -> OAuthConsumer 57 | - get_token() -> OAuthToken 58 | 59 | - fetch_request_token (OAuthRequest) -> OAuthToken 60 | - fetch_access_token (OAuthRequest) -> OAuthToken 61 | 62 | # OAuthDataStore is a database abstraction used to lookup consumers and tokens 63 | OAuthDataStore: 64 | - lookup_consumer(str key) -> OAuthConsumer 65 | - lookup_token(OAuthConsumer, str token_type, str token_token) -> OAuthToken 66 | - lookup_nonce(OAuthConsumer, OAuthToken, str nonce, int timestamp) -> OAuthToken 67 | - fetch_request_token(OAuthConsumer) -> OAuthToken 68 | - fetch_access_token(OAuthConsumer, OAuthToken) -> OAuthToken 69 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/Mock_OAuthBaseStringRequest.php: -------------------------------------------------------------------------------- 1 | provided_base_string = $bs; } 11 | public function get_signature_base_string() { return $this->provided_base_string; } 12 | } 13 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/Mock_OAuthDataStore.php: -------------------------------------------------------------------------------- 1 | consumer = new OAuthConsumer("key", "secret", NULL); 14 | $this->request_token = new OAuthToken("requestkey", "requestsecret", 1); 15 | $this->access_token = new OAuthToken("accesskey", "accesssecret", 1); 16 | $this->nonce = "nonce"; 17 | } 18 | 19 | function lookup_consumer($consumer_key) { 20 | if ($consumer_key == $this->consumer->key) return $this->consumer; 21 | return NULL; 22 | } 23 | 24 | function lookup_token($consumer, $token_type, $token) { 25 | $token_attrib = $token_type . "_token"; 26 | if ($consumer->key == $this->consumer->key 27 | && $token == $this->$token_attrib->key) { 28 | return $this->$token_attrib; 29 | } 30 | return NULL; 31 | } 32 | 33 | function lookup_nonce($consumer, $token, $nonce, $timestamp) { 34 | if ($consumer->key == $this->consumer->key 35 | && (($token && $token->key == $this->request_token->key) 36 | || ($token && $token->key == $this->access_token->key)) 37 | && $nonce == $this->nonce) { 38 | return $this->nonce; 39 | } 40 | return NULL; 41 | } 42 | 43 | function new_request_token($consumer, $callback = null) { 44 | if ($consumer->key == $this->consumer->key) { 45 | return $this->request_token; 46 | } 47 | return NULL; 48 | } 49 | 50 | function new_access_token($token, $consumer, $verifier = null) { 51 | if ($consumer->key == $this->consumer->key 52 | && $token->key == $this->request_token->key) { 53 | return $this->access_token; 54 | } 55 | return NULL; 56 | } 57 | } -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/Mock_OAuthSignatureMethod_RSA_SHA1.php: -------------------------------------------------------------------------------- 1 | assertEquals('OAuthConsumer[key=key,secret=secret]', (string) $consumer); 9 | } 10 | } -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/OAuthServerTest.php: -------------------------------------------------------------------------------- 1 | consumer = new OAuthConsumer('key', 'secret'); 19 | $this->request_token = new OAuthToken('requestkey', 'requestsecret'); 20 | $this->access_token = new OAuthToken('accesskey', 'accesssecret'); 21 | 22 | $this->hmac_sha1 = new OAuthSignatureMethod_HMAC_SHA1(); 23 | $this->plaintext = new OAuthSignatureMethod_PLAINTEXT(); 24 | 25 | $this->server = new OAuthServer( new Mock_OAuthDataStore() ); 26 | $this->server->add_signature_method( $this->hmac_sha1 ); 27 | $this->server->add_signature_method( $this->plaintext ); 28 | } 29 | 30 | public function testAcceptValidRequest() { 31 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 32 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 33 | list($consumer, $token) = $this->server->verify_request( $request ); 34 | $this->assertEquals( $this->consumer, $consumer ); 35 | $this->assertEquals( $this->access_token, $token ); 36 | 37 | $request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token ); 38 | list($consumer, $token) = $this->server->verify_request( $request ); 39 | $this->assertEquals( $this->consumer, $consumer ); 40 | $this->assertEquals( $this->access_token, $token ); 41 | } 42 | 43 | public function testAcceptRequestWithoutVersion() { 44 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 45 | $request->unset_parameter('oauth_version'); 46 | $request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token ); 47 | 48 | $this->server->verify_request( $request ); 49 | } 50 | 51 | public function testRejectRequestSignedWithRequestToken() { 52 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com'); 53 | $request->sign_request( $this->plaintext, $this->consumer, $this->request_token ); 54 | 55 | $this->setExpectedException('OAuthException'); 56 | $this->server->verify_request( $request ); 57 | } 58 | 59 | public function testRejectRequestWithMissingParameters() { 60 | // The list of required parameters is taken from 61 | // Chapter 7 ("Accessing Protected Resources") 62 | 63 | $required_parameters = array( 64 | 'oauth_consumer_key', 65 | 'oauth_token', 66 | 'oauth_signature_method', 67 | 'oauth_signature', 68 | 'oauth_timestamp', 69 | 'oauth_nonce' 70 | ); 71 | 72 | foreach( $required_parameters AS $required ) { 73 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 74 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 75 | try { 76 | $request->unset_parameter( $required ); 77 | $this->server->verify_request($request); 78 | $this->fail('Allowed a request without `' . $required . '`'); 79 | } catch( OAuthException $e ) { /* expected */ } 80 | } 81 | } 82 | 83 | public function testRejectPastTimestamp() { 84 | // We change the timestamp to be 10 hours ago, it should throw an exception 85 | 86 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 87 | $request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') - 10*60*60, false); 88 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 89 | 90 | $this->setExpectedException('OAuthException'); 91 | $this->server->verify_request($request); 92 | } 93 | 94 | public function testRejectFutureTimestamp() { 95 | // We change the timestamp to be 10 hours in the future, it should throw an exception 96 | 97 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 98 | $request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') + 10*60*60, false); 99 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 100 | 101 | $this->setExpectedException('OAuthException'); 102 | $this->server->verify_request($request); 103 | } 104 | 105 | public function testRejectUsedNonce() { 106 | // We give a known nonce and should see an exception 107 | 108 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 109 | // The Mock datastore is set to say that the `nonce` nonce is known 110 | $request->set_parameter( 'oauth_nonce', 'nonce', false); 111 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 112 | 113 | $this->setExpectedException('OAuthException'); 114 | $this->server->verify_request($request); 115 | } 116 | 117 | public function testRejectInvalidSignature() { 118 | // We change the signature post-signing to be something invalid 119 | 120 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 121 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 122 | $request->set_parameter( 'oauth_signature', '__whatever__', false); 123 | 124 | $this->setExpectedException('OAuthException'); 125 | $this->server->verify_request($request); 126 | } 127 | 128 | public function testRejectInvalidConsumer() { 129 | // We use the consumer-key "unknown", which isn't known by the datastore. 130 | 131 | $unknown_consumer = new OAuthConsumer('unknown', '__unused__'); 132 | 133 | $request = OAuthRequest::from_consumer_and_token( $unknown_consumer, $this->access_token, 'POST', 'http://example.com'); 134 | $request->sign_request( $this->plaintext, $unknown_consumer, $this->access_token ); 135 | 136 | $this->setExpectedException('OAuthException'); 137 | $this->server->verify_request( $request ); 138 | } 139 | 140 | public function testRejectInvalidToken() { 141 | // We use the access-token "unknown" which isn't known by the datastore 142 | 143 | $unknown_token = new OAuthToken('unknown', '__unused__'); 144 | 145 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $unknown_token, 'POST', 'http://example.com'); 146 | $request->sign_request( $this->plaintext, $this->consumer, $unknown_token ); 147 | 148 | $this->setExpectedException('OAuthException'); 149 | $this->server->verify_request( $request ); 150 | } 151 | 152 | public function testRejectUnknownSignatureMethod() { 153 | // We use a server that only supports HMAC-SHA1, but requests with PLAINTEXT signature 154 | 155 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 156 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 157 | 158 | $server = new OAuthServer( new Mock_OAuthDataStore() ); 159 | $server->add_signature_method( $this->hmac_sha1 ); 160 | 161 | $this->setExpectedException('OAuthException'); 162 | $server->verify_request( $request ); 163 | } 164 | 165 | public function testRejectUnknownVersion() { 166 | // We use the version "1.0a" which isn't "1.0", so reject the request 167 | 168 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 169 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 170 | $request->set_parameter('oauth_version', '1.0a', false); 171 | 172 | $this->setExpectedException('OAuthException'); 173 | $this->server->verify_request( $request ); 174 | } 175 | 176 | public function testCreateRequestToken() { 177 | // We request a new Request Token 178 | 179 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com'); 180 | $request->sign_request( $this->plaintext, $this->consumer, NULL ); 181 | 182 | $token = $this->server->fetch_request_token($request); 183 | $this->assertEquals($this->request_token, $token); 184 | } 185 | 186 | public function testRejectSignedRequestTokenRequest() { 187 | // We request a new Request Token, but the request is signed with a token which should fail 188 | 189 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com'); 190 | $request->sign_request( $this->plaintext, $this->consumer, $this->request_token ); 191 | 192 | $this->setExpectedException('OAuthException'); 193 | $token = $this->server->fetch_request_token($request); 194 | } 195 | 196 | public function testCreateAccessToken() { 197 | // We request a new Access Token 198 | 199 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com'); 200 | $request->sign_request( $this->plaintext, $this->consumer, $this->request_token ); 201 | 202 | $token = $this->server->fetch_access_token($request); 203 | $this->assertEquals($this->access_token, $token); 204 | } 205 | 206 | public function testRejectUnsignedAccessTokenRequest() { 207 | // We request a new Access Token, but we didn't sign the request with a Access Token 208 | 209 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com'); 210 | $request->sign_request( $this->plaintext, $this->consumer, NULL ); 211 | 212 | $this->setExpectedException('OAuthException'); 213 | $token = $this->server->fetch_access_token($request); 214 | } 215 | 216 | public function testRejectAccessTokenSignedAccessTokenRequest() { 217 | // We request a new Access Token, but the request is signed with an access token, so fail! 218 | 219 | $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); 220 | $request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); 221 | 222 | $this->setExpectedException('OAuthException'); 223 | $token = $this->server->fetch_access_token($request); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/OAuthSignatureMethodHmacSha1Test.php: -------------------------------------------------------------------------------- 1 | method = new OAuthSignatureMethod_HMAC_SHA1(); 11 | } 12 | 13 | public function testIdentifyAsHmacSha1() { 14 | $this->assertEquals('HMAC-SHA1', $this->method->get_name()); 15 | } 16 | 17 | public function testBuildSignature() { 18 | // Tests taken from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1") 19 | $request = new Mock_OAuthBaseStringRequest('bs'); 20 | $consumer = new OAuthConsumer('__unused__', 'cs'); 21 | $token = NULL; 22 | $this->assertEquals('egQqG5AJep5sJ7anhXju1unge2I=', $this->method->build_signature( $request, $consumer, $token) ); 23 | 24 | $request = new Mock_OAuthBaseStringRequest('bs'); 25 | $consumer = new OAuthConsumer('__unused__', 'cs'); 26 | $token = new OAuthToken('__unused__', 'ts'); 27 | $this->assertEquals('VZVjXceV7JgPq/dOTnNmEfO0Fv8=', $this->method->build_signature( $request, $consumer, $token) ); 28 | 29 | $request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26' 30 | . 'oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26' 31 | . 'oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); 32 | $consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44'); 33 | $token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00'); 34 | $this->assertEquals('tR3+Ty81lMeYAr/Fid0kMTYa/WM=', $this->method->build_signature( $request, $consumer, $token) ); 35 | } 36 | 37 | public function testVerifySignature() { 38 | // Tests taken from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1") 39 | $request = new Mock_OAuthBaseStringRequest('bs'); 40 | $consumer = new OAuthConsumer('__unused__', 'cs'); 41 | $token = NULL; 42 | $signature = 'egQqG5AJep5sJ7anhXju1unge2I='; 43 | $this->assertTrue( $this->method->check_signature( $request, $consumer, $token, $signature) ); 44 | 45 | $request = new Mock_OAuthBaseStringRequest('bs'); 46 | $consumer = new OAuthConsumer('__unused__', 'cs'); 47 | $token = new OAuthToken('__unused__', 'ts'); 48 | $signature = 'VZVjXceV7JgPq/dOTnNmEfO0Fv8='; 49 | $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); 50 | 51 | $request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26' 52 | . 'oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26' 53 | . 'oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); 54 | $consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44'); 55 | $token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00'); 56 | $signature = 'tR3+Ty81lMeYAr/Fid0kMTYa/WM='; 57 | $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); 58 | 59 | } 60 | } -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/OAuthSignatureMethodPlaintextTest.php: -------------------------------------------------------------------------------- 1 | method = new OAuthSignatureMethod_PLAINTEXT(); 11 | } 12 | 13 | public function testIdentifyAsPlaintext() { 14 | $this->assertEquals('PLAINTEXT', $this->method->get_name()); 15 | } 16 | 17 | public function testBuildSignature() { 18 | // Tests based on from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1") 19 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 20 | $consumer = new OAuthConsumer('__unused__', 'cs'); 21 | $token = NULL; 22 | $this->assertEquals('cs&', $this->method->build_signature( $request, $consumer, $token) ); 23 | 24 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 25 | $consumer = new OAuthConsumer('__unused__', 'cs'); 26 | $token = new OAuthToken('__unused__', 'ts'); 27 | $this->assertEquals('cs&ts', $this->method->build_signature( $request, $consumer, $token) ); 28 | 29 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 30 | $consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44'); 31 | $token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00'); 32 | $this->assertEquals('kd94hf93k423kf44&pfkkdhi9sl3r4s00', $this->method->build_signature( $request, $consumer, $token) ); 33 | 34 | // Tests taken from Chapter 9.4.1 ("Generating Signature") from the spec 35 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 36 | $consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88'); 37 | $token = new OAuthToken('__unused__', 'jjd999tj88uiths3'); 38 | $this->assertEquals('djr9rjt0jd78jf88&jjd999tj88uiths3', $this->method->build_signature( $request, $consumer, $token) ); 39 | 40 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 41 | $consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88'); 42 | $token = new OAuthToken('__unused__', 'jjd99$tj88uiths3'); 43 | $this->assertEquals('djr9rjt0jd78jf88&jjd99%24tj88uiths3', $this->method->build_signature( $request, $consumer, $token) ); 44 | } 45 | 46 | public function testVerifySignature() { 47 | // Tests based on from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1") 48 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 49 | $consumer = new OAuthConsumer('__unused__', 'cs'); 50 | $token = NULL; 51 | $signature = 'cs&'; 52 | $this->assertTrue( $this->method->check_signature( $request, $consumer, $token, $signature) ); 53 | 54 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 55 | $consumer = new OAuthConsumer('__unused__', 'cs'); 56 | $token = new OAuthToken('__unused__', 'ts'); 57 | $signature = 'cs&ts'; 58 | $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); 59 | 60 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 61 | $consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44'); 62 | $token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00'); 63 | $signature = 'kd94hf93k423kf44&pfkkdhi9sl3r4s00'; 64 | $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); 65 | 66 | // Tests taken from Chapter 9.4.1 ("Generating Signature") from the spec 67 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 68 | $consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88'); 69 | $token = new OAuthToken('__unused__', 'jjd999tj88uiths3'); 70 | $signature = 'djr9rjt0jd78jf88&jjd999tj88uiths3'; 71 | $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); 72 | 73 | $request = new Mock_OAuthBaseStringRequest('__unused__'); 74 | $consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88'); 75 | $token = new OAuthToken('__unused__', 'jjd99$tj88uiths3'); 76 | $signature = 'djr9rjt0jd78jf88&jjd99%24tj88uiths3'; 77 | $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); 78 | } 79 | } -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/OAuthSignatureMethodRsaSha1Test.php: -------------------------------------------------------------------------------- 1 | method = new Mock_OAuthSignatureMethod_RSA_SHA1(); 12 | } 13 | 14 | public function testIdentifyAsRsaSha1() { 15 | $this->assertEquals('RSA-SHA1', $this->method->get_name()); 16 | } 17 | 18 | public function testBuildSignature() { 19 | if( ! function_exists('openssl_get_privatekey') ) { 20 | $this->markTestSkipped('OpenSSL not available, can\'t test RSA-SHA1 functionality'); 21 | } 22 | 23 | // Tests taken from http://wiki.oauth.net/TestCases section 9.3 ("RSA-SHA1") 24 | $request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacaction.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3D13917289812797014437%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1196666512%26oauth_version%3D1.0%26size%3Doriginal'); 25 | $consumer = new OAuthConsumer('dpf43f3p2l4k3l03', '__unused__'); 26 | $token = NULL; 27 | $signature = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE='; 28 | $this->assertEquals($signature, $this->method->build_signature( $request, $consumer, $token) ); 29 | } 30 | 31 | public function testVerifySignature() { 32 | if( ! function_exists('openssl_get_privatekey') ) { 33 | $this->markTestSkipped('OpenSSL not available, can\'t test RSA-SHA1 functionality'); 34 | } 35 | 36 | // Tests taken from http://wiki.oauth.net/TestCases section 9.3 ("RSA-SHA1") 37 | $request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacaction.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3D13917289812797014437%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1196666512%26oauth_version%3D1.0%26size%3Doriginal'); 38 | $consumer = new OAuthConsumer('dpf43f3p2l4k3l03', '__unused__'); 39 | $token = NULL; 40 | $signature = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE='; 41 | $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); 42 | } 43 | } -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/OAuthTokenTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('oauth_token=token&oauth_token_secret=secret', $token->to_string()); 9 | 10 | $token = new OAuthToken('token&', 'secret%'); 11 | $this->assertEquals('oauth_token=token%26&oauth_token_secret=secret%25', $token->to_string()); 12 | } 13 | public function testConvertToString() { 14 | $token = new OAuthToken('token', 'secret'); 15 | $this->assertEquals('oauth_token=token&oauth_token_secret=secret', (string) $token); 16 | 17 | $token = new OAuthToken('token&', 'secret%'); 18 | $this->assertEquals('oauth_token=token%26&oauth_token_secret=secret%25', (string) $token); 19 | } 20 | } -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/OAuthUtilTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('abcABC123', OAuthUtil::urlencode_rfc3986('abcABC123')); 13 | $this->assertEquals('-._~', OAuthUtil::urlencode_rfc3986('-._~')); 14 | $this->assertEquals('%25', OAuthUtil::urlencode_rfc3986('%')); 15 | $this->assertEquals('%2B', OAuthUtil::urlencode_rfc3986('+')); 16 | $this->assertEquals('%0A', OAuthUtil::urlencode_rfc3986("\n")); 17 | $this->assertEquals('%20', OAuthUtil::urlencode_rfc3986(' ')); 18 | $this->assertEquals('%7F', OAuthUtil::urlencode_rfc3986("\x7F")); 19 | //$this->assertEquals('%C2%80', OAuthUtil::urlencode_rfc3986("\x00\x80")); 20 | //$this->assertEquals('%E3%80%81', OAuthUtil::urlencode_rfc3986("\x30\x01")); 21 | 22 | // Last two checks disabled because of lack of UTF-8 support, or lack 23 | // of knowledge from me (morten.fangel) on how to use it properly.. 24 | 25 | // A few tests to ensure code-coverage 26 | $this->assertEquals( '', OAuthUtil::urlencode_rfc3986(NULL)); 27 | $this->assertEquals( '', OAuthUtil::urlencode_rfc3986(new stdClass())); 28 | } 29 | 30 | public function testUrldecode() { 31 | // Tests taken from 32 | // http://wiki.oauth.net/TestCases ("Parameter Encoding") 33 | $this->assertEquals('abcABC123', OAuthUtil::urldecode_rfc3986('abcABC123')); 34 | $this->assertEquals('-._~', OAuthUtil::urldecode_rfc3986('-._~')); 35 | $this->assertEquals('%', OAuthUtil::urldecode_rfc3986('%25')); 36 | $this->assertEquals('+', OAuthUtil::urldecode_rfc3986('%2B')); 37 | $this->assertEquals("\n", OAuthUtil::urldecode_rfc3986('%0A')); 38 | $this->assertEquals(' ', OAuthUtil::urldecode_rfc3986('%20')); 39 | $this->assertEquals("\x7F", OAuthUtil::urldecode_rfc3986('%7F')); 40 | //$this->assertEquals("\x00\x80", OAuthUtil::urldecode_rfc3986('%C2%80')); 41 | //$this->assertEquals("\x30\x01", OAuthUtil::urldecode_rfc3986('%E3%80%81')); 42 | 43 | // Last two checks disabled because of lack of UTF-8 support, or lack 44 | // of knowledge from me (morten.fangel) on how to use it properly.. 45 | } 46 | 47 | public function testParseParameter() { 48 | // Tests taken from 49 | // http://wiki.oauth.net/TestCases ("Normalize Request Parameters") 50 | 51 | $this->assertEquals( 52 | array('name'=>''), 53 | OAuthUtil::parse_parameters('name') 54 | ); 55 | $this->assertEquals( 56 | array('a'=>'b'), 57 | OAuthUtil::parse_parameters('a=b') 58 | ); 59 | $this->assertEquals( 60 | array('a'=>'b','c'=>'d'), 61 | OAuthUtil::parse_parameters('a=b&c=d') 62 | ); 63 | $this->assertEquals( 64 | array('a'=>array('x!y','x y')), 65 | OAuthUtil::parse_parameters('a=x!y&a=x+y') 66 | ); 67 | $this->assertEquals( 68 | array('x!y'=>'a', 'x' =>'a'), 69 | OAuthUtil::parse_parameters('x!y=a&x=a') 70 | ); 71 | } 72 | 73 | public function testBuildHttpQuery() { 74 | // Tests taken from 75 | // http://wiki.oauth.net/TestCases ("Normalize Request Parameters") 76 | $this->assertEquals( 77 | 'name=', 78 | OAuthUtil::build_http_query(array('name'=>'')) 79 | ); 80 | $this->assertEquals( 81 | 'a=b', 82 | OAuthUtil::build_http_query(array('a'=>'b')) 83 | ); 84 | $this->assertEquals( 85 | 'a=b&c=d', 86 | OAuthUtil::build_http_query(array('a'=>'b','c'=>'d')) 87 | ); 88 | $this->assertEquals( 89 | 'a=x%20y&a=x%21y', 90 | OAuthUtil::build_http_query(array('a'=>array('x!y','x y'))) 91 | ); 92 | $this->assertEquals( 93 | 'x=a&x%21y=a', 94 | OAuthUtil::build_http_query(array('x!y'=>'a', 'x' =>'a')) 95 | ); 96 | 97 | // Test taken from the Spec 9.1.1 98 | $this->assertEquals( 99 | 'a=1&c=hi%20there&f=25&f=50&f=a&z=p&z=t', 100 | OAuthUtil::build_http_query(array('a'=>'1', 'c' =>'hi there', 'f'=>array(25, 50, 'a'), 'z'=>array('p','t'))) 101 | ); 102 | 103 | // From issue 164, by hidetaka 104 | // Based on discussion at 105 | // http://groups.google.com/group/oauth/browse_thread/thread/7c698004be0d536/dced7b6c82b917b2?lnk=gst&q=sort# 106 | $this->assertEquals( 107 | 'x=200&x=25&y=B&y=a', 108 | OAuthUtil::build_http_query(array('x'=>array(25, 200), 'y'=>array('a', 'B'))) 109 | ); 110 | } 111 | 112 | public function testSplitHeader() { 113 | $this->assertEquals( 114 | array('oauth_foo'=>'bar','oauth_baz'=>'bla,rgh'), 115 | OAuthUtil::split_header('OAuth realm="",oauth_foo=bar,oauth_baz="bla,rgh"') 116 | ); 117 | $this->assertEquals( 118 | array(), 119 | OAuthUtil::split_header('OAuth realm="",foo=bar,baz="bla,rgh"') 120 | ); 121 | $this->assertEquals( 122 | array('foo'=>'bar', 'baz'=>'bla,rgh'), 123 | OAuthUtil::split_header('OAuth realm="",foo=bar,baz="bla,rgh"', false) 124 | ); 125 | $this->assertEquals( 126 | array('oauth_foo' => 'hi there'), 127 | OAuthUtil::split_header('OAuth realm="",oauth_foo=hi+there,foo=bar,baz="bla,rgh"') 128 | ); 129 | 130 | } 131 | 132 | public function testGetHeaders() { 133 | if (function_exists('apache_request_headers')) { 134 | $this->markTestSkipped('We assume the apache module is well tested. Since this module is present, no need testing our suplement'); 135 | } 136 | 137 | $_SERVER['HTTP_HOST'] = 'foo'; 138 | $_SERVER['HTTP_X_WHATEVER'] = 'bar'; 139 | $this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar'), OAuthUtil::get_headers() ); 140 | 141 | // Test picking up the Content-Type of POST requests running as an Apache module but not having the ARH method 142 | $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; 143 | $this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar', 'Content-Type'=>'application/x-www-form-urlencoded'), OAuthUtil::get_headers() ); 144 | 145 | // Test picking up the Content-Type of POST requests when using CGI 146 | unset($_SERVER['CONTENT_TYPE']); 147 | $this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar'), OAuthUtil::get_headers() ); 148 | $_ENV['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; 149 | $this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar', 'Content-Type'=>'application/x-www-form-urlencoded'), OAuthUtil::get_headers() ); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/oauth-php/tests/common.php: -------------------------------------------------------------------------------- 1 | get_name() . '_request_ui', array( $this, 'request_ui' ) ); 22 | } 23 | 24 | function get_display( Keyring_Access_Token $token ) { 25 | $meta = $token->get_meta(); 26 | return $meta['username']; 27 | } 28 | 29 | function request_ui() { 30 | // Common Header 31 | echo '
'; 32 | screen_icon( 'ms-admin' ); 33 | echo '

' . __( 'Account Details', 'keyring' ) . '

'; 34 | 35 | // Handle errors 36 | if ( isset( $_GET['error'] ) ) { 37 | echo '
    '; 38 | switch ( $_GET['error'] ) { 39 | case '401': 40 | echo '
  • ' . __( 'Your account details could not be confirmed, please try again.', 'keyring' ) . '
  • '; 41 | break; 42 | case 'empty': 43 | echo '
  • ' . __( 'Please make sure you enter a username and password.', 'keyring' ) . '
  • '; 44 | break; 45 | } 46 | echo '
'; 47 | } 48 | 49 | // Even though it doesn't make too much sense, we support request tokens in HTTP Basic 50 | // to ensure consistency with other services 51 | $request_token = new Keyring_Request_Token( 52 | $this->get_name(), 53 | array(), 54 | apply_filters( 55 | 'keyring_request_token_meta', 56 | array( 57 | 'for' => isset( $_REQUEST['for'] ) ? (string) $_REQUEST['for'] : false 58 | ), 59 | $this->get_name(), 60 | array() // no token 61 | ) 62 | ); 63 | $request_token = apply_filters( 'keyring_request_token', $request_token, $this ); 64 | $request_token_id = $this->store_token( $request_token ); 65 | Keyring_Util::debug( 'HTTP Basic Stored Request token ' . $request_token_id ); 66 | 67 | echo apply_filters( 'keyring_' . $this->get_name() . '_request_ui_intro', '' ); 68 | 69 | // Output basic form for collecting user/pass 70 | echo '

' . sprintf( __( 'Enter your username and password for accessing %s:', 'keyring' ), $this->get_label() ) . '

'; 71 | echo '
'; 72 | echo ''; 73 | echo ''; 74 | echo ''; 75 | wp_nonce_field( 'keyring-verify', 'kr_nonce', false ); 76 | wp_nonce_field( 'keyring-verify-' . $this->get_name(), 'nonce', false ); 77 | echo ''; 78 | echo ''; 79 | echo ''; 80 | echo ''; 81 | echo ''; 82 | echo '
' . __( 'Username', 'keyring' ) . '
' . __( 'Password', 'keyring' ) . '
'; 83 | echo '

'; 84 | echo ''; 85 | echo '' . __( 'Cancel', 'keyring' ) . ''; 86 | echo '

'; 87 | echo '
'; 88 | echo '
'; 89 | ?>get_name() ) ) { 102 | Keyring::error( __( 'Invalid/missing verification nonce.', 'keyring' ) ); 103 | exit; 104 | } 105 | 106 | // Load up the request token that got us here and globalize it 107 | if ( isset( $_REQUEST['state'] ) ) { 108 | global $keyring_request_token; 109 | $state = empty( $_GET['state'] ) ? '' : preg_replace( '/[^\x20-\x7E]/', '', $_GET['state'] ); 110 | $keyring_request_token = $this->store->get_token( array( 'id' => $state, 'type' => 'request' ) ); 111 | Keyring_Util::debug( 'HTTP Basic Loaded Request Token ' . $state ); 112 | Keyring_Util::debug( $keyring_request_token ); 113 | 114 | // Remove request token, don't need it any more. 115 | $this->store->delete( array( 'id' => $state, 'type' => 'request' ) ); 116 | } 117 | 118 | if ( !strlen( $_POST['username'] ) ) { 119 | $url = Keyring_Util::admin_url( 120 | $this->get_name(), 121 | array( 122 | 'action' => 'request', 123 | 'error' => 'empty', 124 | 'kr_nonce' => wp_create_nonce( 'keyring-request' ) 125 | ) 126 | ); 127 | Keyring_Util::debug( $url ); 128 | wp_safe_redirect( $url ); 129 | exit; 130 | } 131 | 132 | // HTTP Basic does not use Keyring_Request_Tokens, since there's only one step 133 | 134 | $token = new Keyring_Access_Token( 135 | $this->get_name(), 136 | base64_encode( $_POST['username'] . ':' . $_POST['password'] ) 137 | ); 138 | $this->set_token( $token ); 139 | $res = $this->request( $this->verify_url, array( 'method' => $this->verify_method ) ); 140 | 141 | // We will get a 401 if they entered an incorrect user/pass combo. ::request 142 | // will then return a Keyring_Error 143 | if ( Keyring_Util::is_error( $res ) ) { 144 | $url = Keyring_Util::admin_url( 145 | $this->get_name(), 146 | array( 147 | 'action' => 'request', 148 | 'error' => '401', 149 | 'kr_nonce' => wp_create_nonce( 'keyring-request' ) 150 | ) 151 | ); 152 | Keyring_Util::debug( $url ); 153 | wp_safe_redirect( $url ); 154 | exit; 155 | } 156 | 157 | $meta = array_merge( array( 'username' => $_POST['username'] ), $this->build_token_meta( $token ) ); 158 | 159 | $access_token = new Keyring_Access_Token( 160 | $this->get_name(), 161 | $token, 162 | $meta 163 | ); 164 | $access_token = apply_filters( 'keyring_access_token', $access_token, array() ); 165 | 166 | // If we didn't get a 401, then we'll assume it's OK 167 | $id = $this->store_token( $access_token ); 168 | $this->verified( $id, $keyring_request_token ); 169 | } 170 | 171 | function request( $url, array $params = array() ) { 172 | if ( $this->requires_token() && empty( $this->token ) ) 173 | return new Keyring_Error( 'keyring-request-error', __( 'No token' ) ); 174 | 175 | if ( $this->requires_token() ) 176 | $params['headers'] = array( 'Authorization' => 'Basic ' . $this->token ); 177 | 178 | $method = 'GET'; 179 | if ( isset( $params['method'] ) ) { 180 | $method = strtoupper( $params['method'] ); 181 | unset( $params['method'] ); 182 | } 183 | 184 | $raw_response = false; 185 | if ( isset( $params['raw_response'] ) ) { 186 | $raw_response = (bool) $params['raw_response']; 187 | unset( $params['raw_response'] ); 188 | } 189 | 190 | Keyring_Util::debug( "HTTP Basic $method $url" ); 191 | Keyring_Util::debug( $params ); 192 | 193 | switch ( strtoupper( $method ) ) { 194 | case 'GET': 195 | $res = wp_remote_get( $url, $params ); 196 | break; 197 | 198 | case 'POST': 199 | $res = wp_remote_post( $url, $params ); 200 | break; 201 | 202 | default: 203 | Keyring::error( __( 'Unsupported method specified for verify_token.', 'keyring' ) ); 204 | exit; 205 | } 206 | 207 | Keyring_Util::debug( $res ); 208 | $this->set_request_response_code( wp_remote_retrieve_response_code( $res ) ); 209 | if ( 200 == wp_remote_retrieve_response_code( $res ) || 201 == wp_remote_retrieve_response_code( $res ) ) { 210 | if ( $raw_response ) 211 | return wp_remote_retrieve_body( $res ); 212 | else 213 | return $this->parse_response( wp_remote_retrieve_body( $res ) ); 214 | } else { 215 | return new Keyring_Error( 'keyring-request-error', $res ); 216 | } 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/core/oauth2.php: -------------------------------------------------------------------------------- 1 | get_name() ) ) { 31 | Keyring::error( __( 'Invalid/missing request nonce.', 'keyring' ) ); 32 | exit; 33 | } 34 | 35 | // Need to create a request token now, so that we have a state to pass 36 | $request_token = new Keyring_Request_Token( 37 | $this->get_name(), 38 | array(), 39 | apply_filters( 40 | 'keyring_request_token_meta', 41 | array( 42 | 'for' => isset( $_REQUEST['for'] ) ? (string) $_REQUEST['for'] : false 43 | ), 44 | $this->get_name(), 45 | array(), // no token 46 | $this 47 | ) 48 | ); 49 | $request_token = apply_filters( 'keyring_request_token', $request_token, $this ); 50 | $request_token_id = $this->store_token( $request_token ); 51 | 52 | $url = $this->authorize_url; 53 | if ( !stristr( $url, '?' ) ) 54 | $url .= '?'; 55 | $params = array( 56 | 'response_type' => 'code', 57 | 'client_id' => $this->key, 58 | 'redirect_uri' => $this->callback_url, 59 | 'state' => $request_token_id, 60 | ); 61 | $params = apply_filters( 'keyring_' . $this->get_name() . '_request_token_params', $params ); 62 | Keyring_Util::debug( 'OAuth2 Redirect URL: ' . $url . _http_build_query( $params, '', '&' ) ); 63 | 64 | wp_redirect( $url . _http_build_query( $params, '', '&' ) ); 65 | exit; 66 | } 67 | 68 | function verify_token() { 69 | Keyring_Util::debug( 'Keyring_Service_OAuth2::verify_token()' ); 70 | if ( !isset( $_REQUEST['nonce'] ) || !wp_verify_nonce( $_REQUEST['nonce'], 'keyring-verify-' . $this->get_name() ) ) { 71 | Keyring::error( __( 'Invalid/missing verification nonce.', 'keyring' ) ); 72 | exit; 73 | } 74 | 75 | if ( !isset( $_GET['code'] ) || !isset( $_GET['state']) ) { 76 | Keyring::error( 77 | sprintf( __( 'There was a problem authorizing with %s. Please try again in a moment.', 'keyring' ), $this->get_label() ) 78 | ); 79 | return false; 80 | } 81 | 82 | // Load up the request token that got us here and globalize it 83 | global $keyring_request_token; 84 | $state = preg_replace( '/[^\x20-\x7E]/', '', $_GET['state'] ); 85 | $keyring_request_token = $this->store->get_token( array( 'id' => $state, 'type' => 'request' ) ); 86 | Keyring_Util::debug( 'OAuth2 Loaded Request Token ' . $state ); 87 | Keyring_Util::debug( $keyring_request_token ); 88 | 89 | if ( !$keyring_request_token ) { 90 | Keyring::error( 91 | sprintf( __( 'Failed to load your request token while connecting to %s. Please try again in a moment.', 'keyring' ), $this->get_label() ) 92 | ); 93 | return false; 94 | } 95 | 96 | $error_debug_info = array(); 97 | 98 | if ( !empty( $keyring_request_token->meta['blog_id'] ) && !empty( $keyring_request_token->meta['user_id'] ) ) { 99 | $error_debug_info = array( 100 | 'blog_id' => $keyring_request_token->meta['blog_id'], 101 | 'user_id' => $keyring_request_token->meta['user_id'] 102 | ); 103 | } 104 | 105 | // Remove request token, don't need it any more. 106 | $this->store->delete( array( 'id' => $state, 'type' => 'request' ) ); 107 | 108 | $url = $this->access_token_url; 109 | if ( !stristr( $url, '?' ) ) 110 | $url .= '?'; 111 | $params = array( 112 | 'client_id' => $this->key, 113 | 'client_secret' => $this->secret, 114 | 'grant_type' => 'authorization_code', 115 | 'redirect_uri' => $this->callback_url, 116 | 'code' => $_GET['code'], 117 | ); 118 | $params = apply_filters( 'keyring_' . $this->get_name() . '_verify_token_params', $params ); 119 | Keyring_Util::debug( 'OAuth2 Access Token URL: ' . $url . http_build_query( $params ) ); 120 | switch ( strtoupper( $this->access_token_method ) ) { 121 | case 'GET': 122 | $res = wp_remote_get( $url . http_build_query( $params ) ); 123 | break; 124 | case 'POST': 125 | $res = wp_remote_post( $url, apply_filters( 'keyring_' . $this->get_name() . '_verify_token_post_params', array( 'body' => $params ) ) ); 126 | break; 127 | } 128 | Keyring_Util::debug( 'OAuth2 Response' ); 129 | Keyring_Util::debug( $res ); 130 | 131 | if ( 200 == wp_remote_retrieve_response_code( $res ) ) { 132 | $token = wp_remote_retrieve_body( $res ); 133 | Keyring_Util::debug( $token ); 134 | 135 | $token = $this->parse_access_token( $token ); 136 | 137 | $access_token = new Keyring_Access_Token( 138 | $this->get_name(), 139 | $token['access_token'], 140 | $this->build_token_meta( $token ) 141 | ); 142 | $access_token = apply_filters( 'keyring_access_token', $access_token, $token ); 143 | 144 | Keyring_Util::debug( 'OAuth2 Access Token for storage' ); 145 | Keyring_Util::debug( $access_token ); 146 | $id = $this->store_token( $access_token ); 147 | $this->verified( $id, $keyring_request_token ); 148 | exit; 149 | } 150 | Keyring::error( 151 | sprintf( __( 'There was a problem authorizing with %s. Please try again in a moment.', 'keyring' ), $this->get_label() ), 152 | $error_debug_info 153 | ); 154 | return false; 155 | } 156 | 157 | /** 158 | * The OAuth2 spec indicates that responses should be in JSON, but separating 159 | * this allows different services to potentially use querystring-encoded 160 | * responses or something else, and just define this method within themselves 161 | * to handle decoding the access_token response. 162 | * 163 | * @param string $token The response from the access_token request 164 | * @return Array containing key/value pairs from the token response 165 | */ 166 | function parse_access_token( $token ) { 167 | return (array) json_decode( $token ); 168 | } 169 | 170 | function request( $url, array $params = array() ) { 171 | Keyring_Util::debug( $url ); 172 | 173 | if ( $this->requires_token() && empty( $this->token ) ) 174 | return new Keyring_Error( 'keyring-request-error', __( 'No token' ) ); 175 | 176 | $token = $this->token ? $this->token : null; 177 | 178 | if ( !is_null( $token ) ) { 179 | if ( $this->authorization_header ) { 180 | // type can be OAuth, Bearer, ... 181 | $params['headers']['Authorization'] = $this->authorization_header . ' ' . (string) $token; 182 | } else { 183 | $url = add_query_arg( array( $this->authorization_parameter => urlencode( (string) $token ) ), $url ); 184 | } 185 | } 186 | 187 | $raw_response = false; 188 | if ( isset( $params['raw_response'] ) ) { 189 | $raw_response = (bool) $params['raw_response']; 190 | unset( $params['raw_response'] ); 191 | } 192 | 193 | $method = 'GET'; 194 | if ( isset( $params['method'] ) ) { 195 | $method = strtoupper( $params['method'] ); 196 | unset( $params['method'] ); 197 | } 198 | 199 | Keyring_Util::debug( 'OAuth2 Params' ); 200 | Keyring_Util::debug( $params ); 201 | 202 | switch ( strtoupper( $method ) ) { 203 | case 'GET': 204 | $res = wp_remote_get( $url, $params ); 205 | break; 206 | 207 | case 'POST': 208 | $params = array_merge( array( 'sslverify' => false ), $params ); 209 | $res = wp_remote_post( $url, $params ); 210 | break; 211 | 212 | default: 213 | $params = array_merge( array( 'method' => $method, 'sslverify' => false ), $params ); 214 | $res = wp_remote_request( $url, $params ); 215 | break; 216 | } 217 | 218 | Keyring_Util::debug( 'OAuth2 Response' ); 219 | Keyring_Util::debug( $res ); 220 | 221 | $this->set_request_response_code( wp_remote_retrieve_response_code( $res ) ); 222 | if ( in_array( wp_remote_retrieve_response_code( $res ), array( 200, 201, 202 ) ) ) { 223 | if ( $raw_response ) { 224 | return wp_remote_retrieve_body( $res ); 225 | } else { 226 | return $this->parse_response( wp_remote_retrieve_body( $res ) ); 227 | } 228 | } else { 229 | return new Keyring_Error( 'keyring-request-error', $res ); 230 | } 231 | } 232 | 233 | /** 234 | * OAuth2 implementations generally use JSON. You can still override this 235 | * per service if you like, but by default we'll assume JSON. 236 | */ 237 | function parse_response( $response ) { 238 | return json_decode( $response ); 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/500px.php: -------------------------------------------------------------------------------- 1 | authorization_header = true; 21 | $this->authorization_realm = 'api.500px.com'; 22 | 23 | $this->set_endpoint( 'request_token', 'https://api.500px.com/v1/oauth/request_token', 'GET' ); 24 | $this->set_endpoint( 'authorize', 'https://api.500px.com/v1/oauth/authorize', 'GET' ); 25 | $this->set_endpoint( 'access_token', 'https://api.500px.com/v1/oauth/access_token', 'GET' ); 26 | $this->set_endpoint( 'authenticate', 'https://api.500px.com/v1/oauth/authorize', 'GET' ); 27 | $this->set_endpoint( 'users', 'https://api.500px.com/v1/users', 'GET' ); 28 | 29 | $creds = $this->get_credentials(); 30 | $this->app_id = $creds['app_id']; 31 | $this->key = $creds['key']; 32 | $this->secret = $creds['secret']; 33 | 34 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 35 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 36 | 37 | $this->requires_token( true ); 38 | } 39 | 40 | function basic_ui_intro() { 41 | echo '

' . sprintf( __( 'To connect to 500px, you\'ll need to create an application at 500px.com.', 'keyring' ), 'https://500px.com/settings/applications' ) . '

'; 42 | echo '

' . __( "Once you've created your app, enter the Consumer Key and Consumer Secret below.", 'keyring' ) . '

'; 43 | } 44 | 45 | function parse_response( $response ) { 46 | return json_decode( $response ); 47 | } 48 | 49 | function build_token_meta( $token ) { 50 | // Set the token so that we can make requests using it 51 | $this->set_token( 52 | new Keyring_Access_Token( 53 | $this->get_name(), 54 | new OAuthToken( 55 | $token['oauth_token'], 56 | $token['oauth_token_secret'] 57 | ) 58 | ) 59 | ); 60 | 61 | $response = $this->request( "https://api.500px.com/v1/users", array( 'method' => 'GET' ) ); 62 | 63 | if ( Keyring_Util::is_error( $response ) ) { 64 | $meta = array(); 65 | } else { 66 | $meta = array( 67 | 'user_id' => $response->user->id, 68 | 'username' => $response->user->username, 69 | 'name' => $response->user->fullname, 70 | 'picture' => $response->user->userpic_https_url, 71 | ); 72 | } 73 | 74 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 75 | } 76 | 77 | function get_display( Keyring_Access_Token $token ) { 78 | return $token->get_meta( 'username' ); 79 | } 80 | 81 | function test_connection() { 82 | $response = $this->request( $this->users_url, array( 'method' => $this->users_method ) ); 83 | if ( ! Keyring_Util::is_error( $response ) ) { 84 | return true; 85 | } 86 | 87 | return $response; 88 | } 89 | } 90 | 91 | add_action( 'keyring_load_services', array( 'Keyring_Service_500px', 'init' ) ); 92 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/delicious.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'verify', 'https://api.del.icio.us/v1/posts/update', 'GET' ); 10 | $this->requires_token( true ); 11 | } 12 | 13 | function _get_credentials() { 14 | return false; 15 | } 16 | 17 | function parse_response( $data ) { 18 | return simplexml_load_string( $data ); 19 | } 20 | 21 | function get_display( Keyring_Access_Token $token ) { 22 | return $token->get_meta( 'username' ); 23 | } 24 | 25 | function test_connection() { 26 | $response = $this->request( 'https://api.del.icio.us/v1/posts/all?results=1' ); 27 | if ( ! Keyring_Util::is_error( $response ) ) { 28 | return true; 29 | } 30 | 31 | return $response; 32 | } 33 | } 34 | 35 | add_action( 'keyring_load_services', array( 'Keyring_Service_Delicious', 'init' ) ); 36 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/eventbrite.php: -------------------------------------------------------------------------------- 1 | get_name() . '_request_token_params', array( $this, 'add_connection_referrer' ) ); 18 | 19 | $this->set_endpoint( 'authorize', self::OAUTH_BASE . 'authorize', 'GET' ); 20 | $this->set_endpoint( 'access_token', self::OAUTH_BASE . 'token', 'POST' ); 21 | $this->set_endpoint( 'self', self::API_BASE . 'users/me/', 'GET' ); 22 | 23 | // Enable "basic" UI for entering key/secret 24 | if ( ! KEYRING__HEADLESS_MODE ) { 25 | add_action( 'keyring_eventbrite_manage_ui', array( $this, 'basic_ui' ) ); 26 | add_filter( 'keyring_eventbrite_basic_ui_intro', array( $this, 'basic_ui_intro' ) ); 27 | } 28 | 29 | $creds = $this->get_credentials(); 30 | $this->app_id = $creds['app_id']; 31 | $this->key = $creds['key']; 32 | $this->secret = $creds['secret']; 33 | 34 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 35 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 36 | 37 | $this->authorization_header = 'Bearer'; 38 | $this->authorization_parameter = false; 39 | } 40 | 41 | /** 42 | * Append a referrer to the oAuth request made to Eventbrite, at their request 43 | * 44 | * See http://themedevp2.wordpress.com/2013/12/05/can-we-add-refwpoauth-to/ 45 | * 46 | * @param array $params 47 | * @filter keyring_eventbrite_request_token_params 48 | * @return array 49 | */ 50 | public function add_connection_referrer( $params ) { 51 | if ( ! isset( $params['ref'] ) ) { 52 | $params['ref'] = 'wpoauth'; 53 | } 54 | 55 | return $params; 56 | } 57 | 58 | function basic_ui_intro() { 59 | echo '

' . sprintf( __( "To get started, register an OAuth client on Eventbrite. The most important setting is the OAuth redirect_uri, which should be set to %s. You can set the other values to whatever you like.", 'keyring' ), esc_url( Keyring_Util::admin_url( 'eventbrite', array( 'action' => 'verify' ) ) ) ) . '

'; 60 | echo '

' . __( "Once you've saved those changes, copy the APPLICATION KEY value into the API Key field, then click the 'Show' link next to the OAuth client secret, copy the value into the API Secret field and click save (you don't need an App ID value for Eventbrite).", 'keyring' ) . '

'; 61 | } 62 | 63 | function build_token_meta( $token ) { 64 | $this->set_token( 65 | new Keyring_Access_Token( 66 | $this->get_name(), 67 | $token['access_token'], 68 | array() 69 | ) 70 | ); 71 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 72 | $meta = array(); 73 | if ( !Keyring_Util::is_error( $response ) ) { 74 | if ( isset( $response->emails->email ) ) { 75 | $meta['username'] = $response->emails->email; 76 | } 77 | 78 | if ( isset( $response->id ) ) { 79 | $meta['user_id'] = $response->id; 80 | } 81 | 82 | if ( isset( $response->name ) ) { 83 | $meta['name'] = $response->name; 84 | } 85 | } 86 | 87 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, null, $this ); 88 | } 89 | 90 | function get_display( Keyring_Access_Token $token ) { 91 | return $token->get_meta( 'name' ); 92 | } 93 | 94 | function parse_response( $response ) { 95 | return json_decode( $response ); 96 | } 97 | 98 | function test_connection() { 99 | $res = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 100 | if ( !Keyring_Util::is_error( $res ) ) { 101 | return true; 102 | } 103 | 104 | return $res; 105 | } 106 | } 107 | 108 | add_action( 'keyring_load_services', array( 'Keyring_Service_Eventbrite', 'init' ) ); 109 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/facebook.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'authorize', 'https://www.facebook.com/v2.2/dialog/oauth', 'GET' ); 21 | $this->set_endpoint( 'access_token', 'https://graph.facebook.com/v2.2/oauth/access_token', 'GET' ); 22 | $this->set_endpoint( 'self', 'https://graph.facebook.com/v2.2/me', 'GET' ); 23 | $this->set_endpoint( 'profile_pic', 'https://graph.facebook.com/v2.2/me/picture/?redirect=false&width=150&height=150', 'GET' ); 24 | 25 | $creds = $this->get_credentials(); 26 | $this->app_id = $creds['app_id']; 27 | $this->key = $creds['key']; 28 | $this->secret = $creds['secret']; 29 | 30 | $kr_nonce = wp_create_nonce( 'keyring-verify' ); 31 | $nonce = wp_create_nonce( 'keyring-verify-facebook' ); 32 | $this->redirect_uri = Keyring_Util::admin_url( self::NAME, array( 'action' => 'verify', 'kr_nonce' => $kr_nonce, 'nonce' => $nonce, ) ); 33 | 34 | $this->requires_token( true ); 35 | 36 | add_filter( 'keyring_facebook_request_token_params', array( $this, 'filter_request_token' ) ); 37 | } 38 | 39 | function basic_ui_intro() { 40 | echo '

' . __( "If you haven't already, you'll need to set up an app on Facebook:", 'keyring' ) . '

'; 41 | echo '
    '; 42 | echo '
  1. ' . sprintf( __( "Click + Create New App at the top-right of this page", 'keyring' ), 'https://developers.facebook.com/apps' ) . '
  2. '; 43 | echo '
  3. ' . __( "Enter a name for your app (maybe the name of your website?) and a Category, click Continue (you can skip optional things)", 'keyring' ) . '
  4. '; 44 | echo '
  5. ' . __( "Enter whatever is in the CAPTCHA and click Continue", 'keyring' ) . '
  6. '; 45 | echo '
  7. ' . sprintf( __( "Click Settings on the left and then Advanced at the top of that page. Under Valid OAuth redirect URIs, enter your domain name. That value is probably %s", 'keyring' ), $_SERVER['HTTP_HOST'] ) . '
  8. '; 46 | echo '
  9. ' . sprintf( __( "Click the Website with Facebook Login box and enter the URL to your website, which is probably %s", 'keyring' ), get_bloginfo( 'url' ) ) . '
  10. '; 47 | echo '
  11. ' . __( "Click Save Changes", 'keyring' ) . '
  12. '; 48 | echo '
'; 49 | echo '

' . __( "Once you're done configuring your app, copy and paste your App ID and App Secret (in the top section of your app's Basic details) into the appropriate fields below. Leave the App Key field blank.", 'keyring' ) . '

'; 50 | } 51 | 52 | function _get_credentials() { 53 | if ( 54 | defined( 'KEYRING__FACEBOOK_ID' ) 55 | && 56 | defined( 'KEYRING__FACEBOOK_SECRET' ) 57 | ) { 58 | return array( 59 | 'app_id' => constant( 'KEYRING__FACEBOOK_ID' ), 60 | 'key' => constant( 'KEYRING__FACEBOOK_ID' ), 61 | 'secret' => constant( 'KEYRING__FACEBOOK_SECRET' ), 62 | ); 63 | } else { 64 | $all = apply_filters( 'keyring_credentials', get_option( 'keyring_credentials' ) ); 65 | if ( !empty( $all['facebook'] ) ) { 66 | $creds = $all['facebook']; 67 | $creds['key'] = $creds['app_id']; 68 | return $creds; 69 | } 70 | 71 | // Return null to allow fall-thru to checking generic constants + DB 72 | return null; 73 | } 74 | } 75 | 76 | function is_configured() { 77 | $credentials = $this->get_credentials(); 78 | return !empty( $credentials['app_id'] ) && !empty( $credentials['secret'] ); 79 | } 80 | 81 | /** 82 | * Add scope to the outbound URL, and allow developers to modify it 83 | * @param array $params Core request parameters 84 | * @return Array containing originals, plus the scope parameter 85 | */ 86 | function filter_request_token( $params ) { 87 | if ( $scope = implode( ',', apply_filters( 'keyring_facebook_scope', array() ) ) ) 88 | $params['scope'] = $scope; 89 | return $params; 90 | } 91 | 92 | /** 93 | * Facebook decided to make things interesting and mix OAuth1 and 2. They return 94 | * their access tokens using query string encoding, so we handle that here. 95 | */ 96 | function parse_access_token( $token ) { 97 | parse_str( $token, $token ); 98 | return $token; 99 | } 100 | 101 | function build_token_meta( $token ) { 102 | $this->set_token( 103 | new Keyring_Access_Token( 104 | $this->get_name(), 105 | $token['access_token'], 106 | array() 107 | ) 108 | ); 109 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 110 | if ( Keyring_Util::is_error( $response ) ) { 111 | $meta = array(); 112 | } else { 113 | $meta = array( 114 | 'user_id' => $response->id, 115 | 'name' => $response->name, 116 | 'picture' => "https://graph.facebook.com/v2.2/{$response->id}/picture?type=large", 117 | ); 118 | } 119 | 120 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 121 | } 122 | 123 | function get_display( Keyring_Access_Token $token ) { 124 | return $token->get_meta( 'name' ); 125 | } 126 | 127 | function test_connection() { 128 | $res = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 129 | if ( ! Keyring_Util::is_error( $res ) ) 130 | return true; 131 | 132 | return $res; 133 | } 134 | 135 | /** 136 | * Get a list of FB Pages that this user has permissions to manage 137 | * @param Keyring_Token $connection A connection to FB. 138 | * @return Array containing the raw results for each page, or empty if none. 139 | */ 140 | function get_fb_pages( $connection = false ) { 141 | if ( $connection ) 142 | $this->set_token( $connection ); 143 | 144 | $additional_external_users = array(); 145 | $fb_accounts = $this->request( 'https://graph.facebook.com/v2.2/me/accounts/' ); 146 | if ( ! empty( $fb_accounts ) && ! is_wp_error( $fb_accounts ) ) { 147 | foreach ( $fb_accounts->data as $fb_account ) { 148 | $fb_page = $this->request( 'https://graph.facebook.com/v2.2/' . urlencode( $fb_account->id ) ); 149 | 150 | // only continue with this account as a viable option if we can post content to it 151 | if ( ! $fb_page->is_published || ! $fb_page->can_post ) { 152 | continue; 153 | } 154 | 155 | $this_fb_page = array( 156 | 'id' => $fb_page->id, 157 | 'name' => $fb_page->name, 158 | 'access_token' => $fb_account->access_token, 159 | 'category' => $fb_page->category, 160 | 'picture' => null, 161 | ); 162 | 163 | $picture = $this->request( 'https://graph.facebook.com/v2.2/' . urlencode( $fb_account->id ) . '/picture?redirect=false' ); 164 | if ( !empty( $picture->data ) ) { 165 | $this_fb_page['picture'] = esc_url_raw( $picture->data->url ); 166 | } 167 | 168 | $additional_external_users[] = (object) $this_fb_page; 169 | } 170 | } 171 | 172 | 173 | return $additional_external_users; 174 | } 175 | 176 | function fetch_additional_external_users() { 177 | return $this->get_fb_pages(); 178 | } 179 | } 180 | 181 | add_action( 'keyring_load_services', array( 'Keyring_Service_Facebook', 'init' ) ); 182 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/fitbit.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'authorize', 'https://www.fitbit.com/oauth2/authorize', 'GET' ); 23 | $this->set_endpoint( 'access_token', 'https://api.fitbit.com/oauth2/token', 'POST' ); 24 | $this->set_endpoint( 'refresh', 'https://api.fitbit.com/oauth2/token', 'POST' ); 25 | $this->set_endpoint( 'profile', 'https://api.fitbit.com/1/user/-/profile.json', 'GET' ); 26 | 27 | $creds = $this->get_credentials(); 28 | $this->app_id = $creds['app_id']; 29 | $this->key = $creds['key']; 30 | $this->secret = $creds['secret']; 31 | 32 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 33 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 34 | 35 | // Fitbit requires an exact match on Redirect URI, which means we can't send any nonces 36 | $this->callback_url = remove_query_arg( array( 'nonce', 'kr_nonce' ), $this->callback_url ); 37 | add_action( 'pre_keyring_fitbit_verify', array( $this, 'redirect_incoming_verify' ) ); 38 | 39 | // Send authorization via header 40 | $this->authorization_header = 'Bearer'; 41 | 42 | add_filter( 'keyring_fitbit_request_token_params', array( $this, 'request_token_params' ) ); 43 | add_filter( 'keyring_fitbit_verify_token_params', array( $this, 'verify_token_params' ) ); 44 | add_filter( 'keyring_fitbit_verify_token_post_params', array( $this, 'verify_token_post_params' ) ); 45 | 46 | add_filter( 'keyring_access_token', array( $this, 'fix_access_token_meta' ), 10, 2 ); 47 | } 48 | 49 | function basic_ui_intro() { 50 | echo '

' . sprintf( __( 'Go to Fitbit and create a new application, which allows Keyring to talk to Fitbit.', 'keyring' ), 'https://dev.fitbit.com/apps/new' ) . '

'; 51 | echo '

' . sprintf( __( "You can use anything for the name/description details etc. Make sure you set the OAuth 2.0 Application Type to Personal (grants you some extra access) and set your Callback URL to %s. You only need Read-Only access if you are syncing data, but Read & Write will let you update details as well.", 'keyring' ), Keyring_Util::admin_url( self::NAME, array( 'action' => 'verify' ) ) ) . '

'; 52 | } 53 | 54 | function request_token_params( $params ) { 55 | $params['scope'] = apply_filters( 'keyring_fitbit_scope', self::SCOPE ); 56 | return $params; 57 | } 58 | 59 | function verify_token_params( $params ) { 60 | unset( $params['client_id'] ); 61 | unset( $params['client_secret'] ); 62 | return $params; 63 | } 64 | 65 | function verify_token_post_params( $params ) { 66 | $params['headers'] = $this->get_basic_auth(); 67 | return $params; 68 | } 69 | 70 | function fix_access_token_meta( $access_token, $token ) { 71 | if ( 'fitbit' !== $access_token->get_name() ) { 72 | return $access_token; 73 | } 74 | 75 | return new Keyring_Access_Token( 76 | $this->get_name(), 77 | $token['access_token'], 78 | array_merge( $access_token->get_meta(), $this->get_token()->get_meta() ) // refresh_token has been updated, and we want to make sure we store it 79 | ); 80 | } 81 | 82 | function get_basic_auth() { 83 | return array( 'Authorization' => 'Basic ' . base64_encode( $this->key . ':' . $this->secret ) ); 84 | } 85 | 86 | function redirect_incoming_verify( $request ) { 87 | if ( ! isset( $request['kr_nonce'] ) ) { 88 | $kr_nonce = wp_create_nonce( 'keyring-verify' ); 89 | $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() ); 90 | wp_safe_redirect( 91 | Keyring_Util::admin_url( 92 | $this->get_name(), 93 | array( 94 | 'action' => 'verify', 95 | 'kr_nonce' => $kr_nonce, 96 | 'nonce' => $nonce, 97 | 'state' => $request['state'], 98 | 'code' => $request['code'], // Auth code from successful response (maybe) 99 | ) 100 | ) 101 | ); 102 | exit; 103 | } 104 | } 105 | 106 | function build_token_meta( $token ) { 107 | $meta = array( 108 | 'user_id' => $token['user_id'], 109 | 'expires' => time() + $token['expires_in'], 110 | 'refresh_token' => $token['refresh_token'], 111 | ); 112 | 113 | $this->set_token( 114 | new Keyring_Access_Token( 115 | $this->get_name(), 116 | $token['access_token'], 117 | $meta 118 | ) 119 | ); 120 | 121 | $response = $this->request( $this->profile_url ); 122 | if ( ! Keyring_Util::is_error( $response ) ) { 123 | $meta['name'] = $response->user->fullName; 124 | $meta['picture'] = $response->user->avatar; 125 | $meta['first_date'] = $response->user->memberSince; 126 | $meta['_classname'] = get_called_class(); 127 | } 128 | 129 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, array(), $this ); 130 | } 131 | 132 | function get_display( Keyring_Access_Token $token ) { 133 | return $token->get_meta( 'name' ); 134 | } 135 | 136 | function refresh_token() { 137 | // Request a new token, using the refresh_token 138 | $token = $this->get_token(); 139 | $meta = $token->get_meta(); 140 | if ( empty( $meta['refresh_token'] ) ) { 141 | return false; 142 | } 143 | 144 | // Don't bother if this token is valid for a while 145 | if ( ! $token->is_expired( 20 ) ) { 146 | return; 147 | } 148 | 149 | // Refresh our access token 150 | $response = wp_remote_post( $this->refresh_url, array( 151 | 'method' => $this->refresh_method, 152 | 'headers' => $this->get_basic_auth(), 153 | 'body' => array( 154 | 'grant_type' => 'refresh_token', 155 | 'refresh_token' => $meta['refresh_token'], 156 | ) 157 | ) ); 158 | 159 | if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { 160 | return false; 161 | } 162 | 163 | $return = json_decode( wp_remote_retrieve_body( $response ) ); 164 | $meta['refresh_token'] = $return->refresh_token; 165 | $meta['expires'] = $return->expires_in; 166 | $this->set_token( 167 | new Keyring_Access_Token( 168 | $this->get_name(), 169 | $return->access_token, 170 | $meta 171 | ) 172 | ); 173 | } 174 | 175 | // Need to potentially refresh token before each request 176 | function request( $url, array $params = array() ) { 177 | $this->refresh_token(); 178 | return parent::request( $url, $params ); 179 | } 180 | 181 | function test_connection() { 182 | $response = $this->request( $this->profile_url, array( 'method' => $this->profile_method ) ); 183 | if ( ! Keyring_Util::is_error( $response ) ) { 184 | return true; 185 | } 186 | 187 | return $response; 188 | } 189 | } 190 | 191 | add_action( 'keyring_load_services', array( 'Keyring_Service_Fitbit', 'init' ) ); 192 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/flickr.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'request_token', 'https://www.flickr.com/services/oauth/request_token', 'GET' ); 21 | $this->set_endpoint( 'authorize', 'https://www.flickr.com/services/oauth/authorize', 'GET' ); 22 | $this->set_endpoint( 'access_token', 'https://www.flickr.com/services/oauth/access_token', 'GET' ); 23 | 24 | $creds = $this->get_credentials(); 25 | $this->app_id = $creds['app_id']; 26 | $this->key = $creds['key']; 27 | $this->secret = $creds['secret']; 28 | 29 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 30 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 31 | 32 | $this->requires_token( true ); 33 | } 34 | 35 | function basic_ui_intro() { 36 | echo '

' . sprintf( __( 'To connect to Flickr, you\'ll need to create an application at Flickr.com. If this is a personal website then you can use a non-commercial key (which will be approved automatically).', 'keyring' ), 'http://www.flickr.com/services/apps/create/apply/?' ) . '

'; 37 | echo '

' . __( "Once you've created your app, enter the API Key and Secret below (App ID is not required for Flickr apps).", 'keyring' ) . '

'; 38 | } 39 | 40 | function build_token_meta( $token ) { 41 | // Need to make a request to get full information 42 | $this->set_token( 43 | new Keyring_Access_Token( 44 | $this->get_name(), 45 | new OAuthToken( 46 | $token['oauth_token'], 47 | $token['oauth_token_secret'] 48 | ) 49 | ) 50 | ); 51 | $url = "https://api.flickr.com/services/rest/?"; 52 | $params = array( 53 | 'method' => 'flickr.people.getInfo', 54 | 'api_key' => $this->key, 55 | 'user_id' => $token['user_nsid'], 56 | ); 57 | $url = $url . http_build_query( $params ); 58 | 59 | $response = $this->request( $url, array( 'method' => 'GET' ) ); 60 | if ( Keyring_Util::is_error( $response ) ) { 61 | $meta = array(); 62 | } else { 63 | $meta = array( 64 | 'user_id' => $token['user_nsid'], 65 | 'username' => $token['username'], 66 | 'name' => $token['fullname'], 67 | 'picture' => "http://farm{$response->person->iconfarm}.staticflickr.com/{$response->person->iconserver}/buddyicons/{$token['user_nsid']}.jpg", 68 | ); 69 | } 70 | 71 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 72 | } 73 | 74 | function get_display( Keyring_Access_Token $token ) { 75 | $return = ''; 76 | $meta = $token->get_meta(); 77 | if ( !empty( $meta['name'] ) ) 78 | return $meta['name']; 79 | else if ( !empty( $meta['username'] ) ) 80 | return $meta['username']; 81 | } 82 | 83 | /** 84 | * Custom request method so that we can force JSON for Flickr, which otherwise 85 | * uses XML. 86 | * @param string $url The URL to request 87 | * @param array $params Any additional parameters requried for this reqeust 88 | * @return Mixed with either a Keyring_Error, or a decoded JSON response object 89 | */ 90 | function request( $url, array $params = array() ) { 91 | // http://www.flickr.com/services/api/response.json.html 92 | $url = add_query_arg( 93 | array( 94 | 'format' => 'json', // Always return JSON 95 | 'nojsoncallback' => 1, // Don't wrap it in a callback 96 | ), 97 | $url ); 98 | return parent::request( $url, $params ); 99 | } 100 | 101 | /** 102 | * Since we're forcing all requests to be for JSON data, we can decode 103 | * all responses as JSON as well. 104 | * @param string $response Full content of the response 105 | * @return JSON object representation of the response 106 | */ 107 | function parse_response( $response ) { 108 | return json_decode( $response ); 109 | } 110 | 111 | function test_connection() { 112 | $url = "https://api.flickr.com/services/rest/?"; 113 | $params = array( 114 | 'method' => 'flickr.test.login', 115 | 'api_key' => $this->key, 116 | ); 117 | $url = $url . http_build_query( $params ); 118 | 119 | $response = $this->request( $url ); 120 | if ( ! Keyring_Util::is_error( $response ) ) { 121 | return true; 122 | } 123 | 124 | return $response; 125 | } 126 | } 127 | 128 | add_action( 'keyring_load_services', array( 'Keyring_Service_Flickr', 'init' ) ); 129 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/foursquare.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'authorize', 'https://foursquare.com/oauth2/authenticate', 'GET' ); 25 | $this->set_endpoint( 'access_token', 'https://foursquare.com/oauth2/access_token', 'GET' ); 26 | $this->set_endpoint( 'self', 'https://api.foursquare.com/v2/users/self', 'GET' ); 27 | 28 | $creds = $this->get_credentials(); 29 | $this->app_id = $creds['app_id']; 30 | $this->key = $creds['key']; 31 | $this->secret = $creds['secret']; 32 | 33 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 34 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 35 | } 36 | 37 | function basic_ui_intro() { 38 | echo '

' . sprintf( __( 'If you haven\'t already, you\'ll need to create a new app at Foursquare. You should only need to worry about these settings:', 'keyring' ), 'https://foursquare.com/developers/register' ) . '

'; 39 | echo '
    '; 40 | echo '
  1. ' . __( "Your app name: enter whatever you like, maybe your website's name?", 'keyring' ) . '
  2. '; 41 | echo '
  3. ' . sprintf( __( "Download / welcome page url: just enter your website's URL, %s", 'keyring' ), get_bloginfo( 'url' ) ) . '
  4. '; 42 | echo '
  5. ' . sprintf( __( "Redirect URI(s): Copy-paste this, %s", 'keyring' ), Keyring_Util::admin_url( 'foursquare', array( 'action' => 'verify' ) ) ) . '
  6. '; 43 | echo '
  7. ' . __( "New users can connect via the web: check the box", 'keyring' ) . '
  8. '; 44 | echo '
'; 45 | echo '

' . __( "Once you've saved those changes, copy the Client id value into the API Key field, and the Client secret value into the API Secret field and click save (you don't need an App ID value for Foursquare).", 'keyring' ) . '

'; 46 | } 47 | 48 | function build_token_meta( $token ) { 49 | $token = new Keyring_Access_Token( $this->get_name(), $token['access_token'], array() ); 50 | $this->set_token( $token ); 51 | $res = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 52 | if ( Keyring_Util::is_error( $res ) ) { 53 | $meta = array(); 54 | } else { 55 | $meta = array( 56 | 'user_id' => $res->response->user->id, 57 | 'first_name' => $res->response->user->firstName, 58 | 'last_name' => $res->response->user->lastName, 59 | 'picture' => $res->response->user->photo->prefix . '300x300' . $res->response->user->photo->suffix, 60 | ); 61 | } 62 | 63 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $res, $this ); 64 | } 65 | 66 | function get_display( Keyring_Access_Token $token ) { 67 | $meta = $token->get_meta(); 68 | return trim( $meta['first_name'] . ' ' . $meta['last_name'] ); 69 | } 70 | 71 | function request( $url, array $params = array() ) { 72 | $url = add_query_arg( array( 'v' => self::API_VERSION ), $url ); 73 | return parent::request( $url, $params ); 74 | } 75 | 76 | function test_connection() { 77 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 78 | if ( ! Keyring_Util::is_error( $response ) ) { 79 | return true; 80 | } 81 | 82 | return $response; 83 | } 84 | } 85 | 86 | add_action( 'keyring_load_services', array( 'Keyring_Service_Foursquare', 'init' ) ); 87 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/google-contacts.php: -------------------------------------------------------------------------------- 1 | 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->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 44 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 45 | 46 | $this->authorization_header = 'Bearer'; // Oh, you 47 | $this->authorization_parameter = false; 48 | 49 | // Need to reset the callback because Google is very strict about where it sends people 50 | if ( !empty( $creds['redirect_uri'] ) ) 51 | $this->callback_url = $creds['redirect_uri']; // Allow user to manually enter a redirect URI 52 | else 53 | $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 54 | } 55 | 56 | function basic_ui_intro() { 57 | echo '

' . sprintf( __( "Google controls access to all of their APIs through their API Console. Go to the console and click the project dropdown just under the logo in the upper left of the screen. Click Create… to create a new project. Enter a name and then click Create project. 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' ) . '

'; 58 | echo '

' . __( "Now you need to set up an OAuth Client ID.", 'keyring' ) . '

'; 59 | echo '
    '; 60 | echo '
  1. ' . __( "Click API Access in the menu on the left.", 'keyring' ) . '
  2. '; 61 | echo '
  3. ' . __( "Click the big blue button labelled Create an OAuth 2.0 client ID…", 'keyring' ) . '
  4. '; 62 | echo '
  5. ' . __( "You must enter a Product name, but you can skip the logo and home page URL", 'keyring' ) . '
  6. '; 63 | echo '
  7. ' . __( "Leave the Application type set to Web application", 'keyring' ) . '
  8. '; 64 | echo '
  9. ' . __( "Next to Your site or hostname, click (more options)", 'keyring' ) . '
  10. '; 65 | echo '
  11. ' . sprintf( __( "In the Authorized Redirect URIs box, enter the URL %s", 'keyring' ), Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) ) ) . '
  12. '; 66 | echo '
  13. ' . sprintf( __( "For the Authorized JavaScript Origins, enter the URL of your domain, e.g. http://%s", 'keyring' ), $_SERVER['HTTP_HOST'] ) . '
  14. '; 67 | echo '
  15. ' . __( "Click Create client ID when you're done", 'keyring' ) . '
  16. '; 68 | echo '
'; 69 | echo '

' . __( "Once you've saved your details, copy the Client ID into the Client ID field below, and the Client secret value into Client Secret. The Redirect URI box should fill itself out for you.", 'keyring' ) . '

'; 70 | } 71 | 72 | function _get_credentials() { 73 | if ( 74 | defined( 'KEYRING__GOOGLECONTACTS_KEY' ) 75 | && 76 | defined( 'KEYRING__GOOGLECONTACTS_SECRET' ) 77 | ) { 78 | return array( 79 | 'redirect_uri' => defined( 'KEYRING__GOOGLECONTACTS_URI' ) ? constant( 'KEYRING__GOOGLECONTACTS_URI' ) : '', // optional 80 | 'key' => constant( 'KEYRING__GOOGLECONTACTS_KEY' ), 81 | 'secret' => constant( 'KEYRING__GOOGLECONTACTS_SECRET' ), 82 | ); 83 | } else { 84 | return null; 85 | } 86 | } 87 | 88 | function request_token_params( $params ) { 89 | $params['scope'] = self::SCOPE; 90 | return $params; 91 | } 92 | 93 | function redirect_incoming_verify( $request ) { 94 | if ( !isset( $request['kr_nonce'] ) ) { 95 | // First request, from Google. Nonce it and move on. 96 | $kr_nonce = wp_create_nonce( 'keyring-verify' ); 97 | $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() ); 98 | wp_safe_redirect( 99 | Keyring_Util::admin_url( 100 | $this->get_name(), 101 | array( 102 | 'action' => 'verify', 103 | 'kr_nonce' => $kr_nonce, 104 | 'nonce' => $nonce, 105 | 'state' => $request['state'], 106 | 'code' => $request['code'], // Auth code from successful response (maybe) 107 | ) 108 | ) 109 | ); 110 | exit; 111 | } 112 | } 113 | 114 | function build_token_meta( $token ) { 115 | $meta = array(); 116 | if ( !$token ) 117 | return $meta; 118 | 119 | $token = new Keyring_Access_Token( $this->get_name(), new OAuthToken( $token['access_token'], '' ), array() ); 120 | $this->set_token( $token ); 121 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 122 | if ( !Keyring_Util::is_error( $response ) ) { 123 | $meta = array( 124 | 'user_id' => $response->id, 125 | 'name' => $response->name, 126 | 'profile' => $response->link, 127 | 'picture' => $response->picture, 128 | ); 129 | } 130 | 131 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 132 | } 133 | 134 | function get_display( Keyring_Access_Token $token ) { 135 | return $token->get_meta( 'name' ); 136 | } 137 | 138 | function request( $url, array $params = array() ) { 139 | // add header (version), required for all requests 140 | $params['headers']['GData-Version'] = self::API_VERSION; 141 | 142 | return parent::request( $url, $params ); 143 | } 144 | 145 | // Minor modifications from Keyring_Service::basic_ui 146 | function basic_ui() { 147 | if ( !isset( $_REQUEST['nonce'] ) || !wp_verify_nonce( $_REQUEST['nonce'], 'keyring-manage-' . $this->get_name() ) ) { 148 | Keyring::error( __( 'Invalid/missing management nonce.', 'keyring' ) ); 149 | exit; 150 | } 151 | 152 | // Common Header 153 | echo '
'; 154 | screen_icon( 'ms-admin' ); 155 | echo '

' . __( 'Keyring Service Management', 'keyring' ) . '

'; 156 | echo '

' . __( '← Back', 'keyring' ) . '

'; 157 | echo '

' . sprintf( __( '%s API Credentials', 'keyring' ), esc_html( $this->get_label() ) ) . '

'; 158 | 159 | // Handle actually saving credentials 160 | if ( isset( $_POST['api_key'] ) && isset( $_POST['api_secret'] ) ) { 161 | // Store credentials against this service 162 | $this->update_credentials( array( 163 | 'key' => stripslashes( $_POST['api_key'] ), 164 | 'secret' => stripslashes( $_POST['api_secret'] ), 165 | 'redirect_uri' => stripslashes( $_POST['redirect_uri'] ), 166 | ) ); 167 | echo '

' . __( 'Credentials saved.', 'keyring' ) . '

'; 168 | } 169 | 170 | $api_key = $api_secret = $redirect_uri = ''; 171 | if ( $creds = $this->get_credentials() ) { 172 | $api_key = $creds['key']; 173 | $api_secret = $creds['secret']; 174 | $redirect_uri = $creds['redirect_uri']; 175 | } 176 | 177 | echo apply_filters( 'keyring_' . $this->get_name() . '_basic_ui_intro', '' ); 178 | 179 | if ( ! $redirect_uri ) 180 | $redirect_uri = Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) ); 181 | 182 | // Output basic form for collecting key/secret 183 | echo '
'; 184 | echo ''; 185 | echo ''; 186 | wp_nonce_field( 'keyring-manage', 'kr_nonce', false ); 187 | wp_nonce_field( 'keyring-manage-' . $this->get_name(), 'nonce', false ); 188 | echo ''; 189 | echo ''; 190 | echo ''; 191 | echo ''; 192 | echo ''; 193 | echo ''; 194 | echo ''; 195 | echo '
' . __( 'Client ID', 'keyring' ) . '
' . __( 'Client Secret', 'keyring' ) . '
' . __( 'Redirect URI', 'keyring' ) . '
'; 196 | echo '

'; 197 | echo ''; 198 | echo '' . __( 'Cancel', 'keyring' ) . ''; 199 | echo '

'; 200 | echo '
'; 201 | echo '
'; 202 | } 203 | 204 | function test_connection() { 205 | $res = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 206 | if ( !Keyring_Util::is_error( $res ) ) 207 | return true; 208 | 209 | return $res; 210 | } 211 | } 212 | 213 | add_action( 'keyring_load_services', array( 'Keyring_Service_GoogleContacts', 'init' ) ); 214 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/instagram.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'authorize', 'https://api.instagram.com/oauth/authorize/', 'GET' ); 22 | $this->set_endpoint( 'access_token', 'https://api.instagram.com/oauth/access_token', 'POST' ); 23 | $this->set_endpoint( 'self', 'https://api.instagram.com/v1/users/self/', 'GET' ); 24 | 25 | $creds = $this->get_credentials(); 26 | $this->app_id = $creds['app_id']; 27 | $this->key = $creds['key']; 28 | $this->secret = $creds['secret']; 29 | 30 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 31 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 32 | 33 | $this->authorization_header = false; // Send in querystring 34 | $this->authorization_parameter = 'access_token'; 35 | } 36 | 37 | function basic_ui_intro() { 38 | echo '

' . sprintf( __( 'To get started, register an OAuth client on Instagram. The most important setting is the OAuth redirect_uri, which should be set to %2$s. You can set the other values to whatever you like.', 'keyring' ), 'http://instagram.com/developer/clients/register/', Keyring_Util::admin_url( 'instagram', array( 'action' => 'verify' ) ) ) . '

'; 39 | echo '

' . __( "Once you've saved those changes, copy the CLIENT ID value into the API Key field, and the CLIENT SECRET value into the API Secret field and click save (you don't need an App ID value for Instagram).", 'keyring' ) . '

'; 40 | } 41 | 42 | function build_token_meta( $token ) { 43 | if ( empty( $token['user'] ) ) { 44 | $meta = array(); 45 | } else { 46 | $meta = array( 47 | 'user_id' => $token['user']->id, 48 | 'username' => $token['user']->username, 49 | 'name' => $token['user']->full_name, 50 | 'picture' => $token['user']->profile_picture, 51 | ); 52 | } 53 | 54 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, null, $this ); 55 | } 56 | 57 | function get_display( Keyring_Access_Token $token ) { 58 | return $token->get_meta( 'name' ); 59 | } 60 | 61 | function test_connection() { 62 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 63 | if ( ! Keyring_Util::is_error( $response ) ) { 64 | return true; 65 | } 66 | 67 | return $response; 68 | } 69 | } 70 | 71 | add_action( 'keyring_load_services', array( 'Keyring_Service_Instagram', 'init' ) ); 72 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/instapaper.php: -------------------------------------------------------------------------------- 1 | authorization_header = true; 22 | 23 | $this->set_endpoint( 'access_token', 'https://www.instapaper.com/api/1/oauth/access_token', 'POST' ); 24 | $this->set_endpoint( 'verify', 'https://www.instapaper.com/api/1/account/verify_credentials', 'POST' ); 25 | 26 | $creds = $this->get_credentials(); 27 | $this->app_id = $creds['app_id']; 28 | $this->key = $creds['key']; 29 | $this->secret = $creds['secret']; 30 | 31 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 32 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 33 | 34 | $this->requires_token( true ); 35 | } 36 | 37 | function basic_ui_intro() { 38 | echo '

' . sprintf( __( 'To use the Instapaper API, you need to get manually approved. Apply here, then wait for a reply email.', 'keyring' ), 'http://www.instapaper.com/main/request_oauth_consumer_token' ) . '

'; 39 | echo '

' . __( "Once you get approved, you'll get an email back with your details. Copy the OAuth consumer key value into the API Key field, and the OAuth consumer secret value into the API Secret field and click save (you don't need an App ID value for Instapaper).", 'keyring' ) . '

'; 40 | } 41 | 42 | /** 43 | * Mostly duplicated from HTTP Basic 44 | */ 45 | function request_ui() { 46 | // Common Header 47 | echo '
'; 48 | screen_icon( 'ms-admin' ); 49 | echo '

' . __( 'Account Details', 'keyring' ) . '

'; 50 | 51 | // Handle errors 52 | if ( isset( $_GET['error'] ) ) { 53 | echo '
    '; 54 | switch ( $_GET['error'] ) { 55 | case '401': 56 | echo '
  • ' . __( 'Your account details could not be confirmed, please try again.', 'keyring' ) . '
  • '; 57 | break; 58 | case 'empty': 59 | echo '
  • ' . __( 'Please make sure you enter a username and password.', 'keyring' ) . '
  • '; 60 | break; 61 | } 62 | echo '
'; 63 | } 64 | 65 | // Even though it doesn't make too much sense, we support request tokens in HTTP Basic 66 | // to ensure consistency with other services 67 | $request_token = new Keyring_Request_Token( 68 | $this->get_name(), 69 | array(), 70 | apply_filters( 71 | 'keyring_request_token_meta', 72 | array( 73 | 'for' => isset( $_REQUEST['for'] ) ? (string) $_REQUEST['for'] : false 74 | ), 75 | $this->get_name(), 76 | array() // no token 77 | ) 78 | ); 79 | $request_token = apply_filters( 'keyring_request_token', $request_token, $this ); 80 | $request_token_id = $this->store_token( $request_token ); 81 | Keyring_Util::debug( 'xAuth/Instapaper Stored Request token ' . $request_token_id ); 82 | 83 | echo apply_filters( 'keyring_' . $this->get_name() . '_request_ui_intro', '' ); 84 | 85 | // Output basic form for collecting user/pass 86 | echo '

' . sprintf( __( 'Enter your username (or email address) and password for accessing %s:', 'keyring' ), $this->get_label() ) . '

'; 87 | echo '
'; 88 | echo ''; 89 | echo ''; 90 | echo ''; 91 | wp_nonce_field( 'keyring-verify', 'kr_nonce', false ); 92 | wp_nonce_field( 'keyring-verify-' . $this->get_name(), 'nonce', false ); 93 | echo ''; 94 | echo ''; 95 | echo ''; 96 | echo ''; 97 | echo ''; 98 | echo '
' . __( 'Email address', 'keyring' ) . '
' . __( 'Password', 'keyring' ) . '
'; 99 | echo '

'; 100 | echo ''; 101 | echo '' . __( 'Cancel', 'keyring' ) . ''; 102 | echo '

'; 103 | echo '
'; 104 | echo '
'; 105 | ?>get_name() ) ) { 116 | Keyring::error( __( 'Invalid/missing verification nonce.', 'keyring' ) ); 117 | exit; 118 | } 119 | 120 | // Load up the request token that got us here and globalize it 121 | if ( $_REQUEST['state'] ) { 122 | global $keyring_request_token; 123 | $state = (int) $_REQUEST['state']; 124 | $keyring_request_token = $this->store->get_token( array( 'id' => $state, 'type' => 'request' ) ); 125 | Keyring_Util::debug( 'xAuth/Instapaper Loaded Request Token ' . $_REQUEST['state'] ); 126 | Keyring_Util::debug( $keyring_request_token ); 127 | 128 | // Remove request token, don't need it any more. 129 | $this->store->delete( array( 'id' => $state, 'type' => 'request' ) ); 130 | } 131 | 132 | if ( !strlen( $_POST['username'] ) ) { 133 | $url = Keyring_Util::admin_url( 134 | $this->get_name(), 135 | array( 136 | 'action' => 'request', 137 | 'error' => 'empty', 138 | 'kr_nonce' => wp_create_nonce( 'keyring-request' ) 139 | ) 140 | ); 141 | Keyring_Util::debug( $url ); 142 | wp_safe_redirect( $url ); 143 | exit; 144 | } 145 | 146 | $body = array( 147 | 'x_auth_mode' => 'client_auth', 148 | 'x_auth_password' => $_POST['password'], 149 | 'x_auth_username' => $_POST['username'], 150 | ); 151 | ksort( $body ); 152 | $this->set_token( new Keyring_Access_Token( $this->get_name(), null, array() ) ); 153 | $res = $this->request( $this->access_token_url, array( 'method' => $this->access_token_method, 'raw_response' => true, 'body' => $body ) ); 154 | Keyring_Util::debug( 'OAuth1 Access Token Response' ); 155 | Keyring_Util::debug( $res ); 156 | 157 | // We will get a 401 if they entered an incorrect user/pass combo. ::request 158 | // will then return a Keyring_Error 159 | if ( Keyring_Util::is_error( $res ) ) { 160 | $url = Keyring_Util::admin_url( 161 | $this->get_name(), 162 | array( 163 | 'action' => 'request', 164 | 'error' => '401', 165 | 'kr_nonce' => wp_create_nonce( 'keyring-request' ) 166 | ) 167 | ); 168 | Keyring_Util::debug( $url ); 169 | wp_safe_redirect( $url ); 170 | exit; 171 | } 172 | 173 | parse_str( $res, $token ); 174 | 175 | $meta = array_merge( array( 'username' => $_POST['username'] ), $this->build_token_meta( $token ) ); 176 | 177 | $access_token = new Keyring_Access_Token( 178 | $this->get_name(), 179 | new OAuthToken( $token['oauth_token'], $token['oauth_token_secret'] ), 180 | $meta 181 | ); 182 | $access_token = apply_filters( 'keyring_access_token', $access_token ); 183 | 184 | // If we didn't get a 401, then we'll assume it's OK 185 | $id = $this->store_token( $access_token ); 186 | $this->verified( $id, $keyring_request_token ); 187 | } 188 | 189 | function parse_response( $response ) { 190 | return json_decode( $response ); 191 | } 192 | 193 | function build_token_meta( $token ) { 194 | // Set the token so that we can make requests using it 195 | $this->set_token( 196 | new Keyring_Access_Token( 197 | $this->get_name(), 198 | new OAuthToken( 199 | $token['oauth_token'], 200 | $token['oauth_token_secret'] 201 | ) 202 | ) 203 | ); 204 | 205 | $response = $this->request( $this->verify_url, array( 'method' => $this->verify_method ) ); 206 | if ( Keyring_Util::is_error( $response ) ) { 207 | $meta = array(); 208 | } else { 209 | $meta = array( 210 | 'user_id' => $response[0]->user_id, 211 | 'username' => $response[0]->username, 212 | 'name' => $response[0]->username, 213 | '_classname' => get_called_class(), 214 | ); 215 | } 216 | 217 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 218 | } 219 | 220 | function get_display( Keyring_Access_Token $token ) { 221 | return $token->get_meta( 'username' ); 222 | } 223 | 224 | function test_connection() { 225 | $response = $this->request( $this->verify_url, array( 'method' => $this->verify_method ) ); 226 | if ( !Keyring_Util::is_error( $response ) ) 227 | return true; 228 | 229 | return $response; 230 | } 231 | } 232 | 233 | add_action( 'keyring_load_services', array( 'Keyring_Service_Instapaper', 'init' ) ); 234 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/linkedin.php: -------------------------------------------------------------------------------- 1 | authorization_header = true; 15 | $this->authorization_realm = "api.linkedin.com"; 16 | 17 | // Enable "basic" UI for entering key/secret 18 | if ( ! KEYRING__HEADLESS_MODE ) { 19 | add_action( 'keyring_linkedin_manage_ui', array( $this, 'basic_ui' ) ); 20 | add_filter( 'keyring_linkedin_basic_ui_intro', array( $this, 'basic_ui_intro' ) ); 21 | } 22 | 23 | $this->set_endpoint( 'request_token', 'https://api.linkedin.com/uas/oauth/requestToken', 'POST' ); 24 | $this->set_endpoint( 'authorize', 'https://api.linkedin.com/uas/oauth/authenticate', 'GET' ); 25 | $this->set_endpoint( 'access_token', 'https://api.linkedin.com/uas/oauth/accessToken', 'GET' ); 26 | 27 | $creds = $this->get_credentials(); 28 | $this->app_id = $creds['app_id']; 29 | $this->key = $creds['key']; 30 | $this->secret = $creds['secret']; 31 | 32 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 33 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 34 | 35 | add_filter( 'keyring_linkedin_request_scope', array( $this, 'member_permissions' ) ); 36 | } 37 | 38 | function basic_ui_intro() { 39 | echo '

' . sprintf( __( "To connect to LinkedIn, you'll first need to create an app. A lot of the details are required, but they're not actually important to the operation of your app, since Keyring will override any important settings.", 'keyring' ), 'https://www.linkedin.com/secure/developer?newapp=' ) . '

'; 40 | echo '

' . __( "Once you've created your app, go down to the OAuth Keys section and copy the API Key value into the API Key field below, and the Secret Key value into the API Secret field and click save (you don't need an App ID value for LinkedIn).", 'keyring' ) . '

'; 41 | } 42 | 43 | function parse_response( $response ) { 44 | if ( 'set_token( 58 | new Keyring_Access_Token( 59 | $this->get_name(), 60 | new OAuthToken( 61 | $token['oauth_token'], 62 | $token['oauth_token_secret'] 63 | ) 64 | ) 65 | ); 66 | 67 | // Get user profile information 68 | $response = $this->request( "https://api.linkedin.com/v1/people/~:(id,formatted-name,picture-url)?format=json" ); 69 | if ( Keyring_Util::is_error( $response ) ) { 70 | $meta = array(); 71 | } else { 72 | $this->person = $response; 73 | $meta = array( 74 | 'user_id' => $this->person->id, 75 | 'name' => $this->person->formattedName, 76 | 'picture' => $this->person->pictureUrl, 77 | ); 78 | } 79 | 80 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 81 | } 82 | 83 | function get_display( Keyring_Access_Token $token ) { 84 | return $token->get_meta( 'name' ); 85 | } 86 | 87 | function test_connection() { 88 | $res = $this->request( "https://api.linkedin.com/v1/people/~:(id,formatted-name)?format=json" ); 89 | if ( !Keyring_Util::is_error( $res ) ) 90 | return true; 91 | 92 | return $res; 93 | } 94 | } 95 | 96 | add_action( 'keyring_load_services', array( 'Keyring_Service_LinkedIn', 'init' ) ); 97 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/moves.php: -------------------------------------------------------------------------------- 1 | place_types = array( 17 | 'unknown' => __( 'Unknown', 'keyring' ), 18 | 'home' => __( 'Home', 'keyring' ), 19 | 'work' => __( 'Work', 'keyring' ), 20 | 'school' => __( 'School', 'keyring' ), 21 | 'user' => __( 'Manually Named', 'keyring' ), 22 | 'foursquare' => __( 'Selected from foursquare', 'keyring' ), 23 | ); 24 | 25 | $this->activity_types = array( 26 | 'wlk' => __( 'Walking', 'keyring' ), 27 | 'cyc' => __( 'Cycling', 'keyring' ), 28 | 'run' => __( 'Running', 'keyring' ), 29 | 'trp' => __( 'Transport', 'keyring' ), 30 | ); 31 | 32 | // Enable "basic" UI for entering key/secret 33 | if ( ! KEYRING__HEADLESS_MODE ) { 34 | add_action( 'keyring_moves_manage_ui', array( $this, 'basic_ui' ) ); 35 | add_filter( 'keyring_moves_basic_ui_intro', array( $this, 'basic_ui_intro' ) ); 36 | } 37 | 38 | $this->set_endpoint( 'authorize', 'https://api.moves-app.com/oauth/v1/authorize', 'GET' ); 39 | $this->set_endpoint( 'access_token', 'https://api.moves-app.com/oauth/v1/access_token', 'POST' ); 40 | $this->set_endpoint( 'verify_token', 'https://api.moves-app.com/oauth/v1/tokeninfo', 'GET' ); 41 | $this->set_endpoint( 'profile', 'https://api.moves-app.com/api/1.1/user/profile', 'GET' ); 42 | 43 | $creds = $this->get_credentials(); 44 | $this->app_id = $creds['app_id']; 45 | $this->key = $creds['key']; 46 | $this->secret = $creds['secret']; 47 | 48 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 49 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 50 | 51 | // Moves requires an exact match on Redirect URI, which means we can't send any nonces 52 | $this->callback_url = remove_query_arg( array( 'nonce', 'kr_nonce' ), $this->callback_url ); 53 | add_action( 'pre_keyring_moves_verify', array( $this, 'redirect_incoming_verify' ) ); 54 | 55 | $this->authorization_header = 'Bearer'; 56 | $this->authorization_parameter = false; 57 | 58 | add_filter( 'keyring_moves_request_token_params', array( $this, 'request_token_params' ) ); 59 | } 60 | 61 | function basic_ui_intro() { 62 | echo '

' . sprintf( __( 'Head over and create a new application on Moves-app which you\'ll use to connect.', 'keyring' ), 'https://dev.moves-app.com/apps/new' ) . '

'; 63 | echo '

' . sprintf( __( "Once it's created, click the Development tab. Your App ID and API Key are both shown on that page as Client ID. Enter your Client secret in the API Secret box. On that tab there is also a Redirect URI box, which you should set to %s.", 'keyring' ), Keyring_Util::admin_url( self::NAME, array( 'action' => 'verify' ) ) ) . '

'; 64 | } 65 | 66 | function request_token_params( $params ) { 67 | $params['scope'] = apply_filters( 'keyring_moves_scope', self::SCOPE ); 68 | return $params; 69 | } 70 | 71 | function redirect_incoming_verify( $request ) { 72 | if ( !isset( $request['kr_nonce'] ) ) { 73 | $kr_nonce = wp_create_nonce( 'keyring-verify' ); 74 | $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() ); 75 | wp_safe_redirect( 76 | Keyring_Util::admin_url( 77 | $this->get_name(), 78 | array( 79 | 'action' => 'verify', 80 | 'kr_nonce' => $kr_nonce, 81 | 'nonce' => $nonce, 82 | 'state' => $request['state'], 83 | 'code' => $request['code'], // Auth code from successful response (maybe) 84 | ) 85 | ) 86 | ); 87 | exit; 88 | } 89 | } 90 | 91 | function build_token_meta( $token ) { 92 | $meta = array( 93 | 'user_id' => $token['user_id'], 94 | 'refresh_token' => $token['refresh_token'], 95 | 'expires' => time() + $token['expires_in'], 96 | '_classname' => get_called_class(), 97 | ); 98 | 99 | $this->set_token( 100 | new Keyring_Access_Token( 101 | $this->get_name(), 102 | $token['access_token'], 103 | array() 104 | ) 105 | ); 106 | $response = $this->request( $this->profile_url ); 107 | if ( !Keyring_Util::is_error( $response ) ) { 108 | $meta['first_date'] = $response->profile->firstDate; 109 | } 110 | 111 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, array(), $this ); 112 | } 113 | 114 | function get_display( Keyring_Access_Token $token ) { 115 | return $token->get_meta( 'user_id' ); 116 | } 117 | 118 | function test_connection() { 119 | $response = $this->request( $this->profile_url, array( 'method' => $this->profile_method ) ); 120 | if ( ! Keyring_Util::is_error( $response ) ) { 121 | return true; 122 | } 123 | 124 | return $response; 125 | } 126 | } 127 | 128 | add_action( 'keyring_load_services', array( 'Keyring_Service_Moves', 'init' ) ); 129 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/nest.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'authorize', 'https://home.nest.com/login/oauth2', 'GET' ); 22 | $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' ); 24 | 25 | $creds = $this->get_credentials(); 26 | $this->app_id = $creds['app_id']; 27 | $this->key = $creds['key']; 28 | $this->secret = $creds['secret']; 29 | 30 | $this->authorization_header = 'Bearer'; 31 | 32 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 33 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 34 | 35 | // Nest ignores our redirect_uri, and just redirects back to a static URI 36 | add_action( 'pre_keyring_nest_verify', array( $this, 'redirect_incoming_verify' ) ); 37 | } 38 | 39 | function redirect_incoming_verify( $request ) { 40 | if ( !isset( $request['kr_nonce'] ) ) { 41 | // First request, from Pinterest. Nonce it and move on. 42 | $kr_nonce = wp_create_nonce( 'keyring-verify' ); 43 | $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() ); 44 | wp_safe_redirect( 45 | Keyring_Util::admin_url( 46 | $this->get_name(), 47 | array( 48 | 'action' => 'verify', 49 | 'kr_nonce' => $kr_nonce, 50 | 'nonce' => $nonce, 51 | 'state' => $request['state'], 52 | 'code' => $request['code'], // Auth code from successful response (maybe) 53 | ) 54 | ) 55 | ); 56 | exit; 57 | } 58 | } 59 | 60 | function basic_ui_intro() { 61 | echo '

' . sprintf( __( 'You will need to create a Developer account, and set up a Nest Product (that is what they call apps). The most important setting is the Redirect URI, which should be set to %2$s. Make sure you select appropriate permissions as well.', 'keyring' ), 'https://developers.nest.com/products/new', Keyring_Util::admin_url( $this->get_name(), array( 'action' => 'verify' ) ) ) . '

'; 62 | echo '

' . __( "Once you've set that up, copy your Product ID value into the API Key field, and the Product Secret value into the API Secret field and click save (you don't need an App ID value for Nest).", 'keyring' ) . '

'; 63 | } 64 | 65 | function build_token_meta( $token ) { 66 | $this->set_token( 67 | new Keyring_Access_Token( 68 | $this->get_name(), 69 | $token['access_token'], 70 | array() 71 | ) 72 | ); 73 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 74 | if ( Keyring_Util::is_error( $response ) ) { 75 | $meta = array(); 76 | } else { 77 | if ( ! empty( $response->structures ) ) { 78 | $label = array(); 79 | foreach ( $response->structures as $id => $structure ) { 80 | $label[] = $structure->name; 81 | } 82 | $meta = array( 83 | 'name' => implode( ' / ', $label ), 84 | ); 85 | } 86 | } 87 | 88 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 89 | } 90 | 91 | function get_display( Keyring_Access_Token $token ) { 92 | return $token->get_meta( 'name' ); 93 | } 94 | 95 | function test_connection() { 96 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 97 | if ( ! Keyring_Util::is_error( $response ) ) { 98 | return true; 99 | } 100 | 101 | return $response; 102 | } 103 | } 104 | 105 | add_action( 'keyring_load_services', array( 'Keyring_Service_Nest', 'init' ) ); 106 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/pinterest.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'authorize', 'https://api.pinterest.com/oauth/', 'GET' ); 23 | $this->set_endpoint( 'access_token', 'https://api.pinterest.com/v1/oauth/token', 'POST' ); 24 | $this->set_endpoint( 'self', 'https://api.pinterest.com/v1/me/?fields=first_name,last_name,username,image', 'GET' ); // undocumented, but required to get the `image` in a single request 25 | 26 | $creds = $this->get_credentials(); 27 | $this->app_id = $creds['app_id']; 28 | $this->key = $creds['key']; 29 | $this->secret = $creds['secret']; 30 | 31 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 32 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 33 | 34 | // Send auth token in query string 35 | $this->authorization_header = false; 36 | $this->authorization_parameter = 'access_token'; 37 | 38 | add_filter( 'keyring_pinterest_request_token_params', array( $this, 'request_token_params' ) ); 39 | 40 | // Handle Pinterest's annoying limitation of not allowing us to redirect to a dynamic URL 41 | add_action( 'pre_keyring_pinterest_verify', array( $this, 'redirect_incoming_verify' ) ); 42 | 43 | // Strip nonces, since you can't save them in your app config, and Pinterest is strict about redirect_uris 44 | // Can also only return you to an HTTPS address 45 | $this->callback_url = remove_query_arg( array( 'nonce', 'kr_nonce' ), $this->callback_url ); 46 | } 47 | 48 | function request_token_params( $params ) { 49 | $params['scope'] = apply_filters( 'keyring_pinterest_scope', self::SCOPE ); 50 | return $params; 51 | } 52 | 53 | function redirect_incoming_verify( $request ) { 54 | if ( !isset( $request['kr_nonce'] ) ) { 55 | // First request, from Pinterest. Nonce it and move on. 56 | $kr_nonce = wp_create_nonce( 'keyring-verify' ); 57 | $nonce = wp_create_nonce( 'keyring-verify-' . $this->get_name() ); 58 | wp_safe_redirect( 59 | Keyring_Util::admin_url( 60 | $this->get_name(), 61 | array( 62 | 'action' => 'verify', 63 | 'kr_nonce' => $kr_nonce, 64 | 'nonce' => $nonce, 65 | 'state' => $request['state'], 66 | 'code' => $request['code'], // Auth code from successful response (maybe) 67 | ) 68 | ) 69 | ); 70 | exit; 71 | } 72 | } 73 | 74 | function basic_ui_intro() { 75 | echo '

' . sprintf( __( 'To get started, register an API client on Pinterest. The most important setting is the OAuth redirect_uri, which should be set to %2$s. You can set the other values to whatever you like.', 'keyring' ), 'https://developers.pinterest.com/apps/', Keyring_Util::admin_url( 'pinterest', array( 'action' => 'verify' ) ) ) . '

'; 76 | echo '

' . __( "Once you're approved, copy your CLIENT ID value into the API Key field, and the CLIENT SECRET value into the API Secret field and click save (you don't need an App ID value for Pinterest).", 'keyring' ) . '

'; 77 | } 78 | 79 | function build_token_meta( $token ) { 80 | $this->set_token( 81 | new Keyring_Access_Token( 82 | $this->get_name(), 83 | $token['access_token'], 84 | array() 85 | ) 86 | ); 87 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 88 | if ( Keyring_Util::is_error( $response ) ) { 89 | $meta = array(); 90 | } else { 91 | $meta = array( 92 | 'user_id' => $response->data->id, 93 | 'username' => $response->data->username, 94 | 'name' => $response->data->first_name . ' ' . $response->data->last_name, 95 | 'picture' => $response->data->image->{'60x60'}->url // Pinterest violate their own docs that this should be 'small' 96 | ); 97 | } 98 | 99 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 100 | } 101 | 102 | function get_display( Keyring_Access_Token $token ) { 103 | return $token->get_meta( 'name' ); 104 | } 105 | 106 | function test_connection() { 107 | $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) ); 108 | if ( ! Keyring_Util::is_error( $response ) ) { 109 | return true; 110 | } 111 | 112 | return $response; 113 | } 114 | } 115 | 116 | add_action( 'keyring_load_services', array( 'Keyring_Service_Pinterest', 'init' ) ); 117 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/runkeeper.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'authorize', 'https://runkeeper.com/apps/authorize', 'GET' ); 22 | $this->set_endpoint( 'access_token', 'https://runkeeper.com/apps/token', 'POST' ); 23 | $this->set_endpoint( 'deauthorize', 'https://runkeeper.com/apps/de-authorize', 'POST' ); 24 | $this->set_endpoint( 'user', 'https://api.runkeeper.com/user', 'GET' ); 25 | $this->set_endpoint( 'profile', 'https://api.runkeeper.com/profile', 'GET' ); 26 | 27 | $creds = $this->get_credentials(); 28 | $this->app_id = $creds['app_id']; 29 | $this->key = $creds['key']; 30 | $this->secret = $creds['secret']; 31 | 32 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 33 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 34 | 35 | $this->authorization_header = 'Bearer'; 36 | $this->authorization_parameter = false; 37 | } 38 | 39 | function basic_ui_intro() { 40 | echo '

' . sprintf( __( 'You\'ll need to register a new application on RunKeeper so that you can connect. Be sure to check the Read Health Information option under Permissions Requests (and explain why you want to read that data). You will also be required to set an Estimated Date of Publication.', 'keyring' ), 'http://runkeeper.com/partner/applications/register' ) . '

'; 41 | echo '

' . __( "Once you've registered your application, click the Application Keys and URLs next to it, and copy the Client ID into the API Key field below, and the Client Secret value into API Secret.", 'keyring' ) . '

'; 42 | } 43 | 44 | function build_token_meta( $token ) { 45 | $this->set_token( 46 | new Keyring_Access_Token( 47 | $this->get_name(), 48 | $token['access_token'], 49 | array() 50 | ) 51 | ); 52 | $response = $this->request( $this->user_url, array( 'method' => $this->user_method ) ); 53 | if ( Keyring_Util::is_error( $response ) ) { 54 | $meta = array(); 55 | } else { 56 | // Only useful thing in that request is userID 57 | $meta = array( 'user_id' => (int) $response->userID ); 58 | 59 | // Now get the rest of their profile 60 | $profile = $this->request( $this->profile_url, array( 'method' => $this->profile_method ) ); 61 | if ( !Keyring_Util::is_error( $profile ) ) { 62 | $meta['username'] = substr( $profile->profile, strrpos( $profile->profile, '/' ) + 1 ); 63 | $meta['name'] = $profile->name; 64 | $meta['picture'] = $profile->large_picture; 65 | } 66 | 67 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $profile, $this ); 68 | } 69 | return array(); 70 | } 71 | 72 | function get_display( Keyring_Access_Token $token ) { 73 | return $token->get_meta( 'name' );; 74 | } 75 | 76 | function test_connection() { 77 | $response = $this->request( $this->user_url, array( 'method' => $this->user_method ) ); 78 | if ( ! Keyring_Util::is_error( $response ) ) { 79 | return true; 80 | } 81 | 82 | return $response; 83 | } 84 | } 85 | 86 | add_action( 'keyring_load_services', array( 'Keyring_Service_RunKeeper', 'init' ) ); 87 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/tripit.php: -------------------------------------------------------------------------------- 1 | authorization_header = true; 21 | $this->authorization_realm = false; 22 | 23 | $this->set_endpoint( 'request_token', 'https://api.tripit.com/oauth/request_token', 'POST' ); 24 | $this->set_endpoint( 'authorize', 'https://www.tripit.com/oauth/authorize', 'GET' ); 25 | $this->set_endpoint( 'access_token', 'https://api.tripit.com/oauth/access_token', 'POST' ); 26 | $this->set_endpoint( 'verify', 'https://api.tripit.com/v1/get/profile/id/me', 'GET' ); 27 | 28 | $creds = $this->get_credentials(); 29 | $this->app_id = $creds['app_id']; 30 | $this->key = $creds['key']; 31 | $this->secret = $creds['secret']; 32 | 33 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 34 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 35 | 36 | $this->requires_token( true ); 37 | } 38 | 39 | function basic_ui_intro() { 40 | echo '

' . sprintf( __( 'If you haven\'t created an app on TripIt yet, create one now. Make sure you select \'Full API Application\' and \'Web application or widget\'; other than that the settings are all up to you.', 'keyring' ), 'https://www.tripit.com/developer/create' ) . '

'; 41 | echo '

' . __( "Once you've created your app, you will see a yellow box at the top of the page, where you can get your API Key and API Secret, to enter below (you don't need an App ID value for TripIt).", 'keyring' ) . '

'; 42 | } 43 | 44 | function parse_response( $response ) { 45 | return json_decode( $response ); 46 | } 47 | 48 | function build_token_meta( $token ) { 49 | // Set the token so that we can make requests using it 50 | $this->set_token( 51 | new Keyring_Access_Token( 52 | $this->get_name(), 53 | new OAuthToken( 54 | $token['oauth_token'], 55 | $token['oauth_token_secret'] 56 | ) 57 | ) 58 | ); 59 | 60 | $response = $this->request( $this->verify_url, array( 'method' => $this->verify_method ) ); 61 | if ( Keyring_Util::is_error( $response ) ) { 62 | $meta = array(); 63 | } else { 64 | $meta = array( 65 | 'user_id' => $response->Profile->{'@attributes'}->ref, 66 | 'username' => $response->Profile->screen_name, 67 | 'name' => $response->Profile->public_display_name, 68 | 'picture' => $response->Profile->photo_url, 69 | '_classname' => get_called_class(), 70 | ); 71 | } 72 | 73 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 74 | } 75 | 76 | function get_display( Keyring_Access_Token $token ) { 77 | return $token->get_meta( 'name' ); 78 | } 79 | 80 | function request( $url, array $params = array() ) { 81 | $url = add_query_arg( array( 'format' => 'json' ), $url ); 82 | return parent::request( $url, $params ); 83 | } 84 | 85 | function test_connection() { 86 | $response = $this->request( $this->verify_url, array( 'method' => $this->verify_method ) ); 87 | if ( !Keyring_Util::is_error( $response ) ) 88 | return true; 89 | 90 | return $response; 91 | } 92 | } 93 | 94 | add_action( 'keyring_load_services', array( 'Keyring_Service_TripIt', 'init' ) ); 95 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/tumblr.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'request_token', 'http://www.tumblr.com/oauth/request_token', 'POST' ); 21 | $this->set_endpoint( 'authorize', 'http://www.tumblr.com/oauth/authorize', 'GET' ); 22 | $this->set_endpoint( 'access_token', 'http://www.tumblr.com/oauth/access_token', 'POST' ); 23 | 24 | $creds = $this->get_credentials(); 25 | $this->app_id = $creds['app_id']; 26 | $this->key = $creds['key']; 27 | $this->secret = $creds['secret']; 28 | 29 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 30 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 31 | 32 | $this->authorization_header = true; // Send OAuth token in the header, not querystring 33 | $this->authorization_realm = 'tumblr.com'; 34 | } 35 | 36 | function basic_ui_intro() { 37 | echo '

' . sprintf( __( 'To get started, register an application with Tumblr. The Default callback URL should be set to %2$s, and you can enter whatever you like in the other fields.', 'keyring' ), 'http://www.tumblr.com/oauth/register', Keyring_Util::admin_url( 'tumblr', array( 'action' => 'verify' ) ) ) . '

'; 38 | echo '

' . __( "Once you've created your app, copy the OAuth Consumer Key into the API Key field below. Click the Show secret key link, and then copy the Secret Key value into the API Secret field below. You don't need an App ID value for Tumblr.", 'keyring' ) . '

'; 39 | } 40 | 41 | function parse_response( $response ) { 42 | return json_decode( $response ); 43 | } 44 | 45 | function build_token_meta( $token ) { 46 | // Set the token so that we can make requests using it 47 | $this->set_token( 48 | new Keyring_Access_Token( 49 | 'tumblr', 50 | new OAuthToken( 51 | $token['oauth_token'], 52 | $token['oauth_token_secret'] 53 | ) 54 | ) 55 | ); 56 | 57 | $response = $this->request( 'http://api.tumblr.com/v2/user/info', array( 'method' => 'POST' ) ); 58 | 59 | if ( Keyring_Util::is_error( $response ) ) { 60 | $meta = array(); 61 | } else { 62 | $this->person = $response->response->user; 63 | $meta = array( 64 | 'name' => $this->person->name, 65 | ); 66 | } 67 | 68 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 69 | } 70 | 71 | function get_display( Keyring_Access_Token $token ) { 72 | return $token->get_meta( 'name' ); 73 | } 74 | 75 | function test_connection() { 76 | $res = $this->request( 'http://api.tumblr.com/v2/user/info', array( 'method' => 'POST' ) ); 77 | if ( !Keyring_Util::is_error( $res ) ) 78 | return true; 79 | 80 | return $res; 81 | } 82 | } 83 | 84 | add_action( 'keyring_load_services', array( 'Keyring_Service_Tumblr', 'init' ) ); 85 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/twitter.php: -------------------------------------------------------------------------------- 1 | authorization_header = true; 21 | $this->authorization_realm = "twitter.com"; 22 | 23 | $this->set_endpoint( 'request_token', 'https://twitter.com/oauth/request_token', 'POST' ); 24 | $this->set_endpoint( 'authorize', 'https://twitter.com/oauth/authorize', 'GET' ); 25 | $this->set_endpoint( 'access_token', 'https://twitter.com/oauth/access_token', 'POST' ); 26 | $this->set_endpoint( 'verify', 'https://api.twitter.com/1.1/account/verify_credentials.json', 'GET' ); 27 | 28 | $creds = $this->get_credentials(); 29 | $this->app_id = $creds['app_id']; 30 | $this->key = $creds['key']; 31 | $this->secret = $creds['secret']; 32 | 33 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 34 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 35 | 36 | $this->requires_token( true ); 37 | } 38 | 39 | function basic_ui_intro() { 40 | echo '

' . sprintf( __( 'If you haven\'t already, you\'ll need to create an app on Twitter (log in using your normal Twitter account). Make sure you enter something for the Callback URL, even though Keyring will override it with the correct value. Just enter your homepage, e.g. %2$s.', 'keyring' ), 'https://apps.twitter.com/app/new', get_bloginfo( 'url' ) ) . '

'; 41 | echo '

' . __( "Once you've created an app, copy and paste your Consumer key and Consumer secret (from under the OAuth settings section of your app's details) into the boxes below. You don't need an App ID for Twitter.", 'keyring' ) . '

'; 42 | } 43 | 44 | function parse_response( $response ) { 45 | return json_decode( $response ); 46 | } 47 | 48 | function build_token_meta( $token ) { 49 | // Set the token so that we can make requests using it 50 | $this->set_token( 51 | new Keyring_Access_Token( 52 | $this->get_name(), 53 | new OAuthToken( 54 | $token['oauth_token'], 55 | $token['oauth_token_secret'] 56 | ) 57 | ) 58 | ); 59 | 60 | $response = $this->request( $this->verify_url, array( 'method' => $this->verify_method ) ); 61 | if ( Keyring_Util::is_error( $response ) ) { 62 | $meta = array(); 63 | } else { 64 | $meta = array( 65 | 'user_id' => $token['user_id'], 66 | 'username' => $token['screen_name'], 67 | 'name' => $response->name, 68 | 'picture' => str_replace( '_normal.', '.', $response->profile_image_url ), 69 | '_classname' => get_called_class(), 70 | ); 71 | } 72 | 73 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 74 | } 75 | 76 | function get_display( Keyring_Access_Token $token ) { 77 | return '@' . $token->get_meta( 'username' ); 78 | } 79 | 80 | function test_connection() { 81 | $res = $this->request( 'https://api.twitter.com/1.1/account/verify_credentials.json' ); 82 | if ( !Keyring_Util::is_error( $res ) ) 83 | return true; 84 | 85 | // Twitter may return a rate limiting error if the user accesses the sharing settings or post 86 | // page frequently. If so, ignore that error, things are likely aaaa-okay... 87 | $keyring_error_message = $res->get_error_message(); 88 | if ( is_array( $keyring_error_message ) && isset( $keyring_error_message['response']['code'] ) ) { 89 | if ( 429 == absint( $keyring_error_message['response']['code'] ) ) { 90 | return true; 91 | } 92 | } 93 | 94 | return $res; 95 | } 96 | } 97 | 98 | add_action( 'keyring_load_services', array( 'Keyring_Service_Twitter', 'init' ) ); 99 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/services/extended/yahoo.php: -------------------------------------------------------------------------------- 1 | set_endpoint( 'request_token', 'https://api.login.yahoo.com/oauth/v2/get_request_token', 'GET' ); 21 | $this->set_endpoint( 'authorize', 'https://api.login.yahoo.com/oauth/v2/request_auth', 'GET' ); 22 | $this->set_endpoint( 'access_token', 'https://api.login.yahoo.com/oauth/v2/get_token', 'POST' ); 23 | 24 | $creds = $this->get_credentials(); 25 | $this->app_id = $creds['app_id']; 26 | $this->key = $creds['key']; 27 | $this->secret = $creds['secret']; 28 | 29 | $this->consumer = new OAuthConsumer( $this->key, $this->secret, $this->callback_url ); 30 | $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1; 31 | } 32 | 33 | function basic_ui_intro() { 34 | echo '

' . sprintf( __( 'To connect to Yahoo!, you need to Create a new project. Make sure you set the Access Scope to This app requires access to private user data. When you select that, you will be asked for an Application Domain, which should probably be set to http://%2$s. Which APIs you request access for will depend on how Keyring will be used on this site. Common ones will be Contacts, Social Directory, Status, and Updates.', 'keyring' ), 'https://developer.apps.yahoo.com/dashboard/createKey.html', $_SERVER['HTTP_HOST'] ) . '

'; 35 | echo '

' . __( "Once you've created your project, copy and paste your Consumer key and Consumer secret (from under the Authentication Information: OAuth section of your app's details) into the boxes below. You don't need an App ID for Yahoo!.", 'keyring' ) . '

'; 36 | } 37 | 38 | function parse_response( $response ) { 39 | return json_decode( $response ); 40 | } 41 | 42 | function build_token_meta( $token ) { 43 | $expires = isset( $token['oauth_expires_in'] ) ? gmdate( 'Y-m-d H:i:s', time() + $token['oauth_expires_in'] ) : 0; 44 | 45 | $this->set_token( 46 | new Keyring_Access_Token( 47 | 'yahoo', 48 | new OAuthToken( 49 | $token['oauth_token'], 50 | $token['oauth_token_secret'] 51 | ) 52 | ) 53 | ); 54 | 55 | // Get user profile information 56 | $response = $this->request( "http://social.yahooapis.com/v1/user/{$token['xoauth_yahoo_guid']}/profile?format=json" ); 57 | 58 | if ( Keyring_Util::is_error( $response ) ) { 59 | $meta = array(); 60 | } else { 61 | $this->person = $response->profile; 62 | $meta = array( 63 | 'user_id' => $token['xoauth_yahoo_guid'], 64 | 'name' => $this->person->nickname, 65 | 'picture' => $this->person->image->imageUrl, 66 | ); 67 | } 68 | 69 | return apply_filters( 'keyring_access_token_meta', $meta, $this->get_name(), $token, $response, $this ); 70 | } 71 | 72 | function get_display( Keyring_Access_Token$token ) { 73 | return $token->get_meta( 'name' ); 74 | } 75 | 76 | function test_connection() { 77 | $this->maybe_refresh_token(); 78 | 79 | $guid = $this->token->get_meta( 'external_id' ); 80 | 81 | $res = $this->request( 'http://social.yahooapis.com/v1/user/' . $guid . '/profile?format=json' ); 82 | if ( !Keyring_Util::is_error( $res ) ) 83 | return true; 84 | 85 | return $res; 86 | } 87 | 88 | function maybe_refresh_token() { 89 | global $wpdb; 90 | 91 | if ( empty( $this->token->token ) || empty( $this->token->token->tokenExpires ) ) 92 | return; 93 | 94 | if ( $this->token->token->tokenExpires && $this->token->token->tokenExpires < time() ) { 95 | $api_url = 'https://api.login.yahoo.com/oauth/v2/get_token'; 96 | $api_url .= '?oauth_session_handle=' . $this->token->token->sessionHandle; 97 | 98 | $refresh = $this->request( $api_url, array( 99 | 'method' => 'GET', 100 | 'raw_response' => true, 101 | ) ); 102 | 103 | if ( !Keyring_Util::is_error( $refresh ) ) { 104 | $token = $this->parse_access_token( $refresh ); 105 | 106 | // Fake request token 107 | global $keyring_request_token; 108 | $keyring_request_token = new Keyring_Request_Token( 109 | $this->get_name(), 110 | array() 111 | ); 112 | 113 | // Build (real) access token 114 | $access_token = new Keyring_Access_Token( 115 | $this->get_name(), 116 | new OAuthToken( 117 | $token['oauth_token'], 118 | $token['oauth_token_secret'] 119 | ), 120 | $this->build_token_meta( $token ), 121 | $this->token->unique_id 122 | ); 123 | 124 | // Store the updated access token 125 | $access_token = apply_filters( 'keyring_access_token', $access_token, $token ); 126 | $id = $this->store->update( $access_token ); 127 | 128 | // And switch to using it 129 | $this->set_token( $access_token ); 130 | } 131 | } 132 | } 133 | } 134 | 135 | add_action( 'keyring_load_services', array( 'Keyring_Service_Yahoo', 'init' ) ); 136 | -------------------------------------------------------------------------------- /publishiza/keyring/includes/stores/singlestore.php: -------------------------------------------------------------------------------- 1 | __( 'Keyring Request Token', 'keyring' ), 19 | 'description' => __( 'Token or authentication details stored by Keyring. Request tokens are used during the authorization flow.', 'keyring' ), 20 | 'public' => false, 21 | ) ); 22 | 23 | register_post_type( 'kr_access_token', array( 24 | 'label' => __( 'Keyring Access Token', 'keyring' ), 25 | 'description' => __( 'Token or authentication details stored by Keyring. Access tokens are used to make secure requests.', 'keyring' ), 26 | 'public' => false, 27 | ) ); 28 | 29 | $instance = new Keyring_SingleStore; 30 | } 31 | 32 | return $instance; 33 | } 34 | 35 | function insert( $token ) { 36 | // Avoid duplicates by checking to see if this exists already 37 | $found = get_posts( array( 38 | 'posts_per_page' => 1, 39 | 'post_type' => 'kr_' . $token->type() . '_token', 40 | 'meta_key' => 'service', 41 | 'meta_value' => $token->get_name(), 42 | 'author' => get_current_user_id(), 43 | 's' => serialize( $token->token ), // Search the post content for this token 44 | 'exact' => true, // Require exact content match 45 | 'sentence' => true, // Require to search by phrase, otherwise string is split by regex 46 | ) ); 47 | 48 | if ( $found ) { 49 | $token->unique_id = $found[0]->ID; 50 | return $this->update( $token ); 51 | } 52 | 53 | $post = array( 54 | 'post_type' => 'kr_' . $token->type() . '_token', 55 | 'post_status' => 'publish', 56 | 'post_content' => serialize( $token->token ), 57 | ); 58 | $id = wp_insert_post( add_magic_quotes( $post ) ); 59 | if ( $id ) { 60 | // Always record what service this token is for 61 | update_post_meta( $id, 'service', $token->get_name() ); 62 | 63 | // Optionally include any meta related to this token 64 | foreach ( (array) $token->get_meta( false, true ) as $key => $val ) { 65 | update_post_meta( $id, $key, $val ); 66 | } 67 | return $id; 68 | } 69 | return false; 70 | } 71 | 72 | function update( $token ) { 73 | if ( !$token->unique_id ) 74 | return false; 75 | 76 | $id = $token->unique_id; 77 | $post = get_post( $id ); 78 | if ( !$post ) 79 | return false; 80 | 81 | $post->post_content = serialize( $token->token ); 82 | wp_update_post( $post ); 83 | 84 | foreach ( $token->get_meta( false, true ) as $key => $val ) { 85 | update_post_meta( $id, $key, $val ); 86 | } 87 | 88 | return $id; 89 | } 90 | 91 | function delete( $args = array() ) { 92 | if ( !$args['id'] ) 93 | return false; 94 | return wp_delete_post( $args['id'] ); 95 | } 96 | 97 | function get_tokens( $args = array() ) { 98 | $defaults = array( 99 | 'type' => 'access', 100 | 'service' => false, 101 | 'user_id' => get_current_user_id(), 102 | 'blog_id' => get_current_blog_id(), 103 | ); 104 | $args = wp_parse_args( $args, $defaults ); 105 | 106 | $query = array( 107 | 'numberposts' => -1, // all 108 | 'post_type' => 'kr_' . $args['type'] . '_token', 109 | 'author' => $args['user_id'], 110 | ); 111 | 112 | // Get tokens for a specific service 113 | if ( $args['service'] ) { 114 | $query['meta_key'] = 'service'; 115 | $query['meta_value'] = $args['service']; 116 | } 117 | 118 | $token_type = 'request' == $args['type'] ? 'Keyring_Request_Token' : 'Keyring_Access_Token'; 119 | $tokens = array(); 120 | $posts = get_posts( $query ); 121 | if ( count( $posts ) ) { 122 | foreach ( $posts as $post ) { 123 | $meta = get_post_meta( $post->ID ); 124 | foreach ( $meta as $mid => $met ) { 125 | $meta[$mid] = $met[0]; 126 | } 127 | 128 | $tokens[] = new $token_type( 129 | get_post_meta( 130 | $post->ID, 131 | 'service', 132 | true 133 | ), 134 | unserialize( $post->post_content ), 135 | $meta, 136 | $post->ID 137 | ); 138 | } 139 | } 140 | 141 | return $tokens; 142 | } 143 | 144 | function get_token( $args = array() ) { 145 | $defaults = array( 146 | 'id' => false, 147 | 'type' => 'access', 148 | 'service' => false, 149 | 'user_id' => get_current_user_id(), 150 | 'blog_id' => get_current_blog_id(), 151 | ); 152 | $args = wp_parse_args( $args, $defaults ); 153 | 154 | if ( !$args['id'] && !$args['service'] ) 155 | return false; 156 | 157 | $post = get_post( $args['id'] ); 158 | if ( $post ) { 159 | $meta = get_post_meta( $post->ID ); 160 | foreach ( $meta as $mid => $met ) { 161 | $meta[$mid] = $met[0]; 162 | } 163 | 164 | $token_type = 'kr_request_token' == $post->post_type ? 'Keyring_Request_Token' : 'Keyring_Access_Token'; 165 | return new $token_type( 166 | get_post_meta( 167 | $post->ID, 168 | 'service', 169 | true 170 | ), 171 | unserialize( $post->post_content ), 172 | $meta, 173 | $post->ID 174 | ); 175 | } 176 | return false; 177 | } 178 | 179 | function count( $args = array() ) { 180 | return count( $this->get_tokens( $args ) ); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /publishiza/keyring/keyring.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | 12 | // Define this in your wp-config (and set to true) to enable debugging 13 | defined( 'KEYRING__DEBUG_MODE' ) or define( 'KEYRING__DEBUG_MODE', false ); 14 | 15 | // The name of a class which extends Keyring_Store to handle storage/manipulation of tokens. 16 | // Optionally define this in your wp-config.php or some other global config file. 17 | defined( 'KEYRING__TOKEN_STORE' ) or define( 'KEYRING__TOKEN_STORE', 'Keyring_SingleStore' ); 18 | 19 | // Keyring can be run in "headless" mode, which just avoids creating any UI, and leaves 20 | // that up to you. Defaults to off (provides its own basic UI). 21 | defined( 'KEYRING__HEADLESS_MODE' ) or define( 'KEYRING__HEADLESS_MODE', false ); 22 | 23 | // Debug/messaging levels. Don't mess with these 24 | define( 'KEYRING__DEBUG_NOTICE', 1 ); 25 | define( 'KEYRING__DEBUG_WARN', 2 ); 26 | define( 'KEYRING__DEBUG_ERROR', 3 ); 27 | 28 | // Indicates Keyring is installed/active so that other plugins can detect it 29 | define( 'KEYRING__VERSION', '1.7.1' ); 30 | 31 | /** 32 | * Core Keyring class that handles UI and the general flow of requesting access tokens etc 33 | * to manage access to remote services. 34 | * 35 | * @package Keyring 36 | */ 37 | class Keyring { 38 | protected $registered_services = array(); 39 | protected $store = false; 40 | protected $errors = array(); 41 | protected $messages = array(); 42 | protected $token_store = ''; 43 | var $admin_page = 'keyring'; 44 | 45 | function __construct() { 46 | if ( ! KEYRING__HEADLESS_MODE ) { 47 | require_once dirname( __FILE__ ) . '/admin-ui.php'; 48 | Keyring_Admin_UI::init(); 49 | 50 | add_filter( 'keyring_admin_url', function( $url, $params ) { 51 | $url = admin_url( 'tools.php?page=' . Keyring::init()->admin_page ); 52 | return add_query_arg( $params, $url ); 53 | }, 10, 2 ); 54 | } 55 | 56 | // This is used internally to create URLs, and also to know when to 57 | // attach handers. @see admin_url() and request_handlers() 58 | $this->admin_page = apply_filters( 'keyring_admin_page', 'keyring' ); 59 | } 60 | 61 | static function &init( $force_load = false ) { 62 | static $instance = false; 63 | 64 | if ( !$instance ) { 65 | if ( ! KEYRING__HEADLESS_MODE ) 66 | load_plugin_textdomain( 'keyring', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); 67 | $instance = new Keyring; 68 | 69 | // Keyring is being loaded 'late', so we need to do some extra set-up 70 | if ( did_action( 'init' ) || $force_load ) { 71 | $instance->plugins_loaded(); 72 | do_action( 'keyring_load_services' ); 73 | } 74 | } else { 75 | if ( $force_load ) { 76 | $instance->plugins_loaded(); 77 | do_action( 'keyring_load_services' ); 78 | } 79 | } 80 | 81 | return $instance; 82 | } 83 | 84 | static function plugins_loaded() { 85 | // Load stores early so we can confirm they're loaded correctly 86 | require_once dirname( __FILE__ ) . '/store.php'; 87 | do_action( 'keyring_load_token_stores' ); 88 | $keyring = Keyring::init(); 89 | $keyring->token_store = apply_filters( 'keyring_token_store', defined( 'KEYRING__TOKEN_STORE' ) ? KEYRING__TOKEN_STORE : false ); 90 | if ( !class_exists( $keyring->token_store ) || !in_array( 'Keyring_Store', class_parents( $keyring->token_store ) ) ) 91 | wp_die( sprintf( __( 'Invalid KEYRING__TOKEN_STORE specified. Please make sure KEYRING__TOKEN_STORE is set to a valid classname for handling token storage in %s (or wp-config.php)', 'keyring' ), __FILE__ ) ); 92 | 93 | // Load base token and service definitions + core services 94 | require_once dirname( __FILE__ ) . '/token.php'; 95 | require_once dirname( __FILE__ ) . '/service.php'; // Triggers a load of all core + extended service definitions 96 | 97 | // Initiate Keyring 98 | add_action( 'init', array( 'Keyring', 'init' ), 1 ); 99 | 100 | // Load external Services (plugins etc should hook to this to define new ones/extensions) 101 | add_action( 'init', function() { 102 | do_action( 'keyring_load_services' ); 103 | }, 2 ); 104 | 105 | /** 106 | * And trigger request handlers, which plugins and extended Services use to handle UI, 107 | * redirects, errors etc. 108 | * @see ::request_handlers() 109 | */ 110 | add_action( 'admin_init', array( 'Keyring', 'request_handlers' ), 100 ); 111 | } 112 | 113 | /** 114 | * Core request handler which is the crux of everything. An action is called 115 | * here for almost everything Keyring does, so you can use it to intercept 116 | * almost everything. Based entirely on $_REQUEST[page|action|service] 117 | */ 118 | static function request_handlers() { 119 | global $current_user; 120 | 121 | if ( defined( 'KEYRING__FORCE_USER' ) && KEYRING__FORCE_USER && in_array( $_REQUEST['action'], array( 'request', 'verify' ) ) ) { 122 | global $current_user; 123 | $real_user = $current_user->ID; 124 | wp_set_current_user( KEYRING__FORCE_USER ); 125 | } 126 | 127 | if ( 128 | !empty( $_REQUEST['action'] ) 129 | && 130 | in_array( $_REQUEST['action'], apply_filters( 'keyring_core_actions', array( 'request', 'verify', 'created', 'delete', 'manage' ) ) ) 131 | && 132 | !empty( $_REQUEST['service'] ) 133 | && 134 | in_array( $_REQUEST['service'], array_keys( Keyring::get_registered_services() ) ) 135 | ) { 136 | // We have an action here to allow us to do things pre-authorization, just in case 137 | do_action( "pre_keyring_{$_REQUEST['service']}_{$_REQUEST['action']}", $_REQUEST ); 138 | 139 | // Core nonce check required for everything. "keyring-ACTION" is the kr_nonce format 140 | if ( !isset( $_REQUEST['kr_nonce'] ) || !wp_verify_nonce( $_REQUEST['kr_nonce'], 'keyring-' . $_REQUEST['action'] ) ) { 141 | Keyring::error( __( 'Invalid/missing Keyring core nonce. All core actions require a valid nonce.', 'keyring' ) ); 142 | exit; 143 | } 144 | 145 | Keyring_Util::debug( "keyring_{$_REQUEST['service']}_{$_REQUEST['action']}" ); 146 | Keyring_Util::debug( $_GET ); 147 | do_action( "keyring_{$_REQUEST['service']}_{$_REQUEST['action']}", $_REQUEST ); 148 | 149 | if ( 'delete' == $_REQUEST['action'] ) 150 | do_action( "keyring_connection_deleted", $_REQUEST['service'], $_REQUEST ); 151 | } 152 | 153 | if ( defined( 'KEYRING__FORCE_USER' ) && KEYRING__FORCE_USER && in_array( $_REQUEST['action'], array( 'request', 'verify' ) ) ) 154 | wp_set_current_user( $real_user ); 155 | } 156 | 157 | static function register_service( Keyring_Service $service ) { 158 | if ( Keyring_Util::is_service( $service ) ) { 159 | Keyring::init()->registered_services[ $service->get_name() ] = $service; 160 | return true; 161 | } 162 | return false; 163 | } 164 | 165 | static function get_registered_services() { 166 | return Keyring::init()->registered_services; 167 | } 168 | 169 | static function get_service_by_name( $name ) { 170 | $keyring = Keyring::init(); 171 | if ( !isset( $keyring->registered_services[ $name ] ) ) 172 | return null; 173 | 174 | return $keyring->registered_services[ $name ]; 175 | } 176 | 177 | static function get_token_store() { 178 | $keyring = Keyring::init(); 179 | 180 | if ( !$keyring->store ) 181 | $keyring->store = call_user_func( array( $keyring->token_store, 'init' ) ); 182 | 183 | return $keyring->store; 184 | } 185 | 186 | static function message( $str ) { 187 | $keyring = Keyring::init(); 188 | $keyring->messages[] = $str; 189 | } 190 | 191 | /** 192 | * Generic error handler/trigger. 193 | * @param String $str Informational message (user-readable) 194 | * @param array $info Additional information relating to the error. 195 | * @param boolean $die If we should immediately die (default) or continue 196 | */ 197 | static function error( $str, $info = array(), $die = true ) { 198 | $keyring = Keyring::init(); 199 | $keyring->errors[] = $str; 200 | do_action( 'keyring_error', $str, $info, isset( $this ) ? $this : null ); 201 | if ( $die ) { 202 | wp_die( $str, __( 'Keyring Error', 'keyring' ) ); 203 | exit; 204 | } 205 | } 206 | 207 | function has_errors() { 208 | return count( $this->errors ); 209 | } 210 | 211 | function has_messages() { 212 | return count( $this->messages ); 213 | } 214 | 215 | function get_messages() { 216 | return $this->messages; 217 | } 218 | 219 | function get_errors() { 220 | return $this->errors; 221 | } 222 | } 223 | 224 | class Keyring_Util { 225 | static function debug( $str, $level = KEYRING__DEBUG_NOTICE ) { 226 | if ( !KEYRING__DEBUG_MODE ) 227 | return; 228 | 229 | if ( is_object( $str ) || is_array( $str ) ) 230 | $str = print_r( $str, true ); 231 | 232 | switch ( $level ) { 233 | case KEYRING__DEBUG_WARN : 234 | echo "
Keyring Warning: $str
"; 235 | break; 236 | case KEYRING__DEBUG_ERROR : 237 | wp_die( '

Keyring Error:

' . '

' . $str . '

' ); 238 | exit; 239 | } 240 | 241 | error_log( "Keyring: $str" ); 242 | } 243 | 244 | static function is_service( $service ) { 245 | if ( is_object( $service ) && is_subclass_of( $service, 'Keyring_Service' ) ) 246 | return true; 247 | 248 | return false; 249 | } 250 | 251 | static function has_custom_ui( $service, $action ) { 252 | return has_action( "keyring_{$service}_{$action}_ui" ); 253 | } 254 | 255 | /** 256 | * Get a URL to the Keyring admin UI, works kinda like WP's admin_url() 257 | * 258 | * @param string $service Shortname of a specific service. 259 | * @return URL to Keyring admin UI (main listing, or specific service verify process) 260 | */ 261 | static function admin_url( $service = false, $params = array() ) { 262 | $url = admin_url(); 263 | 264 | if ( $service ) 265 | $params['service'] = $service; 266 | 267 | if ( count( $params ) ) 268 | $url = add_query_arg( $params, $url ); 269 | 270 | return apply_filters( 'keyring_admin_url', $url, $params ); 271 | } 272 | 273 | static function connect_to( $service, $for ) { 274 | Keyring_Util::debug( 'Connect to: ' . $service ); 275 | // Redirect into Keyring's auth handler if a valid service is provided 276 | $kr_nonce = wp_create_nonce( 'keyring-request' ); 277 | $request_nonce = wp_create_nonce( 'keyring-request-' . $service ); 278 | wp_safe_redirect( 279 | Keyring_Util::admin_url( 280 | $service, 281 | array( 282 | 'action' => 'request', 283 | 'kr_nonce' => $kr_nonce, 284 | 'nonce' => $request_nonce, 285 | 'for' => $for 286 | ) 287 | ) 288 | ); 289 | exit; 290 | } 291 | 292 | static function token_select_box( $tokens, $name, $create = false ) { 293 | ?>name = strtolower( $service ); // Name of the service this token is for 29 | $this->token = $token; 30 | $this->unique_id = $uniq; 31 | $this->meta = $meta; 32 | $this->get_service(); 33 | } 34 | 35 | function __toString() { 36 | return (string) $this->token; 37 | } 38 | 39 | function get_uniq_id() { 40 | if ( isset( $this->unique_id ) ) 41 | return $this->unique_id; 42 | return null; 43 | } 44 | 45 | function get_display() { 46 | if ( $service = $this->get_service() ) 47 | return $service->get_display( $this ); 48 | return $this->name; 49 | } 50 | 51 | function get_service() { 52 | if ( !$this->service ) { 53 | $class = $this->get_meta( '_classname', true ); 54 | if ( $class && class_exists( $class ) ) { 55 | $this->service = call_user_func( array( $class, 'init' ) ); 56 | } else { 57 | $this->service = Keyring::get_service_by_name( $this->get_name() ); 58 | } 59 | } 60 | return $this->service; 61 | } 62 | 63 | function get_name() { 64 | return $this->name; 65 | } 66 | 67 | /** 68 | * Get a specific piece of meta data for this token, or all meta as an array. 69 | * 70 | * @param mixed $name The key name for a specific meta item, or false for all. 71 | * @param bool $allow_hidden Allow access to "hidden" meta (prefixed with "_") 72 | * @return Mixed meta value, array of meta values, or null 73 | */ 74 | function get_meta( $name = false, $allow_hidden = false ) { 75 | $return = null; 76 | if ( $name ) { 77 | if ( '_' != substr( $name, 0, 1 ) || $allow_hidden ) { 78 | if ( isset( $this->meta[ $name ] ) ) { 79 | $return = $this->meta[ $name ]; 80 | } 81 | } 82 | } else { 83 | foreach ( (array) $this->meta as $key => $val ) { 84 | if ( '_' != substr( $key, 0, 1 ) || $allow_hidden ) { 85 | $return[ $key ] = $val; 86 | } 87 | } 88 | } 89 | 90 | return $return; 91 | } 92 | 93 | /** 94 | * Check if a token has expired, or will expire in the next $window seconds 95 | **/ 96 | function is_expired( $window = 0 ) { 97 | if ( !$expires = $this->get_meta( 'expires' ) ) 98 | return false; // No expires value, assume it's a permanent token 99 | 100 | if ( '0000-00-00 00:00:00' == $expires ) 101 | return false; // Doesn't expire 102 | 103 | if ( ( time() + $window ) > strtotime( $expires ) ) 104 | return true; // Token's expiry time has passed, or will pass before $window 105 | 106 | // Not expired 107 | return false; 108 | } 109 | } 110 | 111 | /** 112 | * During the first phase of the auth flow, we normally want to (or are required to) 113 | * store some details before sending the user off to a remote service to grant access. 114 | * Use a request token to store those details locally, then we can retrieve them when 115 | * we get back to finish the auth flow. 116 | */ 117 | class Keyring_Request_Token extends Keyring_Token { 118 | function __construct( $service, $token, $meta = array(), $uniq = false ) { 119 | $meta['type'] = 'request'; 120 | return parent::__construct( $service, $token, $meta, $uniq ); 121 | } 122 | 123 | function type() { 124 | return 'request'; 125 | } 126 | } 127 | 128 | /** 129 | * Access tokens are what are 'permanently' stored, containing the information required 130 | * to make secure connections/requests on behalf of the user of a remote service. 131 | */ 132 | class Keyring_Access_Token extends Keyring_Token { 133 | function __construct( $service, $token, $meta = array(), $uniq = false ) { 134 | $meta['type'] = 'access'; 135 | return parent::__construct( $service, $token, $meta, $uniq ); 136 | } 137 | 138 | function type() { 139 | return 'access'; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Publishiza === 2 | Contributors: johnjamesjacoby 3 | Tags: post, twitter, tweet, storm 4 | Requires at least: 4.7 5 | Tested up to: 4.8 6 | Stable tag: 1.0.0 7 | License: GPLv2 or later 8 | License URI: https://www.gnu.org/licenses/gpl-2.0.html 9 | Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9Q4F4EL5YJ62J 10 | 11 | Compose and publish a Tweetstorm, all from inside your WordPress. 12 | 13 | == Description == 14 | 15 | Seamlessly integrates into your WordPress dashboard interface. Safe, secure, & efficient. 16 | 17 | Publishiza includes Keyring, a great foundation by my pal by Beau Lebens. 18 | 19 | == Installation == 20 | 21 | * Download and install using the built in WordPress plugin installer. 22 | * Activate in the "Plugins" area of your admin by clicking the "Activate" link. 23 | * Visit: Tools > Keyring 24 | * Add a New Service 25 | * Authorize Publishiza 26 | 27 | == Frequently Asked Questions == 28 | 29 | = Why would I need this? = 30 | 31 | You really like tweetstorming, but you also want to archive your content in your blog. 32 | 33 | == Screenshots == 34 | 1. Publish box 35 | 2. Keyring 36 | 37 | == Changelog == 38 | 39 | = 1.0.0 = 40 | * Initial release 41 | --------------------------------------------------------------------------------