Skip to content

Commit

Permalink
Implement dismiss notification
Browse files Browse the repository at this point in the history
Signed-off-by: Vitor Mattos <vitor@php.rio>
  • Loading branch information
vitormattos committed Mar 9, 2024
1 parent 0dab7a7 commit 4650672
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 17 deletions.
1 change: 1 addition & 0 deletions appinfo/routes/routesNotifyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
'ocs' => [
['name' => 'notify#signer', 'url' => '/api/{apiVersion}/notify/signer', 'verb' => 'POST', 'requirements' => $requirements],
['name' => 'notify#signers', 'url' => '/api/{apiVersion}/notify/signers', 'verb' => 'POST', 'requirements' => $requirements],
['name' => 'notify#notificationDismiss', 'url' => '/api/{apiVersion}/notif/notification', 'verb' => 'DELETE', 'requirements' => $requirements],
],
];
2 changes: 1 addition & 1 deletion lib/Activity/FileToSign.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,6 @@ public function isDefaultEnabledMail() {
* {@inheritdoc}
*/
public function isDefaultEnabledNotification(): bool {
return $this->isDefaultEnabledMail() && $this->canChangeMail();
return false;
}
}
6 changes: 5 additions & 1 deletion lib/Activity/Listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ protected function generateNewSignNotificationActivity(
->setApp(Application::APP_ID)
->setType('file_to_sign')
->setAuthor($actorId)
->setObject('sign', $signRequest->getId(), 'signRequest')
->setObject('signRequest', $signRequest->getId())
->setTimestamp($this->timeFactory->getTime())
->setAffectedUser($identifyMethod->getEntity()->getIdentifierValue());
if ($isNew) {
Expand All @@ -107,6 +107,10 @@ protected function generateNewSignNotificationActivity(
$identifyMethod->getEntity()->getIdentifierValue(),
$signRequest->getDisplayName(),
),
'signRequest' => [
'type' => 'sign-request',
'id' => $signRequest->getId(),
],
]);
$this->activityManager->publish($event);
} catch (\InvalidArgumentException $e) {
Expand Down
15 changes: 15 additions & 0 deletions lib/Activity/Provider/SignRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\L10N\IFactory;
use OCP\RichObjectStrings\Definitions;

class SignRequest implements IProvider {
public function __construct(
protected IFactory $languageFactory,
protected IURLGenerator $url,
protected Definitions $definitions,
protected IManager $activityManager,
protected IUserManager $userManager,
) {
Expand All @@ -46,6 +48,19 @@ public function parse($language, IEvent $event, ?IEvent $previousEvent = null):
throw new \InvalidArgumentException('Wrong app');
}

$this->definitions->definitions['sign-request'] = [
'author' => 'LibreSign',
'since' => '28.0.0',
'parameters' => [
'id' => [
'since' => '28.0.0',
'required' => true,
'description' => 'The id of SignRequest object',
'example' => '12345',
]
]
];

if ($this->activityManager->getRequirePNG()) {
$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath(Application::APP_ID, 'app-dark.png')));
} else {
Expand Down
15 changes: 14 additions & 1 deletion lib/Controller/NotifyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@
use OCP\AppFramework\Http\JSONResponse;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IUserSession;

class NotifyController extends Controller {
public function __construct(
IRequest $request,
private IL10N $l10n,
private NotifyService $notifyService
private NotifyService $notifyService,
private IUserSession $userSession,
) {
parent::__construct(Application::APP_ID, $request);
}
Expand Down Expand Up @@ -91,4 +93,15 @@ public function signer($fileId, $signRequestId): JSONResponse {
'message' => $this->l10n->t('Notification sent with success.')
], Http::STATUS_OK);
}

#[NoAdminRequired]
public function notificationDismiss(int $signRequestId, int $timestamp): JSONResponse {

$this->notifyService->notificationDismiss(
$signRequestId,
$this->userSession->getUser(),
$timestamp
);
return new JSONResponse();
}
}
39 changes: 32 additions & 7 deletions lib/Listener/NotificationListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserSession;
use OCP\Notification\IManager;

