1
0

UserStatusController.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2020, Georg Ehrke
  5. *
  6. * @author Georg Ehrke <oc.list@georgehrke.com>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author Simon Spannagel <simonspa@kth.se>
  9. * @author Kate Döen <kate.doeen@nextcloud.com>
  10. *
  11. * @license GNU AGPL version 3 or any later version
  12. *
  13. * This program is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License as
  15. * published by the Free Software Foundation, either version 3 of the
  16. * License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. *
  26. */
  27. namespace OCA\UserStatus\Controller;
  28. use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
  29. use OCA\UserStatus\Db\UserStatus;
  30. use OCA\UserStatus\Exception\InvalidClearAtException;
  31. use OCA\UserStatus\Exception\InvalidMessageIdException;
  32. use OCA\UserStatus\Exception\InvalidStatusIconException;
  33. use OCA\UserStatus\Exception\InvalidStatusTypeException;
  34. use OCA\UserStatus\Exception\StatusMessageTooLongException;
  35. use OCA\UserStatus\ResponseDefinitions;
  36. use OCA\UserStatus\Service\StatusService;
  37. use OCP\AppFramework\Db\DoesNotExistException;
  38. use OCP\AppFramework\Http;
  39. use OCP\AppFramework\Http\DataResponse;
  40. use OCP\AppFramework\OCS\OCSBadRequestException;
  41. use OCP\AppFramework\OCS\OCSNotFoundException;
  42. use OCP\AppFramework\OCSController;
  43. use OCP\IRequest;
  44. use Psr\Log\LoggerInterface;
  45. /**
  46. * @psalm-import-type UserStatusType from ResponseDefinitions
  47. * @psalm-import-type UserStatusPrivate from ResponseDefinitions
  48. */
  49. class UserStatusController extends OCSController {
  50. public function __construct(
  51. string $appName,
  52. IRequest $request,
  53. private string $userId,
  54. private LoggerInterface $logger,
  55. private StatusService $service,
  56. private CalendarStatusService $calendarStatusService,
  57. ) {
  58. parent::__construct($appName, $request);
  59. }
  60. /**
  61. * Get the status of the current user
  62. *
  63. * @NoAdminRequired
  64. *
  65. * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>
  66. * @throws OCSNotFoundException The user was not found
  67. *
  68. * 200: The status was found successfully
  69. */
  70. public function getStatus(): DataResponse {
  71. try {
  72. $this->calendarStatusService->processCalendarStatus($this->userId);
  73. $userStatus = $this->service->findByUserId($this->userId);
  74. } catch (DoesNotExistException $ex) {
  75. throw new OCSNotFoundException('No status for the current user');
  76. }
  77. return new DataResponse($this->formatStatus($userStatus));
  78. }
  79. /**
  80. * Update the status type of the current user
  81. *
  82. * @NoAdminRequired
  83. *
  84. * @param string $statusType The new status type
  85. * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>
  86. * @throws OCSBadRequestException The status type is invalid
  87. *
  88. * 200: The status was updated successfully
  89. */
  90. public function setStatus(string $statusType): DataResponse {
  91. try {
  92. $status = $this->service->setStatus($this->userId, $statusType, null, true);
  93. $this->service->removeBackupUserStatus($this->userId);
  94. return new DataResponse($this->formatStatus($status));
  95. } catch (InvalidStatusTypeException $ex) {
  96. $this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to an invalid status type "' . $statusType . '"');
  97. throw new OCSBadRequestException($ex->getMessage(), $ex);
  98. }
  99. }
  100. /**
  101. * Set the message to a predefined message for the current user
  102. *
  103. * @NoAdminRequired
  104. *
  105. * @param string $messageId ID of the predefined message
  106. * @param int|null $clearAt When the message should be cleared
  107. * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>
  108. * @throws OCSBadRequestException The clearAt or message-id is invalid
  109. *
  110. * 200: The message was updated successfully
  111. */
  112. public function setPredefinedMessage(string $messageId,
  113. ?int $clearAt): DataResponse {
  114. try {
  115. $status = $this->service->setPredefinedMessage($this->userId, $messageId, $clearAt);
  116. $this->service->removeBackupUserStatus($this->userId);
  117. return new DataResponse($this->formatStatus($status));
  118. } catch (InvalidClearAtException $ex) {
  119. $this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to an invalid clearAt value "' . $clearAt . '"');
  120. throw new OCSBadRequestException($ex->getMessage(), $ex);
  121. } catch (InvalidMessageIdException $ex) {
  122. $this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to an invalid message-id "' . $messageId . '"');
  123. throw new OCSBadRequestException($ex->getMessage(), $ex);
  124. }
  125. }
  126. /**
  127. * Set the message to a custom message for the current user
  128. *
  129. * @NoAdminRequired
  130. *
  131. * @param string|null $statusIcon Icon of the status
  132. * @param string|null $message Message of the status
  133. * @param int|null $clearAt When the message should be cleared
  134. * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>
  135. * @throws OCSBadRequestException The clearAt or icon is invalid or the message is too long
  136. *
  137. * 200: The message was updated successfully
  138. */
  139. public function setCustomMessage(?string $statusIcon,
  140. ?string $message,
  141. ?int $clearAt): DataResponse {
  142. try {
  143. if (($message !== null && $message !== '') || ($clearAt !== null && $clearAt !== 0)) {
  144. $status = $this->service->setCustomMessage($this->userId, $statusIcon, $message, $clearAt);
  145. } else {
  146. $this->service->clearMessage($this->userId);
  147. $status = $this->service->findByUserId($this->userId);
  148. }
  149. $this->service->removeBackupUserStatus($this->userId);
  150. return new DataResponse($this->formatStatus($status));
  151. } catch (InvalidClearAtException $ex) {
  152. $this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to an invalid clearAt value "' . $clearAt . '"');
  153. throw new OCSBadRequestException($ex->getMessage(), $ex);
  154. } catch (InvalidStatusIconException $ex) {
  155. $this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to an invalid icon value "' . $statusIcon . '"');
  156. throw new OCSBadRequestException($ex->getMessage(), $ex);
  157. } catch (StatusMessageTooLongException $ex) {
  158. $this->logger->debug('New user-status for "' . $this->userId . '" was rejected due to a too long status message.');
  159. throw new OCSBadRequestException($ex->getMessage(), $ex);
  160. }
  161. }
  162. /**
  163. * Clear the message of the current user
  164. *
  165. * @NoAdminRequired
  166. *
  167. * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
  168. *
  169. * 200: Message cleared successfully
  170. */
  171. public function clearMessage(): DataResponse {
  172. $this->service->clearMessage($this->userId);
  173. return new DataResponse([]);
  174. }
  175. /**
  176. * Revert the status to the previous status
  177. *
  178. * @NoAdminRequired
  179. *
  180. * @param string $messageId ID of the message to delete
  181. *
  182. * @return DataResponse<Http::STATUS_OK, UserStatusPrivate|array<empty>, array{}>
  183. *
  184. * 200: Status reverted
  185. */
  186. public function revertStatus(string $messageId): DataResponse {
  187. $backupStatus = $this->service->revertUserStatus($this->userId, $messageId, true);
  188. if ($backupStatus) {
  189. return new DataResponse($this->formatStatus($backupStatus));
  190. }
  191. return new DataResponse([]);
  192. }
  193. /**
  194. * @param UserStatus $status
  195. * @return UserStatusPrivate
  196. */
  197. private function formatStatus(UserStatus $status): array {
  198. /** @var UserStatusType $visibleStatus */
  199. $visibleStatus = $status->getStatus();
  200. return [
  201. 'userId' => $status->getUserId(),
  202. 'message' => $status->getCustomMessage(),
  203. 'messageId' => $status->getMessageId(),
  204. 'messageIsPredefined' => $status->getMessageId() !== null,
  205. 'icon' => $status->getCustomIcon(),
  206. 'clearAt' => $status->getClearAt(),
  207. 'status' => $visibleStatus,
  208. 'statusIsUserDefined' => $status->getIsUserDefined(),
  209. ];
  210. }
  211. }