diff options
-rw-r--r-- | appinfo/info.xml | 2 | ||||
-rw-r--r-- | appinfo/routes.php | 18 | ||||
-rw-r--r-- | docs/api-v1.md | 46 | ||||
-rw-r--r-- | lib/AppInfo/Application.php | 2 | ||||
-rw-r--r-- | lib/Controller/CallController.php | 71 | ||||
-rw-r--r-- | lib/Controller/RoomController.php | 77 | ||||
-rw-r--r-- | lib/Controller/SignalingController.php | 4 | ||||
-rw-r--r-- | lib/Manager.php | 2 | ||||
-rw-r--r-- | lib/Migration/Version2001Date20171031102049.php | 51 | ||||
-rw-r--r-- | lib/Participant.php | 10 | ||||
-rw-r--r-- | lib/Room.php | 36 |
11 files changed, 270 insertions, 49 deletions
diff --git a/appinfo/info.xml b/appinfo/info.xml index 07590aebf..60837b272 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -38,7 +38,7 @@ And in the works for the [coming versions](https://github.com/nextcloud/spreed/m <bugs>https://github.com/nextcloud/spreed/issues</bugs> <repository type="git">https://github.com/nextcloud/spreed.git</repository> - <version>2.1.9</version> + <version>2.1.10</version> <dependencies> <nextcloud min-version="13" max-version="13" /> diff --git a/appinfo/routes.php b/appinfo/routes.php index c0aed8a5c..11f867dd6 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -222,6 +222,24 @@ return [ ], ], [ + 'name' => 'Room#joinRoom', + 'url' => '/api/{apiVersion}/room/{token}/participants/active', + 'verb' => 'POST', + 'requirements' => [ + 'apiVersion' => 'v1', + 'token' => '^[a-z0-9]{4,30}$', + ], + ], + [ + 'name' => 'Room#exitRoom', + 'url' => '/api/{apiVersion}/room/{token}/participants/active', + 'verb' => 'DELETE', + 'requirements' => [ + 'apiVersion' => 'v1', + 'token' => '^[a-z0-9]{4,30}$', + ], + ], + [ 'name' => 'Room#promoteModerator', 'url' => '/api/{apiVersion}/room/{token}/moderators', 'verb' => 'POST', diff --git a/docs/api-v1.md b/docs/api-v1.md index 43f3ff295..d60355d08 100644 --- a/docs/api-v1.md +++ b/docs/api-v1.md @@ -283,6 +283,38 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1` + `200 OK` + `404 Not Found` When the room could not be found for the participant +### Join a room (available for call and chat) + +* Method: `POST` +* Endpoint: `/room/{token}/participants/active` +* Data: + + field | type | Description + ------|------|------------ + `password` | string | Optional: Password is only required for users which are of type `4` or `5` and only when the room has `hasPassword` set to true. + +* Response: + - Header: + + `200 OK` + + `403 Forbidden` When the password is required and didn't match + + `404 Not Found` When the room could not be found for the participant + + - Data: + + field | type | Description + ------|------|------------ + `sessionId` | string | 512 character long string + +### Leave a room (not available for call and chat anymore) + +* Method: `DELETE` +* Endpoint: `/room/{token}/participants/active` + +* Response: + - Header: + + `200 OK` + + `404 Not Found` When the room could not be found for the participant + ### Promote a user to a moderator * Method: `POST` @@ -347,24 +379,12 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1` * Method: `POST` * Endpoint: `/call/{token}` -* Data: - - field | type | Description - ------|------|------------ - `password` | string | Optional: Password is only required for users which are of type `4` or `5` and only when the room has `hasPassword` set to true. * Response: - Header: + `200 OK` - + `403 Forbidden` When the password is required and didn't match + `404 Not Found` When the room could not be found for the participant - - Data: - - field | type | Description - ------|------|------------ - `sessionId` | string | 512 character long string - ### Send ping to keep the call alive * Method: `POST` @@ -375,7 +395,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1` + `200 OK` + `404 Not Found` When the room could not be found for the participant -### Leave a call (but staying in the room for future calls) +### Leave a call (but staying in the room for future calls and chat) * Method: `DELETE` * Endpoint: `/call/{token}` diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 62d9c823f..3aa1e3ec7 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -87,6 +87,8 @@ class Application extends App { $dispatcher->addListener(Room::class . '::postRemoveUser', $listener); $dispatcher->addListener(Room::class . '::postRemoveBySession', $listener); $dispatcher->addListener(Room::class . '::postUserDisconnectRoom', $listener); + $dispatcher->addListener(Room::class . '::postSessionJoinCall', $listener); + $dispatcher->addListener(Room::class . '::postSessionLeaveCall', $listener); $dispatcher->addListener(Room::class . '::postAddUsers', function(GenericEvent $event) { /** @var BackendNotifier $notifier */ diff --git a/lib/Controller/CallController.php b/lib/Controller/CallController.php index 00f5b3630..009f2fdd9 100644 --- a/lib/Controller/CallController.php +++ b/lib/Controller/CallController.php @@ -106,8 +106,8 @@ class CallController extends OCSController { $participants = $room->getParticipants(time() - 30); $result = []; foreach ($participants['users'] as $participant => $data) { - if ($data['sessionId'] === '0') { - // User left the room + if ($data['sessionId'] === '0' || !$data['inCall']) { + // User is not active in call continue; } @@ -136,38 +136,36 @@ class CallController extends OCSController { * @UseSession * * @param string $token - * @param string $password * @return DataResponse */ - public function joinCall($token, $password) { + public function joinCall($token) { try { $room = $this->manager->getRoomForParticipantByToken($token, $this->userId); } catch (RoomNotFoundException $e) { return new DataResponse([], Http::STATUS_NOT_FOUND); } - try { - if ($this->userId !== null) { - $sessionIds = $this->manager->getSessionIdsForUser($this->userId); - $newSessionId = $room->enterRoomAsUser($this->userId, $password, $this->session->get('spreed-password') === $room->getToken()); - - if (!empty($sessionIds)) { - $this->messages->deleteMessages($sessionIds); - } - } else { - $newSessionId = $room->enterRoomAsGuest($password, $this->session->get('spreed-password') === $room->getToken()); + if ($this->userId !== null) { + if (!$this->session->exists('spreed-session')) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + $sessionId = $this->session->get('spreed-session'); + } else { + try { + $participant = $room->getParticipant($this->userId); + } catch (ParticipantNotFoundException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + $sessionId = $participant->getSessionId(); + if ($sessionId === '0') { + return new DataResponse([], Http::STATUS_NOT_FOUND); } - } catch (InvalidPasswordException $e) { - return new DataResponse([], Http::STATUS_FORBIDDEN); } - $this->session->remove('spreed-password'); - $this->session->set('spreed-session', $newSessionId); - $room->ping($this->userId, $newSessionId, time()); + $room->changeInCall($sessionId, true); - return new DataResponse([ - 'sessionId' => $newSessionId, - ]); + return new DataResponse(); } /** @@ -201,23 +199,32 @@ class CallController extends OCSController { * @return DataResponse */ public function leaveCall($token) { - $sessionId = $this->session->get('spreed-session'); - $this->session->remove('spreed-session'); - try { $room = $this->manager->getRoomForParticipantByToken($token, $this->userId); + } catch (RoomNotFoundException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } - if ($this->userId === null) { - $participant = $room->getParticipantBySession($sessionId); - $room->removeParticipantBySession($participant); - } else { + if ($this->userId !== null) { + if (!$this->session->exists('spreed-session')) { + return new DataResponse(); + } + $sessionId = $this->session->get('spreed-session'); + } else { + try { $participant = $room->getParticipant($this->userId); - $room->disconnectUserFromAllRooms($participant->getUser()); + } catch (ParticipantNotFoundException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + $sessionId = $participant->getSessionId(); + if ($sessionId === '0') { + return new DataResponse([], Http::STATUS_NOT_FOUND); } - } catch (RoomNotFoundException $e) { - } catch (ParticipantNotFoundException $e) { } + $room->changeInCall($sessionId, false); + return new DataResponse(); } diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 27cd045d8..69a42f61c 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -25,11 +25,13 @@ namespace OCA\Spreed\Controller; +use OCA\Spreed\Exceptions\InvalidPasswordException; use OCA\Spreed\Exceptions\ParticipantNotFoundException; use OCA\Spreed\Exceptions\RoomNotFoundException; use OCA\Spreed\Manager; use OCA\Spreed\Participant; use OCA\Spreed\Room; +use OCA\Spreed\Signaling\Messages; use OCP\Activity\IManager as IActivityManager; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; @@ -57,6 +59,8 @@ class RoomController extends OCSController { private $logger; /** @var Manager */ private $manager; + /** @var Messages */ + private $messages; /** @var INotificationManager */ private $notificationManager; /** @var IActivityManager */ @@ -73,6 +77,7 @@ class RoomController extends OCSController { * @param IGroupManager $groupManager * @param ILogger $logger * @param Manager $manager + * @param Messages $messages * @param INotificationManager $notificationManager * @param IActivityManager $activityManager * @param IL10N $l10n @@ -85,6 +90,7 @@ class RoomController extends OCSController { IGroupManager $groupManager, ILogger $logger, Manager $manager, + Messages $messages, INotificationManager $notificationManager, IActivityManager $activityManager, IL10N $l10n) { @@ -95,6 +101,7 @@ class RoomController extends OCSController { $this->groupManager = $groupManager; $this->logger = $logger; $this->manager = $manager; + $this->messages = $messages; $this->notificationManager = $notificationManager; $this->activityManager = $activityManager; $this->l10n = $l10n; @@ -158,8 +165,10 @@ class RoomController extends OCSController { if ($participant instanceof Participant) { $participantType = $participant->getParticipantType(); + $participantInCall = $participant->isInCall(); } else { $participantType = Participant::GUEST; + $participantInCall = false; } $roomData = [ @@ -169,6 +178,7 @@ class RoomController extends OCSController { 'name' => $room->getName(), 'displayName' => $room->getName(), 'participantType' => $participantType, + 'participantInCall' => $participantInCall, 'count' => $room->getNumberOfParticipants(time() - 30), 'hasPassword' => $room->hasPassword(), ]; @@ -767,6 +777,73 @@ class RoomController extends OCSController { } /** + * @PublicPage + * @UseSession + * + * @param string $token + * @param string $password + * @return DataResponse + */ + public function joinRoom($token, $password) { + try { + $room = $this->manager->getRoomForParticipantByToken($token, $this->userId); + } catch (RoomNotFoundException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + try { + if ($this->userId !== null) { + $sessionIds = $this->manager->getSessionIdsForUser($this->userId); + $newSessionId = $room->enterRoomAsUser($this->userId, $password, $this->session->get('spreed-password') === $room->getToken()); + + if (!empty($sessionIds)) { + $this->messages->deleteMessages($sessionIds); + } + } else { + $newSessionId = $room->enterRoomAsGuest($password, $this->session->get('spreed-password') === $room->getToken()); + } + } catch (InvalidPasswordException $e) { + return new DataResponse([], Http::STATUS_FORBIDDEN); + } + + $this->session->remove('spreed-password'); + $this->session->set('spreed-session', $newSessionId); + $room->ping($this->userId, $newSessionId, time()); + + return new DataResponse([ + 'sessionId' => $newSessionId, + ]); + } + + /** + * @PublicPage + * @UseSession + * + * @param string $token + * @return DataResponse + */ + public function exitRoom($token) { + $sessionId = $this->session->get('spreed-session'); + $this->session->remove('spreed-session'); + + try { + $room = $this->manager->getRoomForParticipantByToken($token, $this->userId); + + if ($this->userId === null) { + $participant = $room->getParticipantBySession($sessionId); + $room->removeParticipantBySession($participant); + } else { + $participant = $room->getParticipant($this->userId); + $room->disconnectUserFromAllRooms($participant->getUser()); + } + } catch (RoomNotFoundException $e) { + } catch (ParticipantNotFoundException $e) { + } + + return new DataResponse(); + } + + /** * @NoAdminRequired * * @param string $token diff --git a/lib/Controller/SignalingController.php b/lib/Controller/SignalingController.php index 0065495a8..0752aebd2 100644 --- a/lib/Controller/SignalingController.php +++ b/lib/Controller/SignalingController.php @@ -191,7 +191,7 @@ class SignalingController extends OCSController { foreach ($participants['users'] as $participant => $data) { if ($data['sessionId'] === '0') { - // Use left the room + // User is not active continue; } @@ -200,6 +200,7 @@ class SignalingController extends OCSController { 'roomId' => $room->getId(), 'lastPing' => $data['lastPing'], 'sessionId' => $data['sessionId'], + 'inCall' => $data['inCall'], ]; } @@ -209,6 +210,7 @@ class SignalingController extends OCSController { 'roomId' => $room->getId(), 'lastPing' => $data['lastPing'], 'sessionId' => $data['sessionId'], + 'inCall' => $data['inCall'], ]; } diff --git a/lib/Manager.php b/lib/Manager.php index 042911d05..99cc14ce7 100644 --- a/lib/Manager.php +++ b/lib/Manager.php @@ -79,7 +79,7 @@ class Manager { * @return Participant */ protected function createParticipantObject(Room $room, array $row) { - return new Participant($this->db, $room, $row['userId'], (int) $row['participantType'], (int) $row['lastPing'], $row['sessionId']); + return new Participant($this->db, $room, $row['userId'], (int) $row['participantType'], (int) $row['lastPing'], $row['sessionId'], (bool) $row['inCall']); } /** diff --git a/lib/Migration/Version2001Date20171031102049.php b/lib/Migration/Version2001Date20171031102049.php new file mode 100644 index 000000000..8cf456474 --- /dev/null +++ b/lib/Migration/Version2001Date20171031102049.php @@ -0,0 +1,51 @@ +<?php +namespace OCA\Spreed\Migration; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\DBAL\Types\Type; +use OCP\Migration\SimpleMigrationStep; +use OCP\Migration\IOutput; + +/** + * Auto-generated migration step: Please modify to your needs! + */ +class Version2001Date20171031102049 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `Schema` + * @param array $options + * @since 13.0.0 + */ + public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `Schema` + * @param array $options + * @return null|Schema + * @since 13.0.0 + */ + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { + /** @var Schema $schema */ + $schema = $schemaClosure(); + + + $table = $schema->getTable('talk_participants'); + $table->addColumn('inCall', Type::BOOLEAN, [ + 'default' => 0, + ]); + + return $schema; + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `Schema` + * @param array $options + * @since 13.0.0 + */ + public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { + } +} diff --git a/lib/Participant.php b/lib/Participant.php index 5b994d148..27a2f32a6 100644 --- a/lib/Participant.php +++ b/lib/Participant.php @@ -44,6 +44,8 @@ class Participant { protected $lastPing; /** @var string */ protected $sessionId; + /** @var bool */ + protected $inCall; /** * @param IDBConnection $db @@ -52,14 +54,16 @@ class Participant { * @param int $participantType * @param int $lastPing * @param string $sessionId + * @param bool $inCall */ - public function __construct(IDBConnection $db, Room $room, $user, $participantType, $lastPing, $sessionId) { + public function __construct(IDBConnection $db, Room $room, $user, $participantType, $lastPing, $sessionId, $inCall) { $this->db = $db; $this->room = $room; $this->user = $user; $this->participantType = $participantType; $this->lastPing = $lastPing; $this->sessionId = $sessionId; + $this->inCall = $inCall; } public function getUser() { @@ -77,4 +81,8 @@ class Participant { public function getSessi |