WordPress.org

Plugin Directory

Changeset 595111


Ignore:
Timestamp:
09/05/12 20:14:56 (20 months ago)
Author:
andy
Message:

jetpack: merge multiuser branch into trunk. adds buttons for other users to link and unlink their wordpress.com accounts. converts token storage to array with user_id keys.

Location:
jetpack/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • jetpack/trunk

  • jetpack/trunk/_inc/jetpack.css

    r589031 r595111  
    2222        } 
    2323 
    24         #jp-header #jp-clouds #jp-disconnect { 
     24 
     25        #jp-header #jp-clouds #jp-disconnectors { 
    2526            font-size: 12px; 
    2627            color: #fff; 
    2728            float: right; 
    28             margin: -35px 25px 0 0; 
    29             text-align: right; 
    30         } 
    31  
    32         #jp-header #jp-clouds #jp-disconnect a { 
     29            margin-top: -35px; 
     30            text-align: left; 
     31            position: relative; 
     32            left: -45px; 
     33        } 
     34 
     35        #jp-header #jp-clouds .jp-disconnect a { 
    3336            background: #8caa46 url( images/status-light.png ) 3px 85% no-repeat; 
    3437            display: inline-block; 
    35             padding: 4px 10px 3px 30px; 
     38            position: relative; 
     39            width: 100%; 
     40            height: 1.7em; 
     41            overflow: hidden; 
     42            padding: 4px 0 3px 30px; 
     43            margin: 0 -20px 3px 0; 
    3644            color: #fff; 
    37             text-align: center; 
    3845            text-decoration: none; 
    3946            border: 1px solid #7a943d; 
     
    4653            text-shadow: 0px -1px 0px rgba( 0,0,0,0.3 ); 
    4754        } 
    48             #jp-header #jp-clouds #jp-disconnect a:hover { 
    49                 background: #8caa46 url( images/status-light.png ) 3px 5% no-repeat; 
     55            #jp-header #jp-clouds .jp-disconnect a:hover { 
     56                background: #8caa46 url( images/status-light.png ) 3px -2% no-repeat; 
    5057                background-color: #839f40; 
    5158                border-color: #6a8037; 
    5259            } 
    5360 
    54             #jp-header #jp-clouds #jp-disconnect span { display: none; } 
     61            #jp-header #jp-clouds .jp-disconnect div { 
     62                position: relative; 
     63                line-height: 1.7em; 
     64                height: 1.7em; 
     65            } 
     66 
     67            #jp-header #jp-clouds .jp-disconnect a:hover div, 
     68            #jp-header #jp-clouds .jp-disconnect a.clicked div { 
     69                top: -1.7em; 
     70            } 
    5571     
    5672    /* Retina Header Clouds & Status Light */ 
     
    6581            } 
    6682             
    67         #jp-header #jp-clouds #jp-disconnect a { 
     83        #jp-header #jp-clouds .jp-disconnect a { 
    6884            background: #8caa46 url( images/status-light-2x.png ) 3px 85% no-repeat; 
    6985            background-size:25px 57px; 
    7086        } 
    71             #jp-header #jp-clouds #jp-disconnect a:hover { 
    72                 background: #8caa46 url( images/status-light-2x.png ) 3px 5% no-repeat; 
     87            #jp-header #jp-clouds .jp-disconnect a:hover { 
     88                background: #8caa46 url( images/status-light-2x.png ) 3px -2% no-repeat; 
    7389                background-size:25px 57px; 
    7490            } 
  • jetpack/trunk/_inc/jetpack.js

    r541426 r595111  
    5858 
    5959        var widerWidth = 0; 
    60         jQuery( '#jp-disconnect' ).hover( function() { 
    61             var t = jQuery( this ), 
    62                 a = t.find( 'a' ), 
    63                 width = t.width(), 
    64                 changeWidth = widerWidth == 0; 
    65  
    66             if ( changeWidth && widerWidth < width ) { 
    67                 widerWidth = width; 
    68             } 
    69             jetpack.statusText = a.html(); 
    70             a.html( jQuery( '#jp-disconnect span' ).html() ); 
    71             width = t.width(); 
    72             if ( changeWidth && widerWidth < width ) { 
    73                 widerWidth = width + 15; 
    74             } 
    75             if ( changeWidth ) { 
    76                 t.width( widerWidth ); 
    77             } 
    78             a.hide().fadeIn(100); 
    79         }, function() { 
    80             var a = jQuery( 'a', this ); 
    81             a.html( jetpack.statusText ); 
    82             a.hide().fadeIn(100); 
    83             jetpack.statusText = null; 
    84         } ).find( 'a' ).click( function() { 
     60        jQuery( '#jp-disconnect a' ).click( function() { 
    8561            if ( confirm( jetpackL10n.ays_disconnect ) ) { 
    86                 jQuery( '#jp-disconnect' ).unbind( 'mouseenter mouseleave' ); 
     62                jQuery( this ).addClass( 'clicked' ).css( { 
     63                    "background-image": 'url( ' + userSettings.url + 'wp-admin/images/wpspin_light.gif )', 
     64                    "background-position": '9px 5px', 
     65                    "background-size": '16px 16px' 
     66                } ).unbind( 'click' ).click( function() { return false; } ); 
     67            } else { 
     68                return false; 
     69            } 
     70        } ); 
     71        jQuery( '#jp-unlink a' ).click( function() { 
     72            if ( confirm( jetpackL10n.ays_unlink ) ) { 
    8773                jQuery( this ).css( { 
    88                     "background-image": 'url( ' + userSettings.url + 'wp-admin/images/wpspin_dark.gif )', 
     74                    "background-image": 'url( ' + userSettings.url + 'wp-admin/images/wpspin_light.gif )', 
    8975                    "background-position": '9px 5px', 
     76                    "background-size": '16px 16px' 
    9077                } ).unbind( 'click' ).click( function() { return false; } ); 
    9178            } else { 
  • jetpack/trunk/jetpack.php

    r589515 r595111  
    2222defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) or define( 'JETPACK__GLOTPRESS_LOCALES_PATH', JETPACK__PLUGIN_DIR . 'locales.php' ); 
    2323 
     24define( 'JETPACK_MASTER_USER', true ); 
     25 
    2426/* 
    2527Options: 
     
    136138        } 
    137139 
     140        // Upgrade from a single user token to a user_id-indexed array and a master_user ID 
     141        if ( !Jetpack::get_option( 'user_tokens' ) ) { 
     142            if ( $user_token = Jetpack::get_option( 'user_token' ) ) { 
     143                $token_parts = explode( '.', $user_token ); 
     144                if ( isset( $token_parts[2] ) ) { 
     145                    $master_user = $token_parts[2]; 
     146                    $user_tokens = array( $master_user => $user_token ); 
     147                    Jetpack::update_options( compact( 'master_user', 'user_tokens' ) ); 
     148                    Jetpack::delete_option( 'user_token' ); 
     149                } else { 
     150                    // @todo: is this even possible? 
     151                    trigger_error( sprintf( 'Jetpack::plugin_upgrade found no user_id in user_token "%s"', $user_token ), E_USER_WARNING ); 
     152                } 
     153            } 
     154        } 
     155 
    138156        // Future: switch on version? If so, think twice before updating version/old_version. 
    139157    } 
     
    198216     */ 
    199217    function is_active() { 
    200         return (bool) Jetpack_Data::get_access_token( 1 ); // 1 just means user token 
     218        return (bool) Jetpack_Data::get_access_token( JETPACK_MASTER_USER ); 
     219    } 
     220 
     221    /** 
     222     * Is the current user linked to a WordPress.com user? 
     223     */ 
     224    function is_user_connected() { 
     225        return (bool) Jetpack_Data::get_access_token( get_current_user_id() ); 
    201226    } 
    202227 
    203228    function current_user_is_connection_owner() { 
    204         $user_token = Jetpack_Data::get_access_token( 1 ); 
     229        $user_token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER ); 
    205230        return $user_token && is_object( $user_token ) && isset( $user_token->external_user_id ) && get_current_user_id() === $user_token->external_user_id; 
    206231    } 
     
    270295            'id',                           // (int)    The Client ID/WP.com Blog ID of this site. 
    271296            'blog_token',                   // (string) The Client Secret/Blog Token of this site. 
    272             'user_token',                   // (string) The User Token of this site. 
     297            'user_token',                   // (string) The User Token of this site. (deprecated) 
     298            'master_user',                  // (int)    The local User ID of the user who connected this site to jetpack.wordpress.com. 
     299            'user_tokens',                  // (array)  User Tokens for each user of this site who has connected to jetpack.wordpress.com. 
    273300            'version',                      // (string) Used during upgrade procedure to auto-activate new modules. version:time 
    274301            'old_version',                  // (string) Used to determine which modules are the most recently added. previous_version:time 
     
    520547 
    521548        return true; 
     549    } 
     550 
     551    /** 
     552     * Enters a user token into the user_tokens option 
     553     * 
     554     * @param int $user_id 
     555     * @param string $token 
     556     * return bool 
     557     */ 
     558    function update_user_token( $user_id, $token, $is_master_user ) { 
     559        // not designed for concurrent updates 
     560        $user_tokens = Jetpack::get_option( 'user_tokens' ); 
     561        if ( ! is_array( $user_tokens ) ) 
     562            $user_tokens = array(); 
     563        $user_tokens[$user_id] = $token; 
     564        if ( $is_master_user ) { 
     565            $master_user = $user_id; 
     566            $options = compact('user_tokens', 'master_user'); 
     567        } else { 
     568            $options = compact('user_tokens'); 
     569        } 
     570        return Jetpack::update_options( $options ); 
    522571    } 
    523572 
     
    10281077            'blog_token', 
    10291078            'user_token', 
     1079            'user_tokens', 
     1080            'master_user', 
    10301081            'time_diff', 
    10311082            'fallback_no_verify_ssl_certs', 
     
    10351086            Jetpack::update_option( 'activated', 4 ); 
    10361087        } 
     1088    } 
     1089 
     1090    /** 
     1091     * Unlinks the current user from the linked WordPress.com user 
     1092     */ 
     1093    function unlink_user() { 
     1094        if ( !$tokens = Jetpack::get_option( 'user_tokens' ) ) 
     1095            return false; 
     1096 
     1097        $user_id = get_current_user_id(); 
     1098 
     1099        if ( Jetpack::get_option( 'master_user' ) == $user_id ) 
     1100            return false; 
     1101 
     1102        if ( !isset( $tokens[$user_id] ) ) 
     1103            return false; 
     1104 
     1105        Jetpack::load_xml_rpc_client(); 
     1106        $xml = new Jetpack_IXR_Client( compact( 'user_id' ) ); 
     1107        $xml->query( 'jetpack.unlink_user', $user_id ); 
     1108 
     1109        unset( $tokens[$user_id] ); 
     1110 
     1111        Jetpack::update_option( 'user_tokens', $tokens ); 
     1112 
     1113        return true; 
    10371114    } 
    10381115 
     
    10661143        } 
    10671144 
    1068         $is_active = Jetpack::is_active(); 
    1069  
    1070         if ( !$is_active ) { 
     1145        if ( Jetpack::is_active() ) { 
    10711146            if ( 4 != Jetpack::get_option( 'activated' ) ) { 
    10721147                // Show connect notice on dashboard and plugins pages 
     
    10911166        add_action( 'wp_ajax_jetpack_debug', array( $this, 'ajax_debug' ) ); 
    10921167 
    1093         if ( $is_active ) { 
     1168        if ( Jetpack::is_active() ) { 
    10941169            // Artificially throw errors in certain whitelisted cases during plugin activation 
    10951170            add_action( 'activate_plugin', array( $this, 'throw_error_on_activate_plugin' ) ); 
     
    13111386    function admin_styles() { 
    13121387        global $wp_styles; 
    1313         wp_enqueue_style( 'jetpack', plugins_url( basename( dirname( __FILE__ ) ) . '/_inc/jetpack.css' ), false, JETPACK__VERSION . '-20120701' ); 
     1388        wp_enqueue_style( 'jetpack', plugins_url( basename( dirname( __FILE__ ) ) . '/_inc/jetpack.css' ), false, JETPACK__VERSION . '-20120805' ); 
    13141389        $wp_styles->add_data( 'jetpack', 'rtl', true ); 
    13151390    } 
    13161391 
    13171392    function admin_scripts() { 
    1318         wp_enqueue_script( 'jetpack-js', plugins_url( basename( dirname( __FILE__ ) ) ) . '/_inc/jetpack.js', array( 'jquery' ), JETPACK__VERSION . '-20111115' ); 
     1393        wp_enqueue_script( 'jetpack-js', plugins_url( basename( dirname( __FILE__ ) ) ) . '/_inc/jetpack.js', array( 'jquery' ), JETPACK__VERSION . '-20120805' ); 
    13191394        wp_localize_script( 'jetpack-js', 'jetpackL10n', array( 
    13201395                'ays_disconnect' => "This will deactivate all Jetpack modules.\nAre you sure you want to disconnect?", 
     1396                'ays_unlink'     => "This will stop sending notifications for this user.\nAre you sure you want to unlink?", 
    13211397                'ays_dismiss'    => "This will deactivate Jetpack.\nAre you sure you want to deactivate Jetpack?", 
    13221398            ) ); 
     
    14371513     * 9 - Jetpack_Client_Server::get_token() 
    14381514     * 10- GET https://jetpack.wordpress.com/jetpack.token/1/ with 
    1439      *     client_id, client_secret, grant_type, code, redirect_uri:action=authorize, state, scope, user_email 
     1515     *     client_id, client_secret, grant_type, code, redirect_uri:action=authorize, state, scope, user_email, user_login 
    14401516     * 11- which responds with 
    14411517     *     access_token, token_type, scope 
     
    14631539            switch ( $_GET['action'] ) { 
    14641540            case 'authorize' : 
    1465                 if ( Jetpack::is_active() ) { 
     1541                if ( Jetpack::is_active() && Jetpack::is_user_connected() ) { 
    14661542                    Jetpack::state( 'message', 'already_authorized' ); 
    14671543                    wp_safe_redirect( Jetpack::admin_url() ); 
     
    15081584                Jetpack::state( 'message', 'module_deactivated' ); 
    15091585                Jetpack::state( 'module', $module ); 
     1586                wp_safe_redirect( Jetpack::admin_url() ); 
     1587                exit; 
     1588            case 'unlink' : 
     1589                check_admin_referer( 'jetpack-unlink' ); 
     1590                $this->unlink_user(); 
     1591                Jetpack::state( 'message', 'unlinked' ); 
    15101592                wp_safe_redirect( Jetpack::admin_url() ); 
    15111593                exit; 
     
    16871769            $this->message .= Jetpack::jetpack_comment_notice(); 
    16881770            break; 
     1771 
     1772        case 'linked' : 
     1773            $this->message  = __( "<strong>You&#8217;re fueled up and ready to go.</strong> ", 'jetpack' ); 
     1774            $this->message .= Jetpack::jetpack_comment_notice(); 
     1775            break; 
     1776 
     1777        case 'unlinked' : 
     1778            $user = wp_get_current_user(); 
     1779            $this->message = sprintf( __( '<strong>You have unlinked your account (%s) from WordPress.com.</strong>', 'jetpack' ), $user->user_login ); 
     1780            break; 
    16891781        } 
    16901782 
     
    18061898        } 
    18071899 
    1808         $token = Jetpack_Data::get_access_token( 0 ); 
     1900        $token = Jetpack_Data::get_access_token(); 
    18091901        if ( !$token || is_wp_error( $token ) ) { 
    18101902            return false; 
     
    18331925                'scope' => $signed_role, 
    18341926                'user_email' => $user->user_email, 
     1927                'user_login' => $user->user_login, 
    18351928            ) ); 
    18361929 
     
    18641957        $role = $this->translate_current_user_to_role(); 
    18651958        $is_connected = Jetpack::is_active(); 
     1959        $user_token = Jetpack_Data::get_access_token($current_user->ID); 
     1960        $is_user_connected = $user_token && !is_wp_error($user_token); 
     1961        $is_master_user = $current_user->ID == Jetpack::get_option( 'master_user' ); 
    18661962        $module = false; 
    18671963    ?> 
     
    18731969                <div id="jp-clouds"> 
    18741970                    <?php if ( $is_connected ) : ?> 
    1875                     <div id="jp-disconnect"> 
    1876                         <a href="<?php echo wp_nonce_url( Jetpack::admin_url( array( 'action' => 'disconnect' ) ), 'jetpack-disconnect' ); ?>"><?php _e( 'Connected to WordPress.com', 'jetpack' ); ?></a> 
    1877                         <span><?php _e( 'Disconnect from WordPress.com', 'jetpack' ) ?></span> 
     1971                    <div id="jp-disconnectors"> 
     1972                    <div id="jp-disconnect" class="jp-disconnect"> 
     1973                        <a href="<?php echo wp_nonce_url( Jetpack::admin_url( array( 'action' => 'disconnect' ) ), 'jetpack-disconnect' ); ?>"><div class="deftext"><?php _e( 'Connected to WordPress.com', 'jetpack' ); ?></div><div class="hovertext"><?php _e( 'Disconnect from WordPress.com', 'jetpack' ) ?></div></a> 
     1974                    </div> 
     1975                        <?php if ( $is_user_connected && !$is_master_user ) : ?> 
     1976                        <div id="jp-unlink" class="jp-disconnect"> 
     1977                            <a href="<?php echo wp_nonce_url( Jetpack::admin_url( array( 'action' => 'unlink' ) ), 'jetpack-unlink' ); ?>"><div class="deftext"><?php _e( 'User linked to WordPress.com', 'jetpack' ); ?></div><div class="hovertext"><?php _e( 'Unlink user from WordPress.com', 'jetpack' ) ?></div></a> 
     1978                        </div> 
     1979                        <?php endif; ?> 
    18781980                    </div> 
    18791981                    <?php endif; ?> 
     
    19142016                </div> 
    19152017 
     2018            <?php elseif ( ! $is_user_connected ) : ?> 
     2019 
     2020                <div id="message" class="updated jetpack-message jp-connect"> 
     2021                    <div class="jetpack-wrap-container"> 
     2022                        <div class="jetpack-text-container"> 
     2023                            <h4> 
     2024                                <p><?php _e( "To enable all of the Jetpack features you&#8217;ll need to link your account here to your WordPress.com account using the button to the right.", 'jetpack' ) ?></p> 
     2025                            </h4> 
     2026                        </div> 
     2027                        <div class="jetpack-install-container"> 
     2028                            <p class="submit"><a href="<?php echo $this->build_connect_url() ?>" class="button-connector" id="wpcom-connect"><?php _e( 'Link accounts with WordPress.com', 'jetpack' ); ?></a></p> 
     2029                        </div> 
     2030                    </div> 
     2031                </div> 
     2032 
     2033            <?php else /* blog and user are connected */ : ?> 
     2034                <?php /* TODO: if not master user, show user disconnect button? */ ?> 
    19162035            <?php endif; ?> 
    19172036 
     
    20012120        <ul> 
    20022121        <?php 
     2122        // Extract the current_user's token 
     2123        $user_id = get_current_user_id(); 
     2124        $user_tokens = Jetpack::get_option( 'user_tokens' ); 
     2125        if ( is_array( $user_tokens ) && array_key_exists( $user_id, $user_tokens ) ) { 
     2126            $user_token = $user_tokens[$user_id]; 
     2127        } else { 
     2128            $user_token = '[this user has no token]'; 
     2129        } 
     2130        unset( $user_tokens ); 
     2131 
    20032132        foreach ( array( 
    20042133            'CLIENT_ID'   => 'id', 
    20052134            'BLOG_TOKEN'  => 'blog_token', 
    2006             'USER_TOKEN'  => 'user_token', 
     2135            'MASTER_USER' => 'master_user', 
    20072136            'CERT'        => 'fallback_no_verify_ssl_certs', 
    20082137            'TIME_DIFF'   => 'time_diff', 
     
    20132142            <li><?php echo esc_html( $label ); ?>: <code><?php echo esc_html( Jetpack::get_option( $option_name ) ); ?></code></li> 
    20142143        <?php endforeach; ?> 
     2144            <li>USER_ID: <code><?php echo esc_html( $user_id ); ?></code></li> 
     2145            <li>USER_TOKEN: <code><?php echo esc_html( $user_token ); ?></code></li> 
    20152146            <li>PHP_VERSION: <code><?php echo esc_html( PHP_VERSION ); ?></code></li> 
    20162147            <li>WORDPRESS_VERSION: <code><?php echo esc_html( $GLOBALS['wp_version'] ); ?></code></li> 
     
    26282759        } 
    26292760 
    2630         $token = Jetpack_Data::get_access_token( $args ); 
     2761        $token = Jetpack_Data::get_access_token( $args['user_id'] ); 
    26312762        if ( !$token ) { 
    26322763            return new Jetpack_Error( 'missing_token' ); 
     
    28222953     * @return object|false 
    28232954     */ 
    2824     function get_access_token( $args ) { 
    2825         if ( is_numeric( $args ) ) { 
    2826             $args = array( 'user_id' => $args ); 
    2827         } 
    2828  
    2829         if ( $args['user_id'] ) { 
    2830             if ( !$token = Jetpack::get_option( 'user_token' ) ) { 
     2955    function get_access_token( $user_id = false ) { 
     2956        if ( $user_id ) { 
     2957            if ( !$tokens = Jetpack::get_option( 'user_tokens' ) ) { 
     2958                return false; 
     2959            } 
     2960            if ( $user_id === JETPACK_MASTER_USER ) { 
     2961                if ( !$user_id = Jetpack::get_option( 'master_user' ) ) { 
     2962                    return false; 
     2963                } 
     2964            } 
     2965            if ( !$token = $tokens[$user_id] ) { 
    28312966                return false; 
    28322967            } 
     
    28352970                return false; 
    28362971            } 
    2837             $args['user_id'] = $token_chunks[2]; 
     2972            if ( $user_id != $token_chunks[2] ) { 
     2973                return false; 
     2974            } 
    28382975            $token = "{$token_chunks[0]}.{$token_chunks[1]}"; 
    28392976        } else { 
     
    28462983        return (object) array( 
    28472984            'secret' => $token, 
    2848             'external_user_id' => (int) $args['user_id'], 
     2985            'external_user_id' => (int) $user_id, 
    28492986        ); 
    28502987    } 
     
    29233060            } 
    29243061 
    2925             Jetpack::update_option( 'user_token', sprintf( '%s.%d', $token, $current_user_id ), true ); 
    2926             Jetpack::state( 'message', 'authorized' ); 
     3062            $is_master_user = ! Jetpack::is_active(); 
     3063 
     3064            Jetpack::update_user_token( $current_user_id, sprintf( '%s.%d', $token, $current_user_id ), $is_master_user ); 
     3065 
     3066 
     3067            if ( $is_master_user ) { 
     3068                Jetpack::state( 'message', 'authorized' ); 
     3069            } else { 
     3070                Jetpack::state( 'message', 'linked' ); 
     3071                // Don't activate anything since we are just connecting a user. 
     3072                break; 
     3073            } 
    29273074 
    29283075            if ( $active_modules = Jetpack::get_option( 'active_modules' ) ) { 
     
    29733120        } 
    29743121 
    2975         $client_secret = Jetpack_Data::get_access_token( 0 ); 
     3122        $client_secret = Jetpack_Data::get_access_token(); 
    29763123        if ( !$client_secret ) { 
    29773124            return new Jetpack_Error( 'client_secret', __( 'You need to register your Jetpack before connecting it.', 'jetpack' ) ); 
Note: See TracChangeset for help on using the changeset viewer.