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 @@