Skip to content

Commit 9f21561

Browse files
committed
Adjust: make addresses required & avoid enumerations in messages
1 parent 5b66701 commit 9f21561

File tree

11 files changed

+1361
-372
lines changed

11 files changed

+1361
-372
lines changed

doc/api/api-v1-public.json

Lines changed: 71 additions & 46 deletions
Large diffs are not rendered by default.

library/Notifications/Api/OpenApiDescriptionElement/OadV1GetPlural.php

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,9 @@ public function __construct(
2020
?string $description = null,
2121
?string $summary = null,
2222
?array $tags = null,
23-
?array $filter = null,
2423
?array $parameters = null,
2524
?array $responses = null,
2625
) {
27-
$message = 'Invalid request parameter: Filter column x given, ';
28-
if (empty($filter)) {
29-
$message .= 'no filter allowed';
30-
} else {
31-
if (count($filter) == 1) {
32-
$filterStr = $filter[0];
33-
} elseif (count($filter) == 2) {
34-
$filterStr = $filter[0] . ' and ' . $filter[1];
35-
} else {
36-
$last = array_pop($filter);
37-
$filterStr = implode(', ', $filter) . ' and ' . $last;
38-
}
39-
$message .= sprintf('only %s are allowed', $filterStr);
40-
}
41-
4226
parent::__construct(
4327
path: $path,
4428
operationId: 'list' . $entityName,
@@ -58,13 +42,7 @@ public function __construct(
5842
response: 422,
5943
examples: [
6044
new ResponseExample('InvalidRequestBodyId'),
61-
new OA\Examples(
62-
example: 'InvalidFilterParameter',
63-
summary: 'Invalid filter parameter',
64-
value: [
65-
'message' => $message
66-
]
67-
),
45+
new ResponseExample('InvalidFilterParameter'),
6846
]
6947
),
7048
], $responses ?? []),

library/Notifications/Api/OpenApiDescriptionElement/OadV1Post.php

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public function __construct(
2121
?string $path = null,
2222
?string $description = null,
2323
?string $summary = null,
24-
?array $requiredFields = null,
2524
?array $tags = null,
2625
?array $parameters = null,
2726
?array $responses = null,
@@ -115,23 +114,6 @@ public function __construct(
115114
]
116115
);
117116

118-
if (! empty($requiredFields)) {
119-
$missingRequestBodyFieldsMessage = 'Invalid request body: ';
120-
121-
if (count($requiredFields) == 1) {
122-
$requiredFieldsStr = $requiredFields[0];
123-
} elseif (count($requiredFields) == 2) {
124-
$requiredFieldsStr = $requiredFields[0] . ' and ' . $requiredFields[1];
125-
} else {
126-
$last = array_pop($requiredFields);
127-
$requiredFieldsStr = implode(', ', $requiredFields) . ' and ' . $last;
128-
}
129-
$missingRequestBodyFieldsMessage .= sprintf(
130-
'the fields %s must be present and of type string',
131-
$requiredFieldsStr
132-
);
133-
}
134-
135117
parent::__construct(
136118
path: $path,
137119
operationId: ($hasIdentifier ? 'replace' : 'create') . $entityName,
@@ -164,16 +146,9 @@ public function __construct(
164146
summary: $entityName . ' already exists',
165147
value: ['message' => $entityName . ' already exists'],
166148
),
149+
new ResponseExample('InvalidRequestBodyFieldFormat'),
167150
new ResponseExample('InvalidRequestBodyId'),
168-
],
169-
empty($requiredFields)
170-
? []
171-
: [
172-
new OA\Examples(
173-
example: 'MissingRequiredRequestBodyField',
174-
summary: 'Missing required request body field',
175-
value: ['message' => $missingRequestBodyFieldsMessage],
176-
)
151+
new ResponseExample('MissingRequiredRequestBodyField')
177152
],
178153
$examples422 ?? []
179154
)

