Merge pull request #2425 from nextcloud/ref/user

Separate public userId from displayName
This commit is contained in:
René Gieling 2022-05-21 11:06:30 +02:00 коммит произвёл GitHub
Родитель e32ea94858 8d364fc0d6
Коммит 1f67cc88fe
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
29 изменённых файлов: 315 добавлений и 426 удалений

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

@ -62,43 +62,34 @@ class AdminController extends Controller {
* @NoCSRFRequired
*/
public function index(): TemplateResponse {
return new TemplateResponse('polls', 'polls.tmpl',
['urlGenerator' => $this->urlGenerator]);
return new TemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]);
}
/**
* Get list of polls for administrative purposes
*/
public function list(): DataResponse {
return $this->response(function () {
return $this->pollService->listForAdmin();
});
return $this->response(fn () => $this->pollService->listForAdmin());
}
/**
* Get list of polls for administrative purposes
*/
public function takeover(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return $this->pollService->takeover($pollId);
});
return $this->response(fn () => $this->pollService->takeover($pollId));
}
/**
* Switch deleted status (move to deleted polls)
*/
public function toggleArchive(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return $this->pollService->toggleArchive($pollId);
});
return $this->response(fn () => $this->pollService->toggleArchive($pollId));
}
/**
* Delete poll
*/
public function delete(int $pollId): DataResponse {
return $this->responseDeleteTolerant(function () use ($pollId) {
return $this->pollService->delete($pollId);
});
return $this->responseDeleteTolerant(fn () => $this->pollService->delete($pollId));
}
}

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

@ -56,9 +56,7 @@ class CommentApiController extends ApiController {
* @NoCSRFRequired
*/
public function list(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return ['comments' => $this->commentService->list($pollId)];
});
return $this->response(fn () => ['comments' => $this->commentService->list($pollId)]);
}
/**
@ -68,9 +66,7 @@ class CommentApiController extends ApiController {
* @NoCSRFRequired
*/
public function add(int $pollId, string $message): DataResponse {
return $this->response(function () use ($pollId, $message) {
return ['comment' => $this->commentService->add($pollId, null, $message)];
});
return $this->response(fn () => ['comment' => $this->commentService->add($message, $pollId)]);
}
/**
@ -80,8 +76,6 @@ class CommentApiController extends ApiController {
* @NoCSRFRequired
*/
public function delete(int $commentId): DataResponse {
return $this->responseDeleteTolerant(function () use ($commentId) {
return ['comment' => $this->commentService->delete($commentId)];
});
return $this->responseDeleteTolerant(fn () => ['comment' => $this->commentService->delete($commentId)]);
}
}

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

@ -49,9 +49,7 @@ class CommentController extends Controller {
* @NoAdminRequired
*/
public function list(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return ['comments' => $this->commentService->list($pollId)];
});
return $this->response(fn () => ['comments' => $this->commentService->list($pollId)]);
}
/**
@ -59,9 +57,7 @@ class CommentController extends Controller {
* @NoAdminRequired
*/
public function add(int $pollId, string $message): DataResponse {
return $this->response(function () use ($pollId, $message) {
return ['comment' => $this->commentService->add($pollId, null, $message)];
});
return $this->response(fn () => ['comment' => $this->commentService->add($message, $pollId)]);
}
/**
@ -69,8 +65,6 @@ class CommentController extends Controller {
* @NoAdminRequired
*/
public function delete(int $commentId): DataResponse {
return $this->responseDeleteTolerant(function () use ($commentId) {
return ['comment' => $this->commentService->delete($commentId)];
});
return $this->responseDeleteTolerant(fn () => ['comment' => $this->commentService->delete($commentId)]);
}
}

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

@ -56,9 +56,7 @@ class OptionApiController extends ApiController {
* @NoCSRFRequired
*/
public function list(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return ['options' => $this->optionService->list($pollId)];
});
return $this->response(fn () => ['options' => $this->optionService->list($pollId)]);
}
/**
@ -68,9 +66,7 @@ class OptionApiController extends ApiController {
* @NoCSRFRequired
*/
public function add(int $pollId, int $timestamp = 0, string $pollOptionText = '', int $duration = 0): DataResponse {
return $this->responseCreate(function () use ($pollId, $timestamp, $pollOptionText, $duration) {
return ['option' => $this->optionService->add($pollId, $timestamp, $pollOptionText, $duration)];
});
return $this->responseCreate(fn () => ['option' => $this->optionService->add($pollId, $timestamp, $pollOptionText, $duration)]);
}
@ -81,9 +77,7 @@ class OptionApiController extends ApiController {
* @NoCSRFRequired
*/
public function update(int $optionId, int $timestamp = 0, string $pollOptionText = '', int $duration = 0): DataResponse {
return $this->response(function () use ($optionId, $timestamp, $pollOptionText, $duration) {
return ['option' => $this->optionService->update($optionId, $timestamp, $pollOptionText, $duration)];
});
return $this->response(fn () => ['option' => $this->optionService->update($optionId, $timestamp, $pollOptionText, $duration)]);
}
/**
@ -93,9 +87,7 @@ class OptionApiController extends ApiController {
* @NoCSRFRequired
*/
public function delete(int $optionId): DataResponse {
return $this->responseDeleteTolerant(function () use ($optionId) {
return ['option' => $this->optionService->delete($optionId)];
});
return $this->responseDeleteTolerant(fn () => ['option' => $this->optionService->delete($optionId)]);
}
/**
@ -105,9 +97,7 @@ class OptionApiController extends ApiController {
* @NoCSRFRequired
*/
public function confirm(int $optionId): DataResponse {
return $this->response(function () use ($optionId) {
return ['option' => $this->optionService->confirm($optionId)];
});
return $this->response(fn () => ['option' => $this->optionService->confirm($optionId)]);
}
/**
@ -117,8 +107,6 @@ class OptionApiController extends ApiController {
* @NoCSRFRequired
*/
public function setOrder(int $optionId, int $order): DataResponse {
return $this->response(function () use ($optionId, $order) {
return ['option' => $this->optionService->setOrder($optionId, $order)];
});
return $this->response(fn () => ['option' => $this->optionService->setOrder($optionId, $order)]);
}
}

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

