Change handling of objects which refer to deleted shares (#2640)
* add fake share for delete users and hash user id * fix #2636
This commit is contained in:
Родитель
36101e5795
Коммит
58f4554735
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 . ')';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче