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 * @NoCSRFRequired
*/ */
public function index(): TemplateResponse { public function index(): TemplateResponse {
return new TemplateResponse('polls', 'polls.tmpl', return new TemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]);
['urlGenerator' => $this->urlGenerator]);
} }
/** /**
* Get list of polls for administrative purposes * Get list of polls for administrative purposes
*/ */
public function list(): DataResponse { public function list(): DataResponse {
return $this->response(function () { return $this->response(fn () => $this->pollService->listForAdmin());
return $this->pollService->listForAdmin();
});
} }
/** /**
* Get list of polls for administrative purposes * Get list of polls for administrative purposes
*/ */
public function takeover(int $pollId): DataResponse { public function takeover(int $pollId): DataResponse {
return $this->response(function () use ($pollId) { return $this->response(fn () => $this->pollService->takeover($pollId));
return $this->pollService->takeover($pollId);
});
} }
/** /**
* Switch deleted status (move to deleted polls) * Switch deleted status (move to deleted polls)
*/ */
public function toggleArchive(int $pollId): DataResponse { public function toggleArchive(int $pollId): DataResponse {
return $this->response(function () use ($pollId) { return $this->response(fn () => $this->pollService->toggleArchive($pollId));
return $this->pollService->toggleArchive($pollId);
});
} }
/** /**
* Delete poll * Delete poll
*/ */
public function delete(int $pollId): DataResponse { public function delete(int $pollId): DataResponse {
return $this->responseDeleteTolerant(function () use ($pollId) { return $this->responseDeleteTolerant(fn () => $this->pollService->delete($pollId));
return $this->pollService->delete($pollId);
});
} }
} }

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

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

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

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

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

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

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

