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:
René Gieling 2022-10-24 15:27:30 +02:00 коммит произвёл GitHub
Родитель 36101e5795
Коммит 58f4554735
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
17 изменённых файлов: 256 добавлений и 209 удалений

Просмотреть файл

@ -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);
}
}

86
lib/Db/EntityWithUser.php Normal file
Просмотреть файл

@ -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);
}
/**