1
0
Fork 0

implement and use SubscriptionService

This commit is contained in:
Jonathan Treffler 2024-06-12 14:19:52 +02:00
parent a6d4368058
commit c9d4285af4
7 changed files with 150 additions and 25 deletions

25
lib/Controller/Errors.php Normal file
View file

@ -0,0 +1,25 @@
<?php
namespace OCA\DavPush\Controller;
use Closure;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCA\DavPush\Errors\NotFoundException;
trait Errors {
protected function handleNotFound(Closure $callback): JSONResponse {
try {
return new JSONResponse($callback());
} catch (NotFoundException $e) {
return $this->notFoundResponse($e);
}
}
private function notFoundResponse(NotFoundException $e) {
$response = ['error' => get_class($e), 'message' => $e->getMessage()];
return new JSONResponse($response, Http::STATUS_NOT_FOUND);
}
}

View file

@ -29,7 +29,7 @@ namespace OCA\DavPush\Dav;
use OCA\DavPush\Transport\TransportManager; use OCA\DavPush\Transport\TransportManager;
use OCA\DavPush\Db\Subscription; use OCA\DavPush\Db\Subscription;
use OCA\DavPush\Db\SubscriptionMapper; use OCA\DavPush\Service\SubscriptionService;
use OCP\IUserSession; use OCP\IUserSession;
use OCP\IURLGenerator; use OCP\IURLGenerator;
@ -60,7 +60,7 @@ class SubscriptionManagementPlugin extends ServerPlugin {
private IUserSession $userSession, private IUserSession $userSession,
private TransportManager $transportManager, private TransportManager $transportManager,
private IURLGenerator $URLGenerator, private IURLGenerator $URLGenerator,
private SubscriptionMapper $subscriptionMapper, private SubscriptionService $subscriptionService,
private $userId, private $userId,
) { ) {
} }
@ -100,7 +100,7 @@ class SubscriptionManagementPlugin extends ServerPlugin {
$subscriptionType = ""; $subscriptionType = "";
$subscriptionOptions = []; $subscriptionOptions = [];
$subscriptionExpires = False; $subscriptionExpires = 0;
foreach($parameters as $parameter) { foreach($parameters as $parameter) {
if($parameter["name"] == self::PUSH_SUBSCRIPTION && !$subscriptionParameterIncluded) { if($parameter["name"] == self::PUSH_SUBSCRIPTION && !$subscriptionParameterIncluded) {
@ -112,8 +112,8 @@ class SubscriptionManagementPlugin extends ServerPlugin {
} else { } else {
$errors[] = "only one subscription allowed"; $errors[] = "only one subscription allowed";
} }
} elseif($parameter["name"] == self::PUSH_EXPIRES && !$subscriptionExpires) { } elseif($parameter["name"] == self::PUSH_EXPIRES && $subscriptionExpires === 0) {
$subscriptionExpires = \DateTime::createFromFormat(self::IMF_FIXDATE_FORMAT, $parameter["value"]); $subscriptionExpires = \DateTime::createFromFormat(self::IMF_FIXDATE_FORMAT, $parameter["value"])->getTimestamp();
} }
} }
@ -148,18 +148,7 @@ class SubscriptionManagementPlugin extends ServerPlugin {
$response->setStatus($responseStatus); $response->setStatus($responseStatus);
// create subscription entry in db // create subscription entry in db
$subscription = new Subscription(); $subscription = $this->subscriptionService->create($this->userId, $node->getName(), $subscriptionType, $subscriptionExpires, $data);
$subscription->setUserId($this->userId);
$subscription->setCollectionName($node->getName());
$subscription->setTransport($subscriptionType);
$subscription->setCreationTimestamp(time());
if(!$subscriptionExpires) {
$subscription->setExpirationTimestamp(0);
} else {
$subscription->setExpirationTimestamp($subscriptionExpires->getTimestamp());
}
$subscription->setData(json_encode($data));
$subscription = $this->subscriptionMapper->insert($subscription);
// generate default unsubscribe link, unless transport requested a custom url // generate default unsubscribe link, unless transport requested a custom url
$unsubscribeLink = $unsubscribeLink ?? $this->URLGenerator->getAbsoluteURL("/apps/dav_push/subscriptions/" . $subscription->getId()); $unsubscribeLink = $unsubscribeLink ?? $this->URLGenerator->getAbsoluteURL("/apps/dav_push/subscriptions/" . $subscription->getId());

View file

@ -34,18 +34,31 @@ class SubscriptionMapper extends QBMapper {
} }
/** /**
* @param string $userId
* @param string $collectionName * @param string $collectionName
* @return Subscription[] * @return Subscription[]
*/ */
public function findAll(string $userId, string $collectionName): array { public function findAll(string $collectionName): array {
/* @var $qb IQueryBuilder */ /* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('*') $qb->select('*')
->from(self::TABLENAME) ->from(self::TABLENAME)
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))) ->where($qb->expr()->eq('collection_name', $qb->createNamedParameter($collectionName)));
->andWhere($qb->expr()->eq('collection_name', $qb->createNamedParameter($collectionName)));
return $this->findEntities($qb);
}
/**
* @param string $userId
* @return Subscription[]
*/
public function findAllByUser(string $userId): array {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from(self::TABLENAME)
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
return $this->findEntities($qb); return $this->findEntities($qb);
} }

View file

@ -0,0 +1,6 @@
<?php
namespace OCA\DavPush\Errors;
abstract class NotFoundException extends \Exception {
}

View file

@ -0,0 +1,6 @@
<?php
namespace OCA\DavPush\Errors;
class SubscriptionNotFound extends NotFoundException {
}

View file

@ -38,14 +38,14 @@ use OCA\DAV\Events\CardUpdatedEvent;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use OCA\DavPush\Db\SubscriptionMapper; use OCA\DavPush\Service\SubscriptionService;
use OCA\DavPush\Transport\TransportManager; use OCA\DavPush\Transport\TransportManager;
class CalendarListener implements IEventListener { class CalendarListener implements IEventListener {
public function __construct( public function __construct(
private LoggerInterface $logger, private LoggerInterface $logger,
private SubscriptionMapper $subscriptionMapper, private SubscriptionService $subscriptionService,
private TransportManager $transportManager, private TransportManager $transportManager,
private $userId, private $userId,
) {} ) {}
@ -57,12 +57,12 @@ class CalendarListener implements IEventListener {
} }
$collectionName = $event->getCalendarData()['uri']; $collectionName = $event->getCalendarData()['uri'];
$subscriptions = $this->subscriptionMapper->findAll($this->userId, $collectionName); $subscriptions = $this->subscriptionService->findAll($collectionName);
foreach($subscriptions as $subscription) { foreach($subscriptions as $subscription) {
$transport = $this->transportManager->getTransport($subscription->getTransport()); $transport = $this->transportManager->getTransport($subscription->getTransport());
try { try {
$transport->notify($this->userId, $collectionName, json_decode($subscription->getData(), True)); $transport->notify($subscription->getUserId(), $collectionName, json_decode($subscription->getData(), True));
} catch (Error $e) { } catch (Error $e) {
$this->logger->error("transport " . $subscription->getTransport() . " failed to deliver notification to subscription " . $subscription->getId()); $this->logger->error("transport " . $subscription->getTransport() . " failed to deliver notification to subscription " . $subscription->getId());
} }

View file

@ -0,0 +1,86 @@
<?php
namespace OCA\DavPush\Service;
use Exception;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCA\DavPush\Errors\SubscriptionNotFound;
use OCA\DavPush\Db\Subscription;
use OCA\DavPush\Db\SubscriptionMapper;
class SubscriptionService {
public function __construct(
private SubscriptionMapper $mapper
) {
}
public function findAll(string $collectionName): array {
return $this->mapper->findAll($collectionName);
}
public function findAllByUser(string $userId): array {
return $this->mapper->findAllByUser($userId);
}
private function handleException(Exception $e): void {
if ($e instanceof DoesNotExistException ||
$e instanceof MultipleObjectsReturnedException) {
throw new SubscriptionNotFound($e->getMessage());
} else {
throw $e;
}
}
public function find(string $userId, int $id) {
try {
return $this->mapper->find($userId, $id);
} catch (Exception $e) {
$this->handleException($e);
}
}
public function create(string $userId, string $collectionName, string $transport, int $expirationTimestamp, $data, ?int $creationTimestamp = null) {
$subscription = new Subscription();
$subscription->setUserId($userId);
$subscription->setCollectionName($collectionName);
$subscription->setTransport($transport);
$subscription->setCreationTimestamp($creationTimestamp ?? time());
$subscription->setExpirationTimestamp($expirationTimestamp);
$subscription->setData(json_encode($data));
$subscription = $this->mapper->insert($subscription);
return $subscription;
}
public function update(string $userId, int $id, ?int $expirationTimestamp, mixed $data) {
try {
$subscription = $this->mapper->find($userId, $id);
if (!is_null($expirationTimestamp)) {
$subscription->setExpirationTimestamp($expirationTimestamp);
}
if (!is_null($data)) {
$subscription->setData(json_encode($data));
}
return $this->mapper->update($subscription);
} catch (Exception $e) {
$this->handleException($e);
}
}
public function delete(string $userId, int $id) {
try {
$subscription = $this->mapper->find($userId, $id);
$this->mapper->delete($subscription);
return $subscription;
} catch (Exception $e) {
$this->handleException($e);
}
}
}