diff --git a/docs/capabilities.md b/docs/capabilities.md index 4dbf2c03607..1be5e408ed8 100644 --- a/docs/capabilities.md +++ b/docs/capabilities.md @@ -119,4 +119,5 @@ * `config => call => predefined-backgrounds` - List of predefined virtual backgrounds. The files are in Talks img/ folder, accessible via the normal image path methods. The list is cached for 5 minutes. * `config => call => can-upload-background` - Boolean flag whether the user can upload a custom virtual background (requires an account and non-zero quota). Uploads should be done to Talk/Backgrounds/ (respecting the user's attachment directory setting). * `config => call => supported-reactions` - A list of emojis supported as call reactions. If the list is absent or empty, clients should not show the emoji reaction option in calls. -* +* `config => conversations => can-create-group` - List with group ids whose members can create group conversations. +* `config => conversations => can-create-public` - List with group ids whose members can create public conversations. diff --git a/docs/settings.md b/docs/settings.md index 9b476365ea7..1dc5b166652 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -62,6 +62,8 @@ Legend: | `allowed_groups` | string[] | `[]` | Yes | 🖌️ | List of group ids that are allowed to use Talk | | `sip_bridge_groups` | string[] | `[]` | Yes | 🖌️ | List of group ids that are allowed to enable SIP dial-in in a conversation | | `start_conversations` | string[] | `[]` | Yes | 🖌️ | List of group ids that are allowed to create conversations | +| `start_group_conversation` | ,string[] | `[]` | Yes | 🖌️ | List of group ids that are allowed to create group conversations | +| `start_public_conversation` | ,string[] | `[]` | Yes | 🖌️ | List of group ids that are allowed to create public conversations | | `hosted-signaling-server-account` | array | `{}` | No | 🖌️ | Account information of the hosted signaling server | | `stun_servers` | array[] | `[]` | Yes | 🖌💻️ | List of STUN servers, should be configured via the web interface or the OCC commands | | `turn_servers` | array[] | `[]` | Yes | 🖌️💻 | List of TURN servers, should be configured via the web interface or the OCC commands | diff --git a/lib/Capabilities.php b/lib/Capabilities.php index 21206a38bdb..133026797e5 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -136,7 +136,11 @@ public function getCapabilities(): array { 'translations' => $this->translationManager->getLanguages(), ], 'conversations' => [ - 'can-create' => $user instanceof IUser && !$this->talkConfig->isNotAllowedToCreateConversations($user) + 'can-create' => $user instanceof IUser && !$this->talkConfig->isNotAllowedToCreateConversations($user), + 'can-create-group' => $user instanceof IUser + && !$this->talkConfig->isNotAllowedToCreateGroupConversations($user), + 'can-create-public' => $user instanceof IUser + && !$this->talkConfig->isNotAllowedToCreatePublicConversations($user), ], 'previews' => [ 'max-gif-size' => (int)$this->serverConfig->getAppValue('spreed', 'max-gif-size', '3145728'), diff --git a/lib/Config.php b/lib/Config.php index da5148c3adc..97a04d09958 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -210,6 +210,24 @@ public function getAllowedConversationsGroupIds(): array { return \is_array($groups) ? $groups : []; } + /** + * @return string[] + */ + public function getAllowedGroupConversationsGroupIds(): array { + $groups = $this->config->getAppValue('spreed', 'start_group_conversations', '[]'); + $groups = json_decode($groups, true); + return \is_array($groups) ? $groups : []; + } + + /** + * @return string[] + */ + public function getAllowedPublicConversationsGroupIds(): array { + $groups = $this->config->getAppValue('spreed', 'start_public_conversations', '[]'); + $groups = json_decode($groups, true); + return \is_array($groups) ? $groups : []; + } + public function isNotAllowedToCreateConversations(IUser $user): bool { $allowedGroups = $this->getAllowedConversationsGroupIds(); if (empty($allowedGroups)) { @@ -220,6 +238,26 @@ public function isNotAllowedToCreateConversations(IUser $user): bool { return empty(array_intersect($allowedGroups, $userGroups)); } + public function isNotAllowedToCreateGroupConversations(IUser $user): bool { + $allowedGroups = $this->getAllowedGroupConversationsGroupIds(); + if (empty($allowedGroups)) { + return false; + } + + $userGroups = $this->groupManager->getUserGroupIds($user); + return empty(array_intersect($allowedGroups, $userGroups)); + } + + public function isNotAllowedToCreatePublicConversations(IUser $user): bool { + $allowedGroups = $this->getAllowedGroupConversationsGroupIds(); + if (empty($allowedGroups)) { + return false; + } + + $userGroups = $this->groupManager->getUserGroupIds($user); + return empty(array_intersect($allowedGroups, $userGroups)); + } + public function getDefaultPermissions(): int { // Admin configured default permissions $configurableDefault = $this->config->getAppValue('spreed', 'default_permissions'); diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 920624aa685..352f4a2f810 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -173,6 +173,8 @@ protected function getTalkHashHeader(): array { $this->config->getAppValue('spreed', 'allowed_groups') . '#' . $this->config->getAppValue('spreed', 'start_calls') . '#' . $this->config->getAppValue('spreed', 'start_conversations') . '#' . + $this->config->getAppValue('spreed', 'start_group_conversations', '') . '#' . + $this->config->getAppValue('spreed', 'start_public_conversations', '') . '#' . $this->config->getAppValue('spreed', 'default_permissions') . '#' . $this->config->getAppValue('spreed', 'breakout_rooms') . '#' . $this->config->getAppValue('spreed', 'federation_enabled') . '#' . diff --git a/lib/Listener/GroupDeletedListener.php b/lib/Listener/GroupDeletedListener.php index 073c81e2fae..fd45dd62f57 100644 --- a/lib/Listener/GroupDeletedListener.php +++ b/lib/Listener/GroupDeletedListener.php @@ -60,6 +60,8 @@ public function handle(Event $event): void { $this->removeGroupFromConfig('sip_bridge_groups', $gid); $this->removeGroupFromConfig('start_conversations', $gid); + $this->removeGroupFromConfig('start_group_conversations', $gid); + $this->removeGroupFromConfig('start_public_conversations', $gid); $this->removeGroupFromConfig('allowed_groups', $gid); // Remove the group itself from being a participant diff --git a/lib/Settings/Admin/AdminSettings.php b/lib/Settings/Admin/AdminSettings.php index b14e229f003..6a67e5d3585 100644 --- a/lib/Settings/Admin/AdminSettings.php +++ b/lib/Settings/Admin/AdminSettings.php @@ -112,6 +112,10 @@ protected function initAllowedGroups(): void { $groups = $this->getGroupDetailsArray($this->talkConfig->getAllowedConversationsGroupIds(), 'start_conversations'); $this->initialState->provideInitialState('start_conversations', $groups); + $groups = $this->getGroupDetailsArray($this->talkConfig->getAllowedConversationsGroupIds(), 'start_group_conversations'); + $this->initialState->provideInitialState('start_group_conversations', $groups); + $groups = $this->getGroupDetailsArray($this->talkConfig->getAllowedConversationsGroupIds(), 'start_public_conversations'); + $this->initialState->provideInitialState('start_public_conversations', $groups); $groups = $this->getGroupDetailsArray($this->talkConfig->getAllowedTalkGroupIds(), 'allowed_groups'); $this->initialState->provideInitialState('allowed_groups', $groups); diff --git a/lib/TInitialState.php b/lib/TInitialState.php index a9e5a5b82af..45b3baace89 100644 --- a/lib/TInitialState.php +++ b/lib/TInitialState.php @@ -104,6 +104,16 @@ protected function publishInitialStateForUser(IUser $user, IRootFolder $rootFold !$this->talkConfig->isNotAllowedToCreateConversations($user) ); + $this->initialState->provideInitialState( + 'start_group_conversations', + !$this->talkConfig->isNotAllowedToCreateGroupConversations($user) + ); + + $this->initialState->provideInitialState( + 'start_public_conversations', + !$this->talkConfig->isNotAllowedToCreatePublicConversations($user) + ); + $this->initialState->provideInitialState( 'circles_enabled', $appManager->isEnabledForUser('circles', $user) @@ -172,6 +182,16 @@ protected function publishInitialStateForGuest(): void { false ); + $this->initialState->provideInitialState( + 'start_group_conversations', + false + ); + + $this->initialState->provideInitialState( + 'start_public_conversations', + false + ); + $this->initialState->provideInitialState( 'circles_enabled', false diff --git a/tests/php/CapabilitiesTest.php b/tests/php/CapabilitiesTest.php index ef3896596a7..d24b5aaf53f 100644 --- a/tests/php/CapabilitiesTest.php +++ b/tests/php/CapabilitiesTest.php @@ -203,6 +203,8 @@ public function testGetCapabilitiesGuest(): void { ], 'conversations' => [ 'can-create' => false, + 'can-create-group' => false, + 'can-create-public' => false, ], 'previews' => [ 'max-gif-size' => 200000, @@ -218,21 +220,24 @@ public function testGetCapabilitiesGuest(): void { public function dataGetCapabilitiesUserAllowed(): array { return [ - [true, false, 'none', true, Participant::PRIVACY_PRIVATE], - [false, true, '1 MB', true, Participant::PRIVACY_PUBLIC], - [false, true, '0 B', false, Participant::PRIVACY_PUBLIC], + [true, false, false, false, 'none', true, Participant::PRIVACY_PRIVATE], + [false, true, true, true, '1 MB', true, Participant::PRIVACY_PUBLIC], + [false, true, true, true, '0 B', false, Participant::PRIVACY_PUBLIC], ]; } /** * @dataProvider dataGetCapabilitiesUserAllowed - * @param bool $isNotAllowed - * @param bool $canCreate - * @param string $quota - * @param bool $canUpload - * @param int $readPrivacy */ - public function testGetCapabilitiesUserAllowed(bool $isNotAllowed, bool $canCreate, string $quota, bool $canUpload, int $readPrivacy): void { + public function testGetCapabilitiesUserAllowed( + bool $isNotAllowed, + bool $canCreate, + bool $canCreateGroup, + bool $canCreatePublic, + string $quota, + bool $canUpload, + int $readPrivacy + ): void { $capabilities = new Capabilities( $this->serverConfig, $this->talkConfig, @@ -270,6 +275,16 @@ public function testGetCapabilitiesUserAllowed(bool $isNotAllowed, bool $canCrea ->with($user) ->willReturn($isNotAllowed); + $this->talkConfig->expects($this->once()) + ->method('isNotAllowedToCreateGroupConversations') + ->with($user) + ->willReturn($isNotAllowed); + + $this->talkConfig->expects($this->once()) + ->method('isNotAllowedToCreatePublicConversations') + ->with($user) + ->willReturn($isNotAllowed); + $this->talkConfig->expects($this->once()) ->method('getUserReadPrivacy') ->with('uid') @@ -324,6 +339,8 @@ public function testGetCapabilitiesUserAllowed(bool $isNotAllowed, bool $canCrea ], 'conversations' => [ 'can-create' => $canCreate, + 'can-create-group' => $canCreateGroup, + 'can-create-public' => $canCreatePublic, ], 'previews' => [ 'max-gif-size' => 200000,