diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2022-03-14 15:26:47 +0300 |
---|---|---|
committer | Maxence Lange <maxence@artificial-owl.com> | 2022-03-14 15:27:28 +0300 |
commit | 28a4f591c484ce9808371b21ea03978a4ee22af7 (patch) | |
tree | ae8eb1a549cc00ff7b0156e6fc3b1651bbf6ceb1 | |
parent | 43c353370f1aea268b99f0556f2f1f5c74501720 (diff) |
ocs endpoint /membershipsenh/noid/ocs-memberships
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
-rw-r--r-- | appinfo/routes.php | 2 | ||||
-rw-r--r-- | lib/Controller/AdminController.php | 69 | ||||
-rw-r--r-- | lib/Controller/LocalController.php | 44 | ||||
-rw-r--r-- | lib/Db/CoreQueryBuilder.php | 16 | ||||
-rw-r--r-- | lib/Db/MembershipRequest.php | 30 | ||||
-rw-r--r-- | lib/Model/Membership.php | 25 | ||||
-rw-r--r-- | lib/Model/ModelManager.php | 39 | ||||
-rw-r--r-- | lib/Model/Probes/MemberProbe.php | 27 | ||||
-rw-r--r-- | lib/Service/MemberService.php | 32 | ||||
-rw-r--r-- | lib/Service/MembershipService.php | 6 |
10 files changed, 264 insertions, 26 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index 9b4b6d21..4f7c4a89 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -55,6 +55,7 @@ return [ ], ['name' => 'Local#circleJoin', 'url' => '/circles/{circleId}/join', 'verb' => 'PUT'], ['name' => 'Local#circleLeave', 'url' => '/circles/{circleId}/leave', 'verb' => 'PUT'], + ['name' => 'Local#memberships', 'url' => '/memberships', 'verb' => 'GET'], ['name' => 'Local#editName', 'url' => '/circles/{circleId}/name', 'verb' => 'PUT'], ['name' => 'Local#editDescription', 'url' => '/circles/{circleId}/description', 'verb' => 'PUT'], @@ -93,6 +94,7 @@ return [ ], ['name' => 'Admin#circleJoin', 'url' => '/admin/{emulated}/circles/{circleId}/join', 'verb' => 'PUT'], ['name' => 'Admin#circleLeave', 'url' => '/admin/{emulated}/circles/{circleId}/leave', 'verb' => 'PUT'], + ['name' => 'Admin#memberships', 'url' => '/admin/{emulated}/memberships', 'verb' => 'GET'], ['name' => 'Admin#editName', 'url' => '/admin/{emulated}/circles/{circleId}/name', 'verb' => 'PUT'], ['name' => 'Admin#editDescription', 'url' => '/admin/{emulated}/circles/{circleId}/description', 'verb' => 'PUT'], ['name' => 'Admin#editSetting', 'url' => '/admin/{emulated}/circles/{circleId}/setting', 'verb' => 'PUT'], diff --git a/lib/Controller/AdminController.php b/lib/Controller/AdminController.php index 37d7d31a..cf3170e2 100644 --- a/lib/Controller/AdminController.php +++ b/lib/Controller/AdminController.php @@ -31,8 +31,6 @@ declare(strict_types=1); namespace OCA\Circles\Controller; -use OCA\Circles\Tools\Traits\TDeserialize; -use OCA\Circles\Tools\Traits\TNCLogger; use Exception; use OCA\Circles\Exceptions\ContactAddressBookNotFoundException; use OCA\Circles\Exceptions\ContactFormatException; @@ -46,12 +44,15 @@ use OCA\Circles\Model\FederatedUser; use OCA\Circles\Model\Member; use OCA\Circles\Model\Probes\BasicProbe; use OCA\Circles\Model\Probes\CircleProbe; +use OCA\Circles\Model\Probes\MemberProbe; use OCA\Circles\Service\CircleService; use OCA\Circles\Service\ConfigService; use OCA\Circles\Service\FederatedUserService; use OCA\Circles\Service\MemberService; use OCA\Circles\Service\MembershipService; use OCA\Circles\Service\SearchService; +use OCA\Circles\Tools\Traits\TDeserialize; +use OCA\Circles\Tools\Traits\TNCLogger; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSException; use OCP\AppFramework\OCSController; @@ -150,11 +151,11 @@ class AdminController extends OcsController { } catch (Exception $e) { $this->e( $e, [ - 'emulated' => $emulated, - 'name' => $name, - 'members' => $personal, - 'local' => $local - ] + 'emulated' => $emulated, + 'name' => $name, + 'members' => $personal, + 'local' => $local + ] ); throw new OcsException($e->getMessage(), $e->getCode()); } @@ -211,11 +212,11 @@ class AdminController extends OcsController { } catch (Exception $e) { $this->e( $e, [ - 'emulated' => $emulated, - 'circleId' => $circleId, - 'userId' => $userId, - 'type' => $type - ] + 'emulated' => $emulated, + 'circleId' => $circleId, + 'userId' => $userId, + 'type' => $type + ] ); throw new OCSException($e->getMessage(), $e->getCode()); } @@ -263,6 +264,7 @@ class AdminController extends OcsController { * @param string $emulated * @param int $limit * @param int $offset + * * @return DataResponse * @throws OCSException */ @@ -468,7 +470,12 @@ class AdminController extends OcsController { * @return DataResponse * @throws OCSException */ - public function editSetting(string $emulated, string $circleId, string $setting, ?string $value = null): DataResponse { + public function editSetting( + string $emulated, + string $circleId, + string $setting, + ?string $value = null + ): DataResponse { try { $this->setLocalFederatedUser($emulated); @@ -482,9 +489,6 @@ class AdminController extends OcsController { } - - - /** * @param string $emulated * @param string $circleId @@ -530,6 +534,39 @@ class AdminController extends OcsController { /** * @param string $emulated + * @param string $type + * @param int $level + * @param string $details + * + * @return DataResponse + * @throws OCSException + */ + public function memberships( + string $emulated, + string $type = 'inherited', + int $level = Member::LEVEL_MEMBER, + string $details = 'false' + ): DataResponse { + try { + $this->setLocalFederatedUser($emulated); + + $probe = new MemberProbe(); + $probe->setMinimumLevel($level); + $probe->initiatorAsDirectMember((strtolower($type) === 'direct')); + $probe->detailedMembership(strtolower($details) === 'true'); + + $result = $this->memberService->getMemberships($probe); + + return new DataResponse($this->serializeArray($result)); + } catch (Exception $e) { + $this->e($e, ['type' => $type, 'level' => $level]); + throw new OCSException($e->getMessage(), $e->getCode()); + } + } + + + /** + * @param string $emulated * * @throws FederatedUserException * @throws FederatedUserNotFoundException diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php index efa78363..94ce73b9 100644 --- a/lib/Controller/LocalController.php +++ b/lib/Controller/LocalController.php @@ -31,8 +31,6 @@ declare(strict_types=1); namespace OCA\Circles\Controller; -use OCA\Circles\Tools\Traits\TDeserialize; -use OCA\Circles\Tools\Traits\TNCLogger; use Exception; use OCA\Circles\Exceptions\FederatedUserException; use OCA\Circles\Exceptions\FederatedUserNotFoundException; @@ -44,12 +42,15 @@ use OCA\Circles\Model\FederatedUser; use OCA\Circles\Model\Member; use OCA\Circles\Model\Probes\BasicProbe; use OCA\Circles\Model\Probes\CircleProbe; +use OCA\Circles\Model\Probes\MemberProbe; use OCA\Circles\Service\CircleService; use OCA\Circles\Service\ConfigService; use OCA\Circles\Service\FederatedUserService; use OCA\Circles\Service\MemberService; use OCA\Circles\Service\MembershipService; use OCA\Circles\Service\SearchService; +use OCA\Circles\Tools\Traits\TDeserialize; +use OCA\Circles\Tools\Traits\TNCLogger; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSException; use OCP\AppFramework\OCSController; @@ -329,6 +330,39 @@ class LocalController extends OcsController { /** * @NoAdminRequired * + * @param string $type + * @param int $level + * @param bool $details + * + * @return DataResponse + * @throws OCSException + */ + public function memberships( + string $type = 'inherited', + int $level = Member::LEVEL_MEMBER, + string $details = 'false' + ): DataResponse { + try { + $this->setCurrentFederatedUser(); + + $probe = new MemberProbe(); + $probe->setMinimumLevel($level) + ->initiatorAsDirectMember((strtolower($type) === 'direct')) + ->detailedMembership(strtolower($details) === 'true'); + + $result = $this->memberService->getMemberships($probe); + + return new DataResponse($this->serializeArray($result)); + } catch (Exception $e) { + $this->e($e, ['type' => $type, 'level' => $level]); + throw new OCSException($e->getMessage(), $e->getCode()); + } + } + + + /** + * @NoAdminRequired + * * @param string $circleId * @param string $memberId * @param string|int $level @@ -512,7 +546,11 @@ class LocalController extends OcsController { * @return DataResponse * @throws OCSException */ - public function editSetting(string $circleId, string $setting, ?string $value = null): DataResponse { + public function editSetting( + string $circleId, + string $setting, + ?string $value = null + ): DataResponse { try { $this->setCurrentFederatedUser(); diff --git a/lib/Db/CoreQueryBuilder.php b/lib/Db/CoreQueryBuilder.php index 5f1992e7..8ef85070 100644 --- a/lib/Db/CoreQueryBuilder.php +++ b/lib/Db/CoreQueryBuilder.php @@ -163,6 +163,13 @@ class CoreQueryBuilder extends ExtendedQueryBuilder { ] ], self::MEMBERSHIPS => [ + self::CIRCLE => [ + self::MEMBERSHIPS => [ // needed ? + self::CONFIG, + self::INITIATOR + ], + self::INITIATOR => [self::INHERITED_BY => [self::MEMBERSHIPS]] + ], self::CONFIG ], self::SHARE => [ @@ -386,6 +393,14 @@ class CoreQueryBuilder extends ExtendedQueryBuilder { /** + * @param int $level + */ + public function minLevel(int $level): void { + $this->gt('level', $level, true); + } + + + /** * @param Circle $circle */ public function filterCircle(Circle $circle): void { @@ -1131,7 +1146,6 @@ class CoreQueryBuilder extends ExtendedQueryBuilder { ) ); - $listMembershipCircleAlias = [$aliasMembership]; if ($this->getBool('initiatorDirectMember', $options, false)) { try { diff --git a/lib/Db/MembershipRequest.php b/lib/Db/MembershipRequest.php index 0d1f5ccd..6cec645e 100644 --- a/lib/Db/MembershipRequest.php +++ b/lib/Db/MembershipRequest.php @@ -32,8 +32,10 @@ declare(strict_types=1); namespace OCA\Circles\Db; use OCA\Circles\Exceptions\MembershipNotFoundException; +use OCA\Circles\Exceptions\RequestBuilderException; use OCA\Circles\Model\FederatedUser; use OCA\Circles\Model\Membership; +use OCA\Circles\Model\Probes\MemberProbe; use OCP\DB\QueryBuilder\IQueryBuilder; /** @@ -103,11 +105,37 @@ class MembershipRequest extends MembershipRequestBuilder { /** + * @param MemberProbe|null $probe + * @param FederatedUser|null $initiator + * + * @return Membership[] + * @throws RequestBuilderException + */ + public function getMemberships(FederatedUser $initiator, MemberProbe $probe): array { + $qb = $this->getMembershipSelectSql(); + $qb->limitToSingleId($initiator->getSingleId()); + $qb->leftJoinCircleConfig(CoreQueryBuilder::MEMBERSHIPS); + + $qb->minLevel($probe->getMinimumLevel()); + if ($probe->directMemberInitiator()) { + $qb->limitInt('inheritance_depth', 1); + } + + if ($probe->isDetailedMembership()) { + $qb->setOptions([CoreQueryBuilder::MEMBERSHIPS, CoreQueryBuilder::CIRCLE], ['getData' => true]); + $qb->leftJoinCircle(CoreQueryBuilder::MEMBERSHIPS, $initiator); + } + + return $this->getItemsFromRequest($qb); + } + + + /** * @param string $singleId * * @return Membership[] */ - public function getMemberships(string $singleId): array { + public function getMembershipsBySingleId(string $singleId): array { $qb = $this->getMembershipSelectSql(); $qb->limitToSingleId($singleId); $qb->leftJoinCircleConfig(CoreQueryBuilder::MEMBERSHIPS); diff --git a/lib/Model/Membership.php b/lib/Model/Membership.php index bba5145c..59203854 100644 --- a/lib/Model/Membership.php +++ b/lib/Model/Membership.php @@ -74,6 +74,9 @@ class Membership extends ManagedModel implements IDeserializable, IQueryRow, Jso /** @var array */ private $inheritanceDetails = []; + /** @var Circle */ + private $circle; + /** * Membership constructor. @@ -271,6 +274,21 @@ class Membership extends ManagedModel implements IDeserializable, IQueryRow, Jso } + public function hasCircle(): bool { + return (!is_null($this->circle)); + } + + public function setCircle(Circle $circle): self { + $this->circle = $circle; + + return $this; + } + + public function getCircle(): Circle { + return $this->circle; + } + + /** * @param array $data * @@ -315,6 +333,8 @@ class Membership extends ManagedModel implements IDeserializable, IQueryRow, Jso $this->setInheritancePath($this->getArray($prefix . 'inheritance_path', $data)); $this->setInheritanceDepth($this->getInt($prefix . 'inheritance_depth', $data)); + $this->getManager()->manageImportFromDatabase($this, $data, $prefix); + return $this; } @@ -338,6 +358,11 @@ class Membership extends ManagedModel implements IDeserializable, IQueryRow, Jso $result['inheritanceDetails'] = $this->getInheritanceDetails(); } + if ($this->hasCircle()) { + $result['circle'] = $this->getCircle(); + } + return $result; } + } diff --git a/lib/Model/ModelManager.php b/lib/Model/ModelManager.php index 175214b9..09620ad2 100644 --- a/lib/Model/ModelManager.php +++ b/lib/Model/ModelManager.php @@ -31,7 +31,6 @@ declare(strict_types=1); namespace OCA\Circles\Model; -use OCA\Circles\Tools\Traits\TNCLogger; use OCA\Circles\AppInfo\Application; use OCA\Circles\Db\CircleRequest; use OCA\Circles\Db\CoreQueryBuilder; @@ -57,6 +56,7 @@ use OCA\Circles\Service\ConfigService; use OCA\Circles\Service\InterfaceService; use OCA\Circles\Service\MembershipService; use OCA\Circles\Service\RemoteService; +use OCA\Circles\Tools\Traits\TNCLogger; use OCP\IURLGenerator; /** @@ -208,7 +208,7 @@ class ModelManager { * @param IEntity $member */ public function getMemberships(IEntity $member): void { - $memberships = $this->membershipRequest->getMemberships($member->getSingleId()); + $memberships = $this->membershipRequest->getMembershipsBySingleId($member->getSingleId()); $member->setMemberships($memberships); } @@ -245,6 +245,12 @@ class ModelManager { } } + if ($model instanceof Membership) { + if ($base === '') { + $base = CoreQueryBuilder::MEMBERSHIPS; + } + } + if ($model instanceof ShareWrapper) { if ($base === '') { $base = CoreQueryBuilder::SHARE; @@ -272,6 +278,10 @@ class ModelManager { $this->importIntoMember($model, $data, $path, $prefix); } + if ($model instanceof Membership) { + $this->importIntoMembership($model, $data, $path, $prefix); + } + if ($model instanceof FederatedUser) { $this->importIntoFederatedUser($model, $data, $path, $prefix); } @@ -392,6 +402,31 @@ class ModelManager { /** + * @param Membership $membership + * @param array $data + * @param string $path + * @param string $prefix + */ + private function importIntoMembership( + Membership $membership, + array $data, + string $path, + string $prefix + ): void { + switch ($path) { + case CoreQueryBuilder::CIRCLE: + try { + $circle = new Circle(); + $circle->importFromDatabase($data, $prefix); + $membership->setCircle($circle); + } catch (CircleNotFoundException $e) { + } + break; + } + } + + + /** * @param FederatedUser $federatedUser * @param array $data * @param string $path diff --git a/lib/Model/Probes/MemberProbe.php b/lib/Model/Probes/MemberProbe.php index e2cdb1bb..60a1f42c 100644 --- a/lib/Model/Probes/MemberProbe.php +++ b/lib/Model/Probes/MemberProbe.php @@ -53,6 +53,9 @@ class MemberProbe extends BasicProbe { /** @var bool */ private $initiatorDirectMember = false; + /** @var bool */ + private $detailedMembership = false; + /** * allow the initiator as a requesting member @@ -76,6 +79,19 @@ class MemberProbe extends BasicProbe { /** + * returns memberships with details about Circle and Initiator + */ + public function detailedMembership(bool $detailed = true): self { + $this->detailedMembership = $detailed; + + return $this; + } + + public function isDetailedMembership(): bool { + return $this->detailedMembership; + } + + /** * @param bool $include * * @return $this @@ -111,6 +127,17 @@ class MemberProbe extends BasicProbe { /** + * @param int $level + * + * @return $this + */ + public function setMinimumLevel(int $level): self { + $this->minimumLevel = $level; + + return $this; + } + + /** * @return int */ public function getMinimumLevel(): int { diff --git a/lib/Service/MemberService.php b/lib/Service/MemberService.php index 58e1d261..4f496729 100644 --- a/lib/Service/MemberService.php +++ b/lib/Service/MemberService.php @@ -33,6 +33,7 @@ namespace OCA\Circles\Service; use OCA\Circles\Db\CircleRequest; use OCA\Circles\Db\MemberRequest; +use OCA\Circles\Db\MembershipRequest; use OCA\Circles\Exceptions\CircleNotFoundException; use OCA\Circles\Exceptions\ContactAddressBookNotFoundException; use OCA\Circles\Exceptions\ContactFormatException; @@ -59,6 +60,7 @@ use OCA\Circles\IFederatedUser; use OCA\Circles\Model\Federated\FederatedEvent; use OCA\Circles\Model\FederatedUser; use OCA\Circles\Model\Member; +use OCA\Circles\Model\Membership; use OCA\Circles\Model\Probes\MemberProbe; use OCA\Circles\Tools\Model\SimpleDataStore; use OCA\Circles\Tools\Traits\TArrayTools; @@ -82,6 +84,9 @@ class MemberService { /** @var MemberRequest */ private $memberRequest; + /** @var MembershipRequest */ + private $membershipRequest; + /** @var FederatedUserService */ private $federatedUserService; @@ -100,13 +105,16 @@ class MemberService { * * @param CircleRequest $circleRequest * @param MemberRequest $memberRequest + * @param MembershipRequest $membershipRequest * @param FederatedUserService $federatedUserService + * @param MembershipService $membershipService * @param FederatedEventService $federatedEventService * @param RemoteStreamService $remoteStreamService */ public function __construct( CircleRequest $circleRequest, MemberRequest $memberRequest, + MembershipRequest $membershipRequest, FederatedUserService $federatedUserService, MembershipService $membershipService, FederatedEventService $federatedEventService, @@ -114,6 +122,7 @@ class MemberService { ) { $this->circleRequest = $circleRequest; $this->memberRequest = $memberRequest; + $this->membershipRequest = $membershipRequest; $this->federatedUserService = $federatedUserService; $this->membershipService = $membershipService; $this->federatedEventService = $federatedEventService; @@ -367,4 +376,27 @@ class MemberService { return true; } + + + /** + * @param MemberProbe|null $probe + * + * @return Membership[] + * @throws InitiatorNotFoundException + * @throws RequestBuilderException + */ + public function getMemberships(?MemberProbe $probe = null): array { + $this->federatedUserService->mustHaveCurrentUser(); + + if (is_null($probe)) { + $probe = new MemberProbe(); + $probe->mustBeMember(); + } + + return $this->membershipRequest->getMemberships( + $this->federatedUserService->getCurrentUser(), + $probe + ); + } + } diff --git a/lib/Service/MembershipService.php b/lib/Service/MembershipService.php index faa53537..cbd69ea8 100644 --- a/lib/Service/MembershipService.php +++ b/lib/Service/MembershipService.php @@ -31,8 +31,6 @@ declare(strict_types=1); namespace OCA\Circles\Service; -use OCA\Circles\Tools\Exceptions\ItemNotFoundException; -use OCA\Circles\Tools\Traits\TNCLogger; use OCA\Circles\Db\CircleRequest; use OCA\Circles\Db\MemberRequest; use OCA\Circles\Db\MembershipRequest; @@ -44,6 +42,8 @@ use OCA\Circles\Model\Circle; use OCA\Circles\Model\FederatedUser; use OCA\Circles\Model\Member; use OCA\Circles\Model\Membership; +use OCA\Circles\Tools\Exceptions\ItemNotFoundException; +use OCA\Circles\Tools\Traits\TNCLogger; /** * Class MembershipService @@ -232,7 +232,7 @@ class MembershipService { * @return int */ private function updateMembershipsDatabase(string $singleId, array $memberships): int { - $known = $this->membershipRequest->getMemberships($singleId); + $known = $this->membershipRequest->getMembershipsBySingleId($singleId); $deprecated = $this->removeDeprecatedMemberships($memberships, $known); if (!empty($deprecated)) { |