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
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2021-01-27 16:46:34 +0300
committerJoas Schilling <coding@schilljs.com>2021-02-02 18:22:17 +0300
commit4d27b096c5e151fbf2c1d244c008e634ca33ada4 (patch)
tree900afc02c1b6123215458baa56cd24287f6552a0
parent54fa5b2ad936b974405165911d40c66a68f1931e (diff)
Allow to share RichObjects to chats
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r--appinfo/routes.php9
-rw-r--r--lib/Chat/ChatManager.php5
-rw-r--r--lib/Chat/Parser/SystemMessage.php4
-rw-r--r--lib/Controller/ChatController.php146
4 files changed, 129 insertions, 35 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php
index db32cbd72..87e15f034 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -181,6 +181,15 @@ return [
'token' => '^[a-z0-9]{4,30}$',
],
],
+ [
+ 'name' => 'Chat#shareObjectToChat',
+ 'url' => '/api/{apiVersion}/chat/{token}/share',
+ 'verb' => 'POST',
+ 'requirements' => [
+ 'apiVersion' => 'v1',
+ 'token' => '^[a-z0-9]{4,30}$',
+ ],
+ ],
/**
* Conversation (Room)
diff --git a/lib/Chat/ChatManager.php b/lib/Chat/ChatManager.php
index 4202a3a46..2209dfa72 100644
--- a/lib/Chat/ChatManager.php
+++ b/lib/Chat/ChatManager.php
@@ -123,7 +123,10 @@ class ChatManager {
$comment->setMessage($message, self::MAX_CHAT_LENGTH);
$comment->setCreationDateTime($creationDateTime);
if ($referenceId !== null) {
- $comment->setReferenceId($referenceId);
+ $referenceId = trim(substr($referenceId, 0, 40));
+ if ($referenceId !== '') {
+ $comment->setReferenceId($referenceId);
+ }
}
if ($parentId !== null) {
$comment->setParentId((string) $parentId);
diff --git a/lib/Chat/Parser/SystemMessage.php b/lib/Chat/Parser/SystemMessage.php
index ab1534480..563351799 100644
--- a/lib/Chat/Parser/SystemMessage.php
+++ b/lib/Chat/Parser/SystemMessage.php
@@ -329,6 +329,10 @@ class SystemMessage {
$parsedMessage = $this->l->t('You shared a file which is no longer available');
}
}
+ } elseif ($message === 'object_shared') {
+ $parsedParameters['object'] = $parameters['metaData'];
+ $parsedMessage = '{object}';
+ $chatMessage->setMessageType('comment');
} elseif ($message === 'matterbridge_config_added') {
$parsedMessage = $this->l->t('{actor} set up Matterbridge to synchronize this conversation with other chats.');
if ($currentUserIsActor) {
diff --git a/lib/Controller/ChatController.php b/lib/Controller/ChatController.php
index 4c5706086..49257cbca 100644
--- a/lib/Controller/ChatController.php
+++ b/lib/Controller/ChatController.php
@@ -51,6 +51,8 @@ use OCP\EventDispatcher\IEventDispatcher;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IUserManager;
+use OCP\RichObjectStrings\InvalidObjectExeption;
+use OCP\RichObjectStrings\IValidator;
use OCP\User\Events\UserLiveStatusEvent;
use OCP\UserStatus\IManager as IUserStatusManager;
use OCP\UserStatus\IUserStatus;
@@ -108,6 +110,9 @@ class ChatController extends AEnvironmentAwareController {
/** @var IEventDispatcher */
protected $eventDispatcher;
+ /** @var IValidator */
+ protected $richObjectValidator;
+
/** @var IL10N */
private $l;
@@ -129,6 +134,7 @@ class ChatController extends AEnvironmentAwareController {
ISearchResult $searchResult,
ITimeFactory $timeFactory,
IEventDispatcher $eventDispatcher,
+ IValidator $richObjectValidator,
IL10N $l) {
parent::__construct($appName, $request);
@@ -148,9 +154,58 @@ class ChatController extends AEnvironmentAwareController {
$this->searchResult = $searchResult;
$this->timeFactory = $timeFactory;
$this->eventDispatcher = $eventDispatcher;
+ $this->richObjectValidator = $richObjectValidator;
$this->l = $l;
}
+ protected function getActorInfo(string $actorDisplayName = ''): array {
+ if ($this->userId === null) {
+ $actorType = Attendee::ACTOR_GUESTS;
+ $sessionId = $this->session->getSessionForRoom($this->room->getToken());
+ // The character limit for actorId is 64, but the spreed-session is
+ // 256 characters long, so it has to be hashed to get an ID that
+ // fits (except if there is no session, as the actorId should be
+ // empty in that case but sha1('') would generate a hash too
+ // instead of returning an empty string).
+ $actorId = $sessionId ? sha1($sessionId) : 'failed-to-get-session';
+
+ if ($sessionId && $actorDisplayName) {
+ $this->guestManager->updateName($this->room, $this->participant, $actorDisplayName);
+ }
+ } else {
+ $actorType = Attendee::ACTOR_USERS;
+ $actorId = $this->userId;
+ }
+
+ return [$actorType, $actorId];
+ }
+
+ public function parseCommentToResponse(IComment $comment, Message $parentMessage = null): DataResponse {
+ $chatMessage = $this->messageParser->createMessage($this->room, $this->participant, $comment, $this->l);
+ $this->messageParser->parseMessage($chatMessage);
+
+ if (!$chatMessage->getVisibility()) {
+ $response = new DataResponse([], Http::STATUS_CREATED);
+ if ($this->participant->getAttendee()->getReadPrivacy() === Participant::PRIVACY_PUBLIC) {
+ $response->addHeader('X-Chat-Last-Common-Read', $this->chatManager->getLastCommonReadMessage($this->room));
+ }
+ return $response;
+ }
+
+ $this->participantService->updateLastReadMessage($this->participant, (int) $comment->getId());
+
+ $data = $chatMessage->toArray();
+ if ($parentMessage instanceof Message) {
+ $data['parent'] = $parentMessage->toArray();
+ }
+
+ $response = new DataResponse($data, Http::STATUS_CREATED);
+ if ($this->participant->getAttendee()->getReadPrivacy() === Participant::PRIVACY_PUBLIC) {
+ $response->addHeader('X-Chat-Last-Common-Read', $this->chatManager->getLastCommonReadMessage($this->room));
+ }
+ return $response;
+ }
+
/**
* @PublicPage
* @RequireParticipant
@@ -171,24 +226,7 @@ class ChatController extends AEnvironmentAwareController {
* found".
*/
public function sendMessage(string $message, string $actorDisplayName = '', string $referenceId = '', int $replyTo = 0): DataResponse {
- if ($this->userId === null) {
- $actorType = Attendee::ACTOR_GUESTS;
- $sessionId = $this->session->getSessionForRoom($this->room->getToken());
- // The character limit for actorId is 64, but the spreed-session is
- // 256 characters long, so it has to be hashed to get an ID that
- // fits (except if there is no session, as the actorId should be
- // empty in that case but sha1('') would generate a hash too
- // instead of returning an empty string).
- $actorId = $sessionId ? sha1($sessionId) : 'failed-to-get-session';
-
- if ($sessionId && $actorDisplayName) {
- $this->guestManager->updateName($this->room, $this->participant, $actorDisplayName);
- }
- } else {
- $actorType = Attendee::ACTOR_USERS;
- $actorId = $this->userId;
- }
-
+ [$actorType, $actorId] = $this->getActorInfo($actorDisplayName);
if (!$actorId) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
@@ -220,29 +258,69 @@ class ChatController extends AEnvironmentAwareController {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
- $chatMessage = $this->messageParser->createMessage($this->room, $this->participant, $comment, $this->l);
- $this->messageParser->parseMessage($chatMessage);
+ return $this->parseCommentToResponse($comment, $parentMessage);
+ }
- if (!$chatMessage->getVisibility()) {
- $response = new DataResponse([], Http::STATUS_CREATED);
- if ($this->participant->getAttendee()->getReadPrivacy() === Participant::PRIVACY_PUBLIC) {
- $response->addHeader('X-Chat-Last-Common-Read', $this->chatManager->getLastCommonReadMessage($this->room));
- }
- return $response;
+ /**
+ * @PublicPage
+ * @RequireParticipant
+ * @RequireReadWriteConversation
+ * @RequireModeratorOrNoLobby
+ *
+ * Sends a rich-object to the given room.
+ *
+ * The author and timestamp are automatically set to the current user/guest
+ * and time.
+ *
+ * @param string $objectType
+ * @param string $objectId
+ * @param string $metaData
+ * @param string $actorDisplayName
+ * @param string $referenceId
+ * @return DataResponse the status code is "201 Created" if successful, and
+ * "404 Not found" if the room or session for a guest user was not
+ * found".
+ */
+ public function shareObjectToChat(string $objectType, string $objectId, string $metaData = '', string $actorDisplayName = '', string $referenceId = ''): DataResponse {
+ [$actorType, $actorId] = $this->getActorInfo($actorDisplayName);
+ if (!$actorId) {
+ return new DataResponse([], Http::STATUS_NOT_FOUND);
}
- $this->participantService->updateLastReadMessage($this->participant, (int) $comment->getId());
+ $data = $metaData !== '' ? json_decode($metaData, true) : [];
+ if (!is_array($data)) {
+ $data = [];
+ }
+ $data['type'] = $objectType;
+ $data['id'] = $objectId;
- $data = $chatMessage->toArray();
- if ($parentMessage instanceof Message) {
- $data['parent'] = $parentMessage->toArray();
+ try {
+ $this->richObjectValidator->validate('{object}', ['object' => $data]);
+ } catch (InvalidObjectExeption $e) {
+ return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
- $response = new DataResponse($data, Http::STATUS_CREATED);
- if ($this->participant->getAttendee()->getReadPrivacy() === Participant::PRIVACY_PUBLIC) {
- $response->addHeader('X-Chat-Last-Common-Read', $this->chatManager->getLastCommonReadMessage($this->room));
+ $this->participantService->ensureOneToOneRoomIsFilled($this->room);
+ $creationDateTime = $this->timeFactory->getDateTime('now', new \DateTimeZone('UTC'));
+
+ $message = json_encode([
+ 'message' => 'object_shared',
+ 'parameters' => [
+ 'objectType' => $objectType,
+ 'objectId' => $objectId,
+ 'metaData' => $data,
+ ],
+ ]);
+
+ try {
+ $comment = $this->chatManager->addSystemMessage($this->room, $actorType, $actorId, $message, $creationDateTime, true, $referenceId);
+ } catch (MessageTooLongException $e) {
+ return new DataResponse([], Http::STATUS_REQUEST_ENTITY_TOO_LARGE);
+ } catch (\Exception $e) {
+ return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
- return $response;
+
+ return $this->parseCommentToResponse($comment);
}
/**