Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2020-05-08 18:00:15 +0300
committerGitHub <noreply@github.com>2020-05-08 18:00:15 +0300
commitf6efeba96b5a2cf2a54962aa1e48ed055c9f721a (patch)
treec5bcf0eebd0bba2f205c5be804ebe161e8f80263 /lib
parent2b6a0b86775b07611fd7d09ea3094746ebe6192b (diff)
parent02f887acfe4206a876b5f31e52f5ed25252ebdbd (diff)
Merge pull request #3465 from PhrozenByte/feature/cmd-room
Add talk:room:* CLI commands
Diffstat (limited to 'lib')
-rw-r--r--lib/Command/Room/Add.php110
-rw-r--r--lib/Command/Room/Create.php147
-rw-r--r--lib/Command/Room/Delete.php76
-rw-r--r--lib/Command/Room/Demote.php94
-rw-r--r--lib/Command/Room/Promote.php94
-rw-r--r--lib/Command/Room/Remove.php94
-rw-r--r--lib/Command/Room/TRoomCommand.php338
-rw-r--r--lib/Command/Room/Update.php152
8 files changed, 1105 insertions, 0 deletions
diff --git a/lib/Command/Room/Add.php b/lib/Command/Room/Add.php
new file mode 100644
index 000000000..d213beb1e
--- /dev/null
+++ b/lib/Command/Room/Add.php
@@ -0,0 +1,110 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Talk\Command\Room;
+
+use Exception;
+use OC\Core\Command\Base;
+use OCA\Talk\Exceptions\RoomNotFoundException;
+use OCA\Talk\Manager;
+use OCA\Talk\Room;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Add extends Base {
+ use TRoomCommand;
+
+ /** @var IUserManager */
+ public $userManager;
+
+ /** @var Manager */
+ public $manager;
+
+ public function __construct(IUserManager $userManager, Manager $manager) {
+ parent::__construct();
+
+ $this->userManager = $userManager;
+ $this->manager = $manager;
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('talk:room:add')
+ ->setDescription('Adds users to a room')
+ ->addArgument(
+ 'token',
+ InputArgument::REQUIRED,
+ 'Token of the room to add users to'
+ )->addOption(
+ 'user',
+ null,
+ InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+ 'Invites the given users to the room'
+ )->addOption(
+ 'group',
+ null,
+ InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+ 'Invites all members of the given groups to the room'
+ )->addOption(
+ 'circle',
+ null,
+ InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+ 'Invites all members of the given circles to the room'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): ?int {
+ $token = $input->getArgument('token');
+ $users = $input->getOption('user');
+ $groups = $input->getOption('group');
+ $circles = $input->getOption('circle');
+
+ try {
+ $room = $this->manager->getRoomByToken($token);
+ } catch (RoomNotFoundException $e) {
+ $output->writeln('<error>Room not found.</error>');
+ return 1;
+ }
+
+ if (!in_array($room->getType(), [Room::GROUP_CALL, Room::PUBLIC_CALL], true)) {
+ $output->writeln('<error>Room is no group call.</error>');
+ return 1;
+ }
+
+ try {
+ $this->addRoomParticipants($room, $users);
+ $this->addRoomParticipantsByGroup($room, $groups);
+ $this->addRoomParticipantsByCircle($room, $circles);
+ } catch (Exception $e) {
+ $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
+ return 1;
+ }
+
+ $output->writeln('<info>Users successfully added to room.</info>');
+ return 0;
+ }
+}
diff --git a/lib/Command/Room/Create.php b/lib/Command/Room/Create.php
new file mode 100644
index 000000000..f2003e45d
--- /dev/null
+++ b/lib/Command/Room/Create.php
@@ -0,0 +1,147 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Talk\Command\Room;
+
+use Exception;
+use OC\Core\Command\Base;
+use OCA\Talk\Manager;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Create extends Base {
+ use TRoomCommand;
+
+ /** @var IUserManager */
+ public $userManager;
+
+ /** @var Manager */
+ public $manager;
+
+ public function __construct(IUserManager $userManager, Manager $manager) {
+ parent::__construct();
+
+ $this->userManager = $userManager;
+ $this->manager = $manager;
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('talk:room:create')
+ ->setDescription('Create a new room')
+ ->addArgument(
+ 'name',
+ InputArgument::REQUIRED,
+ 'The name of the room to create'
+ )->addOption(
+ 'user',
+ null,
+ InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+ 'Invites the given users to the room to create'
+ )->addOption(
+ 'group',
+ null,
+ InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+ 'Invites all members of the given group to the room to create'
+ )->addOption(
+ 'circle',
+ null,
+ InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+ 'Invites all members of the given circle to the room to create'
+ )->addOption(
+ 'public',
+ null,
+ InputOption::VALUE_NONE,
+ 'Creates the room as public room if set'
+ )->addOption(
+ 'readonly',
+ null,
+ InputOption::VALUE_NONE,
+ 'Creates the room with read-only access only if set'
+ )->addOption(
+ 'password',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'Protects the room to create with the given password'
+ )->addOption(
+ 'owner',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'Sets the given user as owner of the room to create'
+ )->addOption(
+ 'moderator',
+ null,
+ InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
+ 'Promotes the given users to moderators'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): ?int {
+ $name = $input->getArgument('name');
+ $users = $input->getOption('user');
+ $groups = $input->getOption('group');
+ $circles = $input->getOption('circle');
+ $public = $input->getOption('public');
+ $readonly = $input->getOption('readonly');
+ $password = $input->getOption('password');
+ $owner = $input->getOption('owner');
+ $moderators = $input->getOption('moderator');
+
+ $name = trim($name);
+ if (!$this->validateRoomName($name)) {
+ $output->writeln("<error>Invalid room name.</error>");
+ return 1;
+ }
+
+ $room = $public ? $this->manager->createPublicRoom($name): $this->manager->createGroupRoom($name);
+
+ try {
+ $this->setRoomReadOnly($room, $readonly);
+
+ if ($password !== null) {
+ $this->setRoomPassword($room, $password);
+ }
+
+ $this->addRoomParticipants($room, $users);
+ $this->addRoomParticipantsByGroup($room, $groups);
+ $this->addRoomParticipantsByCircle($room, $circles);
+ $this->addRoomModerators($room, $moderators);
+
+ if ($owner !== null) {
+ $this->setRoomOwner($room, $owner);
+ }
+ } catch (Exception $e) {
+ $room->deleteRoom();
+
+ $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
+ return 1;
+ }
+
+ $output->writeln('<info>Room successfully created.</info>');
+ return 0;
+ }
+}
diff --git a/lib/Command/Room/Delete.php b/lib/Command/Room/Delete.php
new file mode 100644
index 000000000..d065cc469
--- /dev/null
+++ b/lib/Command/Room/Delete.php
@@ -0,0 +1,76 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Talk\Command\Room;
+
+use OC\Core\Command\Base;
+use OCA\Talk\Exceptions\RoomNotFoundException;
+use OCA\Talk\Manager;
+use OCA\Talk\Room;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Delete extends Base {
+ /** @var Manager */
+ public $manager;
+
+ public function __construct(Manager $manager) {
+ parent::__construct();
+
+ $this->manager = $manager;
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('talk:room:delete')
+ ->setDescription('Deletes a room')
+ ->addArgument(
+ 'token',
+ InputArgument::REQUIRED,
+ 'Token of the room to delete'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): ?int {
+ $token = $input->getArgument('token');
+
+ try {
+ $room = $this->manager->getRoomByToken($token);
+ } catch (RoomNotFoundException $e) {
+ $output->writeln('<error>Room not found.</error>');
+ return 1;
+ }
+
+ if (!in_array($room->getType(), [Room::GROUP_CALL, Room::PUBLIC_CALL], true)) {
+ $output->writeln('<error>Room is no group call.</error>');
+ return 1;
+ }
+
+ $room->deleteRoom();
+
+ $output->writeln('<info>Room successfully deleted.</info>');
+ return 0;
+ }
+}
diff --git a/lib/Command/Room/Demote.php b/lib/Command/Room/Demote.php
new file mode 100644
index 000000000..008030811
--- /dev/null
+++ b/lib/Command/Room/Demote.php
@@ -0,0 +1,94 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Talk\Command\Room;
+
+use Exception;
+use OC\Core\Command\Base;
+use OCA\Talk\Exceptions\RoomNotFoundException;
+use OCA\Talk\Manager;
+use OCA\Talk\Room;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Demote extends Base {
+ use TRoomCommand;
+
+ /** @var IUserManager */
+ public $userManager;
+
+ /** @var Manager */
+ public $manager;
+
+ public function __construct(IUserManager $userManager, Manager $manager) {
+ parent::__construct();
+
+ $this->userManager = $userManager;
+ $this->manager = $manager;
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('talk:room:demote')
+ ->setDescription('Demotes participants of a room to regular users')
+ ->addArgument(
+ 'token',
+ InputArgument::REQUIRED,
+ 'Token of the room in which users should be demoted'
+ )->addArgument(
+ 'participant',
+ InputArgument::REQUIRED | InputArgument::IS_ARRAY,
+ 'Demotes the given participants of the room to regular users'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): ?int {
+ $token = $input->getArgument('token');
+ $users = $input->getArgument('participant');
+
+ try {
+ $room = $this->manager->getRoomByToken($token);
+ } catch (RoomNotFoundException $e) {
+ $output->writeln('<error>Room not found.</error>');
+ return 1;
+ }
+
+ if (!in_array($room->getType(), [Room::GROUP_CALL, Room::PUBLIC_CALL], true)) {
+ $output->writeln('<error>Room is no group call.</error>');
+ return 1;
+ }
+
+ try {
+ $this->removeRoomModerators($room, $users);
+ } catch (Exception $e) {
+ $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
+ return 1;
+ }
+
+ $output->writeln('<info>Users successfully remove from room.</info>');
+ return 0;
+ }
+}
diff --git a/lib/Command/Room/Promote.php b/lib/Command/Room/Promote.php
new file mode 100644
index 000000000..c55315343
--- /dev/null
+++ b/lib/Command/Room/Promote.php
@@ -0,0 +1,94 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Talk\Command\Room;
+
+use Exception;
+use OC\Core\Command\Base;
+use OCA\Talk\Exceptions\RoomNotFoundException;
+use OCA\Talk\Manager;
+use OCA\Talk\Room;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Promote extends Base {
+ use TRoomCommand;
+
+ /** @var IUserManager */
+ public $userManager;
+
+ /** @var Manager */
+ public $manager;
+
+ public function __construct(IUserManager $userManager, Manager $manager) {
+ parent::__construct();
+
+ $this->userManager = $userManager;
+ $this->manager = $manager;
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('talk:room:promote')
+ ->setDescription('Promotes participants of a room to moderators')
+ ->addArgument(
+ 'token',
+ InputArgument::REQUIRED,
+ 'Token of the room in which users should be promoted'
+ )->addArgument(
+ 'participant',
+ InputArgument::REQUIRED | InputArgument::IS_ARRAY,
+ 'Promotes the given participants of the room to moderators'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): ?int {
+ $token = $input->getArgument('token');
+ $users = $input->getArgument('participant');
+
+ try {
+ $room = $this->manager->getRoomByToken($token);
+ } catch (RoomNotFoundException $e) {
+ $output->writeln('<error>Room not found.</error>');
+ return 1;
+ }
+
+ if (!in_array($room->getType(), [Room::GROUP_CALL, Room::PUBLIC_CALL], true)) {
+ $output->writeln('<error>Room is no group call.</error>');
+ return 1;
+ }
+
+ try {
+ $this->addRoomModerators($room, $users);
+ } catch (Exception $e) {
+ $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
+ return 1;
+ }
+
+ $output->writeln('<info>Users successfully added to room.</info>');
+ return 0;
+ }
+}
diff --git a/lib/Command/Room/Remove.php b/lib/Command/Room/Remove.php
new file mode 100644
index 000000000..0c0f77012
--- /dev/null
+++ b/lib/Command/Room/Remove.php
@@ -0,0 +1,94 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Talk\Command\Room;
+
+use Exception;
+use OC\Core\Command\Base;
+use OCA\Talk\Exceptions\RoomNotFoundException;
+use OCA\Talk\Manager;
+use OCA\Talk\Room;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Remove extends Base {
+ use TRoomCommand;
+
+ /** @var IUserManager */
+ public $userManager;
+
+ /** @var Manager */
+ public $manager;
+
+ public function __construct(IUserManager $userManager, Manager $manager) {
+ parent::__construct();
+
+ $this->userManager = $userManager;
+ $this->manager = $manager;
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('talk:room:remove')
+ ->setDescription('Remove users from a room')
+ ->addArgument(
+ 'token',
+ InputArgument::REQUIRED,
+ 'Token of the room to remove users from'
+ )->addArgument(
+ 'user',
+ InputArgument::REQUIRED | InputArgument::IS_ARRAY,
+ 'Removes the given users from the room'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): ?int {
+ $token = $input->getArgument('token');
+ $users = $input->getArgument('user');
+
+ try {
+ $room = $this->manager->getRoomByToken($token);
+ } catch (RoomNotFoundException $e) {
+ $output->writeln('<error>Room not found.</error>');
+ return 1;
+ }
+
+ if (!in_array($room->getType(), [Room::GROUP_CALL, Room::PUBLIC_CALL], true)) {
+ $output->writeln('<error>Room is no group call.</error>');
+ return 1;
+ }
+
+ try {
+ $this->removeRoomParticipants($room, $users);
+ } catch (Exception $e) {
+ $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
+ return 1;
+ }
+
+ $output->writeln('<info>Users successfully remove from room.</info>');
+ return 0;
+ }
+}
diff --git a/lib/Command/Room/TRoomCommand.php b/lib/Command/Room/TRoomCommand.php
new file mode 100644
index 000000000..1b65d8d0d
--- /dev/null
+++ b/lib/Command/Room/TRoomCommand.php
@@ -0,0 +1,338 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Talk\Command\Room;
+
+use InvalidArgumentException;
+use OCA\Circles\Api\v1\Circles;
+use OCA\Circles\Model\Member;
+use OCA\Talk\Exceptions\ParticipantNotFoundException;
+use OCA\Talk\Participant;
+use OCA\Talk\Room;
+use OCP\IUser;
+
+trait TRoomCommand
+{
+ /**
+ * @param Room $room
+ * @param string $name
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function setRoomName(Room $room, string $name): void {
+ $name = trim($name);
+ if ($name === $room->getName()) {
+ return;
+ }
+
+ if (!$this->validateRoomName($name)) {
+ throw new InvalidArgumentException('Invalid room name.');
+ }
+
+ if (!$room->setName($name)) {
+ throw new InvalidArgumentException('Unable to change room name.');
+ }
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return bool
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function validateRoomName(string $name): bool {
+ $name = trim($name);
+ return (($name !== '') && !isset($name[255]));
+ }
+
+ /**
+ * @param Room $room
+ * @param bool $public
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function setRoomPublic(Room $room, bool $public): void {
+ if ($public === ($room->getType() === Room::PUBLIC_CALL)) {
+ return;
+ }
+
+ if (!$public && $room->hasPassword()) {
+ throw new InvalidArgumentException('Unable to change password protected public room to private room.');
+ }
+
+ if (!$room->setType($public ? Room::PUBLIC_CALL : Room::GROUP_CALL)) {
+ throw new InvalidArgumentException('Unable to change room type.');
+ }
+ }
+
+ /**
+ * @param Room $room
+ * @param bool $readOnly
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function setRoomReadOnly(Room $room, bool $readOnly): void {
+ if ($readOnly === ($room->getReadOnly() === Room::READ_ONLY)) {
+ return;
+ }
+
+ if (!$room->setReadOnly($readOnly ? Room::READ_ONLY : Room::READ_WRITE)) {
+ throw new InvalidArgumentException('Unable to change room state.');
+ }
+ }
+
+ /**
+ * @param Room $room
+ * @param string $password
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function setRoomPassword(Room $room, string $password): void {
+ if ($room->hasPassword() ? $room->verifyPassword($password)['result'] : ($password === '')) {
+ return;
+ }
+
+ if (($password !== '') && ($room->getType() !== Room::PUBLIC_CALL)) {
+ throw new InvalidArgumentException('Unable to add password protection to private room.');
+ }
+
+ if (!$room->setPassword($password)) {
+ throw new InvalidArgumentException('Unable to change room password.');
+ }
+ }
+
+ /**
+ * @param Room $room
+ * @param string $userId
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function setRoomOwner(Room $room, string $userId): void {
+ try {
+ $participant = $room->getParticipant($userId);
+ } catch (ParticipantNotFoundException $e) {
+ throw new InvalidArgumentException(sprintf("User '%s' is no participant.", $userId));
+ }
+
+ $room->setParticipantType($participant, Participant::OWNER);
+ }
+
+ /**
+ * @param Room $room
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function unsetRoomOwner(Room $room): void {
+ foreach ($room->getParticipants() as $participant) {
+ if ($participant->getParticipantType() === Participant::OWNER) {
+ $room->setParticipantType($participant, Participant::USER);
+ }
+ }
+ }
+
+ /**
+ * @param Room $room
+ * @param string[] $groupIds
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function addRoomParticipantsByGroup(Room $room, array $groupIds): void {
+ if (!$groupIds) {
+ return;
+ }
+
+ $groupManager = \OC::$server->getGroupManager();
+
+ $users = [];
+ foreach ($groupIds as $groupId) {
+ $group = $groupManager->get($groupId);
+ if ($group === null) {
+ throw new InvalidArgumentException(sprintf("Group '%s' not found.", $groupId));
+ }
+
+ $groupUsers = array_map(function (IUser $user) {
+ return $user->getUID();
+ }, $group->getUsers());
+
+ $users = array_merge($users, array_values($groupUsers));
+ }
+
+ $this->addRoomParticipants($room, $users);
+ }
+
+ /**
+ * @param Room $room
+ * @param string[] $circleIds
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function addRoomParticipantsByCircle(Room $room, array $circleIds): void {
+ if (!$circleIds) {
+ return;
+ }
+
+ if (!\OC::$server->getAppManager()->isEnabledForUser('circles')) {
+ throw new InvalidArgumentException("App 'circles' is not enabled.");
+ }
+
+ $users = [];
+ foreach ($circleIds as $circleId) {
+ try {
+ $circle = Circles::detailsCircle($circleId);
+ } catch (\Exception $e) {
+ throw new InvalidArgumentException(sprintf("Circle '%s' not found.", $circleId));
+ }
+
+ $circleUsers = array_filter($circle->getMembers(), function (Member $member) {
+ if (($member->getType() !== Member::TYPE_USER) || ($member->getUserId() === '')) {
+ return false;
+ }
+
+ return in_array($member->getStatus(), [Member::STATUS_INVITED, Member::STATUS_MEMBER], true);
+ });
+
+ $users = array_merge($users, $circleUsers);
+ }
+
+ $this->addRoomParticipants($room, $users);
+ }
+
+ /**
+ * @param Room $room
+ * @param string[] $userIds
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function addRoomParticipants(Room $room, array $userIds): void {
+ if (!$userIds) {
+ return;
+ }
+
+ $userManager = \OC::$server->getUserManager();
+
+ $participants = [];
+ foreach ($userIds as $userId) {
+ $user = $userManager->get($userId);
+ if ($user === null) {
+ throw new InvalidArgumentException(sprintf("User '%s' not found.", $userId));
+ }
+
+ if (isset($participants[$user->getUID()])) {
+ // nothing to do, user is going to be a participant already
+ continue;
+ }
+
+ try {
+ $room->getParticipant($user->getUID());
+
+ // nothing to do, user is a participant already
+ continue;
+ } catch (ParticipantNotFoundException $e) {
+ // we expect the user not to be a participant yet
+ }
+
+ $participants[$user->getUID()] = [
+ 'userId' => $user->getUID(),
+ ];
+ }
+
+ \call_user_func_array([$room, 'addUsers'], $participants);
+ }
+
+ /**
+ * @param Room $room
+ * @param string[] $userIds
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function removeRoomParticipants(Room $room, array $userIds): void {
+ $userManager = \OC::$server->getUserManager();
+
+ $users = [];
+ foreach ($userIds as $userId) {
+ try {
+ $room->getParticipant($userId);
+ } catch (ParticipantNotFoundException $e) {
+ throw new InvalidArgumentException(sprintf("User '%s' is no participant.", $userId));
+ }
+
+ $users[] = $userManager->get($userId);
+ }
+
+ foreach ($users as $user) {
+ $room->removeUser($user, Room::PARTICIPANT_REMOVED);
+ }
+ }
+
+ /**
+ * @param Room $room
+ * @param string[] $userIds
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function addRoomModerators(Room $room, array $userIds): void {
+ $participants = [];
+ foreach ($userIds as $userId) {
+ try {
+ $participant = $room->getParticipant($userId);
+ } catch (ParticipantNotFoundException $e) {
+ throw new InvalidArgumentException(sprintf("User '%s' is no participant.", $userId));
+ }
+
+ if ($participant->getParticipantType() !== Participant::OWNER) {
+ $participants[] = $participant;
+ }
+ }
+
+ foreach ($participants as $participant) {
+ $room->setParticipantType($participant, Participant::MODERATOR);
+ }
+ }
+
+ /**
+ * @param Room $room
+ * @param string[] $userIds
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function removeRoomModerators(Room $room, array $userIds): void {
+ $participants = [];
+ foreach ($userIds as $userId) {
+ try {
+ $participant = $room->getParticipant($userId);
+ } catch (ParticipantNotFoundException $e) {
+ throw new InvalidArgumentException(sprintf("User '%s' is no participant.", $userId));
+ }
+
+ if ($participant->getParticipantType() === Participant::MODERATOR) {
+ $participants[] = $participant;
+ }
+ }
+
+ foreach ($participants as $participant) {
+ $room->setParticipantType($participant, Participant::USER);
+ }
+ }
+}
diff --git a/lib/Command/Room/Update.php b/lib/Command/Room/Update.php
new file mode 100644
index 000000000..500e898a8
--- /dev/null
+++ b/lib/Command/Room/Update.php
@@ -0,0 +1,152 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Talk\Command\Room;
+
+use Exception;
+use OC\Core\Command\Base;
+use OCA\Talk\Exceptions\RoomNotFoundException;
+use OCA\Talk\Manager;
+use OCA\Talk\Room;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Update extends Base {
+ use TRoomCommand;
+
+ /** @var IUserManager */
+ public $userManager;
+
+ /** @var Manager */
+ public $manager;
+
+ public function __construct(IUserManager $userManager, Manager $manager) {
+ parent::__construct();
+
+ $this->userManager = $userManager;
+ $this->manager = $manager;
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('talk:room:update')
+ ->setDescription('Updates a room')
+ ->addArgument(
+ 'token',
+ InputArgument::REQUIRED,
+ 'The token of the room to update'
+ )->addOption(
+ 'name',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'Sets a new name for the room'
+ )->addOption(
+ 'public',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'Modifies the room to be a public room (value 1) or private room (value 0)'
+ )->addOption(
+ 'readonly',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'Modifies the room to be read-only (value 1) or read-write (value 0)'
+ )->addOption(
+ 'password',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'Sets a new password for the room; pass an empty value to remove password protection'
+ )->addOption(
+ 'owner',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'Sets the given user as owner of the room; pass an empty value to remove the owner'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): ?int {
+ $token = $input->getArgument('token');
+ $name = $input->getOption('name');
+ $public = $input->getOption('public');
+ $readOnly = $input->getOption('readonly');
+ $password = $input->getOption('password');
+ $owner = $input->getOption('owner');
+
+ if (!in_array($public, [null, '0', '1'], true)) {
+ $output->writeln('<error>Invalid value for option "--public" given.</error>');
+ return 1;
+ }
+
+ if (!in_array($readOnly, [null, '0', '1'], true)) {
+ $output->writeln('<error>Invalid value for option "--readonly" given.</error>');
+ return 1;
+ }
+
+ try {
+ $room = $this->manager->getRoomByToken($token);
+ } catch (RoomNotFoundException $e) {
+ $output->writeln('<error>Room not found.</error>');
+ return 1;
+ }
+
+ if (!in_array($room->getType(), [Room::GROUP_CALL, Room::PUBLIC_CALL], true)) {
+ $output->writeln('<error>Room is no group call.</error>');
+ return 1;
+ }
+
+ try {
+ if ($name !== null) {
+ $this->setRoomName($room, $name);
+ }
+
+ if ($public !== null) {
+ $this->setRoomPublic($room, ($public === '1'));
+ }
+
+ if ($readOnly !== null) {
+ $this->setRoomReadOnly($room, ($readOnly === '1'));
+ }
+
+ if ($password !== null) {
+ $this->setRoomPassword($room, $password);
+ }
+
+ if ($owner !== null) {
+ if ($owner !== '') {
+ $this->setRoomOwner($room, $owner);
+ } else {
+ $this->unsetRoomOwner($room);
+ }
+ }
+ } catch (Exception $e) {
+ $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
+ return 1;
+ }
+
+ $output->writeln('<info>Room successfully updated.</info>');
+ return 0;
+ }
+}