aboutsummaryrefslogtreecommitdiffstats
path: root/apps/user_status/lib/Controller/HeartbeatController.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/user_status/lib/Controller/HeartbeatController.php')
-rw-r--r--apps/user_status/lib/Controller/HeartbeatController.php94
1 files changed, 94 insertions, 0 deletions
diff --git a/apps/user_status/lib/Controller/HeartbeatController.php b/apps/user_status/lib/Controller/HeartbeatController.php
new file mode 100644
index 00000000000..30f4af6572a
--- /dev/null
+++ b/apps/user_status/lib/Controller/HeartbeatController.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\UserStatus\Controller;
+
+use OCA\UserStatus\Db\UserStatus;
+use OCA\UserStatus\ResponseDefinitions;
+use OCA\UserStatus\Service\StatusService;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\ApiRoute;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCSController;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\IRequest;
+use OCP\IUserSession;
+use OCP\User\Events\UserLiveStatusEvent;
+use OCP\UserStatus\IUserStatus;
+
+/**
+ * @psalm-import-type UserStatusPrivate from ResponseDefinitions
+ */
+class HeartbeatController extends OCSController {
+
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private IEventDispatcher $eventDispatcher,
+ private IUserSession $userSession,
+ private ITimeFactory $timeFactory,
+ private StatusService $service,
+ ) {
+ parent::__construct($appName, $request);
+ }
+
+ /**
+ * Keep the status alive
+ *
+ * @param string $status Only online, away
+ *
+ * @return DataResponse<Http::STATUS_OK, UserStatusPrivate, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NO_CONTENT, list<empty>, array{}>
+ *
+ * 200: Status successfully updated
+ * 204: User has no status to keep alive
+ * 400: Invalid status to update
+ */
+ #[NoAdminRequired]
+ #[ApiRoute(verb: 'PUT', url: '/api/v1/heartbeat')]
+ public function heartbeat(string $status): DataResponse {
+ if (!\in_array($status, [IUserStatus::ONLINE, IUserStatus::AWAY], true)) {
+ return new DataResponse([], Http::STATUS_BAD_REQUEST);
+ }
+
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
+ }
+
+ $event = new UserLiveStatusEvent(
+ $user,
+ $status,
+ $this->timeFactory->getTime()
+ );
+
+ $this->eventDispatcher->dispatchTyped($event);
+
+ $userStatus = $event->getUserStatus();
+ if (!$userStatus) {
+ return new DataResponse([], Http::STATUS_NO_CONTENT);
+ }
+
+ /** @psalm-suppress UndefinedInterfaceMethod */
+ return new DataResponse($this->formatStatus($userStatus->getInternal()));
+ }
+
+ private function formatStatus(UserStatus $status): array {
+ return [
+ 'userId' => $status->getUserId(),
+ 'message' => $status->getCustomMessage(),
+ 'messageId' => $status->getMessageId(),
+ 'messageIsPredefined' => $status->getMessageId() !== null,
+ 'icon' => $status->getCustomIcon(),
+ 'clearAt' => $status->getClearAt(),
+ 'status' => $status->getStatus(),
+ 'statusIsUserDefined' => $status->getIsUserDefined(),
+ ];
+ }
+}