@ -23,9 +23,6 @@
namespace OCA\Polls\Controller;
use DateTime;
use DateInterval;
use DateTimeZone;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
@ -68,15 +65,11 @@ class OptionController extends Controller {
* @NoAdminRequired
*/
public function add(int $pollId, int $timestamp = 0, string $text = '', int $duration = 0): DataResponse {
return $this->responseCreate(function () use ($pollId, $timestamp, $text, $duration) {
return ['option' => $this->optionService->add($pollId, $timestamp, $text, $duration)];
});
return $this->responseCreate(fn () => ['option' => $this->optionService->add($pollId, $timestamp, $text, $duration)]);
}
public function addBulk(int $pollId, string $text = ''): DataResponse {
return $this->responseCreate(function () use ($pollId, $text) {
return ['options' => $this->optionService->addBulk($pollId, $text)];
});
return $this->responseCreate(fn () => ['options' => $this->optionService->addBulk($pollId, $text)]);
}
/**
@ -84,9 +77,7 @@ class OptionController extends Controller {
* @NoAdminRequired
*/
public function update(int $optionId, int $timestamp, string $text, int $duration): DataResponse {
return $this->response(function () use ($optionId, $timestamp, $text, $duration) {
return ['option' => $this->optionService->update($optionId, $timestamp, $text, $duration)];
});
return $this->response(fn () => ['option' => $this->optionService->update($optionId, $timestamp, $text, $duration)]);
}
/**
@ -94,9 +85,7 @@ class OptionController extends Controller {
* @NoAdminRequired
*/
public function delete(int $optionId): DataResponse {
return $this->responseDeleteTolerant(function () use ($optionId) {
return ['option' => $this->optionService->delete($optionId)];
});
return $this->responseDeleteTolerant(fn () => ['option' => $this->optionService->delete($optionId)]);
}
/**
@ -104,9 +93,7 @@ class OptionController extends Controller {
* @NoAdminRequired
*/
public function confirm(int $optionId): DataResponse {
return $this->response(function () use ($optionId) {
return ['option' => $this->optionService->confirm($optionId)];
});
return $this->response(fn () => ['option' => $this->optionService->confirm($optionId)]);
}
/**
@ -114,9 +101,7 @@ class OptionController extends Controller {
* @NoAdminRequired
*/
public function reorder(int $pollId, array $options): DataResponse {
return $this->response(function () use ($pollId, $options) {
return ['options' => $this->optionService->reorder($pollId, $options)];
});
return $this->response(fn () => ['options' => $this->optionService->reorder($pollId, $options)]);
}
/**
@ -124,9 +109,7 @@ class OptionController extends Controller {
* @NoAdminRequired
*/
public function sequence(int $optionId, int $step, string $unit, int $amount): DataResponse {
return $this->response(function () use ($optionId, $step, $unit, $amount) {
return ['options' => $this->optionService->sequence($optionId, $step, $unit, $amount)];
});
return $this->response(fn () => ['options' => $this->optionService->sequence($optionId, $step, $unit, $amount)]);
}
/**
@ -134,9 +117,7 @@ class OptionController extends Controller {
* @NoAdminRequired
*/
public function shift(int $pollId, int $step, string $unit): DataResponse {
return $this->response(function () use ($pollId, $step, $unit) {
return ['options' => $this->optionService->shift($pollId, $step, $unit)];
});
return $this->response(fn () => ['options' => $this->optionService->shift($pollId, $step, $unit)]);
}
/**
@ -144,28 +125,6 @@ class OptionController extends Controller {
* @NoAdminRequired
*/
public function findCalendarEvents(int $optionId, string $tz): DataResponse {
return $this->response(function () use ($optionId, $tz) {
return ['events' => $this->calendarService->getEvents($optionId, $tz)];
});
return $this->response(fn () => ['events' => $this->calendarService->getEvents($optionId, $tz)]);
}
// /**
// * findCalendarEvents
// * @NoAdminRequired
// */
// public function findCalendarEvents_old(int $optionId, string $tz): DataResponse {
// return $this->response(function () use ($optionId, $tz) {
// $option = $this->optionService->get($optionId);
// $timezone = new DateTimeZone($tz);
// $searchFrom = (new DateTime())->setTimeZone($timezone);
// $searchTo = (new DateTime())->setTimeZone($timezone);
// // Search calendar entries which end inside one hour before option start time and one hour after option end time
// $searchFrom->setTimestamp($option->getTimestamp())->sub(new DateInterval('PT1H'));
// $searchTo->setTimestamp($option->getTimestamp() + $option->getDuration())->add(new DateInterval('PT1H'));
// $events = $this->calendarService->getEvents($searchFrom, $searchTo, $timezone);
// return ['events' => $events];
// });
// }
}

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

@ -54,8 +54,7 @@ class PageController extends Controller {
* @NoCSRFRequired
*/
public function index(): TemplateResponse {
return new TemplateResponse('polls', 'polls.tmpl',
['urlGenerator' => $this->urlGenerator]);
return new TemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]);
}
/**
@ -64,7 +63,6 @@ class PageController extends Controller {
*/
public function vote(int $id): TemplateResponse {
$this->notificationService->removeNotification($id);
return new TemplateResponse('polls', 'polls.tmpl',
['urlGenerator' => $this->urlGenerator]);
return new TemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]);
}
}

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

@ -68,10 +68,8 @@ class PollController extends Controller {
* Get list of polls
* @NoAdminRequired
*/
public function list(): DataResponse {
return $this->response(function () {
// return $this->pollService->list();
$appSettings = new AppSettings;
return [
'list' => $this->pollService->list(),
@ -86,51 +84,39 @@ class PollController extends Controller {
* @NoAdminRequired
*/
public function get(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
$this->acl->setPollId($pollId);
return [
'acl' => $this->acl,
'poll' => $this->acl->getPoll(),
];
});
$this->acl->setPollId($pollId);
return $this->response(fn () => [
'acl' => $this->acl,
'poll' => $this->acl->getPoll(),
]);
}
/**
* Add poll
* @NoAdminRequired
*/
public function add(string $type, string $title): DataResponse {
return $this->responseCreate(function () use ($type, $title) {
return $this->pollService->add($type, $title);
});
return $this->responseCreate(fn () => $this->pollService->add($type, $title));
}
/**
* Update poll configuration
* @NoAdminRequired
*/
public function update(int $pollId, array $poll): DataResponse {
return $this->response(function () use ($pollId, $poll) {
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
return [
'poll' => $this->pollService->update($pollId, $poll),
'acl' => $this->acl->setPollId($pollId),
];
});
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
return $this->response(fn () => [
'poll' => $this->pollService->update($pollId, $poll),
'acl' => $this->acl->setPollId($pollId),
]);
}
/**
* Switch deleted status (move to deleted polls)
* @NoAdminRequired
*/
public function toggleArchive(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return $this->pollService->toggleArchive($pollId);
});
return $this->response(fn () => $this->pollService->toggleArchive($pollId));
}
/**
@ -139,9 +125,7 @@ class PollController extends Controller {
*/
public function delete(int $pollId): DataResponse {
return $this->responseDeleteTolerant(function () use ($pollId) {
return $this->pollService->delete($pollId);
});
return $this->responseDeleteTolerant(fn () => $this->pollService->delete($pollId));
}
/**
@ -149,22 +133,16 @@ class PollController extends Controller {
* @NoAdminRequired
*/
public function clone(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
$poll = $this->pollService->clone($pollId);
$this->optionService->clone($pollId, $poll->getId());
return $poll;
});
$poll = $this->pollService->clone($pollId);
$this->optionService->clone($pollId, $poll->getId());
return $this->get($pollId);
}
/**
* Collect email addresses from particitipants
* @NoAdminRequired
*/
public function getParticipantsEmailAddresses(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return $this->pollService->getParticipantsEmailAddresses($pollId);
});
return $this->response(fn () => $this->pollService->getParticipantsEmailAddresses($pollId));
}
}

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

