Allow to disable calling functionality

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2021-04-07 11:43:44 +02:00
Родитель 7f0f7c2d5a
Коммит 0fc503a8ac
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7076EA9751AACDDA
11 изменённых файлов: 55 добавлений и 5 удалений

Просмотреть файл

@ -96,3 +96,4 @@ title: Capabilities
## 15 ## 15
* `chat-permission` - When permission 128 is required to post chat messages, reaction or share items to the conversation * `chat-permission` - When permission 128 is required to post chat messages, reaction or share items to the conversation
* `sip-support-nopin` - Whether SIP can be configured to not require a custom attendee PIN * `sip-support-nopin` - Whether SIP can be configured to not require a custom attendee PIN
* `config => call => enabled` - Whether calling is enabled on the instance or not

Просмотреть файл

@ -108,6 +108,9 @@ class Capabilities implements IPublicCapability {
'attachments' => [ 'attachments' => [
'allowed' => $user instanceof IUser, 'allowed' => $user instanceof IUser,
], ],
'call' => [
'enabled' => ((int) $this->serverConfig->getAppValue('spreed', 'start_calls', Room::START_CALL_EVERYONE)) !== Room::START_CALL_NOONE,
],
'chat' => [ 'chat' => [
'max-length' => ChatManager::MAX_CHAT_LENGTH, 'max-length' => ChatManager::MAX_CHAT_LENGTH,
'read-privacy' => Participant::PRIVACY_PUBLIC, 'read-privacy' => Participant::PRIVACY_PUBLIC,

Просмотреть файл

@ -60,6 +60,7 @@ class CallController extends AEnvironmentAwareController {
/** /**
* @PublicPage * @PublicPage
* @RequireCallEnabled
* @RequireParticipant * @RequireParticipant
* @RequireReadWriteConversation * @RequireReadWriteConversation
* @RequireModeratorOrNoLobby * @RequireModeratorOrNoLobby
@ -101,6 +102,7 @@ class CallController extends AEnvironmentAwareController {
/** /**
* @PublicPage * @PublicPage
* @RequireCallEnabled
* @RequireParticipant * @RequireParticipant
* @RequireReadWriteConversation * @RequireReadWriteConversation
* @RequireModeratorOrNoLobby * @RequireModeratorOrNoLobby
@ -133,6 +135,7 @@ class CallController extends AEnvironmentAwareController {
/** /**
* @PublicPage * @PublicPage
* @RequireCallEnabled
* @RequireParticipant * @RequireParticipant
* *
* @param int flags * @param int flags

Просмотреть файл

@ -149,6 +149,7 @@ class RoomController extends AEnvironmentAwareController {
$this->config->getAppValue('spreed', 'signaling_servers', '') . '#' . $this->config->getAppValue('spreed', 'signaling_servers', '') . '#' .
$this->config->getAppValue('spreed', 'signaling_mode', '') . '#' . $this->config->getAppValue('spreed', 'signaling_mode', '') . '#' .
$this->config->getAppValue('spreed', 'allowed_groups', '') . '#' . $this->config->getAppValue('spreed', 'allowed_groups', '') . '#' .
$this->config->getAppValue('spreed', 'start_calls', '') . '#' .
$this->config->getAppValue('spreed', 'start_conversations', '') . '#' . $this->config->getAppValue('spreed', 'start_conversations', '') . '#' .
$this->config->getAppValue('spreed', 'has_reference_id', '') . '#' . $this->config->getAppValue('spreed', 'has_reference_id', '') . '#' .
$this->config->getAppValue('spreed', 'sip_bridge_groups', '[]') . '#' . $this->config->getAppValue('spreed', 'sip_bridge_groups', '[]') . '#' .

Просмотреть файл

@ -26,6 +26,7 @@ namespace OCA\Talk\Middleware;
use OCA\Talk\Config; use OCA\Talk\Config;
use OCA\Talk\Exceptions\ForbiddenException; use OCA\Talk\Exceptions\ForbiddenException;
use OCA\Talk\Middleware\Exceptions\CanNotUseTalkException; use OCA\Talk\Middleware\Exceptions\CanNotUseTalkException;
use OCA\Talk\Room;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\Response;
@ -33,17 +34,25 @@ use OCP\AppFramework\Http\RedirectToDefaultAppResponse;
use OCP\AppFramework\Middleware; use OCP\AppFramework\Middleware;
use OCP\AppFramework\OCS\OCSException; use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCSController; use OCP\AppFramework\OCSController;
use OCP\AppFramework\Utility\IControllerMethodReflector;
use OCP\IConfig;
use OCP\IUser; use OCP\IUser;
use OCP\IUserSession; use OCP\IUserSession;
class CanUseTalkMiddleware extends Middleware { class CanUseTalkMiddleware extends Middleware {
private IUserSession $userSession; private IUserSession $userSession;
private Config $config; private IControllerMethodReflector $reflector;
private Config $talkConfig;
private IConfig $serverConfig;
public function __construct(IUserSession $userSession, public function __construct(IUserSession $userSession,
Config $config) { IControllerMethodReflector $reflector,
Config $talkConfig,
IConfig $serverConfig) {
$this->userSession = $userSession; $this->userSession = $userSession;
$this->config = $config; $this->reflector = $reflector;
$this->talkConfig = $talkConfig;
$this->serverConfig = $serverConfig;
} }
/** /**
@ -54,7 +63,12 @@ class CanUseTalkMiddleware extends Middleware {
*/ */
public function beforeController($controller, $methodName): void { public function beforeController($controller, $methodName): void {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if ($user instanceof IUser && $this->config->isDisabledForUser($user)) { if ($user instanceof IUser && $this->talkConfig->isDisabledForUser($user)) {
throw new CanNotUseTalkException();
}
if ($this->reflector->hasAnnotation('RequireCallEnabled')
&& ((int) $this->serverConfig->getAppValue('spreed', 'start_calls')) === Room::START_CALL_NOONE) {
throw new CanNotUseTalkException(); throw new CanNotUseTalkException();
} }
} }

Просмотреть файл

@ -95,6 +95,10 @@ class Participant {
public function canStartCall(IConfig $config): bool { public function canStartCall(IConfig $config): bool {
$defaultStartCall = (int) $config->getAppValue('spreed', 'start_calls', Room::START_CALL_EVERYONE); $defaultStartCall = (int) $config->getAppValue('spreed', 'start_calls', Room::START_CALL_EVERYONE);
if ($defaultStartCall === Room::START_CALL_NOONE) {
return false;
}
if (!($this->getPermissions() & Attendee::PERMISSIONS_CALL_START)) { if (!($this->getPermissions() & Attendee::PERMISSIONS_CALL_START)) {
return false; return false;
} }

Просмотреть файл

@ -93,6 +93,7 @@ class Room {
public const START_CALL_EVERYONE = 0; public const START_CALL_EVERYONE = 0;
public const START_CALL_USERS = 1; public const START_CALL_USERS = 1;
public const START_CALL_MODERATORS = 2; public const START_CALL_MODERATORS = 2;
public const START_CALL_NOONE = 3;
public const PARTICIPANT_REMOVED = 'remove'; public const PARTICIPANT_REMOVED = 'remove';
public const PARTICIPANT_LEFT = 'leave'; public const PARTICIPANT_LEFT = 'leave';

Просмотреть файл

@ -59,6 +59,11 @@ trait TInitialState {
); );
} }
$this->initialState->provideInitialState(
'call_enabled',
((int) $this->serverConfig->getAppValue('spreed', 'start_calls')) !== Room::START_CALL_NOONE
);
$this->initialState->provideInitialState( $this->initialState->provideInitialState(
'signaling_mode', 'signaling_mode',
$this->talkConfig->getSignalingMode() $this->talkConfig->getSignalingMode()

Просмотреть файл

@ -109,6 +109,7 @@ const startCallOptions = [
{ value: 0, label: t('spreed', 'Everyone') }, { value: 0, label: t('spreed', 'Everyone') },
{ value: 1, label: t('spreed', 'Users and moderators') }, { value: 1, label: t('spreed', 'Users and moderators') },
{ value: 2, label: t('spreed', 'Moderators only') }, { value: 2, label: t('spreed', 'Moderators only') },
{ value: 3, label: t('spreed', 'Disable calls') },
] ]
export default { export default {

Просмотреть файл

@ -83,12 +83,14 @@ import isInLobby from '../../mixins/isInLobby'
import participant from '../../mixins/participant' import participant from '../../mixins/participant'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip' import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
import { emit } from '@nextcloud/event-bus' import { emit } from '@nextcloud/event-bus'
import { loadState } from '@nextcloud/initial-state'
import BrowserStorage from '../../services/BrowserStorage' import BrowserStorage from '../../services/BrowserStorage'
import Actions from '@nextcloud/vue/dist/Components/Actions' import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import VideoOff from 'vue-material-design-icons/VideoOff' import VideoOff from 'vue-material-design-icons/VideoOff'
import MenuDown from 'vue-material-design-icons/MenuDown' import MenuDown from 'vue-material-design-icons/MenuDown'
import Button from '@nextcloud/vue/dist/Components/Button' import Button from '@nextcloud/vue/dist/Components/Button'
export default { export default {
name: 'CallButton', name: 'CallButton',
@ -125,6 +127,7 @@ export default {
data() { data() {
return { return {
loading: false, loading: false,
callEnabled: false,
} }
}, },
@ -227,7 +230,8 @@ export default {
}, },
showStartCallButton() { showStartCallButton() {
return this.conversation.readOnly === CONVERSATION.STATE.READ_WRITE return this.callEnabled
&& this.conversation.readOnly === CONVERSATION.STATE.READ_WRITE
&& !this.isInCall && !this.isInCall
}, },
@ -241,6 +245,10 @@ export default {
}, },
}, },
mounted() {
this.callEnabled = loadState('spreed', 'call_enabled')
},
methods: { methods: {
isParticipantTypeModerator(participantType) { isParticipantTypeModerator(participantType) {
return [PARTICIPANT.TYPE.OWNER, PARTICIPANT.TYPE.MODERATOR, PARTICIPANT.TYPE.GUEST_MODERATOR].indexOf(participantType) !== -1 return [PARTICIPANT.TYPE.OWNER, PARTICIPANT.TYPE.MODERATOR, PARTICIPANT.TYPE.GUEST_MODERATOR].indexOf(participantType) !== -1

Просмотреть файл

@ -29,6 +29,7 @@ use OCA\Talk\Capabilities;
use OCA\Talk\Chat\CommentsManager; use OCA\Talk\Chat\CommentsManager;
use OCA\Talk\Config; use OCA\Talk\Config;
use OCA\Talk\Participant; use OCA\Talk\Participant;
use OCA\Talk\Room;
use OCP\Capabilities\IPublicCapability; use OCP\Capabilities\IPublicCapability;
use OCP\IConfig; use OCP\IConfig;
use OCP\IUser; use OCP\IUser;
@ -130,6 +131,7 @@ class CapabilitiesTest extends TestCase {
->willReturnMap([ ->willReturnMap([
['spreed', 'has_reference_id', 'no', 'no'], ['spreed', 'has_reference_id', 'no', 'no'],
['spreed', 'max-gif-size', '3145728', '200000'], ['spreed', 'max-gif-size', '3145728', '200000'],
['spreed', 'start_calls', Room::START_CALL_EVERYONE, Room::START_CALL_EVERYONE],
]); ]);
$this->assertInstanceOf(IPublicCapability::class, $capabilities); $this->assertInstanceOf(IPublicCapability::class, $capabilities);
@ -140,6 +142,9 @@ class CapabilitiesTest extends TestCase {
'attachments' => [ 'attachments' => [
'allowed' => false, 'allowed' => false,
], ],
'call' => [
'enabled' => true,
],
'chat' => [ 'chat' => [
'max-length' => 32000, 'max-length' => 32000,
'read-privacy' => 0, 'read-privacy' => 0,
@ -209,6 +214,7 @@ class CapabilitiesTest extends TestCase {
->willReturnMap([ ->willReturnMap([
['spreed', 'has_reference_id', 'no', 'yes'], ['spreed', 'has_reference_id', 'no', 'yes'],
['spreed', 'max-gif-size', '3145728', '200000'], ['spreed', 'max-gif-size', '3145728', '200000'],
['spreed', 'start_calls', Room::START_CALL_EVERYONE, Room::START_CALL_NOONE],
]); ]);
$this->assertInstanceOf(IPublicCapability::class, $capabilities); $this->assertInstanceOf(IPublicCapability::class, $capabilities);
@ -225,6 +231,9 @@ class CapabilitiesTest extends TestCase {
'allowed' => true, 'allowed' => true,
'folder' => '/Talk', 'folder' => '/Talk',
], ],
'call' => [
'enabled' => false,
],
'chat' => [ 'chat' => [
'max-length' => 32000, 'max-length' => 32000,
'read-privacy' => $readPrivacy, 'read-privacy' => $readPrivacy,