Passed
Branch master (6aefea)
by litefeel
08:42
created

Writing_On_GitHub_Request::is_ping()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
/**
3
 * Request management object.
4
 * @package Writing_On_GitHub
5
 */
6
7
/**
8
 * Class Writing_On_GitHub_Request
9
 */
10
class Writing_On_GitHub_Request {
11
12
    /**
13
     * Application container.
14
     *
15
     * @var Writing_On_GitHub
16
     */
17
    protected $app;
18
19
    /**
20
     * Raw request data.
21
     *
22
     * @var string
23
     */
24
    protected $raw_data;
25
26
    /**
27
     * Headers
28
     * @var array
29
     */
30
    protected $headers;
31
32
    /**
33
     * Writing_On_GitHub_Request constructor.
34
     *
35
     * @param Writing_On_GitHub $app Application container.
36
     */
37
    public function __construct( Writing_On_GitHub $app ) {
38
        $this->app = $app;
39
    }
40
41
    /**
42
     * Validates the header's secret.
43
     *
44
     * @return true|WP_Error
45
     */
46
    public function is_secret_valid() {
47
        $headers = $this->headers();
48
49
        $this->raw_data = $this->read_raw_data();
50
51
        // Validate request secret.
52
        $hash = hash_hmac( 'sha1', $this->raw_data, $this->secret() );
53
        if ( 'sha1=' . $hash !== $headers['X-Hub-Signature'] ) {
54
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type WP_Error|true.
Loading history...
55
        }
56
57
        //      [X-Hub-Signature] => sha1=3cf3da70de401f7dfff053392f60cc534efed3b4
58
        //     [Content-Type] => application/json
59
        //     [X-Github-Delivery] => b2102500-0acf-11e7-8acb-fd86a3497c2f
60
        //     [X-Github-Event] => ping
61
62
        return true;
63
    }
64
65
    /**
66
     * Validates the ping event.
67
     * @return boolean
68
     */
69
    public function is_ping() {
70
        return 'ping' == $this->webhook_event();
71
    }
72
73
    /**
74
     * Validates the push event.
75
     * @return boolean
76
     */
77
    public function is_push() {
78
        return 'push' == $this->webhook_event();
79
    }
80
81
    /**
82
     * Return X-Github-Event in headers.
83
     * @return string
84
     */
85
    public function webhook_event() {
86
        $headers = $this->headers();
87
        return $headers['X-Github-Event'];
88
    }
89
90
    /**
91
     * Returns a payload object for the given request.
92
     *
93
     * @return Writing_On_GitHub_Payload
94
     */
95
    public function payload() {
96
        return new Writing_On_GitHub_Payload( $this->app, $this->raw_data );
97
    }
98
99
    /**
100
     * Cross-server header support.
101
     *
102
     * Returns an array of the request's headers.
103
     *
104
     * @return array
105
     */
106
    protected function headers() {
107
        if ( ! empty( $this->headers ) ) {
108
            return $this->headers;
109
        }
110
111
        if ( function_exists( 'getallheaders' ) ) {
112
113
            $this->headers = getallheaders();
0 ignored issues
show
Documentation Bug introduced by
It seems like getallheaders() can also be of type false. However, the property $headers is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
114
            return $this->headers;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->headers could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
115
        }
116
        /**
117
         * Nginx and pre 5.4 workaround.
118
         * @see http://www.php.net/manual/en/function.getallheaders.php
119
         */
120
        $this->headers = array();
121
        foreach ( $_SERVER as $name => $value ) {
122
            if ( 'HTTP_' === substr( $name, 0, 5 ) ) {
123
                $this->headers[ str_replace( ' ', '-', ucwords( strtolower( str_replace( '_', ' ', substr( $name, 5 ) ) ) ) ) ] = $value;
124
            }
125
        }
126
127
        return $this->headers;
128
    }
129
130
    /**
131
     * Reads the raw data from STDIN.
132
     *
133
     * @return string
134
     */
135
    protected function read_raw_data() {
136
        return file_get_contents( 'php://input' );
0 ignored issues
show
introduced by
file_get_contents is highly discouraged, please use wpcom_vip_file_get_contents() instead.
Loading history...
137
    }
138
139
    /**
140
     * Returns the Webhook secret
141
     *
142
     * @return string
143
     */
144
    protected function secret() {
145
        return get_option( 'wogh_secret' );
0 ignored issues
show
Bug Best Practice introduced by
The expression return get_option('wogh_secret') could also return false which is incompatible with the documented return type string. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
146
    }
147
}
148