@ -64,9 +64,7 @@ class PreferencesController extends Controller {
* @NoCSRFRequired
*/
public function get(): DataResponse {
return $this->response(function (): Preferences {
return $this->preferencesService->get();
});
return $this->response(fn () => $this->preferencesService->get());
}
/**
@ -77,9 +75,7 @@ class PreferencesController extends Controller {
if (!$this->userSession->isLoggedIn()) {
return new DataResponse([], Http::STATUS_OK);
}
return $this->response(function () use ($settings) {
return $this->preferencesService->write($settings);
});
return $this->response(fn () => $this->preferencesService->write($settings));
}
/**

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

@ -31,12 +31,10 @@ use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\Template\PublicTemplateResponse;
use OCA\Polls\Exceptions\NoUpdatesException;
use OCA\Polls\Db\Share;
use OCA\Polls\Db\Poll;
use OCA\Polls\Db\Comment;
use OCA\Polls\Model\Acl;
use OCA\Polls\Service\AnonymizeService;
use OCA\Polls\Service\CommentService;
use OCA\Polls\Service\MailService;
use OCA\Polls\Service\OptionService;
@ -136,11 +134,9 @@ class PublicController extends Controller {
*/
public function votePage() {
if ($this->userSession->isLoggedIn()) {
return new TemplateResponse('polls', 'polls.tmpl', [
'urlGenerator' => $this->urlGenerator]);
return new TemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]);
} else {
return new PublicTemplateResponse('polls', 'polls.tmpl', [
'urlGenerator' => $this->urlGenerator]);
return new PublicTemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]);
}
}
@ -150,13 +146,11 @@ class PublicController extends Controller {
* @NoAdminRequired
*/
public function getPoll(string $token): DataResponse {
return $this->response(function () use ($token) {
$this->acl->setToken($token);
return [
'acl' => $this->acl,
'poll' => AnonymizeService::replaceUserId($this->acl->getPoll()),
];
});
$this->acl->setToken($token);
return $this->response(fn () => [
'acl' => $this->acl,
'poll' => $this->pollService->get($this->acl->getPollId()),
]);
}
/**
@ -166,21 +160,7 @@ class PublicController extends Controller {
*/
public function watchPoll(string $token, ?int $offset): DataResponse {
$pollId = $this->acl->setToken($token)->getPollId();
return $this->responseLong(function () use ($pollId, $offset) {
$start = time();
$timeout = 30;
$offset = $offset ?? $start;
while (empty($updates) && time() <= $start + $timeout) {
sleep(1);
$updates = $this->watchService->getUpdates($pollId, $offset);
}
if (empty($updates)) {
throw new NoUpdatesException;
}
return ['updates' => $updates];
});
return $this->responseLong(fn () => ['updates' => $this->watchService->watchUpdates($pollId, $offset)]);
}
/**
@ -189,9 +169,8 @@ class PublicController extends Controller {
* @NoAdminRequired
*/
public function getShare(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['share' => $this->shareService->get($token, true)];
});
$validateShareType = true;
return $this->response(fn () => ['share' => $this->shareService->get($token, $validateShareType)]);
}
/**
@ -200,9 +179,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function getComments(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['comments' => AnonymizeService::replaceUserId($this->commentService->list(0, $token))];
});
return $this->response(fn () => ['comments' => $this->commentService->list(null, $token)]);
}
/**
@ -211,9 +188,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function getVotes(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['votes' => AnonymizeService::replaceUserId($this->voteService->list(0, $token))];
});
return $this->response(fn () => ['votes' => $this->voteService->list(null, $token)]);
}
/**
@ -222,9 +197,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function deleteUser(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['deleted' => $this->voteService->delete(0, '', $token)];
});
return $this->response(fn () => ['deleted' => $this->voteService->delete(null, null, $token)]);
}
/**
@ -233,9 +206,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function getOptions(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['options' => AnonymizeService::replaceUserId($this->optionService->list(0, $token))];
});
return $this->response(fn () => ['options' => $this->optionService->list(null, $token)]);
}
/**
@ -244,9 +215,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function addOption(string $token, int $timestamp = 0, string $text = '', int $duration = 0): DataResponse {
return $this->responseCreate(function () use ($token, $timestamp, $text, $duration) {
return ['option' => $this->optionService->add(0, $timestamp, $text, $duration, $token)];
});
return $this->responseCreate(fn () => ['option' => $this->optionService->add(null, $timestamp, $text, $duration, $token)]);
}
/**
@ -255,9 +224,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function deleteOption(string $token, int $optionId): DataResponse {
return $this->responseDeleteTolerant(function () use ($token, $optionId) {
return ['option' => $this->optionService->delete($optionId, $token)];
});
return $this->responseDeleteTolerant(fn () => ['option' => $this->optionService->delete($optionId, $token)]);
}
/**
@ -266,9 +233,7 @@ class PublicController extends Controller {
* @NoAdminRequired
*/
public function getSubscription(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['subscribed' => $this->subscriptionService->get(0, $token)];
});
return $this->response(fn () => ['subscribed' => $this->subscriptionService->get(null, $token)]);
}
/**
@ -277,9 +242,7 @@ class PublicController extends Controller {
* @NoAdminRequired
*/
public function setVote(int $optionId, string $setTo, string $token): DataResponse {
return $this->response(function () use ($optionId, $setTo, $token) {
return ['vote' => $this->voteService->set($optionId, $setTo, $token)];
});
return $this->response(fn () => ['vote' => $this->voteService->set($optionId, $setTo, $token)]);
}
/**
@ -288,9 +251,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function addComment(string $token, string $message): DataResponse {
return $this->response(function () use ($token, $message) {
return ['comment' => $this->commentService->add(0, $token, $message)];
});
return $this->response(fn () => ['comment' => $this->commentService->add($message, null, $token)]);
}
/**
@ -299,9 +260,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function deleteComment(int $commentId, string $token): DataResponse {
return $this->responseDeleteTolerant(function () use ($commentId, $token) {
return ['comment' => $this->commentService->delete($commentId, $token)];
});
return $this->responseDeleteTolerant(fn () => ['comment' => $this->commentService->delete($commentId, $token)]);
}
/**
@ -310,9 +269,7 @@ class PublicController extends Controller {
* @NoAdminRequired
*/
public function subscribe(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['subscribed' => $this->subscriptionService->set(true, 0, $token)];
});
return $this->response(fn () => ['subscribed' => $this->subscriptionService->set(true, null, $token)]);
}
/**
@ -321,9 +278,7 @@ class PublicController extends Controller {
* @NoAdminRequired
*/
public function unsubscribe(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['subscribed' => $this->subscriptionService->set(true, 0, $token)];
});
return $this->response(fn () => ['subscribed' => $this->subscriptionService->set(true, null, $token)]);
}
/**
@ -334,9 +289,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function validatePublicUsername(string $userName, string $token): DataResponse {
return $this->response(function () use ($userName, $token) {
return ['result' => $this->systemService->validatePublicUsername($userName, $token), 'name' => $userName];
});
return $this->response(fn () => ['result' => $this->systemService->validatePublicUsername($userName, $token), 'name' => $userName]);
}
/**
@ -345,9 +298,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function validateEmailAddress(string $emailAddress): DataResponse {
return $this->response(function () use ($emailAddress) {
return ['result' => $this->systemService->validateEmailAddress($emailAddress), 'emailAddress' => $emailAddress];
});
return $this->response(fn () => ['result' => $this->systemService->validateEmailAddress($emailAddress), 'emailAddress' => $emailAddress]);
}
/**
@ -356,9 +307,7 @@ class PublicController extends Controller {
* @NoAdminRequired
*/
public function setEmailAddress(string $token, string $emailAddress = ''): DataResponse {
return $this->response(function () use ($token, $emailAddress) {
return ['share' => $this->shareService->setEmailAddress($token, $emailAddress, true)];
});
return $this->response(fn () => ['share' => $this->shareService->setEmailAddress($token, $emailAddress, true)]);
}
/**
@ -367,9 +316,7 @@ class PublicController extends Controller {
* @NoAdminRequired
*/
public function deleteEmailAddress(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['share' => $this->shareService->deleteEmailAddress($token)];
});
return $this->response(fn () => ['share' => $this->shareService->deleteEmailAddress($token)]);
}
/**
@ -379,9 +326,7 @@ class PublicController extends Controller {
* @PublicPage
*/
public function register(string $token, string $userName, string $emailAddress = ''): DataResponse {
return $this->responseCreate(function () use ($token, $userName, $emailAddress) {
return ['share' => $this->shareService->register($token, $userName, $emailAddress)];
});
return $this->responseCreate(fn () => ['share' => $this->shareService->register($token, $userName, $emailAddress)]);
}
/**
@ -391,8 +336,6 @@ class PublicController extends Controller {
* @PublicPage
*/
public function resendInvitation(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['share' => $this->mailService->resendInvitation($token)];
});
return $this->response(fn () => ['share' => $this->mailService->resendInvitation($token)]);
}
}

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

