WordPress.org

Making WordPress.org

Changeset 9564


Ignore:
Timestamp:
03/04/2020 05:10:57 AM (21 months ago)
Author:
dd32
Message:

Trac: Github PRs: Switch to using a Github App Token for authentication with Github.

This significantly increases the number of API requests that can be made per hour, and enables access to several additional API endpoints.

This uses the MIT licensed https://github.com/adhocore/php-jwt to generate the JWTs as required by the Github App API.

See #4903, #5052.

Location:
sites/trunk/api.wordpress.org/public_html/dotorg/trac/pr
Files:
4 added
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/api.wordpress.org/public_html/dotorg/trac/pr/functions.php

    r9539 r9564  
    7272            [
    7373                'Accept: application/json',
    74                 'Authorization: ' . get_authorization_token(),
     74                'Authorization: ' . get_authorization_token( $url ),
    7575            ],
    7676            $headers
     
    8989 * Fetch an Authorization token for a Github API request.
    9090 */
    91 function get_authorization_token() {
    92     global $wpdb;
    93 
    94     // TODO: This needs to be switched to a Github App token.
    95     // This works temporarily to avoid the low unauthenticated limits.
    96     return 'BEARER ' . $wpdb->get_var( "SELECT access_token FROM wporg_github_users WHERE github_user = 'dd32'");
     91function get_authorization_token( $url ) {
     92    // There are two different tokens used, JWT and App Installation tokens.
     93    if ( false !== stripos( $url, 'api.github.com/app' ) ) {
     94        // App Endpoint, that's a JWT token
     95        return 'BEARER ' . get_jwt_app_token();
     96    } else {
     97        // Regular Endpoint, use an App Installation token
     98        return 'BEARER ' . get_app_install_token();
     99    }
     100}
     101
     102/**
     103 * Fetch a JWT Authorization token for the Github /app API endpoints.
     104 */
     105function get_jwt_app_token() {
     106    $token = wp_cache_get( GH_TRAC_APP_ID, 'API:JWT-token' );
     107    if ( $token ) {
     108        return $token;
     109    }
     110
     111    include_once __DIR__ . '/adhocore-php-jwt/ValidatesJWT.php';
     112    include_once __DIR__ . '/adhocore-php-jwt/JWTException.php';
     113    include_once __DIR__ . '/adhocore-php-jwt/JWT.php';
     114
     115    $key = openssl_pkey_get_private( base64_decode( GH_TRAC_APP_PRIV_KEY ) );
     116    $jwt = new \Ahc\Jwt\JWT( $key, 'RS256' );
     117
     118    $token = $jwt->encode([
     119        'iat' => time(),
     120        'exp' => time() + 10*60,
     121        'iss' => GH_TRAC_APP_ID,
     122    ]);
     123
     124    // Cache it for 9 mins (It's valid for 10min)
     125    wp_cache_set( GH_TRAC_APP_ID, $token, 'API:JWT-token', 9 * 60 );
     126
     127    return $token;
     128}
     129
     130/**
     131 * Fetch an App Authorization token for accessing Github Resources.
     132 *
     133 * This assumes that the Github App will only ever be installed on the @WordPress organization.
     134 */
     135function get_app_install_token() {
     136    $token = wp_cache_get( GH_TRAC_APP_ID . '-install-token', 'API:JWT-token' );
     137    if ( $token ) {
     138        return $token;
     139    }
     140
     141    $installs = api_request(
     142        '/app/installations',
     143        null,
     144        [ 'Accept: application/vnd.github.machine-man-preview+json' ]
     145    );
     146    if ( ! $installs || empty( $installs[0]->access_tokens_url ) ) {
     147        return false;
     148    }
     149
     150    $access_token = api_request(
     151        $installs[0]->access_tokens_url,
     152        null,
     153        [ 'Accept: application/vnd.github.machine-man-preview+json' ],
     154        'POST'
     155    );
     156    if ( ! $access_token || empty( $access_token->token ) ) {
     157        return false;
     158    }
     159
     160    $token     = $access_token->token;
     161    $token_exp = strtotime( $access_token->expires_at );
     162
     163    // Cache the token for 1 minute less than what it's valid for.
     164    wp_cache_set( GH_TRAC_APP_ID . '-install-token', $token, 'API:JWT-token', $token_exp - time() - 60 );
     165
     166    return $token;
    97167}
    98168
  • sites/trunk/api.wordpress.org/public_html/dotorg/trac/pr/webhook.php

    r9539 r9564  
    44require dirname( dirname( dirname( __DIR__ ) ) ) . '/init.php';
    55require dirname( dirname( dirname( __DIR__ ) ) ) . '/includes/hyperdb/bb-10-hyper-db.php';
     6require dirname( dirname( dirname( __DIR__ ) ) ) . '/includes/object-cache.php';
     7\wp_cache_init();
    68
    79require __DIR__ . '/functions.php';
Note: See TracChangeset for help on using the changeset viewer.