WordPress.org

Making WordPress.org

Changeset 3983


Ignore:
Timestamp:
09/07/2016 06:02:21 AM (23 months ago)
Author:
dd32
Message:

GitHub Sync: Add support for the application/x-www-form-urlencoded webhook format and add documentation.

Location:
sites/trunk/api.wordpress.org/public_html/dotorg/github-sync
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/api.wordpress.org/public_html/dotorg/github-sync/feature-plugins.php

    r2698 r3983  
    11<?php
    22/**
    3  * A easy webhook to allow feature plugins to be sync'd to WordPress.org plugins SVN easier.
     3 * This webhook is very basic, but handles syncing a select few featured plugins over to plugins.svn.wordpress.org during development.
     4 *
     5 * To have your *feature project* handled by this sync script:
     6 * - Ensure you're listed on https://make.wordpress.org/core/features-as-plugins/ if you're not, ping in #meta
     7 * - Ping in #meta to get your project added to the whitelist within this file
     8 * - Add `https://api.wordpress.org/dotorg/github-sync/feature-plugins.php` as a `push` webhook on github with the secret we'll provide you.
     9 * - Push to github master and watch https://plugins.trac.wordpress.org/log/$plugin_slug/
     10 * - Profit from all the Open Source points you're getting!
    411 */
    512
     
    815class GH2WORG {
    916
    10     private $whitelisted_repos = array(
    11         // Github User/Repo => plugins.svn.wordpress.org/****/trunk/
    12         'dd32/feature-plugin-testing' => 'test-plugin-3',
    13         'voldemortensen/menu-customizer' => 'menu-customizer',
    14         'georgestephanis/two-factor' => 'two-factor',
     17    private $whitelisted_repos = [
     18        // Github.com/{$user/repo-name} => plugins.svn.wordpress.org/{$slug}/trunk/
     19        'dd32/feature-plugin-testing'           => 'test-plugin-3',
     20        'georgestephanis/two-factor'            => 'two-factor',
    1521        'georgestephanis/application-passwords' => 'application-passwords',
    16         'obenland/shiny-updates' => 'shiny-updates',
    17         'pento/react' => 'react',
    18     );
     22        'obenland/shiny-updates'                => 'shiny-updates',
     23        'pento/react'                           => 'react',
     24    ];
    1925
    2026    function __construct() {
    21         $this->populate_post_vars();
    22 
    23         if ( ! $this->verify_github_signature() ) {
    24             die( 'Cheating, huh?' );
    25         }
    26 
    27         $repo_name = $_POST['repository']['full_name'];
    28         $repo_url  = $_POST['repository']['git_url'];
    29 
    30         if ( ! $this->verify_valid_plugin( $repo_name ) ) {
    31             die( 'Sorry, This Github repo is not configured for WordPress.org Plugins SVN Github Sync. Please contact us.' );
    32         }
     27        $repo_name = $this->get_notified_repo();
    3328
    3429        $svn_directory = $this->whitelisted_repos[ $repo_name ];
    3530
    36         $this->process_github_to_svn( $repo_url, $svn_directory );
     31        if ( ! $repo_name || ! $svn_directory ) {
     32            die( 'Sorry, This Github repo is not configured for WordPress.org Plugins SVN Github Sync. Please ping in #meta on Slack for assistance.' );
     33        }
     34
     35        $this->process_github_to_svn( $repo_name, $svn_directory );
    3736    }
    3837
    39     function populate_post_vars() {
    40         if ( 'application/json' == $_SERVER['HTTP_CONTENT_TYPE'] ) {
    41             $_POST = @json_decode( file_get_contents('php://input'), true );
    42         } else {
    43             // Assuming Magic Quotes disabled like a good host.
    44             $_POST = @json_decode( $_POST['payload'], true );
     38    /**
     39     * Determines the Github Repo (user/repo) which Github is notifying us about.
     40     *
     41     * - Extracts the repo from both `application/json` and `application/x-www-form-urlencoded` webhook variants.
     42     * - Verifies the signature of the request
     43     *
     44     * @return string|bool Github repo on success, false on failure.
     45     */
     46    function get_notified_repo() {
     47        $github_payload = file_get_contents( 'php://input' );
     48        $signature_of_payload = 'sha1=' . hash_hmac( 'sha1', $github_payload, FEATURE_PLUGIN_GH_SYNC_SECRET );
     49
     50        if ( ! hash_equals( $signature_of_payload, $_SERVER['HTTP_X_HUB_SIGNATURE'] ) ) {
     51            return false;
    4552        }
     53
     54        /*
     55         * Extract the payload from the `php://input` stream, although this is also present in
     56         * $_POST, the Github signature is of this raw data, so we'll use that data.
     57         */
     58        if ( 'application/x-www-form-urlencoded' === $_SERVER['HTTP_CONTENT_TYPE'] ) {
     59            parse_str( $github_payload, $github_payload );
     60            $github_payload = $github_payload['payload'];
     61        }
     62
     63        return json_decode( $github_payload, true )['repository']['full_name'];
    4664    }
    4765
    48     function verify_github_signature() {
    49         if ( empty( $_SERVER['HTTP_X_HUB_SIGNATURE'] ) )
    50             return false;
     66    /**
     67     * Triggers the shell script to migrate the Git commit to plugins.svn
     68     *
     69     * @param string $github_repo   The Github Repo which was modified (user/repo).
     70     * @param string $svn_directory The plugins.svn directory/plugin (plugin-slug).
     71     */
     72    function process_github_to_svn( $github_repo, $svn_directory ) {
    5173
    52         list( $algo, $hash ) = explode( '=', $_SERVER['HTTP_X_HUB_SIGNATURE'], 2 );
    53 
    54         // Todo? Doesn't handle standard $_POST, only application/json
    55         $hmac = hash_hmac( $algo, file_get_contents('php://input' ), FEATURE_PLUGIN_GH_SYNC_SECRET );
    56 
    57         return $hash === $hmac;
    58     }
    59 
    60     function verify_valid_plugin( $repo ) {
    61         return isset( $this->whitelisted_repos[ $repo ] );
    62     }
    63 
    64     function process_github_to_svn( $github_url, $svn_directory ) {
    65 
    66         putenv( 'PHP_SVN_USER=' . FEATURE_PLUGIN_GH_SYNC_USER );
     74        putenv( 'PHP_SVN_USER='     . FEATURE_PLUGIN_GH_SYNC_USER );
    6775        putenv( 'PHP_SVN_PASSWORD=' . FEATURE_PLUGIN_GH_SYNC_PASS );
    6876
    69         echo shell_exec( __DIR__ . "/feature-plugins.sh $github_url $svn_directory 2>&1" );
     77        $github_repo   = escapeshellarg( $github_repo );
     78        $svn_directory = escapeshellarg( $svn_directory );
     79
     80        echo shell_exec( __DIR__ . "/feature-plugins.sh $github_repo $svn_directory 2>&1" );
    7081
    7182        putenv( 'PHP_SVN_USER' );
  • sites/trunk/api.wordpress.org/public_html/dotorg/github-sync/feature-plugins.sh

    r2295 r3983  
    11#!/bin/bash
    22
    3 GITHUB_URL=$1;
     3GITHUB_REPO=$1;
    44SVN_PLUGIN=$2;
    55
     
    1616
    1717# Validate all Parameters are present
    18 if [ ! $GITHUB_URL ] || [ ! $SVN_PLUGIN ] || [ ! $PHP_SVN_USER ] || [ ! $PHP_SVN_PASSWORD ]; then
     18if [ ! $GITHUB_REPO ] || [ ! $SVN_PLUGIN ] || [ ! $PHP_SVN_USER ] || [ ! $PHP_SVN_PASSWORD ]; then
    1919    echo "Invalid Input, missing parameter"; exit 1
    2020fi
    2121
     22GITHUB_URL="git://github.com/$GITHUB_REPO.git"
    2223SVN_URL="https://plugins.svn.wordpress.org/$SVN_PLUGIN/trunk/"
    2324ASSETS_SVN_URL="https://plugins.svn.wordpress.org/$SVN_PLUGIN/assets/"
Note: See TracChangeset for help on using the changeset viewer.