library/Notifications/Api/OpenApiDescriptionElement/OadV1Put.php

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,13 @@ public function __construct(
2121
?string $path = null,
2222
?string $description = null,
2323
?string $summary = null,
24-
?array $requiredFields = null,
2524
?RequestBody $requestBody = null,
2625
?array $tags = null,
2726
?array $parameters = null,
2827
?array $responses = null,
2928
?array $examples400 = null,
3029
?array $examples422 = null,
3130
) {
32-
$missingRequestBodyFieldsMessage = 'Invalid request body: ';
33-
if (! empty($requiredFields)) {
34-
if (count($requiredFields) == 1) {
35-
$requiredFieldsStr = $requiredFields[0];
36-
} elseif (count($requiredFields) == 2) {
37-
$requiredFieldsStr = $requiredFields[0] . ' and ' . $requiredFields[1];
38-
} else {
39-
$last = array_pop($requiredFields);
40-
$requiredFieldsStr = implode(', ', $requiredFields) . ' and ' . $last;
41-
}
42-
$missingRequestBodyFieldsMessage .= sprintf(
43-
'the fields %s must be present and of type string',
44-
$requiredFieldsStr
45-
);
46-
}
47-
4831
parent::__construct(
4932
path: $path,
5033
operationId: 'update' . $entityName,
@@ -140,17 +123,10 @@ public function __construct(
140123
summary: $entityName . ' already exists',
141124
value: ['message' => $entityName . ' already exists'],
142125
),
126+
new ResponseExample('InvalidRequestBodyFieldFormat'),
143127
new ResponseExample('InvalidRequestBodyId'),
144-
new ResponseExample('IdentifierMismatch')
145-
],
146-
empty($requiredFields)
147-
? []
148-
: [
149-
new OA\Examples(
150-
example: 'MissingRequiredRequestBodyField',
151-
summary: 'Missing required request body field',
152-
value: ['message' => $missingRequestBodyFieldsMessage],
153-
)
128+
new ResponseExample('IdentifierMismatch'),
129+
new ResponseExample('MissingRequiredRequestBodyField')
154130
],
155131
$examples422 ?? []
156132
)

library/Notifications/Api/OpenApiDescriptionElement/Response/Example/ResponseExample.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,21 @@
2727
summary: 'Invalid content type',
2828
value: ['message' => 'Invalid request header: Content-Type must be application/json'],
2929
)]
30+
#[OA\Examples(
31+
example: 'InvalidFilterParameter',
32+
summary: 'Invalid filter parameter',
33+
value: ['message' => 'Invalid request parameter: Filter column x is not allowed']
34+
)]
3035
#[OA\Examples(
3136
example: 'InvalidIdentifier',
3237
summary: 'Identifier is not valid',
3338
value: ['message' => 'The given identifier is not a valid UUID']
3439
)]
40+
#[OA\Examples(
41+
example: 'InvalidRequestBodyFieldFormat',
42+
summary: 'Invalid request body field format',
43+
value: ['message' => 'Invalid request body: expects x to be of type y'],
44+
)]
3545
#[OA\Examples(
3646
example: 'InvalidRequestBodyFormat',
3747
summary: 'Invalid request body format',
@@ -42,6 +52,11 @@
4252
summary: 'Invalid request body id',
4353
value: ['message' => 'Invalid request body: given id is not a valid UUID'],
4454
)]
55+
#[OA\Examples(
56+
example: 'MissingRequiredRequestBodyField',
57+
summary: 'Missing required request body field',
58+
value: ['message' => 'Invalid request body: the field x must be present'],
59+
)]
4560
#[OA\Examples(
4661
example: 'NoIdentifierWithFilter',
4762
summary: 'No identifier with filter',

