|
9 | 9 |
|
10 | 10 | namespace OCA\Notifications\Controller; |
11 | 11 |
|
| 12 | +use OCA\Notifications\App; |
| 13 | +use OCA\Notifications\ResponseDefinitions; |
12 | 14 | use OCP\AppFramework\Http; |
13 | 15 | use OCP\AppFramework\Http\Attribute\OpenAPI; |
14 | 16 | use OCP\AppFramework\Http\DataResponse; |
|
18 | 20 | use OCP\IUser; |
19 | 21 | use OCP\IUserManager; |
20 | 22 | use OCP\Notification\IManager; |
| 23 | +use OCP\Notification\IncompleteNotificationException; |
| 24 | +use OCP\Notification\InvalidValueException; |
| 25 | +use OCP\RichObjectStrings\InvalidObjectExeption; |
| 26 | +use OCP\RichObjectStrings\IValidator; |
| 27 | +use Psr\Log\LoggerInterface; |
21 | 28 |
|
| 29 | +/** |
| 30 | + * @psalm-import-type NotificationsRichObjectParameter from ResponseDefinitions |
| 31 | + */ |
22 | 32 | class APIController extends OCSController { |
23 | 33 | public function __construct( |
24 | 34 | string $appName, |
25 | 35 | IRequest $request, |
26 | 36 | protected ITimeFactory $timeFactory, |
27 | 37 | protected IUserManager $userManager, |
28 | 38 | protected IManager $notificationManager, |
| 39 | + protected App $notificationApp, |
| 40 | + protected IValidator $richValidator, |
| 41 | + protected LoggerInterface $logger, |
29 | 42 | ) { |
30 | 43 | parent::__construct($appName, $request); |
31 | 44 | } |
32 | 45 |
|
33 | 46 | /** |
34 | | - * Generate a notification for a user |
| 47 | + * Generate a notification for a user (deprecated, use v3 instead) |
35 | 48 | * |
36 | 49 | * @param string $userId ID of the user |
37 | 50 | * @param string $shortMessage Subject of the notification |
38 | 51 | * @param string $longMessage Message of the notification |
39 | 52 | * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, null, array{}> |
| 53 | + * @deprecated 30.0.0 |
40 | 54 | * |
41 | 55 | * 200: Notification generated successfully |
42 | 56 | * 400: Generating notification is not possible |
43 | 57 | * 404: User not found |
44 | 58 | */ |
45 | 59 | #[OpenAPI(scope: OpenAPI::SCOPE_ADMINISTRATION)] |
46 | 60 | public function generateNotification(string $userId, string $shortMessage, string $longMessage = ''): DataResponse { |
| 61 | + $response = $this->generateNotificationV3($userId, $shortMessage, $longMessage); |
| 62 | + if ($response->getStatus() === Http::STATUS_OK) { |
| 63 | + return new DataResponse(); |
| 64 | + } |
| 65 | + |
| 66 | + // Translate to old status code |
| 67 | + $error = $response->getData()['error'] ?? null; |
| 68 | + $code = match($error) { |
| 69 | + 'user' => Http::STATUS_NOT_FOUND, |
| 70 | + 'subject', |
| 71 | + 'message' => Http::STATUS_BAD_REQUEST, |
| 72 | + default => Http::STATUS_INTERNAL_SERVER_ERROR, |
| 73 | + }; |
| 74 | + return new DataResponse(null, $code); |
| 75 | + } |
| 76 | + |
| 77 | + /** |
| 78 | + * Generate a notification with rich object parameters for a user |
| 79 | + * |
| 80 | + * @param string $userId ID of the user |
| 81 | + * @param string $subject Subject of the notification |
| 82 | + * @param string $message Message of the notification |
| 83 | + * @param array<string, NotificationsRichObjectParameter> $subjectParameters Rich objects to fill the subject placeholders, {@see \OCP\RichObjectStrings\Definitions} |
| 84 | + * @param array<string, NotificationsRichObjectParameter> $messageParameters Rich objects to fill the message placeholders, {@see \OCP\RichObjectStrings\Definitions} |
| 85 | + * @return DataResponse<Http::STATUS_OK, array{id: int}, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: string}, array{}> |
| 86 | + * |
| 87 | + * 200: Notification generated successfully, returned id is the notification ID for future delete requests |
| 88 | + * 400: Provided data was invalid, check error field of the response of log file for details |
| 89 | + */ |
| 90 | + #[OpenAPI(scope: OpenAPI::SCOPE_ADMINISTRATION)] |
| 91 | + public function generateNotificationV3( |
| 92 | + string $userId, |
| 93 | + string $subject = '', |
| 94 | + string $message = '', |
| 95 | + array $subjectParameters = [], |
| 96 | + array $messageParameters = [], |
| 97 | + ): DataResponse { |
47 | 98 | $user = $this->userManager->get($userId); |
48 | 99 |
|
49 | 100 | if (!$user instanceof IUser) { |
50 | | - return new DataResponse(null, Http::STATUS_NOT_FOUND); |
| 101 | + return new DataResponse(['error' => 'user'], Http::STATUS_BAD_REQUEST); |
51 | 102 | } |
52 | 103 |
|
53 | | - if ($shortMessage === '' || strlen($shortMessage) > 255) { |
54 | | - return new DataResponse(null, Http::STATUS_BAD_REQUEST); |
| 104 | + if ($subject === '' || strlen($subject) > 255) { |
| 105 | + return new DataResponse(['error' => 'subject'], Http::STATUS_BAD_REQUEST); |
55 | 106 | } |
56 | 107 |
|
57 | | - if ($longMessage !== '' && strlen($longMessage) > 4000) { |
58 | | - return new DataResponse(null, Http::STATUS_BAD_REQUEST); |
| 108 | + if ($message !== '' && strlen($message) > 4000) { |
| 109 | + return new DataResponse(['error' => 'message'], Http::STATUS_BAD_REQUEST); |
59 | 110 | } |
60 | 111 |
|
61 | 112 | $notification = $this->notificationManager->createNotification(); |
62 | 113 | $datetime = $this->timeFactory->getDateTime(); |
63 | 114 |
|
64 | 115 | try { |
| 116 | + if (!empty($subjectParameters)) { |
| 117 | + $this->richValidator->validate($subject, $subjectParameters); |
| 118 | + } |
| 119 | + if ($message !== '' && !empty($messageParameters)) { |
| 120 | + $this->richValidator->validate($message, $messageParameters); |
| 121 | + } |
65 | 122 | $notification->setApp('admin_notifications') |
66 | 123 | ->setUser($user->getUID()) |
67 | 124 | ->setDateTime($datetime) |
68 | 125 | ->setObject('admin_notifications', dechex($datetime->getTimestamp())) |
69 | | - ->setSubject('ocs', [$shortMessage]); |
| 126 | + ->setSubject( |
| 127 | + 'ocs', |
| 128 | + [ |
| 129 | + 'subject' => $subject, |
| 130 | + 'parameters' => $subjectParameters, |
| 131 | + ] |
| 132 | + ); |
70 | 133 |
|
71 | | - if ($longMessage !== '') { |
72 | | - $notification->setMessage('ocs', [$longMessage]); |
| 134 | + if ($message !== '') { |
| 135 | + $notification->setMessage( |
| 136 | + 'ocs', |
| 137 | + [ |
| 138 | + 'message' => $message, |
| 139 | + 'parameters' => $messageParameters, |
| 140 | + ] |
| 141 | + ); |
73 | 142 | } |
74 | 143 |
|
75 | 144 | $this->notificationManager->notify($notification); |
76 | | - } catch (\InvalidArgumentException) { |
77 | | - return new DataResponse(null, Http::STATUS_INTERNAL_SERVER_ERROR); |
| 145 | + } catch (InvalidObjectExeption $e) { |
| 146 | + $this->logger->error('Invalid rich object parameter provided: ' . $e->getMessage(), ['exception' => $e]); |
| 147 | + return new DataResponse(['error' => 'parameters'], Http::STATUS_BAD_REQUEST); |
| 148 | + } catch (InvalidValueException|IncompleteNotificationException $e) { |
| 149 | + $this->logger->error('Invalid value for notification provided: ' . $e->getMessage(), ['exception' => $e]); |
| 150 | + return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); |
78 | 151 | } |
79 | 152 |
|
80 | | - return new DataResponse(); |
| 153 | + return new DataResponse(['id' => (int) $this->notificationApp->getLastInsertedId()]); |
81 | 154 | } |
82 | 155 | } |
0 commit comments