diff --git a/docs/conversation.md b/docs/conversation.md index 4956578e2b6..54a6b7ed689 100644 --- a/docs/conversation.md +++ b/docs/conversation.md @@ -247,10 +247,16 @@ * Response: - Status code: + `200 OK` + + `400 Bad Request` When the password does not match the password policy. Show `ocs.data.message` to the user in this case + `403 Forbidden` When the current user is not a moderator or owner + `403 Forbidden` When the conversation is not a public conversation + `404 Not Found` When the conversation could not be found for the participant + - Data: + field | type | Description + ---|---|--- + `message` | string | Only available on `400 Bad Request`, translated error with the violated password policy rules + ## Set default or call permissions for a conversation * Method: `PUT` diff --git a/lib/Command/Room/TRoomCommand.php b/lib/Command/Room/TRoomCommand.php index 280f96b8d5f..157682cf084 100644 --- a/lib/Command/Room/TRoomCommand.php +++ b/lib/Command/Room/TRoomCommand.php @@ -35,6 +35,7 @@ use OCA\Talk\Room; use OCA\Talk\Service\ParticipantService; use OCA\Talk\Service\RoomService; +use OCP\HintException; use OCP\IGroup; use OCP\IGroupManager; use OCP\IUser; @@ -183,8 +184,12 @@ protected function setRoomPassword(Room $room, string $password): void { throw new InvalidArgumentException('Unable to add password protection to private room.'); } - if (!$room->setPassword($password)) { - throw new InvalidArgumentException('Unable to change room password.'); + try { + if (!$this->roomService->setPassword($room, $password)) { + throw new InvalidArgumentException('Unable to change room password.'); + } + } catch (HintException $e) { + throw new InvalidArgumentException($e->getHint()); } } diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 3d5e542ed6f..40c457de339 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -56,6 +56,7 @@ use OCP\Comments\IComment; use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudIdManager; +use OCP\HintException; use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; @@ -1315,7 +1316,14 @@ public function setPassword(string $password): DataResponse { return new DataResponse([], Http::STATUS_FORBIDDEN); } - $this->room->setPassword($password); + try { + $this->roomService->setPassword($this->room, $password); + } catch (HintException $e) { + return new DataResponse([ + 'message' => $e->getHint(), + ], Http::STATUS_BAD_REQUEST); + } + return new DataResponse(); } diff --git a/lib/Room.php b/lib/Room.php index a965dda8c8c..e022c938f52 100644 --- a/lib/Room.php +++ b/lib/Room.php @@ -426,6 +426,10 @@ public function getPassword(): string { return $this->password; } + public function setPassword(string $password): void { + $this->password = $password; + } + public function getRemoteServer(): string { return $this->remoteServer; } @@ -692,32 +696,6 @@ public function setName(string $newName, ?string $oldName = null): bool { return true; } - /** - * @param string $password Currently it is only allowed to have a password for Room::TYPE_PUBLIC - * @return bool True when the change was valid, false otherwise - */ - public function setPassword(string $password): bool { - if ($this->getType() !== self::TYPE_PUBLIC) { - return false; - } - - $hash = $password !== '' ? $this->hasher->hash($password) : ''; - - $event = new ModifyRoomEvent($this, 'password', $password); - $this->dispatcher->dispatch(self::EVENT_BEFORE_PASSWORD_SET, $event); - - $update = $this->db->getQueryBuilder(); - $update->update('talk_rooms') - ->set('password', $update->createNamedParameter($hash)) - ->where($update->expr()->eq('id', $update->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT))); - $update->executeStatement(); - $this->password = $hash; - - $this->dispatcher->dispatch(self::EVENT_AFTER_PASSWORD_SET, $event); - - return true; - } - /** * @param \DateTime $now * @return bool diff --git a/lib/Service/RoomService.php b/lib/Service/RoomService.php index ca5f8cb8a24..f33aeab12c1 100644 --- a/lib/Service/RoomService.php +++ b/lib/Service/RoomService.php @@ -35,8 +35,10 @@ use OCA\Talk\Webinary; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\EventDispatcher\IEventDispatcher; +use OCP\HintException; use OCP\IDBConnection; use OCP\IUser; +use OCP\Security\Events\ValidatePasswordPolicyEvent; use OCP\Security\IHasher; use OCP\Share\IManager as IShareManager; @@ -473,6 +475,39 @@ public function setDescription(Room $room, string $description): bool { return true; } + /** + * @param string $password Currently it is only allowed to have a password for Room::TYPE_PUBLIC + * @return bool True when the change was valid, false otherwise + * @throws HintException + */ + public function setPassword(Room $room, string $password): bool { + if ($room->getType() !== Room::TYPE_PUBLIC) { + return false; + } + + if ($password !== '') { + $event = new ValidatePasswordPolicyEvent($password); + $this->dispatcher->dispatchTyped($event); + } + + $hash = $password !== '' ? $this->hasher->hash($password) : ''; + + $event = new ModifyRoomEvent($room, 'password', $password); + $this->dispatcher->dispatch(Room::EVENT_BEFORE_PASSWORD_SET, $event); + + $update = $this->db->getQueryBuilder(); + $update->update('talk_rooms') + ->set('password', $update->createNamedParameter($hash)) + ->where($update->expr()->eq('id', $update->createNamedParameter($room->getId(), IQueryBuilder::PARAM_INT))); + $update->executeStatement(); + + $room->setPassword($hash); + + $this->dispatcher->dispatch(Room::EVENT_AFTER_PASSWORD_SET, $event); + + return true; + } + public function verifyPassword(Room $room, string $password): array { $event = new VerifyRoomPasswordEvent($room, $password); $this->dispatcher->dispatch(Room::EVENT_PASSWORD_VERIFY, $event); diff --git a/src/components/ConversationSettings/LinkShareSettings.vue b/src/components/ConversationSettings/LinkShareSettings.vue index 8b53cb0d627..14706ed416b 100644 --- a/src/components/ConversationSettings/LinkShareSettings.vue +++ b/src/components/ConversationSettings/LinkShareSettings.vue @@ -163,9 +163,13 @@ export default { } else { showSuccess(t('spreed', 'Conversation password has been removed')) } - } catch (e) { - console.error('Error saving conversation password', e) - showError(t('spreed', 'Error occurred while saving conversation password')) + } catch (error) { + console.error('Error saving conversation password', error) + if (error?.response?.data?.ocs?.data?.message) { + showError(error.response.data.ocs.data.message) + } else { + showError(t('spreed', 'Error occurred while saving conversation password')) + } } this.isSaving = false }, diff --git a/src/components/LeftSidebar/NewGroupConversation/PasswordProtect/PasswordProtect.vue b/src/components/LeftSidebar/NewGroupConversation/PasswordProtect/PasswordProtect.vue index c2142988a83..59e193fb361 100644 --- a/src/components/LeftSidebar/NewGroupConversation/PasswordProtect/PasswordProtect.vue +++ b/src/components/LeftSidebar/NewGroupConversation/PasswordProtect/PasswordProtect.vue @@ -22,16 +22,22 @@