@ -23,9 +23,6 @@
namespace OCA\Polls\Controller; namespace OCA\Polls\Controller;
use DateTime;
use DateInterval;
use DateTimeZone;
use OCP\IRequest; use OCP\IRequest;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\DataResponse;
@ -68,15 +65,11 @@ class OptionController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function add(int $pollId, int $timestamp = 0, string $text = '', int $duration = 0): DataResponse { public function add(int $pollId, int $timestamp = 0, string $text = '', int $duration = 0): DataResponse {
return $this->responseCreate(function () use ($pollId, $timestamp, $text, $duration) { return $this->responseCreate(fn () => ['option' => $this->optionService->add($pollId, $timestamp, $text, $duration)]);
return ['option' => $this->optionService->add($pollId, $timestamp, $text, $duration)];
});
} }
public function addBulk(int $pollId, string $text = ''): DataResponse { public function addBulk(int $pollId, string $text = ''): DataResponse {
return $this->responseCreate(function () use ($pollId, $text) { return $this->responseCreate(fn () => ['options' => $this->optionService->addBulk($pollId, $text)]);
return ['options' => $this->optionService->addBulk($pollId, $text)];
});
} }
/** /**
@ -84,9 +77,7 @@ class OptionController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function update(int $optionId, int $timestamp, string $text, int $duration): DataResponse { public function update(int $optionId, int $timestamp, string $text, int $duration): DataResponse {
return $this->response(function () use ($optionId, $timestamp, $text, $duration) { return $this->response(fn () => ['option' => $this->optionService->update($optionId, $timestamp, $text, $duration)]);
return ['option' => $this->optionService->update($optionId, $timestamp, $text, $duration)];
});
} }
/** /**
@ -94,9 +85,7 @@ class OptionController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function delete(int $optionId): DataResponse { public function delete(int $optionId): DataResponse {
return $this->responseDeleteTolerant(function () use ($optionId) { return $this->responseDeleteTolerant(fn () => ['option' => $this->optionService->delete($optionId)]);
return ['option' => $this->optionService->delete($optionId)];
});
} }
/** /**
@ -104,9 +93,7 @@ class OptionController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function confirm(int $optionId): DataResponse { public function confirm(int $optionId): DataResponse {
return $this->response(function () use ($optionId) { return $this->response(fn () => ['option' => $this->optionService->confirm($optionId)]);
return ['option' => $this->optionService->confirm($optionId)];
});
} }
/** /**
@ -114,9 +101,7 @@ class OptionController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function reorder(int $pollId, array $options): DataResponse { public function reorder(int $pollId, array $options): DataResponse {
return $this->response(function () use ($pollId, $options) { return $this->response(fn () => ['options' => $this->optionService->reorder($pollId, $options)]);
return ['options' => $this->optionService->reorder($pollId, $options)];
});
} }
/** /**
@ -124,9 +109,7 @@ class OptionController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function sequence(int $optionId, int $step, string $unit, int $amount): DataResponse { public function sequence(int $optionId, int $step, string $unit, int $amount): DataResponse {
return $this->response(function () use ($optionId, $step, $unit, $amount) { return $this->response(fn () => ['options' => $this->optionService->sequence($optionId, $step, $unit, $amount)]);
return ['options' => $this->optionService->sequence($optionId, $step, $unit, $amount)];
});
} }
/** /**
@ -134,9 +117,7 @@ class OptionController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function shift(int $pollId, int $step, string $unit): DataResponse { public function shift(int $pollId, int $step, string $unit): DataResponse {
return $this->response(function () use ($pollId, $step, $unit) { return $this->response(fn () => ['options' => $this->optionService->shift($pollId, $step, $unit)]);
return ['options' => $this->optionService->shift($pollId, $step, $unit)];
});
} }
/** /**
@ -144,28 +125,6 @@ class OptionController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function findCalendarEvents(int $optionId, string $tz): DataResponse { public function findCalendarEvents(int $optionId, string $tz): DataResponse {
return $this->response(function () use ($optionId, $tz) { return $this->response(fn () => ['events' => $this->calendarService->getEvents($optionId, $tz)]);
return ['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 * @NoCSRFRequired
*/ */
public function index(): TemplateResponse { public function index(): TemplateResponse {
return new TemplateResponse('polls', 'polls.tmpl', return new TemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]);
['urlGenerator' => $this->urlGenerator]);
} }
/** /**
@ -64,7 +63,6 @@ class PageController extends Controller {
*/ */
public function vote(int $id): TemplateResponse { public function vote(int $id): TemplateResponse {
$this->notificationService->removeNotification($id); $this->notificationService->removeNotification($id);
return new TemplateResponse('polls', 'polls.tmpl', return new TemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]);
['urlGenerator' => $this->urlGenerator]);
} }
} }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -26,18 +26,13 @@ namespace OCA\Polls\Controller;
use OCP\IRequest; use OCP\IRequest;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\DataResponse;
use OCA\Polls\Exceptions\NoUpdatesException;
use OCA\Polls\Service\WatchService; use OCA\Polls\Service\WatchService;
use OCA\Polls\Model\Settings\AppSettings;
class WatchController extends Controller { class WatchController extends Controller {
/** @var WatchService */ /** @var WatchService */
private $watchService; private $watchService;
/** @var AppSettings */
private $appSettings;
use ResponseHandle; use ResponseHandle;
public function __construct( public function __construct(
@ -47,7 +42,6 @@ class WatchController extends Controller {
) { ) {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->watchService = $watchService; $this->watchService = $watchService;
$this->appSettings = new AppSettings;
} }
/** /**
@ -56,25 +50,6 @@ class WatchController extends Controller {
* @NoCSRFRequired * @NoCSRFRequired
*/ */
public function watchPoll(int $pollId, ?int $offset): DataResponse { public function watchPoll(int $pollId, ?int $offset): DataResponse {
return $this->responseLong(function () use ($pollId, $offset) { return $this->responseLong(fn () => ['updates' => $this->watchService->watchUpdates($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];
});
} }
} }

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

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

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

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

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

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

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

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

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

@ -27,6 +27,7 @@ use OCA\Polls\Exceptions\InvalidShareTypeException;
use DateTimeZone; use DateTimeZone;
use OCP\IL10N; use OCP\IL10N;
use OCA\Polls\Db\ShareMapper;
use OCA\Polls\Helper\Container; use OCA\Polls\Helper\Container;
use OCP\Collaboration\Collaborators\ISearch; use OCP\Collaboration\Collaborators\ISearch;
use OCP\Share\IShare; use OCP\Share\IShare;
@ -272,6 +273,20 @@ class UserBase implements \JsonSerializable {
return [$this]; 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 * @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 * $array Input list which should be anonymized must be a collection of Vote or Comment
* Returns the original array with anonymized user names * 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 // get mapping for the complete poll
foreach ($array as &$element) { foreach ($array as &$element) {
if (!$element->getUserId() || $element->getUserId() === $this->userId) { if (!$element->getUserId() || $element->getUserId() === $this->userId) {
@ -79,8 +79,6 @@ class AnonymizeService {
} }
$element->setUserId($this->anonList[$element->getUserId()] ?? 'Unknown user'); $element->setUserId($this->anonList[$element->getUserId()] ?? 'Unknown user');
} }
return $array;
} }
/** /**
@ -115,42 +113,15 @@ class AnonymizeService {
return; 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 * 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)) { if (is_array($arrayOrObject)) {
foreach ($arrayOrObject as $item) { foreach ($arrayOrObject as $item) {
if ($item->getUserId() === $userId) {
continue;
}
if ($item instanceof Comment || $item instanceof Vote) { if ($item instanceof Comment || $item instanceof Vote) {
$item->setUserId($item->getDisplayName()); $item->setUserId($item->getDisplayName());
} }
@ -158,6 +129,11 @@ class AnonymizeService {
$item->setOwner($item->getDisplayName()); $item->setOwner($item->getDisplayName());
} }
} }
return;
}
if ($arrayOrObject->getUserId() === $userId) {
return;
} }
if ($arrayOrObject instanceof Option || $arrayOrObject instanceof Poll) { if ($arrayOrObject instanceof Option || $arrayOrObject instanceof Poll) {
@ -168,6 +144,6 @@ class AnonymizeService {
$arrayOrObject->setUserId($arrayOrObject->getDisplayName()); $arrayOrObject->setUserId($arrayOrObject->getDisplayName());
} }
return $arrayOrObject; return;
} }
} }

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

@ -64,27 +64,35 @@ class CommentService {
/** /**
* Get comments * Get comments
* Read all comments of a poll based on the poll id and return list as array * 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) { if ($token) {
$this->acl->setToken($token); $this->acl->setToken($token);
} else { } else {
$this->acl->setPollId($pollId); $this->acl->setPollId($pollId);
} }
if ($this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) { $comments = $this->commentMapper->findByPoll($this->acl->getPollId());
return $this->commentMapper->findByPoll($this->acl->getPollId());
} else { if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
$this->anonymizer->set($this->acl->getPollId(), $this->acl->getUserId()); $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 * Get comments
* Read all comments of a poll based on the poll id and return list as array * 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); $comments = $this->listFlat($pollId, $token);
$timeTolerance = 5 * 60; // treat comments within 5 minutes as one comment $timeTolerance = 5 * 60; // treat comments within 5 minutes as one comment
$groupedComments = []; $groupedComments = [];
@ -108,7 +116,7 @@ class CommentService {
/** /**
* Add comment * 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) { if ($token) {
$this->acl->setToken($token, Acl::PERMISSION_COMMENT_ADD); $this->acl->setToken($token, Acl::PERMISSION_COMMENT_ADD);
} else { } else {

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

@ -112,7 +112,7 @@ class OptionService {
* *
* @psalm-return array<array-key, Option> * @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) { if ($token) {
$this->acl->setToken($token); $this->acl->setToken($token);
} else { } else {
@ -120,16 +120,18 @@ class OptionService {
} }
try { try {
$this->options = $this->optionMapper->findByPoll($this->acl->getPollId());
if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) { if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
$this->anonymizer->set($this->acl->getpollId(), $this->acl->getUserId()); $this->anonymizer->set($this->acl->getpollId(), $this->acl->getUserId());
$this->options = $this->anonymizer->getOptions(); $this->anonymizer->anonymize($this->options);
} else { } elseif (!$this->acl->getIsLoggedIn()) {
$this->options = $this->optionMapper->findByPoll($this->acl->getPollId()); // 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->votes = $this->voteMapper->findByPoll($this->acl->getPollId());
$this->calculateVotes(); $this->calculateVotes();
if ($this->acl->getPoll()->getHideBookedUp() && !$this->acl->getIsAllowed(Acl::PERMISSION_POLL_EDIT)) { 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)) { if ($this->acl->getIsAllowed(Acl::PERMISSION_POLL_RESULTS_VIEW)) {
$this->calculateRanks(); $this->calculateRanks();
} }
return array_values($this->options);
} catch (DoesNotExistException $e) { } catch (DoesNotExistException $e) {
return []; $this->options = [];
} }
return array_values($this->options);
} }
/** /**
@ -164,7 +166,7 @@ class OptionService {
* *
* @return Option * @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) { if ($token) {
$this->acl->setToken($token, Acl::PERMISSION_OPTIONS_ADD); $this->acl->setToken($token, Acl::PERMISSION_OPTIONS_ADD);
} else { } else {

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

@ -194,9 +194,15 @@ class PollService {
/** /**
* get poll configuration * get poll configuration
*/ */
public function get(int $pollId): Poll { public function get(int $pollId) : Poll {
$this->acl->setPollId($pollId); $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\InvalidShareTypeException;
use OCA\Polls\Exceptions\ShareAlreadyExistsException; use OCA\Polls\Exceptions\ShareAlreadyExistsException;
use OCA\Polls\Exceptions\NotFoundException; use OCA\Polls\Exceptions\NotFoundException;
use OCA\Polls\Exceptions\InvalidUsernameException;
use OCA\Polls\Db\PollMapper; use OCA\Polls\Db\PollMapper;
use OCA\Polls\Db\ShareMapper; 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()) { switch ($this->share->getType()) {
case Share::TYPE_PUBLIC: case Share::TYPE_PUBLIC:
// public shares are always valid // public shares are always valid
@ -200,11 +202,11 @@ class ShareService {
/** /**
* Get share by token * Get share by token
*/ */
public function get(string $token, bool $validate = false): Share { public function get(string $token, bool $validateShareType = false): Share {
try { try {
$this->share = $this->shareMapper->findByToken($token); $this->share = $this->shareMapper->findByToken($token);
if ($validate) { if ($validateShareType) {
$this->validate(); $this->validateShareType();
} }
} catch (DoesNotExistException $e) { } catch (DoesNotExistException $e) {
throw new NotFoundException('Token ' . $token . ' does not exist'); throw new NotFoundException('Token ' . $token . ' does not exist');
@ -216,9 +218,9 @@ class ShareService {
// Test if the user has already access. // Test if the user has already access.
$this->acl->setPollId($this->share->getPollId()); $this->acl->setPollId($this->share->getPollId());
} catch (NotAuthorizedException $e) { } 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 the created share
return $this->create( return $this->createNewShare(
$this->share->getPollId(), $this->share->getPollId(),
UserBase::getUserGroupChild(Share::TYPE_USER, $this->userSession->getUser()->getUID()), UserBase::getUserGroupChild(Share::TYPE_USER, $this->userSession->getUser()->getUID()),
true true
@ -240,11 +242,11 @@ class ShareService {
} }
/** /**
* crate share - MUST BE PRIVATE! * crate a new share
* *
* @return 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; $preventInvitation = $userGroup->getType() === UserBase::TYPE_PUBLIC ?: $preventInvitation;
$token = $this->secureRandom->generate( $token = $this->secureRandom->generate(
16, 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)); $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 * Create a personal share from a public share
* or update an email share with the username * or update an email share with the username
@ -401,17 +425,19 @@ class ShareService {
} }
$this->systemService->validatePublicUsername($userName, $token); $this->systemService->validatePublicUsername($userName, $token);
if ($this->share->getPublicPollEmail() !== Share::EMAIL_DISABLED) { if ($this->share->getPublicPollEmail() !== Share::EMAIL_DISABLED) {
$this->systemService->validateEmailAddress($emailAddress, $this->share->getPublicPollEmail() !== Share::EMAIL_MANDATORY); $this->systemService->validateEmailAddress($emailAddress, $this->share->getPublicPollEmail() !== Share::EMAIL_MANDATORY);
} }
$userId = $this->generatePublicUserId($token);
if ($this->share->getType() === Share::TYPE_PUBLIC) { if ($this->share->getType() === Share::TYPE_PUBLIC) {
// Create new external share for user, who entered the poll via public link, // Create new external share for user, who entered the poll via public link,
// prevent invtation sending, when no email address is given // prevent invtation sending, when no email address is given
$this->create( $this->createNewShare(
$this->share->getPollId(), $this->share->getPollId(),
UserBase::getUserGroupChild(Share::TYPE_EXTERNAL, $userName, $userName, $emailAddress), UserBase::getUserGroupChild(Share::TYPE_EXTERNAL, $userId, $userName, $emailAddress),
!$emailAddress !$emailAddress
); );
$this->eventDispatcher->dispatchTyped(new ShareRegistrationEvent($this->share)); $this->eventDispatcher->dispatchTyped(new ShareRegistrationEvent($this->share));
@ -420,7 +446,7 @@ class ShareService {
// Convert email and contact shares to external share, if user registers // Convert email and contact shares to external share, if user registers
$this->share->setType(Share::TYPE_EXTERNAL); $this->share->setType(Share::TYPE_EXTERNAL);
$this->share->setUserId($userName); $this->share->setUserId($userId);
$this->share->setDisplayName($userName); $this->share->setDisplayName($userName);
// prepare for resending invitation to new email address // prepare for resending invitation to new email address

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

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

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

@ -73,8 +73,10 @@ class VoteService {
/** /**
* Read all votes of a poll based on the poll id and return list as array * 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) { if ($token) {
$this->acl->setToken($token); $this->acl->setToken($token);
} else { } else {
@ -83,18 +85,23 @@ class VoteService {
try { try {
if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_RESULTS_VIEW)) { 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()); 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)) { if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
$this->anonymizer->set($this->acl->getpollId(), $this->acl->getUserId()); $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) { } catch (DoesNotExistException $e) {
return []; $votes = [];
} }
return $votes;
} }
private function checkLimits(Option $option, string $userId): void { private function checkLimits(Option $option, string $userId): void {
@ -156,19 +163,19 @@ class VoteService {
/** /**
* Remove user from poll * 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) { if ($token) {
$this->acl->setToken($token, Acl::PERMISSION_VOTE_EDIT); $this->acl->setToken($token, Acl::PERMISSION_VOTE_EDIT);
$userId = $this->acl->getUserId(); $userId = $this->acl->getUserId();
$pollId = $this->acl->getPollId(); $pollId = $this->acl->getPollId();
} else { } else {
if ($userId) { $this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
} else {
$this->acl->setPollId($pollId, Acl::PERMISSION_VOTE_EDIT);
$userId = $this->acl->getUserId();
}
} }
if (!$userId) {
$userId = $this->acl->getUserId();
}
// fake a vote so that the event can be triggered // fake a vote so that the event can be triggered
// surpress logging of this action // surpress logging of this action
$this->vote = new Vote(); $this->vote = new Vote();

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

@ -27,9 +27,14 @@ use OCP\AppFramework\Db\DoesNotExistException;
use OCA\Polls\Db\Watch; use OCA\Polls\Db\Watch;
use OCA\Polls\Db\WatchMapper; use OCA\Polls\Db\WatchMapper;
use OCA\Polls\Exceptions\NoUpdatesException;
use OCA\Polls\Model\Settings\AppSettings;
class WatchService { class WatchService {
/** @var AppSettings */
private $appSettings;
/** @var WatchMapper */ /** @var WatchMapper */
private $watchMapper; private $watchMapper;
@ -40,9 +45,34 @@ class WatchService {
WatchMapper $watchMapper WatchMapper $watchMapper
) { ) {
$this->watchMapper = $watchMapper; $this->watchMapper = $watchMapper;
$this->appSettings = new AppSettings;
$this->watch = new Watch; $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[] * @return Watch[]
*/ */

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

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