library/Notifications/Api/V1/Channels.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ public function get(?string $identifier, string $queryFilter): ResponseInterface
237237
description: 'List all notification channels or filter by parameters',
238238
summary: 'List all notification channels or filter by parameters',
239239
tags: ['Channels'],
240-
filter: ['id', 'name', 'type'],
241240
parameters: [
242241
new QueryParameter(
243242
name: 'id',
@@ -291,6 +290,26 @@ public static function getChannelId(string $channelIdentifier): int|false
291290
return $channel->id ?? false;
292291
}
293292

293+
/**
294+
* Get the type of the channel
295+
*
296+
* @param string $channelId
297+
*
298+
* @return string
299+
*/
300+
public static function getChannelType(string $channelId): string
301+
{
302+
/** @var stdClass|false $channel */
303+
$channel = Database::get()->fetchOne(
304+
(new Select())
305+
->from('channel')
306+
->columns('type')
307+
->where(['id = ?' => $channelId])
308+
);
309+
310+
return $channel->type;
311+
}
312+
294313
public function prepareRow(stdClass $row): void
295314
{
296315
$row->config = Json::decode($row->config, true);

library/Notifications/Api/V1/ContactGroups.php

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
)]
5656
class ContactGroups extends ApiV1 implements RequestHandlerInterface, EndpointInterface
5757
{
58+
public const REQUIRED_FIELDS = ['id', 'name'];
59+
public const REQUIRED_FIELD_TYPES = ['id' => 'string', 'name' => 'string'];
60+
5861
#[OA\Examples(
5962
example: 'InvalidUserFormat',
6063
summary: 'Invalid user format',
@@ -173,7 +176,6 @@ public function get(?string $identifier, string $queryFilter): ResponseInterface
173176
description: 'Retrieve all Contact Groups or filter them by parameters.',
174177
summary: 'List all Contact Groups or filter by parameters',
175178
tags: ['Contact Groups'],
176-
filter: ['id', 'name'],
177179
parameters: [
178180
new QueryParameter(
179181
name: 'id',
@@ -220,7 +222,6 @@ private function getPlural(string $queryFilter, Select $stmt): ResponseInterface
220222
description: 'Update a Contact Group by UUID, if it doesn\'t exist, it will be created. \
221223
The identifier must be the same as the payload id',
222224
summary: 'Update a Contact Group by UUID',
223-
requiredFields: ['id', 'name'],
224225
requestBody: new OA\RequestBody(
225226
required: true,
226227
content: new OA\JsonContent(
@@ -299,7 +300,6 @@ public function put(string $identifier, array $requestBody): ResponseInterface
299300
path: '/contact-groups',
300301
description: 'Create a new Contact Group',
301302
summary: 'Create a new Contact Group',
302-
requiredFields: ['id', 'name'],
303303
tags: ['Contact Groups'],
304304
examples422: [
305305
new ResponseExample('InvalidUserFormat'),
@@ -313,7 +313,6 @@ public function put(string $identifier, array $requestBody): ResponseInterface
313313
path: '/contact-groups/{identifier}',
314314
description: 'Replace a Contact Group by UUID, the identifier must be different from the payload id',
315315
summary: 'Replace a Contact Group by UUID',
316-
requiredFields: ['id', 'name'],
317316
tags: ['Contact Groups'],
318317
parameters: [
319318
new PathParameter(
@@ -583,24 +582,23 @@ private function assertValidRequestBody(array $requestBody): void
583582
{
584583
$msgPrefix = 'Invalid request body: ';
585584

586-
if (
587-
! isset($requestBody['id'], $requestBody['name'])
588-
|| ! is_string($requestBody['id'])
589-
|| ! is_string($requestBody['name'])
590-
) {
591-
throw new HttpException(
592-
422,
593-
$msgPrefix . 'the fields id and name must be present and of type string'
594-
);
585+
foreach (self::REQUIRED_FIELD_TYPES as $field => $type) {
586+
if (empty($requestBody[$field])) {
587+
throw new HttpException(422, $msgPrefix . "the field $field must be present");
588+
}
589+
590+
if ($type === 'string' && ! is_string($requestBody[$field])) {
591+
throw new HttpException(422, $msgPrefix . "expects $field to be of type string");
592+
}
595593
}
596594

597595
if (! Uuid::isValid($requestBody['id'])) {
598-
throw new HttpBadRequestException($msgPrefix . 'given id is not a valid UUID');
596+
throw new HttpException(422, $msgPrefix . 'given id is not a valid UUID');
599597
}
600598

601599
if (! empty($requestBody['users'])) {
602600
if (! is_array($requestBody['users'])) {
603-
throw new HttpBadRequestException($msgPrefix . 'expects users to be an array');
601+
throw new HttpException(422, $msgPrefix . 'expects users to be an array');
604602
}
605603

606604
foreach ($requestBody['users'] as $user) {

0 commit comments

Comments
 (0)