1
0
Fork 0

conform to spec by updating existing subscription when registering with equivalent options twice instead of creating new subscription

This commit is contained in:
Jonathan Treffler 2024-07-24 13:52:09 +02:00
parent f0f8440eb7
commit 3d5b2c191a
4 changed files with 62 additions and 24 deletions

View file

@ -127,19 +127,62 @@ class SubscriptionManagementPlugin extends ServerPlugin {
if(!is_null($transport)) { if(!is_null($transport)) {
[ [
'success' => $registerSuccess, 'success' => $validateSuccess,
'error' => $registerError, 'errors' => $validateErrors,
'responseStatus' => $responseStatus, ] = $transport->validateOptions($subscriptionOptions);
'response' => $responseContent,
'unsubscribeLink' => $unsubscribeLink,
'data' => $data
] = $transport->registerSubscription($subscriptionOptions);
$responseStatus = $responseStatus ?? Http::STATUS_CREATED; if(!$validateSuccess) {
$data = $data ?? False; if(isset($validateErrors) && !empty($validateErrors)) {
$errors = array_merge($errors, $validateErrors);
} else {
$errors[] = "options validation error";
}
} else {
$existingSubscriptionId = $transport->getSubscriptionIdFromOptions($subscriptionOptions);
if(!$registerSuccess) { $user = $this->userSession->getUser();
$errors[] = $registerError;
if(!is_int($existingSubscriptionId)) {
// create new subscription entry in db
$subscription = $this->subscriptionService->create($user->getUID(), $node->getName(), $subscriptionType, $subscriptionExpires);
[
'success' => $registerSuccess,
'errors' => $registerErrors,
'responseStatus' => $responseStatus,
'response' => $responseContent,
'unsubscribeLink' => $unsubscribeLink,
] = $transport->registerSubscription($subscription->getId(), $subscriptionOptions);
$responseStatus = $responseStatus ?? Http::STATUS_CREATED;
if(!$registerSuccess) {
if(isset($registerErrors) && !empty($registerErrors)) {
$errors = array_merge($errors, $registerErrors);
} else {
$errors[] = "registration error";
}
}
} else {
$subscription = $this->subscriptionService->find($user->getUID(), $existingSubscriptionId);
[
'success' => $updateSuccess,
'errors' => $updateErrors,
] = $transport->updateSubscription($subscription->getId(), $subscriptionOptions);
if(!$updateSuccess) {
if(isset($updateErrors) && !empty($updateErrors)) {
$errors = array_merge($errors, $updateErrors);
} else {
$errors[] = "subscription update error";
}
} else {
$subscription = $this->subscriptionService->update($user->getUID(), $subscription->getId(), $subscriptionExpires);
$responseStatus = Http::STATUS_CREATED;
}
}
} }
} else { } else {
$errors[] = $subscriptionType . " transport does not exist"; $errors[] = $subscriptionType . " transport does not exist";
@ -148,10 +191,6 @@ class SubscriptionManagementPlugin extends ServerPlugin {
if(sizeof($errors) == 0) { if(sizeof($errors) == 0) {
$response->setStatus($responseStatus); $response->setStatus($responseStatus);
// create subscription entry in db
$user = $this->userSession->getUser();
$subscription = $this->subscriptionService->create($user->getUID(), $node->getName(), $subscriptionType, $subscriptionExpires, $data);
// 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());
$response->setHeader("Location", $unsubscribeLink); $response->setHeader("Location", $unsubscribeLink);

View file

@ -21,7 +21,7 @@ class WebPushSubscriptionMapper extends QBMapper {
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
* @throws DoesNotExistException * @throws DoesNotExistException
*/ */
public function findBySubscriptionId(int $subscriptionId): Subscription { public function findBySubscriptionId(int $subscriptionId): WebPushSubscription {
/* @var $qb IQueryBuilder */ /* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('*') $qb->select('*')
@ -37,7 +37,7 @@ class WebPushSubscriptionMapper extends QBMapper {
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
* @throws DoesNotExistException * @throws DoesNotExistException
*/ */
public function findByPushResource(string $pushResource): Subscription { public function findByPushResource(string $pushResource): WebPushSubscription {
/* @var $qb IQueryBuilder */ /* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('*') $qb->select('*')

View file

@ -57,11 +57,11 @@ class WebPushTransport extends Transport {
if(isset($pushResource) && $pushResource !== '') { if(isset($pushResource) && $pushResource !== '') {
return [ return [
'valid' => True, 'success' => True,
]; ];
} else { } else {
return [ return [
'valid' => False, 'success' => False,
'errors' => ["push resource not provided"] 'errors' => ["push resource not provided"]
]; ];
} }
@ -104,5 +104,8 @@ class WebPushTransport extends Transport {
public function updateSubscription($subsciptionId, $options) { public function updateSubscription($subsciptionId, $options) {
// there are no options which can be edited -> NOOP // there are no options which can be edited -> NOOP
return [
'success' => True,
];
} }
} }

View file

@ -55,7 +55,7 @@ class SubscriptionService {
return $subscription; return $subscription;
} }
public function update(string $userId, int $id, ?int $expirationTimestamp, mixed $data) { public function update(string $userId, int $id, ?int $expirationTimestamp) {
try { try {
$subscription = $this->mapper->find($userId, $id); $subscription = $this->mapper->find($userId, $id);
@ -63,10 +63,6 @@ class SubscriptionService {
$subscription->setExpirationTimestamp($expirationTimestamp); $subscription->setExpirationTimestamp($expirationTimestamp);
} }
if (!is_null($data)) {
$subscription->setData(json_encode($data));
}
return $this->mapper->update($subscription); return $this->mapper->update($subscription);
} catch (Exception $e) { } catch (Exception $e) {
$this->handleException($e); $this->handleException($e);