/**
Expand All @@ -41,6 +43,7 @@
class NotificationListener implements IEventListener {
public function __construct(
private IManager $notificationManager,
protected IUserSession $userSession,
private ITimeFactory $timeFactory,
protected IURLGenerator $url,
) {
Expand All @@ -63,21 +66,32 @@ private function sendNewSignNotification(
IIdentifyMethod $identifyMethod,
bool $isNew
): void {
$actor = $this->userSession->getUser();
if (!$actor instanceof IUser) {
return;
}
$notification = $this->notificationManager->createNotification();
$notification
->setApp(AppInfoApplication::APP_ID)
->setObject('sign', 'document')
->setObject('signRequest', (string) $signRequest->getId())
->setDateTime((new \DateTime())->setTimestamp($this->timeFactory->now()->getTimestamp()))
->setUser($identifyMethod->getEntity()->getIdentifierValue());
if ($isNew) {
$notification->setSubject('new_sign_request', [
'file' => $this->getFileParameter($signRequest, $libreSignFile),
]);
$subject = 'new_sign_request';
} else {
$notification->setSubject('update_sign_request', [
'file' => $this->getFileParameter($signRequest, $libreSignFile),
]);
$subject = 'update_sign_request';
}
$notification->setSubject($subject, [
'from' => $this->getUserParameter(
$actor->getUID(),
$actor->getDisplayName(),
),
'file' => $this->getFileParameter($signRequest, $libreSignFile),
'signRequest' => [
'type' => 'sign-request',
'id' => $signRequest->getId(),
],
]);
$this->notificationManager->notify($notification);
}

Expand All @@ -90,4 +104,15 @@ protected function getFileParameter(SignRequest $signRequest, FileEntity $libreS
'link' => $this->url->linkToRouteAbsolute('libresign.page.sign', ['uuid' => $signRequest->getUuid()]),
];
}

protected function getUserParameter(
string $userId,
$displayName,
): array {
return [
'type' => 'user',
'id' => $userId,
'name' => $displayName,
];
}
}
45 changes: 42 additions & 3 deletions lib/Notification/Notifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@
use OCP\Notification\IAction;
use OCP\Notification\INotification;
use OCP\Notification\INotifier;
use OCP\RichObjectStrings\Definitions;

class Notifier implements INotifier {
public function __construct(
private IFactory $factory,
private IURLGenerator $urlGenerator,
private IURLGenerator $url,
private Definitions $definitions,
private FileMapper $fileMapper,
private SignRequestMapper $signRequestMapper
) {
Expand All @@ -56,6 +58,19 @@ public function prepare(INotification $notification, string $languageCode): INot
throw new \InvalidArgumentException();
}

$this->definitions->definitions['sign-request'] = [
'author' => 'LibreSign',
'since' => '28.0.0',
'parameters' => [
'id' => [
'since' => '28.0.0',
'required' => true,
'description' => 'The id of SignRequest object',
'example' => '12345',
]
]
];

$l = $this->factory->get(Application::APP_ID, $languageCode);

switch ($notification->getSubject()) {
Expand All @@ -75,9 +90,19 @@ private function parseSignRequest(
): INotification {
$parameters = $notification->getSubjectParameters();
$notification
->setIcon($this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath(Application::APP_ID, 'app-dark.svg')))
->setIcon($this->url->getAbsoluteURL($this->url->imagePath(Application::APP_ID, 'app-dark.svg')))
->setLink($parameters['file']['link']);
$notification->setParsedSubject($l->t('There is a file for you to sign'));
$subject = $l->t('{from} invited you to sign {file}');
$notification->setParsedSubject(
str_replace(
['{from}', '{file}'],
[
$parameters['from']['name'],
$parameters['file']['name'],
],
$subject
))
->setRichSubject($subject, $parameters);
if ($update) {
$notification->setParsedMessage($l->t('Changes have been made in a file that you have to sign.'));
}
Expand All @@ -90,6 +115,20 @@ private function parseSignRequest(
IAction::TYPE_WEB
);
$notification->addParsedAction($signAction);
$dismissAction = $notification->createAction()
->setParsedLabel($l->t('Dismiss notification'))
->setLink(
$this->url->linkToOCSRouteAbsolute(
'libresign.notify.notificationDismiss',
[
'apiVersion' => 'v1',
'timestamp' => $notification->getDateTime()->getTimestamp(),
'signRequestId' => $parameters['signRequest']['id'],
],
),
IAction::TYPE_DELETE
);
$notification->addParsedAction($dismissAction);
return $notification;
}
}
18 changes: 17 additions & 1 deletion lib/Service/NotifyService.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,24 @@

namespace OCA\Libresign\Service;

use OCA\Libresign\AppInfo\Application;
use OCA\Libresign\Db\SignRequest;
use OCA\Libresign\Db\SignRequestMapper;
use OCA\Libresign\Helper\ValidateHelper;
use OCA\Libresign\Service\IdentifyMethod\IIdentifyMethod;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IUser;
use OCP\IUserSession;
use OCP\Notification\IManager;

class NotifyService {
public function __construct(
private ValidateHelper $validateHelper,
private IUserSession $userSession,
private SignRequestMapper $signRequestMapper,
private IdentifyMethodService $identifyMethodService
private IdentifyMethodService $identifyMethodService,
private ITimeFactory $timeFactory,
private IManager $notificationManager,
) {
}

Expand Down Expand Up @@ -63,6 +69,16 @@ public function signers(int $nodeId, array $signers): void {
}
}

public function notificationDismiss(int $signRequestId, IUser $user, int $timestamp): void {
$notification = $this->notificationManager->createNotification();
$notification->setApp(Application::APP_ID)
->setObject('signRequest', (string) $signRequestId)
->setDateTime($this->timeFactory->getDateTime('@' . $timestamp))
->setUser($user->getUID())
->setSubject('new_sign_request');
$this->notificationManager->markProcessed($notification);
}

private function notify(SignRequest $signRequest, array $signers = []): void {
$identifyMethods = $this->identifyMethodService->getIdentifyMethodsFromSignRequestId($signRequest->getId());
foreach ($identifyMethods as $methodName => $instances) {
Expand Down
8 changes: 5 additions & 3 deletions tests/integration/features/sign/request.feature
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,11 @@ Feature: request-signature
| users | [{"identify":{"account":"signer1"}}] |
| name | document |
Then the response should have a status code 200
And user signer1 has the following notifications
| app | object_type | object_id | subject |
| libresign | sign | document | There is a file for you to sign |
When as user "signer1"
And sending "get" to ocs "/apps/notifications/api/v2/notifications"
Then the response should be a JSON array with the following mandatory values
| key | value |
| ocs | (jq).data\|.[].subject == "admin invited you to sign document"|
And sending "get" to ocs "/apps/activity/api/v2/activity/libresign?since=0"
Then the response should be a JSON array with the following mandatory values
| key | value |
Expand Down

0 comments on commit 4650672

Please sign in to comment.