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
![]() |
|||
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 | $this->headers = array(); |
||
112 | if ( function_exists( 'getallheaders' ) ) { |
||
113 | $headers = getallheaders(); |
||
114 | // github webhook |
||
115 | // content-type: application/json |
||
116 | // Expect: |
||
117 | // User-Agent: GitHub-Hookshot/7a71d82 |
||
118 | // X-GitHub-Delivery: a331b200-2537-11e8-9d7e-ce0853020b44 |
||
119 | // X-GitHub-Event: push |
||
120 | // X-Hub-Signature: sha1=98185ffa2c4684c9a1324c57086709acca9dddc7 |
||
121 | foreach ( $headers as $name => $value ) { |
||
122 | $this->headers[ str_replace( ' ', '-', ucwords( strtolower( str_replace( '-', ' ', $name ) ) ) ) ] = $value; |
||
123 | } |
||
124 | } else { |
||
125 | /** |
||
126 | * Nginx and pre 5.4 workaround. |
||
127 | * @see http://www.php.net/manual/en/function.getallheaders.php |
||
128 | */ |
||
129 | foreach ( $_SERVER as $name => $value ) { |
||
130 | if ( 'HTTP_' === substr( $name, 0, 5 ) ) { |
||
131 | $this->headers[ str_replace( ' ', '-', ucwords( strtolower( str_replace( '_', ' ', substr( $name, 5 ) ) ) ) ) ] = $value; |
||
132 | } |
||
133 | } |
||
134 | } |
||
135 | |||
136 | return $this->headers; |
||
137 | } |
||
138 | |||
139 | /** |
||
140 | * Reads the raw data from STDIN. |
||
141 | * |
||
142 | * @return string |
||
143 | */ |
||
144 | protected function read_raw_data() { |
||
145 | return file_get_contents( 'php://input' ); |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * Returns the Webhook secret |
||
150 | * |
||
151 | * @return string |
||
152 | */ |
||
153 | protected function secret() { |
||
154 | return get_option( 'wogh_secret' ); |
||
0 ignored issues
–
show
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. ![]() |
|||
155 | } |
||
156 | } |
||
157 |