@ -50,9 +50,7 @@ class SettingsController extends Controller {
* @NoAdminRequired
*/
public function getAppSettings(): DataResponse {
return $this->response(function (): array {
return ['appSettings' => $this->settingsService->getAppSettings()];
});
return $this->response(fn () => ['appSettings' => $this->settingsService->getAppSettings()]);
}
/**
@ -60,8 +58,6 @@ class SettingsController extends Controller {
*/
public function writeAppSettings(array $appSettings): DataResponse {
$this->settingsService->writeAppSettings($appSettings);
return $this->response(function (): array {
return ['appSettings' => $this->settingsService->getAppSettings()];
});
return $this->response(fn () => ['appSettings' => $this->settingsService->getAppSettings()]);
}
}

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

@ -61,9 +61,7 @@ class ShareApiController extends ApiController {
* @NoCSRFRequired
*/
public function list(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return ['shares' => $this->shareService->list($pollId)];
});
return $this->response(fn () => ['shares' => $this->shareService->list($pollId)]);
}
/**
@ -73,9 +71,7 @@ class ShareApiController extends ApiController {
* @NoCSRFRequired
*/
public function get(string $token): DataResponse {
return $this->response(function () use ($token) {
return ['share' => $this->shareService->get($token)];
});
return $this->response(fn () => ['share' => $this->shareService->get($token)]);
}
/**
@ -85,9 +81,7 @@ class ShareApiController extends ApiController {
* @NoCSRFRequired
*/
public function add(int $pollId, string $type, string $userId = ''): DataResponse {
return $this->responseCreate(function () use ($pollId, $type, $userId) {
return ['share' => $this->shareService->add($pollId, $type, $userId)];
});
return $this->responseCreate(fn () => ['share' => $this->shareService->add($pollId, $type, $userId)]);
}
/**
@ -97,9 +91,7 @@ class ShareApiController extends ApiController {
* @NoCSRFRequired
*/
public function delete(string $token): DataResponse {
return $this->responseDeleteTolerant(function () use ($token) {
return ['share' => $this->shareService->delete($token)];
});
return $this->responseDeleteTolerant(fn () => ['share' => $this->shareService->delete($token)]);
}
/**
@ -109,13 +101,11 @@ class ShareApiController extends ApiController {
* @NoCSRFRequired
*/
public function sendInvitation(string $token): DataResponse {
return $this->response(function () use ($token) {
$sentResult = $this->mailService->sendInvitation($token);
$share = $this->shareService->get($token);
return [
'share' => $share,
'sentResult' => $sentResult
];
});
$sentResult = $this->mailService->sendInvitation($token);
$share = $this->shareService->get($token);
return $this->response(fn () => [
'share' => $share,
'sentResult' => $sentResult
]);
}
}

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

