Skip to content

Commit

Permalink
Merge pull request #2748 from nextcloud/feature/mention-users
Browse files Browse the repository at this point in the history
  • Loading branch information
juliusknorr authored Aug 25, 2022
2 parents 63a3620 + c56493a commit 242de46
Show file tree
Hide file tree
Showing 50 changed files with 1,250 additions and 40 deletions.
3 changes: 3 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
['name' => 'Session#sync', 'url' => '/session/sync', 'verb' => 'POST'],
['name' => 'Session#push', 'url' => '/session/push', 'verb' => 'POST'],
['name' => 'Session#close', 'url' => '/session/close', 'verb' => 'POST'],
['name' => 'Session#mention', 'url' => '/session/mention', 'verb' => 'PUT'],

['name' => 'PublicSession#create', 'url' => '/public/session/create', 'verb' => 'PUT'],
['name' => 'PublicSession#updateSession', 'url' => '/public/session', 'verb' => 'POST'],
Expand All @@ -46,6 +47,8 @@
['name' => 'PublicSession#close', 'url' => '/public/session/close', 'verb' => 'POST'],

['name' => 'Settings#updateConfig', 'url' => '/settings', 'verb' => 'POST'],

['name' => 'UserApi#index', 'url' => '/api/v1/users', 'verb' => 'POST'],
],
'ocs' => [
['name' => 'Workspace#folder', 'url' => '/workspace', 'verb' => 'GET'],
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions css/style.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@use 'sass:math';

:root {
--text-editor-max-width: 670px
}
Expand Down Expand Up @@ -99,3 +101,4 @@ li.ProseMirror-selectednode:after {
.fadeInLeft {
animation-name: fadeInLeft;
}

4 changes: 2 additions & 2 deletions js/editor-rich.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/editor-rich.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/editor.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/editor.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/files-modal.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion js/files-modal.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions js/text-files.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/text-files.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/text-public.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/text-public.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/text-text.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/text-text.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/text-viewer.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/text-viewer.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/vendors.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions js/vendors.js.LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@

/*! For license information please see NcModal.js.LICENSE.txt */

/*! For license information please see NcUserBubble.js.LICENSE.txt */

/*! For license information please see Tooltip.js.LICENSE.txt */

/*! For license information please see emoji.js.LICENSE.txt */
Expand Down
2 changes: 1 addition & 1 deletion js/vendors.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use OCA\Text\Listeners\FilesSharingLoadAdditionalScriptsListener;
use OCA\Text\Listeners\LoadViewerListener;
use OCA\Text\Listeners\RegisterDirectEditorEventListener;
use OCA\Text\Notification\Notifier;
use OCA\Text\Service\ConfigService;
use OCA\Viewer\Event\LoadViewer;
use OCP\AppFramework\App;
Expand Down Expand Up @@ -64,6 +65,7 @@ public function register(IRegistrationContext $context): void {
$context->registerEventListener(NodeCopiedEvent::class, NodeCopiedListener::class);
$context->registerEventListener(BeforeNodeRenamedEvent::class, BeforeNodeRenamedListener::class);
$context->registerEventListener(BeforeNodeDeletedEvent::class, BeforeNodeDeletedListener::class);
$context->registerNotifierService(Notifier::class);
}

public function boot(IBootContext $context): void {
Expand Down
27 changes: 26 additions & 1 deletion lib/Controller/SessionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,23 @@
namespace OCA\Text\Controller;

use OCA\Text\Service\ApiService;
use OCA\Text\Service\NotificationService;
use OCA\Text\Service\SessionService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\Response;
use OCP\IRequest;

class SessionController extends Controller {
private ApiService $apiService;
private SessionService $sessionService;
private NotificationService $notificationService;

public function __construct(string $appName, IRequest $request, ApiService $apiService) {
public function __construct(string $appName, IRequest $request, ApiService $apiService, SessionService $sessionService, NotificationService $notificationService) {
parent::__construct($appName, $request);
$this->apiService = $apiService;
$this->sessionService = $sessionService;
$this->notificationService = $notificationService;
}

/**
Expand Down Expand Up @@ -77,4 +83,23 @@ public function push(int $documentId, int $sessionId, string $sessionToken, int
public function sync(int $documentId, int $sessionId, string $sessionToken, int $version = 0, string $autosaveContent = null, bool $force = false, bool $manualSave = false): DataResponse {
return $this->apiService->sync($documentId, $sessionId, $sessionToken, $version, $autosaveContent, $force, $manualSave);
}

/**
* @NoAdminRequired
* @PublicPage
* @UserRateThrottle(limit=5, period=120)
*/
public function mention(int $documentId, int $sessionId, string $sessionToken, string $mention): DataResponse {
if (!$this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) {
return new DataResponse([], 403);
}

$currentSession = $this->sessionService->getSession($documentId, $sessionId, $sessionToken);

if ($currentSession->getUserId() === null && !$this->sessionService->isUserInDocument($documentId, $mention)) {
return new DataResponse([], 403);
}

return new DataResponse($this->notificationService->mention($documentId, $mention));
}
}
69 changes: 69 additions & 0 deletions lib/Controller/UserApiController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace OCA\Text\Controller;

use OCA\Text\Service\SessionService;
use \OCP\AppFramework\ApiController;
use OCP\AppFramework\Http\DataResponse;
use OCP\Collaboration\Collaborators\ISearch;
use \OCP\IRequest;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Share\IShare;

class UserApiController extends ApiController {
private ISearch $collaboratorSearch;
private IUserSession $userSession;
private IUserManager $userManager;
private SessionService $sessionService;

public function __construct($appName, IRequest $request, SessionService $sessionService, ISearch $ISearch, IUserManager $userManager, IUserSession $userSession) {
parent::__construct($appName, $request);

$this->sessionService = $sessionService;
$this->collaboratorSearch = $ISearch;
$this->userSession = $userSession;
$this->userManager = $userManager;
$this->sessionService = $sessionService;
}

/**
* @NoAdminRequired
* @PublicPage
*/
public function index(int $documentId, int $sessionId, string $sessionToken, string $filter, int $limit = 5): DataResponse {
if (!$this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) {
return new DataResponse([], 403);
}

$sessions = $this->sessionService->getAllSessions($documentId);

$users = [];

// Add joined users to the autocomplete list
foreach ($sessions as $session) {
$sessionUserId = $session['userId'];
if ($sessionUserId !== null && !isset($users[$sessionUserId])) {
$users[$sessionUserId] = $this->userManager->getDisplayName($sessionUserId);
}
}

$currentSession = $this->sessionService->getSession($documentId, $sessionId, $sessionToken);
if ($currentSession->getUserId() !== null) {
// Add other users to the autocomplete list
[$result] = $this->collaboratorSearch->search($filter, [IShare::TYPE_USER], false, $limit, 0);

foreach ($result['users'] as ['label' => $label, 'value' => $value]) {
if (isset($value['shareWith'])) {
$id = $value['shareWith'];
$users[$id] = $label;
}
}

$user = $this->userSession->getUser();
$users[$user->getUID()] = $user->getDisplayName();
}

return new DataResponse($users);
}
}
18 changes: 18 additions & 0 deletions lib/Db/SessionMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,22 @@ public function deleteByDocumentId($documentId) {
->where($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId)));
return $qb->execute();
}

public function isUserInDocument($documentId, $userId): bool {
$qb = $this->db->getQueryBuilder();
$result = $qb->select('*')
->from($this->getTableName())
->where($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId)))
->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)))
->setMaxResults(1)
->executeQuery();

$data = $result->fetch();
$result->closeCursor();
if ($data === false) {
return false;
}

return true;
}
}
Loading

0 comments on commit 242de46

Please sign in to comment.