Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/polls.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené Gieling <github@dartcafe.de>2022-10-24 16:27:30 +0300
committerGitHub <noreply@github.com>2022-10-24 16:27:30 +0300
commit58f455473591bff6a9ee6fc8c1e46ecf23106f05 (patch)
tree111d9c250981adfa5939c624a1dba11c4c6c12f9
parent36101e5795bdef3a1eee3d00ccd6febea9a8704c (diff)
Change handling of objects which refer to deleted shares (#2640)
* add fake share for delete users and hash user id * fix #2636
-rw-r--r--lib/Db/Comment.php44
-rw-r--r--lib/Db/EntityWithUser.php86
-rw-r--r--lib/Db/IEntityWithUser.php46
-rw-r--r--lib/Db/Option.php53
-rw-r--r--lib/Db/Poll.php31
-rw-r--r--lib/Db/Share.php8
-rw-r--r--lib/Db/ShareMapper.php41
-rw-r--r--lib/Db/Vote.php41
-rw-r--r--lib/Exceptions/NotFoundException.php5
-rw-r--r--lib/Exceptions/ShareNotFoundException.php32
-rw-r--r--lib/Model/Acl.php3
-rw-r--r--lib/Model/Mail/NotificationMail.php2
-rw-r--r--lib/Provider/ActivityProvider.php8
-rw-r--r--lib/Service/AnonymizeService.php19
-rw-r--r--lib/Service/PollService.php6
-rw-r--r--lib/Service/ShareService.php30
-rw-r--r--lib/Service/UserService.php10
17 files changed, 256 insertions, 209 deletions
diff --git a/lib/Db/Comment.php b/lib/Db/Comment.php
index 6e6e9ef7..07ee8a9c 100644
--- a/lib/Db/Comment.php
+++ b/lib/Db/Comment.php
@@ -27,12 +27,6 @@ namespace OCA\Polls\Db;
use JsonSerializable;
-use OCA\Polls\Helper\Container;
-use OCP\IUser;
-use OCP\IUserManager;
-use OCP\AppFramework\Db\Entity;
-use OCP\AppFramework\Db\DoesNotExistException;
-
/**
* @method int getId()
* @method void setId(integer $value)
@@ -45,7 +39,7 @@ use OCP\AppFramework\Db\DoesNotExistException;
* @method int getTimestamp()
* @method void setTimestamp(integer $value)
*/
-class Comment extends Entity implements JsonSerializable {
+class Comment extends EntityWithUser implements JsonSerializable {
public const TABLE = 'polls_comments';
/** @var array $subComments */
@@ -63,17 +57,9 @@ class Comment extends Entity implements JsonSerializable {
/** @var string $comment */
protected $comment = '';
- /** @var IUserManager */
- private $userManager;
-
- /** @var ShareMapper */
- private $shareMapper;
-
public function __construct() {
$this->addType('pollId', 'int');
$this->addType('timestamp', 'int');
- $this->userManager = Container::queryClass(IUserManager::class);
- $this->shareMapper = Container::queryClass(ShareMapper::class);
}
/**
@@ -101,32 +87,4 @@ class Comment extends Entity implements JsonSerializable {
public function getSubComments(): array {
return $this->subComments;
}
-
- public function getDisplayName(): string {
- if (!strncmp($this->userId, 'deleted_', 8)) {
- return 'Deleted User';
- }
-
- if ($this->getIsNoUser()) {
- // get displayName from share
- try {
- $share = $this->shareMapper->findByPollAndUser($this->getPollId(), $this->userId);
- return $share->getDisplayName();
- } catch (DoesNotExistException $e) {
- return $this->userId;
- }
- }
- return $this->userManager->get($this->userId)->getDisplayName();
- }
-
- public function getUser(): array {
- return [
- 'userId' => $this->getUserId(),
- 'displayName' => $this->getDisplayName(),
- 'isNoUser' => $this->getIsNoUser(),
- ];
- }
- public function getIsNoUser(): bool {
- return !($this->userManager->get($this->userId) instanceof IUser);
- }
}
diff --git a/lib/Db/EntityWithUser.php b/lib/Db/EntityWithUser.php
new file mode 100644
index 00000000..6168ae22
--- /dev/null
+++ b/lib/Db/EntityWithUser.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Kai Schröer <git@schroeer.co>
+ *
+ * @author Kai Schröer <git@schroeer.co>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Polls\Db;
+
+use OCA\Polls\Exceptions\ShareNotFoundException;
+use OCA\Polls\Helper\Container;
+use OCP\AppFramework\Db\Entity;
+use OCP\IUser;
+use OCP\IUserManager;
+
+/**
+ * @method string getUserId()
+ * @method int getPollId()
+ */
+
+abstract class EntityWithUser extends Entity {
+ /** @var string $publicUserId */
+ protected $publicUserId = '';
+
+ public function getIsNoUser(): bool {
+ return !(Container::queryClass(IUserManager::class)->get($this->getUserId()) instanceof IUser);
+ }
+
+ public function getDisplayName(): string {
+ if (!$this->getUserId()) {
+ return '';
+ }
+ if ($this->getIsNoUser()) {
+ // get displayName from share
+ try {
+ $share = Container::queryClass(ShareMapper::class)->findByPollAndUser($this->getPollId(), $this->getUserId());
+ } catch (ShareNotFoundException $e) {
+ // User seems to be probaly deleted, use fake share
+ $share = Container::queryClass(ShareMapper::class)->getReplacement($this->getPollId(), $this->getUserId());
+ }
+ return $share->getDisplayName();
+ }
+
+ return Container::queryClass(IUserManager::class)->get($this->getUserId())->getDisplayName();
+ }
+
+ private function getPublicUserId(): string {
+ if (!$this->getUserId()) {
+ return '';
+ }
+
+ if ($this->publicUserId) {
+ return $this->publicUserId;
+ }
+
+ return $this->getUserId();
+ }
+
+ public function generateHashedUserId(): void {
+ $this->publicUserId = hash('md5', $this->getUserId());
+ }
+
+ public function getUser(): array {
+ return [
+ 'userId' => $this->getPublicUserId(),
+ 'displayName' => $this->getDisplayName(),
+ 'isNoUser' => $this->getIsNoUser(),
+ ];
+ }
+}
diff --git a/lib/Db/IEntityWithUser.php b/lib/Db/IEntityWithUser.php
new file mode 100644
index 00000000..5a2a7bd3
--- /dev/null
+++ b/lib/Db/IEntityWithUser.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Kai Schröer <git@schroeer.co>
+ *
+ * @author Kai Schröer <git@schroeer.co>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Polls\Db;
+
+interface IEntityWithUser {
+ /**
+ * Is this object'suser or owner an internal user or external
+ */
+ public function getUserId(): string;
+
+ /**
+ * Returns the displayname of this object's user or owner
+ */
+ public function getDisplayName(): string;
+
+ /**
+ * Creates a hashed version of the userId
+ */
+ public function generateHashedUserId(): void;
+
+ /**
+ * Returns an array with user attributes for jsonSerialize()
+ */
+ public function getUser(): array;
+}
diff --git a/lib/Db/Option.php b/lib/Db/Option.php
index 965d5fc3..9aea04fd 100644
--- a/lib/Db/Option.php
+++ b/lib/Db/Option.php
@@ -30,12 +30,6 @@ use DateTime;
use DateTimeImmutable;
use DateTimeZone;
use JsonSerializable;
-
-use OCA\Polls\Helper\Container;
-use OCP\AppFramework\Db\Entity;
-use OCP\IUser;
-use OCP\IUserManager;
-use OCP\AppFramework\Db\DoesNotExistException;
use OCP\IL10N;
/**
@@ -58,7 +52,7 @@ use OCP\IL10N;
* @method int getTimestamp()
* @method void setTimestamp(integer $value)
*/
-class Option extends Entity implements JsonSerializable {
+class Option extends EntityWithUser implements JsonSerializable {
public const TABLE = 'polls_options';
/** @var int $pollId */
@@ -107,12 +101,6 @@ class Option extends Entity implements JsonSerializable {
/** @var bool $isBookedUp */
public $isBookedUp = false;
- /** @var IUserManager */
- private $userManager;
-
- /** @var ShareMapper */
- private $shareMapper;
-
public function __construct() {
$this->addType('released', 'int');
$this->addType('pollId', 'int');
@@ -120,8 +108,6 @@ class Option extends Entity implements JsonSerializable {
$this->addType('order', 'int');
$this->addType('confirmed', 'int');
$this->addType('duration', 'int');
- $this->userManager = Container::queryClass(IUserManager::class);
- $this->shareMapper = Container::queryClass(ShareMapper::class);
}
/**
@@ -145,15 +131,10 @@ class Option extends Entity implements JsonSerializable {
'votes' => $this->votes,
'isBookedUp' => $this->isBookedUp,
],
- 'owner' => [
- 'userId' => $this->getOwner(),
- 'displayName' => $this->getDisplayName(),
- 'isNoUser' => $this->getOwnerIsNoUser(),
- ],
+ 'owner' => $this->getUser(),
];
}
-
public function getPollOptionText(): string {
if ($this->getTimestamp() && $this->getDuration()) {
return date('c', $this->getTimestamp()) . ' - ' . date('c', $this->getTimestamp() + $this->getDuration());
@@ -194,30 +175,6 @@ class Option extends Entity implements JsonSerializable {
$this->setOwner($userId);
}
- // used for 1.9.0-beta1 installations
- public function getOwner() : string {
- if ($this->owner === 'disallow' || $this->owner === null) {
- return '';
- }
- return $this->owner;
- }
-
- public function getDisplayName(): ?string {
- if (!strncmp($this->getOwner(), 'deleted_', 8)) {
- return 'Deleted User';
- }
-
- if ($this->getOwnerIsNoUser()) {
- try {
- $share = $this->shareMapper->findByPollAndUser($this->getPollId(), $this->getOwner());
- return $share->getDisplayName();
- } catch (DoesNotExistException $e) {
- return $this->getOwner();
- }
- }
- return $this->userManager->get($this->getOwner())->getDisplayName();
- }
-
public function getDateStringLocalized(DateTimeZone $timeZone, IL10N $l10n) {
$mutableFrom = DateTime::createFromImmutable($this->getDateObjectFrom($timeZone));
$mutableTo = DateTime::createFromImmutable($this->getDateObjectTo($timeZone));
@@ -251,9 +208,9 @@ class Option extends Entity implements JsonSerializable {
return $dateTimeFrom . ' - ' . $dateTimeTo;
}
- private function getOwnerIsNoUser(): bool {
- return !$this->userManager->get($this->getOwner()) instanceof IUser;
- }
+ // private function getOwnerIsNoUser(): bool {
+ // return !$this->userManager->get($this->getOwner()) instanceof IUser;
+ // }
/**
* Check, if the date option spans one or more whole days (from 00:00 to 24:00)
diff --git a/lib/Db/Poll.php b/lib/Db/Poll.php
index b22c710a..2b60161c 100644
--- a/lib/Db/Poll.php
+++ b/lib/Db/Poll.php
@@ -28,9 +28,6 @@ namespace OCA\Polls\Db;
use JsonSerializable;
use OCA\Polls\Exceptions\NoDeadLineException;
use OCA\Polls\Helper\Container;
-use OCP\AppFramework\Db\Entity;
-use OCP\IUser;
-use OCP\IUserManager;
use OCP\IURLGenerator;
/**
@@ -78,7 +75,7 @@ use OCP\IURLGenerator;
* @method void setMiscSettings(string $value)
*/
-class Poll extends Entity implements JsonSerializable {
+class Poll extends EntityWithUser implements JsonSerializable {
public const TABLE = 'polls_polls';
public const TYPE_DATE = 'datePoll';
public const TYPE_TEXT = 'textPoll';
@@ -165,9 +162,6 @@ class Poll extends Entity implements JsonSerializable {
/** @var IURLGenerator */
private $urlGenerator;
- /** @var IUserManager */
- private $userManager;
-
/** @var OptionMapper */
private $optionMapper;
@@ -185,9 +179,8 @@ class Poll extends Entity implements JsonSerializable {
$this->addType('important', 'int');
$this->addType('hideBookedUp', 'int');
$this->addType('useNo', 'int');
- $this->urlGenerator = Container::queryClass(IURLGenerator::class);
- $this->userManager = Container::queryClass(IUserManager::class);
$this->optionMapper = Container::queryClass(OptionMapper::class);
+ $this->urlGenerator = Container::queryClass(IURLGenerator::class);
}
/**
@@ -217,10 +210,7 @@ class Poll extends Entity implements JsonSerializable {
'hideBookedUp' => $this->getHideBookedUp(),
'useNo' => $this->getUseNo(),
'autoReminder' => $this->getAutoReminder(),
- 'owner' => [
- 'userId' => $this->getOwner(),
- 'displayName' => $this->getDisplayName(),
- ],
+ 'owner' => $this->getUser(),
];
}
@@ -322,18 +312,16 @@ class Poll extends Entity implements JsonSerializable {
return htmlspecialchars($this->description);
}
- public function getDisplayName(): string {
- return $this->userManager->get($this->owner) instanceof IUser
- ? $this->userManager->get($this->owner)->getDisplayName()
- : $this->owner;
- }
-
private function setMiscSettingsArray(array $value) : void {
$this->setMiscSettings(json_encode($value));
}
- private function getMiscSettingsArray() : ?array {
- return json_decode($this->getMiscSettings(), true);
+ private function getMiscSettingsArray() : array {
+ if ($this->getMiscSettings()) {
+ return json_decode($this->getMiscSettings(), true);
+ }
+
+ return [];
}
public function getTimeToDeadline(int $time = 0): ?int {
@@ -372,7 +360,6 @@ class Poll extends Entity implements JsonSerializable {
throw new NoDeadLineException();
}
-
/**
* @param bool|string|int|array $value
*/
diff --git a/lib/Db/Share.php b/lib/Db/Share.php
index 153857eb..864cafef 100644
--- a/lib/Db/Share.php
+++ b/lib/Db/Share.php
@@ -221,8 +221,12 @@ class Share extends Entity implements JsonSerializable {
$this->setMiscSettings(json_encode($value));
}
- private function getMiscSettingsArray() : ?array {
- return json_decode($this->getMiscSettings(), true);
+ private function getMiscSettingsArray() : array {
+ if ($this->getMiscSettings()) {
+ return json_decode($this->getMiscSettings(), true);
+ }
+
+ return [];
}
/**
diff --git a/lib/Db/ShareMapper.php b/lib/Db/ShareMapper.php
index 49228c42..d2716921 100644
--- a/lib/Db/ShareMapper.php
+++ b/lib/Db/ShareMapper.php
@@ -24,6 +24,9 @@
namespace OCA\Polls\Db;
+use OCA\Polls\Exceptions\ShareNotFoundException;
+use OCA\Polls\Model\UserBase;
+use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\Exception;
use OCP\DB\QueryBuilder\IQueryBuilder;
@@ -102,22 +105,44 @@ class ShareMapper extends QBMapper {
$qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
);
- return $this->findEntity($qb);
+ try {
+ return $this->findEntity($qb);
+ } catch (DoesNotExistException $e) {
+ throw new ShareNotFoundException("Share not found by userId and pollId");
+ }
}
/**
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * Returns a fake share in case of deleted shares
*/
+ public function getReplacement($pollId, $userId): ?Share {
+ if (!$userId) {
+ return null;
+ }
+
+ $share = new Share;
+ $share->setUserId($userId);
+ $share->setPollId($pollId);
+ $share->setType(UserBase::TYPE_EXTERNAL);
+ $share->setToken('deleted_share_' . $userId . '_' . $pollId);
+ $share->setDisplayName('Deleted User');
+ return $share;
+ }
+
public function findByToken(string $token): Share {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq('token', $qb->createNamedParameter($token, IQueryBuilder::PARAM_STR))
- );
-
- return $this->findEntity($qb);
+ ->from($this->getTableName())
+ ->where(
+ $qb->expr()->eq('token', $qb->createNamedParameter($token, IQueryBuilder::PARAM_STR))
+ );
+
+ try {
+ return $this->findEntity($qb);
+ } catch (DoesNotExistException $e) {
+ throw new ShareNotFoundException('Token ' . $token . ' does not exist');
+ }
}
public function deleteByPoll(int $pollId): void {
diff --git a/lib/Db/Vote.php b/lib/Db/Vote.php
index 1c00c21e..243d9e6b 100644
--- a/lib/Db/Vote.php
+++ b/lib/Db/Vote.php
@@ -26,11 +26,6 @@
namespace OCA\Polls\Db;
use JsonSerializable;
-use OCA\Polls\Helper\Container;
-use OCP\IUser;
-use OCP\IUserManager;
-use OCP\AppFramework\Db\Entity;
-use OCP\AppFramework\Db\DoesNotExistException;
/**
* @method int getPollId()
@@ -44,7 +39,7 @@ use OCP\AppFramework\Db\DoesNotExistException;
* @method string getVoteAnswer()
* @method void setVoteAnswer(string $value)
*/
-class Vote extends Entity implements JsonSerializable {
+class Vote extends EntityWithUser implements JsonSerializable {
public const TABLE = 'polls_votes';
/** @var int $pollId */
@@ -62,18 +57,10 @@ class Vote extends Entity implements JsonSerializable {
/** @var string $voteAnswer */
protected $voteAnswer;
- /** @var IUserManager */
- private $userManager;
-
- /** @var ShareMapper */
- private $shareMapper;
-
public function __construct() {
$this->addType('id', 'int');
$this->addType('pollId', 'int');
$this->addType('voteOptionId', 'int');
- $this->userManager = Container::queryClass(IUserManager::class);
- $this->shareMapper = Container::queryClass(ShareMapper::class);
}
/**
@@ -85,31 +72,7 @@ class Vote extends Entity implements JsonSerializable {
'pollId' => $this->getPollId(),
'optionText' => $this->getVoteOptionText(),
'answer' => $this->getVoteAnswer(),
- 'user' => [
- 'userId' => $this->getUserId(),
- 'displayName' => $this->getDisplayName(),
- 'isNoUser' => $this->getIsNoUser(),
- ],
+ 'user' => $this->getUser(),
];
}
-
- public function getDisplayName(): string {
- if (!strncmp($this->userId, 'deleted_', 8)) {
- return 'Deleted User';
- }
-
- if ($this->getIsNoUser()) {
- try {
- $share = $this->shareMapper->findByPollAndUser($this->getPollId(), $this->userId);
- return $share->getDisplayName();
- } catch (DoesNotExistException $e) {
- return $this->userId;
- }
- }
- return $this->userManager->get($this->userId)->getDisplayName();
- }
-
- public function getIsNoUser(): bool {
- return !($this->userManager->get($this->userId) instanceof IUser);
- }
}
diff --git a/lib/Exceptions/NotFoundException.php b/lib/Exceptions/NotFoundException.php
index bb678965..dbd70466 100644
--- a/lib/Exceptions/NotFoundException.php
+++ b/lib/Exceptions/NotFoundException.php
@@ -27,9 +27,8 @@ use OCP\AppFramework\Http;
class NotFoundException extends Exception {
public function __construct(
- string $e = 'Not found',
- int $status = Http::STATUS_NOT_FOUND
+ string $e = 'Not found'
) {
- parent::__construct($e, $status);
+ parent::__construct($e, Http::STATUS_NOT_FOUND);
}
}
diff --git a/lib/Exceptions/ShareNotFoundException.php b/lib/Exceptions/ShareNotFoundException.php
new file mode 100644
index 00000000..60d88d89
--- /dev/null
+++ b/lib/Exceptions/ShareNotFoundException.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * @copyright Copyright (c) 2020 René Gieling <github@dartcafe.de>
+ *
+ * @author René Gieling <github@dartcafe.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Polls\Exceptions;
+
+class ShareNotFoundException extends NotFoundException {
+ public function __construct(
+ string $e = 'Share not found'
+ ) {
+ parent::__construct($e);
+ }
+}
diff --git a/lib/Model/Acl.php b/lib/Model/Acl.php
index bf492402..8c47be4c 100644
--- a/lib/Model/Acl.php
+++ b/lib/Model/Acl.php
@@ -33,6 +33,7 @@ use OCA\Polls\Db\OptionMapper;
use OCA\Polls\Db\PollMapper;
use OCA\Polls\Db\VoteMapper;
use OCA\Polls\Db\ShareMapper;
+use OCA\Polls\Exceptions\ShareNotFoundException;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\IGroupManager;
@@ -130,7 +131,7 @@ class Acl implements JsonSerializable {
$this->poll = $this->pollMapper->find($this->share->getPollId());
$this->validateShareAccess();
$this->request($permission);
- } catch (DoesNotExistException $e) {
+ } catch (ShareNotFoundException $e) {
throw new NotAuthorizedException('Error loading share ' . $token);
}
diff --git a/lib/Model/Mail/NotificationMail.php b/lib/Model/Mail/NotificationMail.php
index 6b0ff2e2..d3b6ced3 100644
--- a/lib/Model/Mail/NotificationMail.php
+++ b/lib/Model/Mail/NotificationMail.php
@@ -108,6 +108,6 @@ class NotificationMail extends MailBase {
VoteEvent::SET => $this->l10n->t('%s has voted.', [$displayName]),
];
- return $logStrings[$logItem->getMessageId()] ?? $logItem->getMessageId() . " (" . $displayName . ")";
+ return $logStrings[$logItem->getMessageId()] ?? $logItem->getMessageId() . ' (' . $displayName . ')';
}
}
diff --git a/lib/Provider/ActivityProvider.php b/lib/Provider/ActivityProvider.php
index 5992b909..7c2ba47d 100644
--- a/lib/Provider/ActivityProvider.php
+++ b/lib/Provider/ActivityProvider.php
@@ -34,6 +34,7 @@ use OCP\Activity\IEventMerger;
use OCP\Activity\IEvent;
use OCA\Polls\Service\ActivityService;
use OCA\Polls\Db\ShareMapper;
+use OCA\Polls\Exceptions\ShareNotFoundException;
class ActivityProvider implements IProvider {
/** @var IFactory */
@@ -110,7 +111,12 @@ class ActivityProvider implements IProvider {
'name' => $actor->getDisplayName(),
];
} else {
- $share = $this->shareMapper->findByPollAndUser($event->getObjectId(), $event->getAuthor());
+ try {
+ $share = $this->shareMapper->findByPollAndUser($event->getObjectId(), $event->getAuthor());
+ } catch (ShareNotFoundException $e) {
+ // User seems to be probaly deleted, use fake share
+ $share = $this->shareMapper->getReplacement($event->getObjectId(), $event->getAuthor());
+ }
$parameters['actor'] = [
'type' => 'guest',
'id' => $share->getUserId(),
diff --git a/lib/Service/AnonymizeService.php b/lib/Service/AnonymizeService.php
index c8321e19..af9f685e 100644
--- a/lib/Service/AnonymizeService.php
+++ b/lib/Service/AnonymizeService.php
@@ -28,7 +28,6 @@ use OCA\Polls\Db\Vote;
use OCA\Polls\Db\VoteMapper;
use OCA\Polls\Db\Comment;
use OCA\Polls\Db\CommentMapper;
-use OCA\Polls\Db\Option;
use OCA\Polls\Db\OptionMapper;
use OCA\Polls\Db\Poll;
@@ -112,21 +111,13 @@ class AnonymizeService {
return;
}
- /**
- * Replaces userIds with displayName to avoid exposing usernames in public polls
- */
public static function replaceUserId(&$arrayOrObject, string $userId) : void {
if (is_array($arrayOrObject)) {
foreach ($arrayOrObject as $item) {
if ($item->getUserId() === $userId) {
continue;
}
- if ($item instanceof Comment || $item instanceof Vote) {
- $item->setUserId($item->getDisplayName());
- }
- if ($item instanceof Option || $item instanceof Poll) {
- $item->setOwner($item->getDisplayName());
- }
+ $item->generateHashedUserId();
}
return;
}
@@ -135,13 +126,7 @@ class AnonymizeService {
return;
}
- if ($arrayOrObject instanceof Option || $arrayOrObject instanceof Poll) {
- $arrayOrObject->setOwner($arrayOrObject->getDisplayName());
- }
-
- if ($arrayOrObject instanceof Comment || $arrayOrObject instanceof Vote) {
- $arrayOrObject->setUserId($arrayOrObject->getDisplayName());
- }
+ $arrayOrObject->generateHashedUserId();
return;
}
diff --git a/lib/Service/PollService.php b/lib/Service/PollService.php
index c5b8a636..f9df6dbe 100644
--- a/lib/Service/PollService.php
+++ b/lib/Service/PollService.php
@@ -208,8 +208,12 @@ class PollService {
/**
* get poll configuration
+ *
+ * @return (\OCA\Polls\Db\Comment|\OCA\Polls\Db\Option|\OCA\Polls\Db\Vote)[]|Poll
+ *
+ * @psalm-return Poll|array<\OCA\Polls\Db\Comment|\OCA\Polls\Db\Option|\OCA\Polls\Db\Vote>
*/
- public function get(int $pollId) : Poll {
+ public function get(int $pollId) {
$this->acl->setPollId($pollId);
$this->poll = $this->pollMapper->find($pollId);
diff --git a/lib/Service/ShareService.php b/lib/Service/ShareService.php
index 9b23def4..ad6c452f 100644
--- a/lib/Service/ShareService.php
+++ b/lib/Service/ShareService.php
@@ -37,6 +37,7 @@ use OCA\Polls\Exceptions\InvalidShareTypeException;
use OCA\Polls\Exceptions\ShareAlreadyExistsException;
use OCA\Polls\Exceptions\NotFoundException;
use OCA\Polls\Exceptions\InvalidUsernameException;
+use OCA\Polls\Exceptions\ShareNotFoundException;
use OCA\Polls\Model\Acl;
use OCA\Polls\Model\UserBase;
use OCP\AppFramework\Db\DoesNotExistException;
@@ -144,13 +145,9 @@ class ShareService {
* Get share by token for accessing the poll
*/
public function get(string $token, bool $validateShareType = false): Share {
- try {
- $this->share = $this->shareMapper->findByToken($token);
- if ($validateShareType) {
- $this->validateShareType();
- }
- } catch (DoesNotExistException $e) {
- throw new NotFoundException('Token ' . $token . ' does not exist');
+ $this->share = $this->shareMapper->findByToken($token);
+ if ($validateShareType) {
+ $this->validateShareType();
}
// Exception: logged in user accesses the poll via public share link
@@ -184,15 +181,10 @@ class ShareService {
* Change share type
*/
public function setType(string $token, string $type): Share {
- try {
- $this->share = $this->shareMapper->findByToken($token);
- $this->acl->setPollId($this->share->getPollId(), Acl::PERMISSION_POLL_EDIT);
- $this->share->setType($type);
- $this->share = $this->shareMapper->update($this->share);
- } catch (DoesNotExistException $e) {
- throw new NotFoundException('Token ' . $token . ' does not exist');
- }
-
+ $this->share = $this->shareMapper->findByToken($token);
+ $this->acl->setPollId($this->share->getPollId(), Acl::PERMISSION_POLL_EDIT);
+ $this->share->setType($type);
+ $this->share = $this->shareMapper->update($this->share);
$this->eventDispatcher->dispatchTyped(new ShareTypeChangedEvent($this->share));
return $this->share;
@@ -207,7 +199,7 @@ class ShareService {
$this->acl->setPollId($this->share->getPollId(), Acl::PERMISSION_POLL_EDIT);
$this->share->setPublicPollEmail($value);
$this->share = $this->shareMapper->update($this->share);
- } catch (DoesNotExistException $e) {
+ } catch (ShareNotFoundException $e) {
throw new NotFoundException('Token ' . $token . ' does not exist');
}
$this->eventDispatcher->dispatchTyped(new ShareChangedRegistrationConstraintEvent($this->share));
@@ -338,7 +330,7 @@ class ShareService {
$this->share = $this->shareMapper->findByToken($token);
$this->acl->setPollId($this->share->getPollId(), Acl::PERMISSION_POLL_EDIT);
$this->shareMapper->delete($this->share);
- } catch (DoesNotExistException $e) {
+ } catch (ShareNotFoundException $e) {
// silently catch
}
@@ -431,7 +423,7 @@ class ShareService {
throw new ShareAlreadyExistsException;
} catch (MultipleObjectsReturnedException $e) {
throw new ShareAlreadyExistsException;
- } catch (DoesNotExistException $e) {
+ } catch (ShareNotFoundException $e) {
// continue
}
}
diff --git a/lib/Service/UserService.php b/lib/Service/UserService.php
index 2d41ccf7..39c865fe 100644
--- a/lib/Service/UserService.php
+++ b/lib/Service/UserService.php
@@ -26,8 +26,8 @@ namespace OCA\Polls\Service;
use OCA\Polls\Db\Share;
use OCA\Polls\Db\ShareMapper;
use OCA\Polls\Db\VoteMapper;
-use OCA\Polls\Exceptions\Exception;
use OCA\Polls\Exceptions\InvalidShareTypeException;
+use OCA\Polls\Exceptions\ShareNotFoundException;
use OCA\Polls\Model\User\Admin;
use OCA\Polls\Model\Group\Circle;
use OCA\Polls\Model\Group\ContactGroup;
@@ -127,10 +127,12 @@ class UserService {
// Otherwise get it from a share that belongs to the poll and return the share user
try {
$share = $this->shareMapper->findByPollAndUser($pollId, $userId);
- return $this->getUserFromShare($share);
- } catch (Exception $e) {
- return null;
+ } catch (ShareNotFoundException $e) {
+ // User seems to be probaly deleted, use fake share
+ $share = $this->shareMapper->getReplacement($pollId, $userId);
}
+
+ return $this->getUserFromShare($share);
}
/**