This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * This source file is proprietary and part of Rebilly. |
||
4 | * |
||
5 | * (c) Rebilly SRL |
||
6 | * Rebilly Ltd. |
||
7 | * Rebilly Inc. |
||
8 | * |
||
9 | * @see https://www.rebilly.com |
||
10 | */ |
||
11 | |||
12 | namespace Rebilly\OpenAPI\PhpUnit; |
||
13 | |||
14 | use PHPUnit\Framework\Assert; |
||
15 | use Psr\Http\Message\RequestInterface; |
||
16 | use Psr\Http\Message\ResponseInterface; |
||
17 | use Psr\Http\Message\StreamInterface; |
||
18 | use Psr\Http\Message\UriInterface; |
||
19 | use Rebilly\OpenAPI\Schema; |
||
20 | use stdClass; |
||
21 | |||
22 | /** |
||
23 | * Asserts data against OpenAPI specification. |
||
24 | */ |
||
25 | trait Asserts |
||
26 | { |
||
27 | /** |
||
28 | * Assert request matches against declared specification. |
||
29 | * |
||
30 | * The list of constraints: |
||
31 | * |
||
32 | * - Assert request method defined |
||
33 | * - Assert request URI declared by host, basePath, schemes and parameters (path, query) |
||
34 | * - Assert content-type declared by consumes |
||
35 | * - Assert headers declared by parameters (header) |
||
36 | * - Assert body declared by parameters (body) |
||
37 | */ |
||
38 | 4 | final protected static function assertRequest(Schema $schema, string $path, RequestInterface $request, string $msg = ''): void |
|
39 | { |
||
40 | 4 | self::assertMethodAllowed($schema, $path, $request->getMethod(), $msg); |
|
41 | 3 | self::assertUri($schema, $path, $request->getMethod(), $request->getUri(), $msg); |
|
42 | 3 | self::assertRequestHeaders($schema, $path, $request->getMethod(), $request->getHeaders(), $msg); |
|
43 | 2 | self::assertRequestBody($schema, $path, $request->getMethod(), $request->getBody(), $msg); |
|
44 | } |
||
45 | |||
46 | /** |
||
47 | * Assert response matches against declared specification. |
||
48 | * |
||
49 | * The list of constraints: |
||
50 | * |
||
51 | * - Assert response status code or default is defined |
||
52 | * - Assert content-type declared by produces from operation |
||
53 | * - Assert headers |
||
54 | * - Assert body |
||
55 | */ |
||
56 | 3 | final protected static function assertResponse(Schema $schema, string $path, string $method, ResponseInterface $response, string $msg = ''): void |
|
57 | { |
||
58 | 3 | self::assertResponseDefined($schema, $path, $method, $response->getStatusCode(), $msg); |
|
59 | 3 | self::assertResponseHeaders( |
|
60 | 3 | $schema, |
|
61 | 3 | $path, |
|
62 | 3 | $method, |
|
63 | 3 | $response->getStatusCode(), |
|
64 | 3 | $response->getHeaders(), |
|
65 | 3 | $msg |
|
66 | ); |
||
67 | 3 | self::assertResponseBody( |
|
68 | 3 | $schema, |
|
69 | 3 | $path, |
|
70 | 3 | $method, |
|
71 | 3 | $response->getStatusCode(), |
|
72 | 3 | $response->getBody(), |
|
73 | 3 | $msg |
|
74 | ); |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * Assert URI matches against declared host, basePath, schemes and parameters (path, query). |
||
79 | * |
||
80 | * The list of constraints: |
||
81 | * |
||
82 | * - Assert URI scheme matches allowed schemes |
||
83 | * - Assert URI host matches defined |
||
84 | * - Assert URI path starts with defined base path |
||
85 | * - Assert URI path matches defined template and path parameters |
||
86 | * - Assert URI path matches defined query parameters |
||
87 | */ |
||
88 | 3 | final protected static function assertUri(Schema $schema, string $path, string $method, UriInterface $uri, string $msg = ''): void |
|
89 | { |
||
90 | 3 | Assert::assertThat( |
|
91 | 3 | $uri, |
|
92 | 3 | new UriConstraint( |
|
93 | 3 | $schema->getServers(), |
|
94 | 3 | $path, |
|
95 | 3 | $schema->getRequestPathParameters($path, $method), |
|
96 | 3 | $schema->getRequestQueryParameters($path, $method) |
|
97 | ), |
||
98 | 3 | $msg |
|
99 | ); |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Assert the endpoint supports given operation. |
||
104 | */ |
||
105 | 4 | final protected static function assertMethodAllowed(Schema $schema, string $path, string $method, string $msg = ''): void |
|
106 | { |
||
107 | 4 | Assert::assertThat( |
|
108 | 4 | $method, |
|
109 | 4 | new MethodsAllowedConstraint($schema->getAllowedMethods($path)), |
|
110 | 4 | $msg |
|
111 | ); |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * Assert the response status code defined. |
||
116 | */ |
||
117 | 3 | final protected static function assertResponseDefined(Schema $schema, string $template, string $method, string $status, string $msg = ''): void |
|
118 | { |
||
119 | 3 | Assert::assertTrue( |
|
120 | 3 | $schema->isResponseDefined($template, mb_strtolower($method), $status), |
|
121 | 3 | $msg ?: "Operation \"{$method} {$template}\" does not support response code \"{$status}\"" |
|
122 | ); |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Assert the endpoint supports given operation. |
||
127 | */ |
||
128 | 2 | final protected static function assertRequestContentType(Schema $schema, string $path, string $method, string $contentType, string $msg = ''): void |
|
129 | { |
||
130 | 2 | Assert::assertThat( |
|
131 | 2 | $contentType, |
|
132 | 2 | new ContentTypeConstraint($schema->getRequestContentTypes($path, $method)), |
|
133 | 2 | $msg |
|
134 | ); |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * Assert the endpoint supports given operation. |
||
139 | */ |
||
140 | 2 | final protected static function assertResponseContentType(Schema $schema, string $path, string $method, string $status, string $contentType, string $msg = ''): void |
|
141 | { |
||
142 | 2 | Assert::assertThat( |
|
143 | 2 | $contentType, |
|
144 | 2 | new ContentTypeConstraint($schema->getResponseContentTypes($path, $method, $status)), |
|
145 | 2 | $msg |
|
146 | ); |
||
147 | } |
||
148 | |||
149 | 3 | final protected static function assertRequestHeaders(Schema $schema, string $path, string $method, array $headers, string $msg = ''): void |
|
150 | { |
||
151 | 3 | Assert::assertThat( |
|
152 | 3 | $headers, |
|
153 | 3 | new HeadersConstraint($schema->getRequestHeaderSchemas($path, mb_strtolower($method))), |
|
154 | 3 | $msg |
|
155 | ); |
||
156 | |||
157 | 3 | if ($schema->isRequestBodyDefined($path, $method) && isset($headers['Content-Type'][0])) { |
|
158 | 2 | self::assertRequestContentType( |
|
159 | 2 | $schema, |
|
160 | 2 | $path, |
|
161 | 2 | mb_strtolower($method), |
|
162 | 2 | $headers['Content-Type'][0], |
|
163 | 2 | $msg |
|
164 | ); |
||
165 | } |
||
166 | } |
||
167 | |||
168 | 3 | final protected static function assertResponseHeaders(Schema $schema, string $path, string $method, string $status, array $headers, string $msg = ''): void |
|
169 | { |
||
170 | 3 | Assert::assertThat( |
|
171 | 3 | $headers, |
|
172 | 3 | new HeadersConstraint( |
|
173 | 3 | $schema->getResponseHeaderSchemas($path, mb_strtolower($method), $status) |
|
174 | ), |
||
175 | 3 | $msg |
|
176 | ); |
||
177 | |||
178 | 3 | if ($schema->isResponseBodyDefined($path, $method, $status) && isset($headers['Content-Type'][0])) { |
|
179 | 2 | self::assertResponseContentType( |
|
180 | 2 | $schema, |
|
181 | 2 | $path, |
|
182 | 2 | $method, |
|
183 | 2 | $status, |
|
184 | 2 | $headers['Content-Type'][0], |
|
185 | 2 | $msg |
|
186 | ); |
||
187 | } |
||
188 | |||
189 | 3 | if (isset($headers['Allow'])) { |
|
190 | 1 | if (isset($headers['Allow'][0]) && mb_strpos($headers['Allow'][0], ',') !== false) { |
|
191 | 1 | $headers['Allow'] = preg_split('#\s*,\s*#', $headers['Allow'][0], -1, PREG_SPLIT_NO_EMPTY); |
|
192 | } |
||
193 | |||
194 | 1 | Assert::assertThat( |
|
195 | 1 | $headers['Allow'], |
|
196 | 1 | new MethodsAllowedConstraint($schema->getAllowedMethods($path)), |
|
197 | 1 | $msg |
|
198 | ); |
||
199 | } |
||
200 | } |
||
201 | |||
202 | 2 | View Code Duplication | final protected static function assertRequestBody(Schema $schema, string $path, string $method, StreamInterface $body = null, string $msg = ''): void |
0 ignored issues
–
show
|
|||
203 | { |
||
204 | 2 | $bodySchema = $schema->getRequestBodySchema($path, mb_strtolower($method)); |
|
205 | |||
206 | 2 | if ($bodySchema) { |
|
207 | 1 | Assert::assertThat( |
|
208 | 1 | json_decode($body), |
|
209 | 1 | new JsonSchemaConstraint($bodySchema, 'request body'), |
|
210 | 1 | $msg |
|
211 | ); |
||
212 | } else { |
||
213 | 1 | Assert::assertEmpty(json_decode($body), $msg); |
|
214 | } |
||
215 | } |
||
216 | |||
217 | 3 | View Code Duplication | final protected static function assertResponseBody(Schema $schema, string $path, string $method, string $status, StreamInterface $body = null, string $msg = ''): void |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
218 | { |
||
219 | 3 | $bodySchema = $schema->getResponseBodySchema($path, mb_strtolower($method), $status); |
|
220 | |||
221 | 3 | if ($bodySchema) { |
|
222 | 2 | Assert::assertThat( |
|
223 | 2 | json_decode($body), |
|
224 | 2 | new JsonSchemaConstraint($bodySchema, 'response body'), |
|
225 | 2 | $msg |
|
226 | ); |
||
227 | } else { |
||
228 | 1 | Assert::assertEmpty(json_decode($body), $msg); |
|
229 | } |
||
230 | } |
||
231 | |||
232 | 1 | final protected static function assertDefinitionSchema(Schema $schema, string $class, stdClass $actual, string $msg = ''): void |
|
233 | { |
||
234 | 1 | Assert::assertThat( |
|
235 | 1 | $actual, |
|
236 | 1 | new JsonSchemaConstraint($schema->getDefinition($class)), |
|
237 | 1 | $msg |
|
238 | ); |
||
239 | } |
||
240 | } |
||
241 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.