Skip to content

Commit 3aa2588

Browse files
wip1
1 parent f4206be commit 3aa2588

File tree

2 files changed

+158
-72
lines changed

2 files changed

+158
-72
lines changed

application/controllers/ApiV1ContactgroupsController.php

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Icinga\Exception\Http\HttpBadRequestException;
88
use Icinga\Exception\Http\HttpException;
9+
use Icinga\Exception\Http\HttpNotFoundException;
910
use Icinga\Module\Notifications\Common\Database;
1011
use Icinga\Util\Environment;
1112
use Icinga\Util\Json;
@@ -142,13 +143,13 @@ function (Filter\Condition $condition) {
142143
$db->beginTransaction();
143144

144145
if ($identifier === null) {
145-
$identifier = $data['id'];
146-
147-
if ($this->getContactgroupId($identifier) !== null) {
146+
if ($this->getContactgroupId($data['id']) !== null) {
148147
throw new HttpException('422', 'Contactgroup already exists');
149148
}
150149

151150
$this->addContactgroup($data);
151+
152+
$identifier = $data['id'];
152153
} else {
153154
$contactgroupId = $this->getContactgroupId($identifier);
154155
if ($contactgroupId === null) {
@@ -194,14 +195,7 @@ function (Filter\Condition $condition) {
194195
$db->delete('contactgroup_member', ['contactgroup_id = ?' => $identifier]);
195196

196197
if (! empty($data['users'])) {
197-
$this->assertUsersExist($data['users']);
198-
199-
foreach ($data['users'] as $userId) {
200-
$db->insert('contactgroup_member', [
201-
'contactgroup_id' => $identifier,
202-
'contact_id' => $userId
203-
]);
204-
}
198+
$this->addUsers($contactgroupId, $data['users']);
205199
}
206200

207201
$responseCode = 204;
@@ -267,22 +261,26 @@ private function fetchUserIdentifiers(int $contactgroupId): ?array
267261
/**
268262
* Assert that the given user IDs exist
269263
*
270-
* @param array $userIds
264+
* @param string $identifier
265+
*
266+
* @return int
271267
*
272-
* @throws HttpException if a group does not exist
268+
* @throws HttpNotFoundException if the user with the given identifier does not exist
273269
*/
274-
private function assertUsersExist(array $userIds): void
270+
private function getUserId(string $identifier): int
275271
{
276-
$existingUserIds = Database::get()->fetchCol(
272+
$user = Database::get()->fetchOne(
277273
(new Select())
278274
->from('contact')
279275
->columns('id')
280-
->where(['id IN (?)' => $userIds])
276+
->where(['external_uuid = ?' => $identifier])
281277
);
282278

283-
if (count($existingUserIds) !== count($userIds)) {
284-
throw new HttpException('404', 'Undefined user identifier given');
279+
if ($user === false) {
280+
throw new HttpNotFoundException('Undefined user identifier given');
285281
}
282+
283+
return $user->id;
286284
}
287285

288286
/**
@@ -308,8 +306,6 @@ private function getContactgroupId(string $identifier): ?int
308306
* Add a new contactgroup with the given data
309307
*
310308
* @param array $data
311-
*
312-
* @throws HttpException if a user does not exist
313309
*/
314310
private function addContactgroup(array $data): void
315311
{
@@ -322,13 +318,27 @@ private function addContactgroup(array $data): void
322318
$id = $db->lastInsertId();
323319

324320
if (! empty($data['users'])) {
325-
$this->assertUsersExist($data['users']);
326-
foreach ($data['users'] as $contactId) {
327-
$db->insert('contactgroup_member', [
328-
'contactgroup_id' => $id,
329-
'contact_id' => $contactId
330-
]);
331-
}
321+
$this->addUsers($id, $data['users']);
322+
}
323+
}
324+
325+
/**
326+
* Add the given users as contactgroup_member with the given id
327+
*
328+
* @param int $contactgroupId
329+
* @param array $users
330+
*
331+
* @return void
332+
*/
333+
private function addUsers(int $contactgroupId, array $users): void
334+
{
335+
foreach ($users as $identifier) {
336+
$contactId = $this->getUserId($identifier);
337+
338+
Database::get()->insert('contactgroup_member', [
339+
'contactgroup_id' => $contactgroupId,
340+
'contact_id' => $contactId
341+
]);
332342
}
333343
}
334344

application/controllers/ApiV1ContactsController.php

Lines changed: 121 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Icinga\Exception\Http\HttpBadRequestException;
88
use Icinga\Exception\Http\HttpException;
9+
use Icinga\Exception\Http\HttpNotFoundException;
910
use Icinga\Module\Notifications\Common\Database;
1011
use Icinga\Util\Environment;
1112
use Icinga\Util\Json;
@@ -164,13 +165,12 @@ function (Filter\Condition $condition) {
164165
$db->beginTransaction();
165166

166167
if ($identifier === null) {
167-
$identifier = $data['id'];
168-
169-
if ($this->getContactId($identifier) !== null) {
168+
if ($this->getContactId($data['id']) !== null) {
170169
throw new HttpException('422', 'Contact already exists');
171170
}
172171

173172
$this->addContact($data);
173+
$identifier = $data['id'];
174174
} else {
175175
$contactId = $this->getContactId($identifier);
176176
if ($contactId === null) {
@@ -181,9 +181,10 @@ function (Filter\Condition $condition) {
181181
throw new HttpException('422', 'Contact already exists');
182182
}
183183

184-
$identifier = $data['id'];
185184
$this->removeContact($contactId);
186185
$this->addContact($data);
186+
187+
$identifier = $data['id'];
187188
}
188189

189190
$db->commitTransaction();
@@ -219,24 +220,11 @@ function (Filter\Condition $condition) {
219220
$db->delete('contactgroup_member', ['contact_id = ?' => $contactId]);
220221

221222
if (! empty($data['addresses'])) {
222-
foreach ($data['addresses'] as $type => $address) {
223-
$db->insert('contact_address', [
224-
'contact_id' => $contactId,
225-
'type' => $type,
226-
'address' => $address
227-
]);
228-
}
223+
$this->addAddresses($contactId, $data['addresses']);
229224
}
230225

231226
if (! empty($data['groups'])) {
232-
$this->assertGroupsExist($data['groups']);
233-
234-
foreach ($data['groups'] as $group) {
235-
$db->insert('contactgroup_member', [
236-
'contact_id' => $contactId,
237-
'contactgroup_id' => $group
238-
]);
239-
}
227+
$this->addGroups($contactId, $data['groups']);
240228
}
241229

242230
$responseCode = 204;
@@ -282,7 +270,8 @@ function (Filter\Condition $condition) {
282270
* @param string $channelName
283271
*
284272
* @return int
285-
* @throws HttpException if the channel does not exist
273+
*
274+
* @throws HttpNotFoundException if the channel does not exist
286275
*/
287276
private function getChannelId(string $channelName): int
288277
{
@@ -294,7 +283,7 @@ private function getChannelId(string $channelName): int
294283
);
295284

296285
if ($channel === false) {
297-
throw new HttpException('404', 'Channel not found');
286+
throw new HttpNotFoundException('Channel not found');
298287
}
299288

300289
return $channel->id;
@@ -341,24 +330,28 @@ private function fetchGroupIdentifiers(int $contactId): ?array
341330
}
342331

343332
/**
344-
* Assert that the given group IDs exist
333+
* Get the group id with the given identifier
345334
*
346-
* @param array $groupIds
335+
* @param string $identifier
347336
*
348-
* @throws HttpException 404 if a group does not exist
337+
* @return int
338+
*
339+
* @throws HttpNotFoundException if the contactgroup with the given identifier does not exist
349340
*/
350-
private function assertGroupsExist(array $groupIds): void
341+
private function getGroupId(string $identifier): int
351342
{
352-
$existingGroupIds = Database::get()->fetchCol(
343+
$group = Database::get()->fetchOne(
353344
(new Select())
354345
->from('contactgroup')
355346
->columns('id')
356-
->where(['id IN (?)' => $groupIds])
347+
->where(['external_uuid = ?' => $identifier])
357348
);
358349

359-
if (count($existingGroupIds) !== count($groupIds)) {
360-
throw new HttpException('404', 'Undefined group identifier given');
350+
if ($group === false) {
351+
throw new HttpNotFoundException('Undefined group identifier given');
361352
}
353+
354+
return $group->id;
362355
}
363356

364357
/**
@@ -385,12 +378,16 @@ protected function getContactId(string $identifier): ?int
385378
*
386379
* @param array $data
387380
*
388-
* @throws HttpException if a group or default_channel does not exist
381+
* @return void
389382
*/
390383
private function addContact(array $data): void
391384
{
392385
$db = Database::get();
393386

387+
if (isset($data['username'])) {
388+
$this->assertUniqueUsername($data['username']);
389+
}
390+
394391
$db->insert('contact', [
395392
'full_name' => $data['full_name'],
396393
'username' => $data['username'] ?? null,
@@ -401,31 +398,108 @@ private function addContact(array $data): void
401398
$contactId = $db->lastInsertId();
402399

403400
if (! empty($data['addresses'])) {
404-
foreach ($data['addresses'] as $type => $address) {
405-
$db->insert('contact_address', [
406-
'contact_id' => $contactId,
407-
'type' => $type,
408-
'address' => $address
409-
]);
410-
}
401+
$this->addAddresses($contactId, $data['addresses']);
411402
}
412403

413404
if (! empty($data['groups'])) {
414-
$this->assertGroupsExist($data['groups']);
415-
416-
foreach ($data['groups'] as $groupId) {
417-
$db->insert('contactgroup_member', [
418-
'contact_id' => $contactId,
419-
'contactgroup_id' => $groupId
420-
]);
421-
}
405+
$this->addGroups($contactId, $data['groups']);
406+
}
407+
}
408+
409+
/**
410+
* Assert that the username is unique
411+
*
412+
* @param string $username
413+
*
414+
* @return void
415+
*
416+
* @throws HttpBadRequestException if the username already exists
417+
*/
418+
private function assertUniqueUsername(string $username): void
419+
{
420+
$user = Database::get()->fetchOne(
421+
(new Select())
422+
->from('contact')
423+
->columns(1)
424+
->where(['username = ?' => $username])
425+
);
426+
427+
if ($user !== false) {
428+
$this->httpBadRequest('Username already exists');
429+
}
430+
}
431+
432+
/**
433+
* Assert that the address type exists
434+
*
435+
* @param array $addressTypes
436+
*
437+
* @return void
438+
*
439+
* @throws HttpBadRequestException if the username already exists
440+
*/
441+
private function assertAddressTypesExist(array $addressTypes): void
442+
{
443+
$types = Database::get()->fetchCol(
444+
(new Select())
445+
->from('available_channel_type')
446+
->columns(1)
447+
->where(['type IN (?)' => $addressTypes])
448+
);
449+
450+
if (count($types) !== count($addressTypes)) {
451+
$this->httpBadRequest('An undefined address type given');
452+
}
453+
}
454+
455+
/**
456+
* Add the groups to the given contact
457+
*
458+
* @param int $contactId
459+
* @param array $groups
460+
*
461+
* @return void
462+
*/
463+
private function addGroups(int $contactId, array $groups): void
464+
{
465+
foreach ($groups as $groupIdentifier) {
466+
$groupId = $this->getGroupId($groupIdentifier);
467+
468+
Database::get()->insert('contactgroup_member', [
469+
'contact_id' => $contactId,
470+
'contactgroup_id' => $groupId
471+
]);
472+
}
473+
}
474+
475+
/**
476+
* Add the addresses to the given contact
477+
*
478+
* @param int $contactId
479+
* @param array $addresses
480+
*
481+
* @return void
482+
*/
483+
private function addAddresses(int $contactId, array $addresses): void
484+
{
485+
$this->assertAddressTypesExist(array_keys($addresses));
486+
487+
foreach ($addresses as $type => $address) {
488+
//TODO: Check if type exists, db allows any type
489+
Database::get()->insert('contact_address', [
490+
'contact_id' => $contactId,
491+
'type' => $type,
492+
'address' => $address
493+
]);
422494
}
423495
}
424496

425497
/**
426498
* Remove the contact with the given id
427499
*
428500
* @param int $id
501+
*
502+
* @return void
429503
*/
430504
private function removeContact(int $id): void
431505
{
@@ -441,6 +515,8 @@ private function removeContact(int $id): void
441515
*
442516
* @param array $data
443517
*
518+
* @return void
519+
*
444520
* @throws HttpBadRequestException
445521
*/
446522
private function assertValidData(array $data): void

0 commit comments

Comments
 (0)