Signed-off-by: dartcafe <github@dartcafe.de>
This commit is contained in:
dartcafe 2022-08-02 22:18:29 +02:00
Родитель c9401b614c
Коммит 5eb21a2125
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: CCE73CEF3035D3C8
6 изменённых файлов: 280 добавлений и 94 удалений

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

@ -26,8 +26,8 @@ namespace OCA\Polls\Controller;
use OCA\Polls\Db\Share;
use OCA\Polls\Exceptions\ShareAlreadyExistsException;
use OCA\Polls\Exceptions\InvalidShareTypeException;
use OCA\Polls\Model\UserGroup\UserBase;
use OCA\Polls\Service\ShareService;
use OCA\Polls\Service\UserService;
use OCP\AppFramework\Http\JSONResponse;
use OCP\ISession;
use OCP\IRequest;
@ -37,14 +37,19 @@ class ShareController extends BaseController {
/** @var ShareService */
private $shareService;
/** @var UserService */
private $userService;
public function __construct(
string $appName,
IRequest $request,
ISession $session,
ShareService $shareService
ShareService $shareService,
UserService $userService
) {
parent::__construct($appName, $request, $session);
$this->shareService = $shareService;
$this->userService = $userService;
}
/**
@ -145,7 +150,7 @@ class ShareController extends BaseController {
throw new InvalidShareTypeException('Cannot resolve members from share type ' . $share->getType());
}
foreach (UserBase::getUserGroupChild($share->getType(), $share->getUserId())->getMembers() as $member) {
foreach ($this->userService->getUser($share->getType(), $share->getUserId())->getMembers() as $member) {
try {
$newShare = $this->shareService->add($share->getPollId(), $member->getType(), $member->getId());
$shares[] = $newShare;

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

@ -30,6 +30,7 @@ use OCP\IURLGenerator;
use OCA\Polls\Model\UserGroup\UserBase;
use OCA\Polls\Model\Settings\AppSettings;
use OCA\Polls\Helper\Container;
use OCA\Polls\Service\UserService;
/**
* @method int getId()
@ -125,11 +126,15 @@ class Share extends Entity implements JsonSerializable {
/** @var AppSettings */
protected $appSettings;
/** @var UserService */
protected $userService;
public function __construct() {
$this->addType('pollId', 'int');
$this->addType('invitationSent', 'int');
$this->addType('reminderSent', 'int');
$this->urlGenerator = Container::queryClass(IURLGenerator::class);
$this->userService = Container::queryClass(UserService::class);
$this->appSettings = new AppSettings;
}
@ -187,7 +192,7 @@ class Share extends Entity implements JsonSerializable {
}
public function getUserObject(): UserBase {
return UserBase::getUserGroupChild(
return $this->userService->getUser(
$this->type,
$this->userId,
$this->displayName,

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

@ -23,15 +23,13 @@
namespace OCA\Polls\Model\UserGroup;
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;
use OCP\IDateTimeZone;
use OCP\IUserSession;
class UserBase implements \JsonSerializable {
public const TYPE = 'generic';
@ -87,6 +85,9 @@ class UserBase implements \JsonSerializable {
/** @var IDateTimeZone */
protected $timezone;
/** @var IUserSession */
protected $userSession;
public function __construct(
string $id,
string $type,
@ -99,6 +100,7 @@ class UserBase implements \JsonSerializable {
$this->l10n = Container::getL10N();
$this->timezone = Container::queryClass(IDateTimeZone::class);
$this->userSession = Container::queryClass(IUserSession::class);
$this->id = $id;
$this->type = $type;
@ -116,10 +118,6 @@ class UserBase implements \JsonSerializable {
return $this->id;
}
public function getUser(): string {
return $this->id;
}
public function getType(): string {
return $this->type;
}
@ -161,6 +159,10 @@ class UserBase implements \JsonSerializable {
return $this->organisation;
}
public function getIsLoggedIn(): bool {
return $this->userSession->isLoggedIn();
}
/**
* @return string[]
*
@ -261,7 +263,6 @@ class UserBase implements \JsonSerializable {
}
}
return $items;
}
@ -273,48 +274,6 @@ 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
*/
public static function getUserGroupChild(string $type, string $id, string $displayName = '', string $emailAddress = '') {
switch ($type) {
case Group::TYPE:
return new Group($id);
case Circle::TYPE:
return new Circle($id);
case Contact::TYPE:
return new Contact($id);
case ContactGroup::TYPE:
return new ContactGroup($id);
case User::TYPE:
return new User($id);
case Admin::TYPE:
return new Admin($id);
case Email::TYPE:
return new Email($id, $displayName, $emailAddress);
case self::TYPE_PUBLIC:
return new GenericUser($id, self::TYPE_PUBLIC);
case self::TYPE_EXTERNAL:
return new GenericUser($id, self::TYPE_EXTERNAL, $displayName, $emailAddress);
default:
throw new InvalidShareTypeException('Invalid share type (' . $type . ')');
}
}
public function jsonSerialize(): array {
return [
'id' => $this->getId(),

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

@ -50,11 +50,8 @@ use Psr\Log\LoggerInterface;
class ShareService {
/** @var LoggerInterface */
private $logger;
/** @var string|null */
private $userId;
/** @var Acl */
private $acl;
/** @var IEventDispatcher */
private $eventDispatcher;
@ -62,36 +59,42 @@ class ShareService {
/** @var IGroupManager */
private $groupManager;
/** @var IUserSession */
private $userSession;
/** @var SystemService */
private $systemService;
/** @var ShareMapper */
private $shareMapper;
/** @var PollMapper */
private $pollMapper;
/** @var ISecureRandom */
private $secureRandom;
/** @var Share */
private $share;
/** @var array */
private $shares = [];
/** @var LoggerInterface */
private $logger;
/** @var MailService */
private $mailService;
/** @var Acl */
private $acl;
/** @var NotificationService */
private $notificationService;
/** @var PollMapper */
private $pollMapper;
/** @var ShareMapper */
private $shareMapper;
/** @var ISecureRandom */
private $secureRandom;
/** @var Share */
private $share;
/** @var array */
private $shares = [];
/** @var SystemService */
private $systemService;
/** @var string|null */
private $userId;
/** @var UserService */
private $userService;
/** @var IUserSession */
private $userSession;
public function __construct(
LoggerInterface $logger,
?string $UserId,
@ -105,7 +108,8 @@ class ShareService {
Share $share,
MailService $mailService,
Acl $acl,
NotificationService $notificationService
NotificationService $notificationService,
UserService $userService
) {
$this->logger = $logger;
$this->userId = $UserId;
@ -120,6 +124,7 @@ class ShareService {
$this->acl = $acl;
$this->notificationService = $notificationService;
$this->userSession = $userSession;
$this->userService = $userService;
}
/**
@ -158,24 +163,26 @@ class ShareService {
* or is accessibale for use by the current user
*/
private function validateShareType() : void {
$currentUser = $this->userService->getCurrentUser();
switch ($this->share->getType()) {
case Share::TYPE_PUBLIC:
// public shares are always valid
break;
case Share::TYPE_USER:
if ($this->share->getUserId() !== $this->userId) {
if ($this->share->getUserId() !== $currentUser->getId()) {
// share is not valid for user
throw new NotAuthorizedException;
}
break;
case Share::TYPE_ADMIN:
if ($this->share->getUserId() !== $this->userId) {
if ($this->share->getUserId() !== $currentUser->getId()) {
// share is not valid for user
throw new NotAuthorizedException;
}
break;
case Share::TYPE_GROUP:
if (!$this->userSession->isLoggedIn()) {
if (!$currentUser->getIsLoggedIn()) {
throw new NotAuthorizedException;
}
@ -216,7 +223,7 @@ class ShareService {
// Return the created share
return $this->createNewShare(
$this->share->getPollId(),
UserBase::getUserGroupChild(Share::TYPE_USER, $this->userSession->getUser()->getUID()),
$this->userService->getUser(Share::TYPE_USER, $this->userSession->getUser()->getUID()),
true
);
}
@ -293,7 +300,7 @@ class ShareService {
}
}
$this->createNewShare($pollId, UserBase::getUserGroupChild($type, $userId, $displayName, $emailAddress));
$this->createNewShare($pollId, $this->userService->getUser($type, $userId, $displayName, $emailAddress));
$this->eventDispatcher->dispatchTyped(new ShareCreateEvent($this->share));
@ -456,7 +463,7 @@ class ShareService {
// prevent invtation sending, when no email address is given
$this->createNewShare(
$this->share->getPollId(),
UserBase::getUserGroupChild(Share::TYPE_EXTERNAL, $userId, $userName, $emailAddress),
$this->userService->getUser(Share::TYPE_EXTERNAL, $userId, $userName, $emailAddress),
!$emailAddress
);
$this->eventDispatcher->dispatchTyped(new ShareRegistrationEvent($this->share));

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

@ -36,24 +36,28 @@ use OCA\Polls\Model\UserGroup\ContactGroup;
use OCA\Polls\Model\UserGroup\Email;
use OCA\Polls\Model\UserGroup\Group;
use OCA\Polls\Model\UserGroup\User;
use OCA\Polls\Model\UserGroup\UserBase;
use OCP\IUserManager;
class SystemService {
private const REGEX_VALID_MAIL = '/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/';
private const REGEX_PARSE_MAIL = '/(?:"?([^"]*)"?\s)?(?:<?(.+@[^>]+)>?)/';
/** @var ShareMapper */
private $shareMapper;
/** @var UserService */
private $userService;
/** @var VoteMapper */
private $voteMapper;
/** @var ShareMapper */
private $shareMapper;
public function __construct(
ShareMapper $shareMapper,
UserService $userService,
VoteMapper $voteMapper
) {
$this->shareMapper = $shareMapper;
$this->userService = $userService;
$this->voteMapper = $voteMapper;
}
@ -127,7 +131,7 @@ class SystemService {
$list[] = new Email($emailAddress, $displayName, $emailAddress);
}
$list = array_merge($list, UserBase::search($query));
$list = array_merge($list, $this->userService->search($query));
}
return $list;

206
lib/Service/UserService.php Normal file
Просмотреть файл

@ -0,0 +1,206 @@
<?php
/**
* @copyright Copyright (c) 2017 Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
*
* @author René Gieling <github@dartcafe.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Polls\Service;
use OCA\Polls\Db\ShareMapper;
use OCA\Polls\Exceptions\Exception;
use OCA\Polls\Exceptions\InvalidShareTypeException;
use OCA\Polls\Model\UserGroup\Admin;
use OCA\Polls\Model\UserGroup\Circle;
use OCA\Polls\Model\UserGroup\Contact;
use OCA\Polls\Model\UserGroup\ContactGroup;
use OCA\Polls\Model\UserGroup\Email;
use OCA\Polls\Model\UserGroup\GenericUser;
use OCA\Polls\Model\UserGroup\Group;
use OCA\Polls\Model\UserGroup\User;
use OCA\Polls\Model\UserGroup\UserBase;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\Collaboration\Collaborators\ISearch;
use OCP\ISession;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Share\IShare;
class UserService {
/** @var ShareMapper */
private $shareMapper;
/** @var ISession */
private $session;
/** @var IUserManager */
private $userManager;
/** @var IUserSession */
private $userSession;
/** @var ISearch */
private $userSearch;
public function __construct(
ISearch $userSearch,
ISession $session,
IUserSession $userSession,
IUserManager $userManager,
ShareMapper $shareMapper
) {
$this->userSearch = $userSearch;
$this->session = $session;
$this->shareMapper = $shareMapper;
$this->userSession = $userSession;
$this->userManager = $userManager;
}
/**
* getCurrentUser - Get current user from userbase or from share in public polls
*/
public function getCurrentUser() {
if ($this->userSession->getUser()) {
return $this->getUserFromShare($this->userSession->getUser()->getUID());
}
$token = $this->session->get('publicPollToken');
if ($token) {
return $this->getUserFromShare($token);
}
throw new DoesNotExistException('User not found');
}
/**
* evaluateUser - Get user by name; and poll in case of a share user of the particulair poll
*/
public function evaluateUser(string $userId, int $pollId = 0): ?UserBase {
$user = $this->userManager->get($userId);
if ($user) {
return new User($userId);
}
try {
$share = $this->shareMapper->findByPollAndUser($pollId, $userId);
return $this->getUser(
$share->getType(),
$share->getUserId(),
$share->getDisplayName(),
$share->getEmailAddress()
);
} catch (Exception $e) {
return null;
}
}
/**
* Create user from share
* @return Admin|Circle|Contact|ContactGroup|Email|GenericUser|Group|User
*/
public function getUserFromShare(string $token) {
$share = $this->shareMapper->findByToken($token);
return $this->getUser(
$share->getType(),
$share->getUserId(),
$share->getDisplayName(),
$share->getEmailAddress()
);
}
/**
* search all possible sharees - use ISearch to respect autocomplete restrictions
*/
public function search(string $query = ''): array {
$items = [];
$types = [
IShare::TYPE_USER,
IShare::TYPE_GROUP,
IShare::TYPE_EMAIL
];
if (Circle::isEnabled() && class_exists('\OCA\Circles\ShareByCircleProvider')) {
$types[] = IShare::TYPE_CIRCLE;
}
[$result, $more] = $this->userSearch->search($query, $types, false, 200, 0);
foreach (($result['users'] ?? []) as $item) {
$items[] = new User($item['value']['shareWith']);
}
foreach (($result['exact']['users'] ?? []) as $item) {
$items[] = new User($item['value']['shareWith']);
}
foreach (($result['groups'] ?? []) as $item) {
$items[] = new Group($item['value']['shareWith']);
}
foreach (($result['exact']['groups'] ?? []) as $item) {
$items[] = new Group($item['value']['shareWith']);
}
$items = array_merge($items, Contact::search($query));
$items = array_merge($items, ContactGroup::search($query));
if (Circle::isEnabled()) {
foreach (($result['circles'] ?? []) as $item) {
$items[] = new Circle($item['value']['shareWith']);
}
foreach (($result['exact']['circles'] ?? []) as $item) {
$items[] = new Circle($item['value']['shareWith']);
}
}
return $items;
}
/**
* create a new user object
* @return Circle|Contact|ContactGroup|Email|GenericUser|Group|User|Admin
*/
public function getUser(string $type, string $id, string $displayName = '', string $emailAddress = ''): UserBase {
switch ($type) {
case Group::TYPE:
return new Group($id);
case Circle::TYPE:
return new Circle($id);
case Contact::TYPE:
return new Contact($id);
case ContactGroup::TYPE:
return new ContactGroup($id);
case User::TYPE:
return new User($id);
case Admin::TYPE:
return new Admin($id);
case Email::TYPE:
return new Email($id, $displayName, $emailAddress);
case UserBase::TYPE_PUBLIC:
return new GenericUser($id, UserBase::TYPE_PUBLIC);
case UserBase::TYPE_EXTERNAL:
return new GenericUser($id, UserBase::TYPE_EXTERNAL, $displayName, $emailAddress);
default:
throw new InvalidShareTypeException('Invalid user type (' . $type . ')');
}
}
}