@ -70,9 +70,7 @@ class ShareController extends Controller {
* @return DataResponse
*/
public function list(int $pollId): DataResponse {
return $this->response(function () use ($pollId): array {
return ['shares' => $this->shareService->list($pollId)];
});
return $this->response(fn () => ['shares' => $this->shareService->list($pollId)]);
}
/**
@ -80,9 +78,7 @@ class ShareController extends Controller {
* @NoAdminRequired
*/
public function add(int $pollId, string $type, string $userId = '', string $displayName = ''): DataResponse {
return $this->responseCreate(function () use ($pollId, $type, $userId, $displayName) {
return ['share' => $this->shareService->add($pollId, $type, $userId, $displayName)];
});
return $this->responseCreate(fn () => ['share' => $this->shareService->add($pollId, $type, $userId, $displayName)]);
}
/**
@ -90,9 +86,7 @@ class ShareController extends Controller {
* @NoAdminRequired
*/
public function userToAdmin(string $token): DataResponse {
return $this->responseCreate(function () use ($token) {
return ['share' => $this->shareService->setType($token, Share::TYPE_ADMIN)];
});
return $this->responseCreate(fn () => ['share' => $this->shareService->setType($token, Share::TYPE_ADMIN)]);
}
/**
@ -100,9 +94,7 @@ class ShareController extends Controller {
* @NoAdminRequired
*/
public function setPublicPollEmail(string $token, string $value): DataResponse {
return $this->response(function () use ($token, $value) {
return ['share' => $this->shareService->setPublicPollEmail($token, $value)];
});
return $this->response(fn () => ['share' => $this->shareService->setPublicPollEmail($token, $value)]);
}
/**
@ -110,9 +102,7 @@ class ShareController extends Controller {
* @NoAdminRequired
*/
public function adminToUser(string $token): DataResponse {
return $this->responseCreate(function () use ($token) {
return ['share' => $this->shareService->setType($token, Share::TYPE_USER)];
});
return $this->responseCreate(fn () => ['share' => $this->shareService->setType($token, Share::TYPE_USER)]);
}
/**
@ -120,9 +110,7 @@ class ShareController extends Controller {
* @NoAdminRequired
*/
public function setEmailAddress(string $token, string $emailAddress = ''): DataResponse {
return $this->response(function () use ($token, $emailAddress) {
return ['share' => $this->shareService->setEmailAddress($token, $emailAddress)];
});
return $this->response(fn () => ['share' => $this->shareService->setEmailAddress($token, $emailAddress)]);
}
/**
@ -131,9 +119,7 @@ class ShareController extends Controller {
* @NoAdminRequired
*/
public function register(string $token, string $userName, string $emailAddress = ''): DataResponse {
return $this->responseCreate(function () use ($token, $userName, $emailAddress) {
return ['share' => $this->shareService->register($token, $userName, $emailAddress)];
});
return $this->responseCreate(fn () => ['share' => $this->shareService->register($token, $userName, $emailAddress)]);
}
/**
@ -142,9 +128,7 @@ class ShareController extends Controller {
*/
public function delete(string $token): DataResponse {
return $this->responseDeleteTolerant(function () use ($token) {
return ['share' => $this->shareService->delete($token)];
});
return $this->responseDeleteTolerant(fn () => ['share' => $this->shareService->delete($token)]);
}
/**
@ -153,12 +137,10 @@ class ShareController extends Controller {
* @NoAdminRequired
*/
public function sendInvitation(string $token): DataResponse {
return $this->response(function () use ($token) {
return [
'share' => $this->shareService->get($token),
'sentResult' => $this->shareService->sendInvitation($token),
];
});
return $this->response(fn () => [
'share' => $this->shareService->get($token),
'sentResult' => $this->shareService->sendInvitation($token),
]);
}
/**

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

@ -49,10 +49,8 @@ class SubscriptionController extends Controller {
* Get subscription status
* @NoAdminRequired
*/
public function get(int $pollId = 0): DataResponse {
return $this->response(function () use ($pollId) {
return ['subscribed' => $this->subscriptionService->get($pollId)];
});
public function get(int $pollId): DataResponse {
return $this->response(fn () => ['subscribed' => $this->subscriptionService->get($pollId)]);
}
/**
@ -60,9 +58,7 @@ class SubscriptionController extends Controller {
* @NoAdminRequired
*/
public function subscribe(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return ['subscribed' => $this->subscriptionService->set(true, $pollId, '')];
});
return $this->response(fn () => ['subscribed' => $this->subscriptionService->set(true, $pollId, '')]);
}
/**
@ -70,8 +66,6 @@ class SubscriptionController extends Controller {
* @NoAdminRequired
*/
public function unsubscribe(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return ['subscribed' => $this->subscriptionService->set(false, $pollId, '')];
});
return $this->response(fn () => ['subscribed' => $this->subscriptionService->set(false, $pollId, '')]);
}
}

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

@ -51,9 +51,7 @@ class VoteController extends Controller {
* @NoCSRFRequired
*/
public function list(int $pollId): DataResponse {
return $this->response(function () use ($pollId) {
return ['votes' => $this->voteService->list($pollId)];
});
return $this->response(fn () => ['votes' => $this->voteService->list($pollId)]);
}
/**
@ -62,9 +60,7 @@ class VoteController extends Controller {
* @NoCSRFRequired
*/
public function set(int $optionId, string $setTo): DataResponse {
return $this->response(function () use ($optionId, $setTo) {
return ['vote' => $this->voteService->set($optionId, $setTo)];
});
return $this->response(fn () => ['vote' => $this->voteService->set($optionId, $setTo)]);
}
/**
@ -72,8 +68,6 @@ class VoteController extends Controller {
* @NoAdminRequired
*/
public function delete(int $pollId, string $userId = ''): DataResponse {
return $this->response(function () use ($pollId, $userId) {
return ['deleted' => $this->voteService->delete($pollId, $userId)];
});
return $this->response(fn () => ['deleted' => $this->voteService->delete($pollId, $userId)]);
}
}

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

@ -26,18 +26,13 @@ namespace OCA\Polls\Controller;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCA\Polls\Exceptions\NoUpdatesException;
use OCA\Polls\Service\WatchService;
use OCA\Polls\Model\Settings\AppSettings;
class WatchController extends Controller {
/** @var WatchService */
private $watchService;
/** @var AppSettings */
private $appSettings;
use ResponseHandle;
public function __construct(
@ -47,7 +42,6 @@ class WatchController extends Controller {
) {
parent::__construct($appName, $request);
$this->watchService = $watchService;
$this->appSettings = new AppSettings;
}
/**
@ -56,25 +50,6 @@ class WatchController extends Controller {
* @NoCSRFRequired
*/
public function watchPoll(int $pollId, ?int $offset): DataResponse {
return $this->responseLong(function () use ($pollId, $offset) {
$start = time();
$timeout = 30;
$offset = $offset ?? $start;
if ($this->appSettings->getStringSetting(AppSettings::SETTING_UPDATE_TYPE) === 'longPolling') {
while (empty($updates) && time() <= $start + $timeout) {
sleep(1);
$updates = $this->watchService->getUpdates($pollId, $offset);
}
} else {
$updates = $this->watchService->getUpdates($pollId, $offset);
}
if (empty($updates)) {
throw new NoUpdatesException;
}
return ['updates' => $updates];
});
return $this->responseLong(fn () => ['updates' => $this->watchService->watchUpdates($pollId, $offset)]);
}
}

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

@ -31,6 +31,7 @@ use OCA\Polls\Helper\Container;
use OCP\IUser;
use OCP\IUserManager;
use OCP\AppFramework\Db\Entity;
use OCP\AppFramework\Db\DoesNotExistException;
/**
* @method int getId()
@ -65,10 +66,14 @@ class Comment extends Entity implements JsonSerializable {
/** @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);
}
public function jsonSerialize() {
@ -98,9 +103,17 @@ class Comment extends Entity implements JsonSerializable {
if (!strncmp($this->userId, 'deleted_', 8)) {
return 'Deleted User';
}
return $this->getIsNoUser()
? $this->userId
: $this->userManager->get($this->userId)->getDisplayName();
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 {

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

@ -31,6 +31,7 @@ use OCA\Polls\Helper\Container;
use OCP\AppFramework\Db\Entity;
use OCP\IUser;
use OCP\IUserManager;
use OCP\AppFramework\Db\DoesNotExistException;
/**
* @method int getId()
@ -104,6 +105,9 @@ class Option extends Entity implements JsonSerializable {
/** @var IUserManager */
private $userManager;
/** @var ShareMapper */
private $shareMapper;
public function __construct() {
$this->addType('released', 'int');
$this->addType('pollId', 'int');
@ -112,6 +116,7 @@ class Option extends Entity implements JsonSerializable {
$this->addType('confirmed', 'int');
$this->addType('duration', 'int');
$this->userManager = Container::queryClass(IUserManager::class);
$this->shareMapper = Container::queryClass(ShareMapper::class);
}
public function jsonSerialize() {
@ -192,9 +197,22 @@ class Option extends Entity implements JsonSerializable {
if (!strncmp($this->getOwner(), 'deleted_', 8)) {
return 'Deleted User';
}
return $this->getOwnerIsNoUser()
? $this->getOwner()
: $this->userManager->get($this->getOwner())->getDisplayName();
// if ($this->getOwner() === '') {
// return '';
// }
// return $this->getOwnerIsNoUser()
// ? $this->getOwner()
// : $this->userManager->get($this->getOwner())->getDisplayName();
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();
}
private function getOwnerIsNoUser(): bool {

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

@ -30,6 +30,7 @@ use OCA\Polls\Helper\Container;
use OCP\IUser;
use OCP\IUserManager;
use OCP\AppFramework\Db\Entity;
use OCP\AppFramework\Db\DoesNotExistException;
/**
* @method int getPollId()
@ -64,11 +65,15 @@ class Vote extends Entity implements JsonSerializable {
/** @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);
}
public function jsonSerialize() {
@ -89,9 +94,16 @@ class Vote extends Entity implements JsonSerializable {
if (!strncmp($this->userId, 'deleted_', 8)) {
return 'Deleted User';
}
return $this->getIsNoUser()
? $this->userId
: $this->userManager->get($this->userId)->getDisplayName();
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 {

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

@ -311,6 +311,8 @@ class Acl implements JsonSerializable {
'isOwner' => $this->getIsOwner(),
'isVoteLimitExceeded' => $this->getIsVoteLimitExceeded(),
'loggedIn' => $this->getIsLoggedIn(),
'isNoUser' => !$this->getIsLoggedIn(),
'isGuest' => !$this->getIsLoggedIn(),
'pollId' => $this->getPollId(),
'token' => $this->getToken(),
'userHasVoted' => $this->getIsParticipant(),
@ -324,7 +326,7 @@ class Acl implements JsonSerializable {
/**
* getIsLogged - Is user logged in to nextcloud?
*/
private function getIsLoggedIn(): bool {
public function getIsLoggedIn(): bool {
return $this->userSession->isLoggedIn();
}

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

@ -27,6 +27,7 @@ use OCA\Polls\Exceptions\InvalidShareTypeException;
use DateTimeZone;
use OCP\IL10N;
use OCA\Polls\Db\ShareMapper;
use OCA\Polls\Helper\Container;
use OCP\Collaboration\Collaborators\ISearch;
use OCP\Share\IShare;
@ -272,6 +273,20 @@ class UserBase implements \JsonSerializable {
return [$this];
}
/**
* @return Admin|Circle|Contact|ContactGroup|Email|GenericUser|Group|User
*/
public static function getUserGroupChildFromShare(string $token) {
$shareMapper = Container::queryClass(ShareMapper::class);
$share = $shareMapper->findByToken($token);
return self::getUserGroupChild(
$share->getType(),
$share->getUserId(),
$share->getDisplayName(),
$share->getEmailAddress()
);
}
/**
* @return Circle|Contact|ContactGroup|Email|GenericUser|Group|User|Admin
*/

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

@ -70,7 +70,7 @@ class AnonymizeService {
* $array Input list which should be anonymized must be a collection of Vote or Comment
* Returns the original array with anonymized user names
*/
private function anonymize(array $array): array {
public function anonymize(array &$array): void {
// get mapping for the complete poll
foreach ($array as &$element) {
if (!$element->getUserId() || $element->getUserId() === $this->userId) {
@ -79,8 +79,6 @@ class AnonymizeService {
}
$element->setUserId($this->anonList[$element->getUserId()] ?? 'Unknown user');
}
return $array;
}
/**
@ -115,42 +113,15 @@ class AnonymizeService {
return;
}
/**
* Anonymizes the comments of a poll
* Returns anonymized comments
*/
public function getComments(): array {
return $this->anonymize($this->commentMapper->findByPoll($this->pollId));
}
/**
* Anonymizes the participants of a poll
* Returns anonymized votes
*/
public function getVotes(): array {
return $this->anonymize($this->voteMapper->findByPoll($this->pollId));
}
/**
* Anonymizes the proposal users
* Returns options with anonymized owners
*/
public function getOptions(): array {
return $this->anonymize($this->optionMapper->findByPoll($this->pollId));
}
/**
* Replaces userIds with displayName to avoid exposing usernames in public polls
*
* @param (Comment|Option|Poll|Vote)[]|Comment|Option|Poll|Vote $arrayOrObject
*
* @return (Comment|Option|Poll|Vote)[]|Comment|Option|Poll|Vote
*
* @psalm-return Comment|Option|Poll|Vote|array<Comment|Option|Poll|Vote>
*/
public static function replaceUserId($arrayOrObject) {
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());
}
@ -158,6 +129,11 @@ class AnonymizeService {
$item->setOwner($item->getDisplayName());
}
}
return;
}
if ($arrayOrObject->getUserId() === $userId) {
return;
}
if ($arrayOrObject instanceof Option || $arrayOrObject instanceof Poll) {
@ -168,6 +144,6 @@ class AnonymizeService {
$arrayOrObject->setUserId($arrayOrObject->getDisplayName());
}
return $arrayOrObject;
return;
}
}

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

@ -64,27 +64,35 @@ class CommentService {
/**
* Get comments
* Read all comments of a poll based on the poll id and return list as array
*
* @return Comment[]
*
*/
public function listFlat(?int $pollId = 0, string $token = ''): array {
public function listFlat(?int $pollId, string $token = '') : array {
if ($token) {
$this->acl->setToken($token);
} else {
$this->acl->setPollId($pollId);
}
if ($this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
return $this->commentMapper->findByPoll($this->acl->getPollId());
} else {
$comments = $this->commentMapper->findByPoll($this->acl->getPollId());
if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
$this->anonymizer->set($this->acl->getPollId(), $this->acl->getUserId());
return $this->anonymizer->getComments();
$this->anonymizer->anonymize($comments);
} elseif (!$this->acl->getIsLoggedIn()) {
// if participant is not logged in avoid leaking user ids
AnonymizeService::replaceUserId($comments, $this->acl->getUserId());
}
return $comments;
}
/**
* Get comments
* Read all comments of a poll based on the poll id and return list as array
*/
public function list(?int $pollId = 0, string $token = ''): array {
public function list(?int $pollId, string $token = ''): array {
$comments = $this->listFlat($pollId, $token);
$timeTolerance = 5 * 60; // treat comments within 5 minutes as one comment
$groupedComments = [];
@ -108,7 +116,7 @@ class CommentService {
/**
* Add comment
*/
public function add(int $pollId = 0, ?string $token = '', string $message = ''): Comment {
public function add(string $message, ?int $pollId = null, ?string $token = null): Comment {
if ($token) {
$this->acl->setToken($token, Acl::PERMISSION_COMMENT_ADD);
} else {

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

@ -112,7 +112,7 @@ class OptionService {
*
* @psalm-return array<array-key, Option>
*/
public function list(int $pollId = 0, string $token = ''): array {
public function list(?int $pollId, ?string $token = null): array {
if ($token) {
$this->acl->setToken($token);
} else {
@ -120,16 +120,18 @@ class OptionService {
}
try {
$this->options = $this->optionMapper->findByPoll($this->acl->getPollId());
if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
$this->anonymizer->set($this->acl->getpollId(), $this->acl->getUserId());
$this->options = $this->anonymizer->getOptions();
} else {
$this->options = $this->optionMapper->findByPoll($this->acl->getPollId());
$this->anonymizer->anonymize($this->options);
} elseif (!$this->acl->getIsLoggedIn()) {
// if participant is not logged in avoid leaking user ids
AnonymizeService::replaceUserId($this->options, $this->acl->getUserId());
}
$this->votes = $this->voteMapper->findByPoll($this->acl->getPollId());
$this->calculateVotes();
if ($this->acl->getPoll()->getHideBookedUp() && !$this->acl->getIsAllowed(Acl::PERMISSION_POLL_EDIT)) {
@ -140,11 +142,11 @@ class OptionService {
if ($this->acl->getIsAllowed(Acl::PERMISSION_POLL_RESULTS_VIEW)) {
$this->calculateRanks();
}
return array_values($this->options);
} catch (DoesNotExistException $e) {
return [];
$this->options = [];
}
return array_values($this->options);
}
/**
@ -164,7 +166,7 @@ class OptionService {
*
* @return Option
*/
public function add(int $pollId, int $timestamp = 0, string $pollOptionText = '', ?int $duration = 0, string $token = ''): Option {
public function add(?int $pollId, int $timestamp = 0, string $pollOptionText = '', ?int $duration = 0, string $token = ''): Option {
if ($token) {
$this->acl->setToken($token, Acl::PERMISSION_OPTIONS_ADD);
} else {

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

@ -194,9 +194,15 @@ class PollService {
/**
* get poll configuration
*/
public function get(int $pollId): Poll {
public function get(int $pollId) : Poll {
$this->acl->setPollId($pollId);
return $this->acl->getPoll();
$this->poll = $this->pollMapper->find($pollId);
if (!$this->acl->getIsLoggedIn()) {
// if participant is not logged in avoid leaking user ids
AnonymizeService::replaceUserId($this->poll, $this->acl->getUserId());
}
return $this->poll;
}
/**

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

@ -35,6 +35,7 @@ use OCA\Polls\Exceptions\NotAuthorizedException;
use OCA\Polls\Exceptions\InvalidShareTypeException;
use OCA\Polls\Exceptions\ShareAlreadyExistsException;
use OCA\Polls\Exceptions\NotFoundException;
use OCA\Polls\Exceptions\InvalidUsernameException;
use OCA\Polls\Db\PollMapper;
use OCA\Polls\Db\ShareMapper;
@ -159,9 +160,10 @@ class ShareService {
}
/**
* Validate share
* Validate if share type is allowed to be used in a public poll
* or is accessibale for use by the current user
*/
private function validate() : void {
private function validateShareType() : void {
switch ($this->share->getType()) {
case Share::TYPE_PUBLIC:
// public shares are always valid
@ -200,11 +202,11 @@ class ShareService {
/**
* Get share by token
*/
public function get(string $token, bool $validate = false): Share {
public function get(string $token, bool $validateShareType = false): Share {
try {
$this->share = $this->shareMapper->findByToken($token);
if ($validate) {
$this->validate();
if ($validateShareType) {
$this->validateShareType();
}
} catch (DoesNotExistException $e) {
throw new NotFoundException('Token ' . $token . ' does not exist');
@ -216,9 +218,9 @@ class ShareService {
// Test if the user has already access.
$this->acl->setPollId($this->share->getPollId());
} catch (NotAuthorizedException $e) {
// If he is not authorized until now, create a new personal share for this user.
// If he is not authorized until now, createNewShare a new personal share for this user.
// Return the created share
return $this->create(
return $this->createNewShare(
$this->share->getPollId(),
UserBase::getUserGroupChild(Share::TYPE_USER, $this->userSession->getUser()->getUID()),
true
@ -240,11 +242,11 @@ class ShareService {
}
/**
* crate share - MUST BE PRIVATE!
* crate a new share
*
* @return Share
*/
private function create(int $pollId, UserBase $userGroup, bool $preventInvitation = false): Share {
private function createNewShare(int $pollId, UserBase $userGroup, bool $preventInvitation = false): Share {
$preventInvitation = $userGroup->getType() === UserBase::TYPE_PUBLIC ?: $preventInvitation;
$token = $this->secureRandom->generate(
16,
@ -297,7 +299,7 @@ class ShareService {
}
}
$this->create($pollId, UserBase::getUserGroupChild($type, $userId, $displayName, $emailAddress));
$this->createNewShare($pollId, UserBase::getUserGroupChild($type, $userId, $displayName, $emailAddress));
$this->eventDispatcher->dispatchTyped(new ShareCreateEvent($this->share));
@ -386,6 +388,28 @@ class ShareService {
}
}
private function generatePublicUserId(string $token, string $prefix = 'ex_'): string {
$publicUserId = '';
while ($publicUserId === '') {
$publicUserId = $prefix . $this->secureRandom->generate(
8,
ISecureRandom::CHAR_DIGITS .
ISecureRandom::CHAR_LOWER .
ISecureRandom::CHAR_UPPER
);
try {
// make sure, the user id is unique
$this->systemService->validatePublicUsername($publicUserId, $token);
} catch (InvalidUsernameException $th) {
$publicUserId = '';
}
}
return $publicUserId;
}
/**
* Create a personal share from a public share
* or update an email share with the username
@ -401,17 +425,19 @@ class ShareService {
}
$this->systemService->validatePublicUsername($userName, $token);
if ($this->share->getPublicPollEmail() !== Share::EMAIL_DISABLED) {
$this->systemService->validateEmailAddress($emailAddress, $this->share->getPublicPollEmail() !== Share::EMAIL_MANDATORY);
}
$userId = $this->generatePublicUserId($token);
if ($this->share->getType() === Share::TYPE_PUBLIC) {
// Create new external share for user, who entered the poll via public link,
// prevent invtation sending, when no email address is given
$this->create(
$this->createNewShare(
$this->share->getPollId(),
UserBase::getUserGroupChild(Share::TYPE_EXTERNAL, $userName, $userName, $emailAddress),
UserBase::getUserGroupChild(Share::TYPE_EXTERNAL, $userId, $userName, $emailAddress),
!$emailAddress
);
$this->eventDispatcher->dispatchTyped(new ShareRegistrationEvent($this->share));
@ -420,7 +446,7 @@ class ShareService {
// Convert email and contact shares to external share, if user registers
$this->share->setType(Share::TYPE_EXTERNAL);
$this->share->setUserId($userName);
$this->share->setUserId($userId);
$this->share->setDisplayName($userName);
// prepare for resending invitation to new email address

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

@ -47,7 +47,7 @@ class SubscriptionService {
$this->acl = $acl;
}
public function get(int $pollId = 0, string $token = ''): bool {
public function get(?int $pollId = null, ?string $token = null): bool {
if ($token) {
$this->acl->setToken($token);
} else {
@ -70,7 +70,7 @@ class SubscriptionService {
$this->subscriptionMapper->insert($subscription);
}
public function set(bool $subscribed, int $pollId = 0, string $token = ''): bool {
public function set(bool $subscribed, ?int $pollId = null, ?string $token = null): bool {
if ($token) {
$this->acl->setToken($token);
} else {

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

@ -73,8 +73,10 @@ class VoteService {
/**
* Read all votes of a poll based on the poll id and return list as array
*
* @return Vote[]
*/
public function list(int $pollId = 0, string $token = ''): array {
public function list(?int $pollId, string $token = '') : array {
if ($token) {
$this->acl->setToken($token);
} else {
@ -83,18 +85,23 @@ class VoteService {
try {
if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_RESULTS_VIEW)) {
// Just return the participants votes, no further anoymizing or obfuscatin is nessecary
return $this->voteMapper->findByPollAndUser($this->acl->getpollId(), $this->acl->getUserId());
}
$votes = $this->voteMapper->findByPoll($this->acl->getpollId());
if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
$this->anonymizer->set($this->acl->getpollId(), $this->acl->getUserId());
return $this->anonymizer->getVotes();
$this->anonymizer->anonymize($votes);
} elseif (!$this->acl->getIsLoggedIn()) {
// if participant is not logged in avoid leaking user ids
AnonymizeService::replaceUserId($votes, $this->acl->getUserId());
}
return $this->voteMapper->findByPoll($this->acl->getpollId());
} catch (DoesNotExistException $e) {
return [];
$votes = [];
}
return $votes;
}
private function checkLimits(Option $option, string $userId): void {
@ -156,19 +163,19 @@ class VoteService {
/**
* Remove user from poll
*/
public function delete(int $pollId = 0, string $userId = '', string $token = ''): string {
public function delete(?int $pollId, ?string $userId, string $token = ''): string {
if ($token) {
$this->acl->setToken($token, Acl::PERMISSION_VOTE_EDIT);
$userId = $this->acl->getUserId();
$pollId = $this->acl->getPollId();
} else {
if ($userId) {
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
} else {
$this->acl->setPollId($pollId, Acl::PERMISSION_VOTE_EDIT);
$userId = $this->acl->getUserId();
}
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
}
if (!$userId) {
$userId = $this->acl->getUserId();
}
// fake a vote so that the event can be triggered
// surpress logging of this action
$this->vote = new Vote();

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

@ -27,9 +27,14 @@ use OCP\AppFramework\Db\DoesNotExistException;
use OCA\Polls\Db\Watch;
use OCA\Polls\Db\WatchMapper;
use OCA\Polls\Exceptions\NoUpdatesException;
use OCA\Polls\Model\Settings\AppSettings;
class WatchService {
/** @var AppSettings */
private $appSettings;
/** @var WatchMapper */
private $watchMapper;
@ -40,9 +45,34 @@ class WatchService {
WatchMapper $watchMapper
) {
$this->watchMapper = $watchMapper;
$this->appSettings = new AppSettings;
$this->watch = new Watch;
}
/**
* Watch poll for updates
*/
public function watchUpdates(int $pollId, ?int $offset): array {
$start = time();
$timeout = 30;
$offset = $offset ?? $start;
if ($this->appSettings->getStringSetting(AppSettings::SETTING_UPDATE_TYPE) === 'longPolling') {
while (empty($updates) && time() <= $start + $timeout) {
sleep(1);
$updates = $this->getUpdates($pollId, $offset);
}
} else {
$updates = $this->getUpdates($pollId, $offset);
}
if (empty($updates)) {
throw new NoUpdatesException;
}
return $updates;
}
/**
* @return Watch[]
*/

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

@ -39,6 +39,8 @@ const defaultAcl = () => ({
allowVote: false,
displayName: '',
isOwner: false,
isNoUser: true,
isGuest: true,
isVoteLimitExceeded: false,
loggedIn: false,
pollId: null,