diff --git a/lib/Api/v1/Circles.php b/lib/Api/v1/Circles.php
index d29f23cfb..2bc933e34 100644
--- a/lib/Api/v1/Circles.php
+++ b/lib/Api/v1/Circles.php
@@ -29,7 +29,6 @@
namespace OCA\Circles\Api\v1;
-use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
use OCA\Circles\Exceptions\CircleNotFoundException;
use OCA\Circles\Exceptions\FederatedUserException;
use OCA\Circles\Exceptions\FederatedUserNotFoundException;
@@ -39,6 +38,7 @@
use OCA\Circles\Exceptions\SingleCircleNotFoundException;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\FederatedUserService;
@@ -101,11 +101,10 @@ public static function listCircles($type, $name = '', $level = 0, $userId = '',
/** @var CircleService $circleService */
$circleService = \OC::$server->get(CircleService::class);
- return $circleService->getCircles(
- null,
- null,
- new SimpleDataStore(['includePersonalCircles' => $personalCircle])
- );
+ $probe = new CircleProbe();
+ $probe->includePersonalCircles($personalCircle);
+
+ return $circleService->getCircles($probe);
}
@@ -145,16 +144,11 @@ public static function joinedCircles($userId = '', $forceAll = false) {
/** @var CircleService $circleService */
$circleService = \OC::$server->get(CircleService::class);
- return $circleService->getCircles(
- null,
- null,
- new SimpleDataStore(
- [
- 'mustBeMember' => true,
- 'includePersonalCircles' => $personalCircle
- ]
- )
- );
+ $probe = new CircleProbe();
+ $probe->mustBeMember();
+ $probe->includePersonalCircles($personalCircle);
+
+ return $circleService->getCircles($probe);
}
diff --git a/lib/CirclesManager.php b/lib/CirclesManager.php
index 130defaaa..24746888e 100644
--- a/lib/CirclesManager.php
+++ b/lib/CirclesManager.php
@@ -33,6 +33,9 @@
use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException;
use OCA\Circles\Exceptions\CircleNotFoundException;
+use OCA\Circles\Exceptions\ContactAddressBookNotFoundException;
+use OCA\Circles\Exceptions\ContactFormatException;
+use OCA\Circles\Exceptions\ContactNotFoundException;
use OCA\Circles\Exceptions\FederatedEventException;
use OCA\Circles\Exceptions\FederatedItemException;
use OCA\Circles\Exceptions\FederatedUserException;
@@ -41,6 +44,7 @@
use OCA\Circles\Exceptions\InitiatorNotFoundException;
use OCA\Circles\Exceptions\InvalidIdException;
use OCA\Circles\Exceptions\MemberNotFoundException;
+use OCA\Circles\Exceptions\MembershipNotFoundException;
use OCA\Circles\Exceptions\OwnerNotFoundException;
use OCA\Circles\Exceptions\RemoteInstanceException;
use OCA\Circles\Exceptions\RemoteNotFoundException;
@@ -52,9 +56,12 @@
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Membership;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\FederatedUserService;
use OCA\Circles\Service\MemberService;
+use OCA\Circles\Service\MembershipService;
use OCP\IUserSession;
/**
@@ -77,6 +84,9 @@ class CirclesManager {
/** @var MemberService */
private $memberService;
+ /** @var MembershipService */
+ private $membershipService;
+
/**
* CirclesManager constructor.
@@ -91,11 +101,13 @@ public function __construct(
FederatedUserService $federatedUserService,
CircleService $circleService,
MemberService $memberService,
+ MembershipService $membershipService,
CirclesQueryHelper $circlesQueryHelper
) {
$this->federatedUserService = $federatedUserService;
$this->circleService = $circleService;
$this->memberService = $memberService;
+ $this->membershipService = $membershipService;
$this->circlesQueryHelper = $circlesQueryHelper;
}
@@ -267,36 +279,114 @@ public function destroyCircle(string $singleId): void {
* @throws InitiatorNotFoundException
* @throws RequestBuilderException
*/
- public function getCircles(): array {
- return $this->circleService->getCircles();
+ public function getCircles(?CircleProbe $probe = null): array {
+ return $this->circleService->getCircles($probe);
}
/**
* @param string $singleId
+ * @param CircleProbe|null $probe
*
* @return Circle
* @throws CircleNotFoundException
* @throws InitiatorNotFoundException
* @throws RequestBuilderException
*/
- public function getCircle(string $singleId): Circle {
- return $this->circleService->getCircle($singleId);
+ public function getCircle(string $singleId, ?CircleProbe $probe = null): Circle {
+ return $this->circleService->getCircle($singleId, $probe);
}
+ /**
+ * @param string $circleId
+ * @param FederatedUser $federatedUser
+ *
+ * @return Member
+ * @throws CircleNotFoundException
+ * @throws ContactAddressBookNotFoundException
+ * @throws ContactFormatException
+ * @throws ContactNotFoundException
+ * @throws FederatedEventException
+ * @throws FederatedItemException
+ * @throws FederatedUserException
+ * @throws InitiatorNotConfirmedException
+ * @throws InitiatorNotFoundException
+ * @throws InvalidIdException
+ * @throws InvalidItemException
+ * @throws OwnerNotFoundException
+ * @throws RemoteInstanceException
+ * @throws RemoteNotFoundException
+ * @throws RemoteResourceNotFoundException
+ * @throws RequestBuilderException
+ * @throws SingleCircleNotFoundException
+ * @throws UnknownRemoteException
+ */
+ public function addMember(string $circleId, FederatedUser $federatedUser): Member {
+ $outcome = $this->memberService->addMember($circleId, $federatedUser);
+ $member = new Member();
+ $member->import($outcome);
+
+ return $member;
+ }
+
/**
- * WIP
+ * @param string $memberId
+ * @param int $level
*
- * @return Circle[]
+ * @return Member
+ * @throws FederatedEventException
+ * @throws FederatedItemException
+ * @throws InitiatorNotConfirmedException
* @throws InitiatorNotFoundException
+ * @throws InvalidItemException
+ * @throws MemberNotFoundException
+ * @throws OwnerNotFoundException
+ * @throws RemoteNotFoundException
+ * @throws RemoteResourceNotFoundException
* @throws RequestBuilderException
+ * @throws UnknownRemoteException
*/
-// public function getAllCircles(): array {
-// $this->federatedUserService->bypassCurrentUserCondition(true);
-// $this->circleService->getCircles();
-// }
+ public function levelMember(string $memberId, int $level): Member {
+ $outcome = $this->memberService->memberLevel($memberId, $level);
+ $member = new Member();
+ $member->import($outcome);
+
+ return $member;
+ }
+
+
+ /**
+ * @param string $memberId
+ *
+ * @throws FederatedEventException
+ * @throws FederatedItemException
+ * @throws InitiatorNotConfirmedException
+ * @throws InitiatorNotFoundException
+ * @throws MemberNotFoundException
+ * @throws OwnerNotFoundException
+ * @throws RemoteNotFoundException
+ * @throws RemoteResourceNotFoundException
+ * @throws RequestBuilderException
+ * @throws UnknownRemoteException
+ */
+ public function removeMember(string $memberId): void {
+ $this->memberService->removeMember($memberId);
+ }
+
+
+ /**
+ * @param string $circleId
+ * @param string $singleId
+ *
+ * @return Membership
+ * @throws MembershipNotFoundException
+ * @throws RequestBuilderException
+ */
+ public function getLink(string $circleId, string $singleId): Membership {
+ return $this->membershipService->getMembership($circleId, $singleId);
+ }
/**
diff --git a/lib/CirclesQueryHelper.php b/lib/CirclesQueryHelper.php
index 97b5e5906..5dbf0cd43 100644
--- a/lib/CirclesQueryHelper.php
+++ b/lib/CirclesQueryHelper.php
@@ -37,6 +37,7 @@
use OCA\Circles\Exceptions\FederatedUserNotFoundException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Model\Circle;
+use OCA\Circles\Model\Member;
use OCA\Circles\Service\FederatedUserService;
use OCP\DB\QueryBuilder\ICompositeExpression;
use OCP\DB\QueryBuilder\IQueryBuilder;
@@ -108,7 +109,7 @@ public function limitToSession(
[CoreQueryBuilder::HELPER],
[
'getData' => $fullDetails,
- 'mustBeMember' => true
+ 'minimumLevel' => Member::LEVEL_MEMBER
]
);
@@ -141,7 +142,7 @@ public function limitToInheritedMembers(
[CoreQueryBuilder::HELPER],
[
'getData' => $fullDetails,
- 'mustBeMember' => true
+ 'minimumLevel' => Member::LEVEL_MEMBER
]
);
diff --git a/lib/Collaboration/v2/CollaboratorSearchPlugin.php b/lib/Collaboration/v2/CollaboratorSearchPlugin.php
index e38d25298..1666993b6 100644
--- a/lib/Collaboration/v2/CollaboratorSearchPlugin.php
+++ b/lib/Collaboration/v2/CollaboratorSearchPlugin.php
@@ -31,10 +31,10 @@
namespace OCA\Circles\Collaboration\v2;
-use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
use Exception;
use OC\Share20\Share;
use OCA\Circles\Model\Circle;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\FederatedUserService;
use OCP\Collaboration\Collaborators\ISearchPlugin;
@@ -85,15 +85,16 @@ public function search($search, $limit, $offset, ISearchResult $searchResult): b
try {
$this->federatedUserService->initCurrentUser();
- $circles = $this->circleService->getCircles(
- $filterCircle, null,
- new SimpleDataStore(
- [
- 'limit' => $limit,
- 'offset' => $offset
- ]
- )
- );
+
+ $probe = new CircleProbe();
+ $probe->setItemsLimit($limit);
+ $probe->setItemsOffset($offset);
+ $probe->setFilterCircle($filterCircle);
+
+ // Issue when searching for circle to be added as member
+ $probe->mustBeMember();
+
+ $circles = $this->circleService->getCircles($probe);
} catch (Exception $e) {
return false;
}
diff --git a/lib/Command/CirclesList.php b/lib/Command/CirclesList.php
index 88ce0a50c..9bb2aeb81 100644
--- a/lib/Command/CirclesList.php
+++ b/lib/Command/CirclesList.php
@@ -33,7 +33,6 @@
use ArtificialOwl\MySmallPhpTools\Exceptions\RequestNetworkException;
use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException;
-use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools;
use ArtificialOwl\MySmallPhpTools\Traits\TStringTools;
use OC\Core\Command\Base;
@@ -55,6 +54,7 @@
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Member;
use OCA\Circles\Model\ModelManager;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\FederatedUserService;
@@ -183,8 +183,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int
true
);
- $params = new SimpleDataStore(['includeSystemCircles' => $input->getOption('all')]);
- $circles = $this->circleService->getCircles(null, $filterMember, $params);
+ $probe = new CircleProbe();
+ if ($input->getOption('all')) {
+ $probe->includeSystemCircles()
+ ->includeSingleCircles()
+ ->includePersonalCircles();
+ }
+ $circles = $this->circleService->getCircles($probe);
}
if (strtolower($input->getOption('output')) === 'json') {
diff --git a/lib/Command/CirclesMemberships.php b/lib/Command/CirclesMemberships.php
index 743ad1bd6..260b95b63 100644
--- a/lib/Command/CirclesMemberships.php
+++ b/lib/Command/CirclesMemberships.php
@@ -61,6 +61,7 @@
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\FederatedUserService;
@@ -366,8 +367,10 @@ private function manageAllMemberships() {
$this->federatedUserService->bypassCurrentUserCondition(true);
- $params = new SimpleDataStore(['includeSystemCircles' => true]);
- $circles = $this->circleService->getCircles(null, null, $params);
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles()
+ ->includePersonalCircles();
+ $circles = $this->circleService->getCircles($probe);
$output = new ConsoleOutput();
$output = $output->section();
diff --git a/lib/Command/CirclesReport.php b/lib/Command/CirclesReport.php
index 9c962a33c..f7a83d8f0 100644
--- a/lib/Command/CirclesReport.php
+++ b/lib/Command/CirclesReport.php
@@ -35,7 +35,6 @@
use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException;
use ArtificialOwl\MySmallPhpTools\IInteractiveShellClient;
use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc22\NC22InteractiveShellSession;
-use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Deserialize;
use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools;
use OC\Core\Command\Base;
@@ -46,6 +45,7 @@
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
use OCA\Circles\Model\Membership;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\Report;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\ConfigService;
@@ -173,11 +173,9 @@ private function generateReport(): Report {
$report->setSource($this->interfaceService->getLocalInstance());
$this->federatedUserService->bypassCurrentUserCondition(true);
- $raw = $this->circleService->getCircles(
- null,
- null,
- new SimpleDataStore(['includeSystemCircles' => true])
- );
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles();
+ $raw = $this->circleService->getCircles($probe);
$circles = [];
foreach ($raw as $circle) {
diff --git a/lib/Command/SharesFiles.php b/lib/Command/SharesFiles.php
index f7ffdc615..d51ab0bc4 100644
--- a/lib/Command/SharesFiles.php
+++ b/lib/Command/SharesFiles.php
@@ -39,6 +39,7 @@
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Exceptions\SingleCircleNotFoundException;
use OCA\Circles\Model\Circle;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\ShareWrapper;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\FederatedUserService;
@@ -302,12 +303,13 @@ private function getShares(
}
if ($with !== '') {
+ $probe = new CircleProbe();
+ $probe->includePersonalCircles();
+
return $this->shareWrapperService->getSharedWith(
$this->federatedUserService->getLocalFederatedUser($with),
$fileId,
- -1,
- 0,
- true
+ $probe
);
}
diff --git a/lib/Controller/RemoteController.php b/lib/Controller/RemoteController.php
index ee863907e..8f9024ce9 100644
--- a/lib/Controller/RemoteController.php
+++ b/lib/Controller/RemoteController.php
@@ -55,6 +55,7 @@
use OCA\Circles\Model\Federated\RemoteInstance;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\FederatedUserService;
@@ -253,7 +254,12 @@ public function circles(): DataResponse {
$filterCircle = $data->gObj('filterCircle');
/** @var Member $filterMember */
$filterMember = $data->gObj('filterMember');
- $circles = $this->circleService->getCircles($filterCircle, $filterMember);
+
+ $probe = new CircleProbe();
+ $probe->setFilterCircle($filterCircle)
+ ->setFilterMember($filterMember);
+
+ $circles = $this->circleService->getCircles($probe);
return new DataResponse($circles);
} catch (Exception $e) {
diff --git a/lib/Db/CircleRequest.php b/lib/Db/CircleRequest.php
index 3b908f530..29dbaed97 100644
--- a/lib/Db/CircleRequest.php
+++ b/lib/Db/CircleRequest.php
@@ -31,7 +31,6 @@
namespace OCA\Circles\Db;
-use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
use OCA\Circles\Exceptions\CircleNotFoundException;
use OCA\Circles\Exceptions\FederatedUserNotFoundException;
use OCA\Circles\Exceptions\InvalidIdException;
@@ -40,9 +39,9 @@
use OCA\Circles\Exceptions\SingleCircleNotFoundException;
use OCA\Circles\IFederatedUser;
use OCA\Circles\Model\Circle;
-use OCA\Circles\Model\Federated\RemoteInstance;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\CircleProbe;
/**
* Class CircleRequest
@@ -151,54 +150,42 @@ public function updateConfig(Circle $circle) {
/**
- * @param Circle|null $circleFilter
- * @param Member|null $memberFilter
* @param IFederatedUser|null $initiator
- * @param RemoteInstance|null $remoteInstance
- * @param SimpleDataStore $params
+ * @param CircleProbe $probe
*
* @return Circle[]
* @throws RequestBuilderException
*/
- public function getCircles(
- ?Circle $circleFilter,
- ?Member $memberFilter,
- ?IFederatedUser $initiator,
- ?RemoteInstance $remoteInstance,
- SimpleDataStore $params
- ): array {
+ public function getCircles(?IFederatedUser $initiator, CircleProbe $probe): array {
$qb = $this->getCircleSelectSql();
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
$qb->setOptions(
[CoreQueryBuilder::CIRCLE],
- [
- 'getData' => true,
- 'mustBeMember' => $params->gBool('mustBeMember'),
- 'initiatorDirectMember' => true
- ]
+ array_merge(
+ $probe->getAsOptions(),
+ [
+ 'getData' => true,
+ 'initiatorDirectMember' => true
+ ]
+ )
);
- if (!$params->gBool('includeSystemCircles')) {
- $qb->filterCircles(
- CoreQueryBuilder::CIRCLE,
- Circle::CFG_SINGLE | Circle::CFG_HIDDEN | Circle::CFG_BACKEND
- );
- }
+ $qb->filterCircles(CoreQueryBuilder::CIRCLE, $probe->filtered());
if (!is_null($initiator)) {
$qb->limitToInitiator(CoreQueryBuilder::CIRCLE, $initiator);
}
- if (!is_null($memberFilter)) {
- $qb->limitToDirectMembership(CoreQueryBuilder::CIRCLE, $memberFilter);
+ if ($probe->hasFilterMember()) {
+ $qb->limitToDirectMembership(CoreQueryBuilder::CIRCLE, $probe->getFilterMember());
}
- if (!is_null($circleFilter)) {
- $qb->filterCircle($circleFilter);
+ if ($probe->hasFilterCircle()) {
+ $qb->filterCircle($probe->getFilterCircle());
}
- if (!is_null($remoteInstance)) {
- $qb->limitToRemoteInstance(CoreQueryBuilder::CIRCLE, $remoteInstance, false);
+ if ($probe->hasFilterRemoteInstance()) {
+ $qb->limitToRemoteInstance(CoreQueryBuilder::CIRCLE, $probe->getFilterRemoteInstance(), false);
}
$qb->countMembers(CoreQueryBuilder::CIRCLE);
- $qb->chunk($params->gInt('offset'), $params->gInt('limit'));
+ $qb->chunk($probe->getItemsOffset(), $probe->getItemsLimit());
return $this->getItemsFromRequest($qb);
}
@@ -212,7 +199,9 @@ public function getCircles(
*/
public function getCirclesByIds(array $circleIds): array {
$qb = $this->getCircleSelectSql();
- $qb->setOptions([CoreQueryBuilder::CIRCLE], ['getData' => true, 'canBeVisitor' => true]);
+ $qb->setOptions(
+ [CoreQueryBuilder::CIRCLE], ['getData' => true, 'minimumLevel' => Member::LEVEL_NONE]
+ );
$qb->limitInArray('unique_id', $circleIds);
// $qb->filterCircles(CoreQueryBuilder::CIRCLE, $filter);
@@ -224,8 +213,7 @@ public function getCirclesByIds(array $circleIds): array {
/**
* @param string $id
* @param IFederatedUser|null $initiator
- * @param RemoteInstance|null $remoteInstance
- * @param int $filter
+ * @param CircleProbe|null $probe
*
* @return Circle
* @throws CircleNotFoundException
@@ -234,34 +222,43 @@ public function getCirclesByIds(array $circleIds): array {
public function getCircle(
string $id,
?IFederatedUser $initiator = null,
- ?RemoteInstance $remoteInstance = null,
- int $filter = Circle::CFG_BACKEND | Circle::CFG_SINGLE | Circle::CFG_HIDDEN
+ ?CircleProbe $probe = null
): Circle {
+ if (is_null($probe)) {
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles()
+ ->includeBackendCircles()
+ ->includeHiddenCircles()
+ ->emulateVisitor();
+ }
+
$qb = $this->getCircleSelectSql();
$qb->setOptions(
[CoreQueryBuilder::CIRCLE],
- [
- 'getData' => true,
- 'canBeVisitor' => true,
- 'initiatorDirectMember' => true
- ]
+ array_merge(
+ $probe->getAsOptions(),
+ [
+ 'getData' => true,
+ 'initiatorDirectMember' => true
+ ]
+ )
);
$qb->limitToUniqueId($id);
- $qb->filterCircles(CoreQueryBuilder::CIRCLE, $filter);
+ $qb->filterCircles(CoreQueryBuilder::CIRCLE, $probe->filtered());
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
// $qb->setOptions(
// [CoreRequestBuilder::CIRCLE, CoreRequestBuilder::INITIATOR], [
// 'mustBeMember' => false,
-// 'canBeVisitor' => true
+// 'viewableAsVisitor' => true
// ]
// );
if (!is_null($initiator)) {
$qb->limitToInitiator(CoreQueryBuilder::CIRCLE, $initiator);
}
- if (!is_null($remoteInstance)) {
- $qb->limitToRemoteInstance(CoreQueryBuilder::CIRCLE, $remoteInstance, false);
+ if ($probe->hasFilterRemoteInstance()) {
+ $qb->limitToRemoteInstance(CoreQueryBuilder::CIRCLE, $probe->getFilterRemoteInstance(), false);
}
$qb->countMembers(CoreQueryBuilder::CIRCLE);
diff --git a/lib/Db/CoreQueryBuilder.php b/lib/Db/CoreQueryBuilder.php
index 68596e881..698a8f997 100644
--- a/lib/Db/CoreQueryBuilder.php
+++ b/lib/Db/CoreQueryBuilder.php
@@ -127,8 +127,7 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
],
self::INITIATOR => [
self::OPTIONS => [
- 'mustBeMember' => true,
- 'canBeVisitor' => false
+ 'minimumLevel' => Member::LEVEL_MEMBER
],
self::BASED_ON,
self::INHERITED_BY => [
@@ -395,6 +394,9 @@ public function filterCircle(Circle $circle): void {
if ($circle->getDisplayName() !== '') {
$this->searchInDBField('display_name', '%' . $circle->getDisplayName() . '%');
}
+ if ($circle->getSource() > 0) {
+ $this->limitInt('source', $circle->getSource());
+ }
if ($circle->getConfig() > 0) {
$this->limitBitwise('config', $circle->getConfig());
}
@@ -1208,7 +1210,7 @@ public function leftJoinInitiator(
);
$default = [];
- if ($this->getBool('canBeVisitor', $options, false)) {
+ if ($this->getBool('emulateVisitor', $options)) {
$default = [
'user_id' => $initiator->getUserId(),
'single_id' => $initiator->getSingleId(),
@@ -1241,8 +1243,6 @@ protected function limitInitiatorVisibility(string $alias): ICompositeExpression
array_push($levelCheck, $this->generateAlias($alias, self::DIRECT_INITIATOR, $options));
}
- $filterPersonalCircle = $this->getBool('filterPersonalCircle', $options, true);
-
$expr = $this->expr();
// Visibility to non-member is
@@ -1251,7 +1251,8 @@ protected function limitInitiatorVisibility(string $alias): ICompositeExpression
// - 4 (Visible to everyone)
$orX = $expr->orX();
- if ($filterPersonalCircle) {
+ // filterPersonalCircles will remove access to Personal Circles as Owner
+ if (!$this->getBool('filterPersonalCircles', $options, false)) {
$orX->add(
$expr->andX(
$this->exprLimitBitwise('config', Circle::CFG_PERSONAL, $aliasMembershipCircle),
@@ -1260,28 +1261,31 @@ protected function limitInitiatorVisibility(string $alias): ICompositeExpression
);
}
+ $minimumLevel = $this->getInt('minimumLevel', $options);
$andXMember = $expr->andX();
$andXMember->add(
- $this->orXCheckLevel($levelCheck, Member::LEVEL_MEMBER),
+ $this->orXCheckLevel($levelCheck, $minimumLevel)
);
- if ($filterPersonalCircle) {
+
+ if (!$this->getBool('includePersonalCircles', $options, false)) {
$andXMember->add(
$this->exprFilterBitwise('config', Circle::CFG_PERSONAL, $aliasMembershipCircle)
);
}
$orX->add($andXMember);
- if (!$this->getBool('mustBeMember', $options, true)) {
+ if ($minimumLevel === 0 && $alias === self::CIRCLE) {
$orX->add($this->exprLimitBitwise('config', Circle::CFG_VISIBLE, $alias));
}
- if ($this->getBool('canBeVisitor', $options, false)) {
- // TODO: should find a better way, also filter on remote initiator on non-federated ?
- $orX->add($this->exprFilterInt('config', Circle::CFG_PERSONAL, $alias));
- }
- if ($this->getBool('canBeVisitorOnOpen', $options, false)) {
+
+ // if Member can be Visitor, we only filter access to Personal Circles
+ if ($this->getBool('viewableThroughKeyhole', $options, false)) {
$andOpen = $expr->andX();
$andOpen->add($this->exprLimitBitwise('config', Circle::CFG_OPEN, $alias));
- $andOpen->add($this->exprFilterBitwise('config', Circle::CFG_REQUEST, $alias));
+ $andOpen->add($this->exprLimitBitwise('config', Circle::CFG_VISIBLE, $alias));
+ if (!$this->configService->getAppValueBool(ConfigService::KEYHOLE_CFG_REQUEST)) {
+ $andOpen->add($this->exprFilterBitwise('config', Circle::CFG_REQUEST, $alias));
+ }
$orX->add($andOpen);
}
@@ -1308,15 +1312,10 @@ protected function limitInitiatorVisibility(string $alias): ICompositeExpression
/**
- * CFG_SINGLE, CFG_HIDDEN and CFG_BACKEND means hidden from listing.
- *
* @param string $aliasCircle
* @param int $flag
*/
- public function filterCircles(
- string $aliasCircle,
- int $flag = Circle::CFG_SINGLE | Circle::CFG_HIDDEN | Circle::CFG_BACKEND
- ): void {
+ public function filterCircles(string $aliasCircle, int $flag): void {
if ($flag === 0) {
return;
}
diff --git a/lib/Db/MemberRequest.php b/lib/Db/MemberRequest.php
index 9051ef9c9..46372adfb 100644
--- a/lib/Db/MemberRequest.php
+++ b/lib/Db/MemberRequest.php
@@ -36,9 +36,9 @@
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\IFederatedUser;
use OCA\Circles\Model\Circle;
-use OCA\Circles\Model\Federated\RemoteInstance;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\MemberProbe;
/**
* Class MemberRequest
@@ -210,8 +210,7 @@ public function updateLevel(Member $member): void {
/**
* @param string $singleId
* @param IFederatedUser|null $initiator
- * @param RemoteInstance|null $remoteInstance
- * @param Member|null $filter
+ * @param MemberProbe|null $probe
*
* @return Member[]
* @throws RequestBuilderException
@@ -219,22 +218,38 @@ public function updateLevel(Member $member): void {
public function getMembers(
string $singleId,
?IFederatedUser $initiator = null,
- ?RemoteInstance $remoteInstance = null,
- ?Member $filter = null
+ ?MemberProbe $probe = null
): array {
+ if (is_null($probe)) {
+ $probe = new MemberProbe();
+ }
+
$qb = $this->getMemberSelectSql($initiator);
$qb->limitToCircleId($singleId);
- $qb->setOptions([CoreQueryBuilder::MEMBER], ['canBeVisitorOnOpen' => true]);
+ $qb->setOptions(
+ [CoreQueryBuilder::MEMBER],
+ array_merge(
+ $probe->getAsOptions(),
+ ['viewableThroughKeyhole' => true]
+ )
+ );
+
$qb->leftJoinCircle(CoreQueryBuilder::MEMBER, $initiator);
$qb->leftJoinInvitedBy(CoreQueryBuilder::MEMBER);
- if (!is_null($remoteInstance)) {
+ if ($probe->hasFilterRemoteInstance()) {
$aliasCircle = $qb->generateAlias(CoreQueryBuilder::MEMBER, CoreQueryBuilder::CIRCLE);
- $qb->limitToRemoteInstance(CoreQueryBuilder::MEMBER, $remoteInstance, true, $aliasCircle);
+ $qb->limitToRemoteInstance(
+ CoreQueryBuilder::MEMBER,
+ $probe->getFilterRemoteInstance(),
+ true,
+ $aliasCircle
+ );
}
- if (!is_null($filter)) {
- $qb->filterDirectMembership(CoreQueryBuilder::MEMBER, $filter);
+
+ if ($probe->hasFilterMember()) {
+ $qb->filterDirectMembership(CoreQueryBuilder::MEMBER, $probe->getFilterMember());
}
$qb->orderBy($qb->getDefaultSelectAlias() . '.level', 'desc');
@@ -290,7 +305,7 @@ public function getMember(string $circleId, string $singleId): Member {
/**
* @param string $memberId
* @param FederatedUser|null $initiator
- * @param bool $canBeVisitor
+ * @param MemberProbe|null $probe
*
* @return Member
* @throws MemberNotFoundException
@@ -299,13 +314,17 @@ public function getMember(string $circleId, string $singleId): Member {
public function getMemberById(
string $memberId,
?FederatedUser $initiator = null,
- bool $canBeVisitor = false
+ ?MemberProbe $probe = null
): Member {
+ if (is_null($probe)) {
+ $probe = new MemberProbe();
+ }
+
$qb = $this->getMemberSelectSql();
$qb->limitToMemberId($memberId);
+ $qb->setOptions([CoreQueryBuilder::MEMBER], $probe->getAsOptions());
if (!is_null($initiator)) {
- $qb->setOptions([CoreQueryBuilder::MEMBER], ['canBeVisitor' => $canBeVisitor]);
$qb->leftJoinCircle(CoreQueryBuilder::MEMBER, $initiator);
}
diff --git a/lib/Db/ShareWrapperRequest.php b/lib/Db/ShareWrapperRequest.php
index f992dc8a5..7625bee07 100644
--- a/lib/Db/ShareWrapperRequest.php
+++ b/lib/Db/ShareWrapperRequest.php
@@ -35,6 +35,7 @@
use OCA\Circles\Exceptions\ShareWrapperNotFoundException;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Membership;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\ShareWrapper;
use OCP\Files\NotFoundException;
use OCP\Share\Exceptions\IllegalIDChangeException;
@@ -307,12 +308,18 @@ public function getSharesByFileId(int $fileId, bool $getData = false): array {
public function getSharedWith(
FederatedUser $federatedUser,
int $nodeId,
- int $offset,
- int $limit,
- bool $getData = false
+ CircleProbe $probe
): array {
$qb = $this->getShareSelectSql();
- $qb->setOptions([CoreQueryBuilder::SHARE], ['getData' => $getData, 'filterPersonalCircle' => false]);
+ $qb->setOptions(
+ [CoreQueryBuilder::SHARE],
+ array_merge(
+ $probe->getAsOptions(),
+ ['getData' => true]
+ )
+ );
+
+ $getData = true;
if ($getData) {
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
}
@@ -327,7 +334,7 @@ public function getSharedWith(
$qb->limitToFileSource($nodeId);
}
- $qb->chunk($offset, $limit);
+ $qb->chunk($probe->getItemsOffset(), $probe->getItemsLimit());
return $this->getItemsFromRequest($qb);
}
@@ -450,4 +457,15 @@ public function delete(int $shareId): void {
$qb->execute();
}
+
+
+ /**
+ * @param string $circleId
+ */
+ public function deleteFromCircle(string $circleId): void {
+ $qb = $this->getShareDeleteSql();
+ $qb->andWhere($qb->exprLimit('share_with', $circleId));
+
+ $qb->execute();
+ }
}
diff --git a/lib/IQueryProbe.php b/lib/IQueryProbe.php
new file mode 100644
index 000000000..971a89e5c
--- /dev/null
+++ b/lib/IQueryProbe.php
@@ -0,0 +1,102 @@
+
+ * @copyright 2021
+ * @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 .
+ *
+ */
+
+
+namespace OCA\Circles;
+
+use OCA\Circles\Model\Circle;
+use OCA\Circles\Model\Federated\RemoteInstance;
+use OCA\Circles\Model\Member;
+
+/**
+ * Interface IQueryProbe
+ *
+ * @package OCA\Circles
+ */
+interface IQueryProbe {
+
+
+ /**
+ * @return int
+ */
+ public function getItemsOffset(): int;
+
+ /**
+ * @return int
+ */
+ public function getItemsLimit(): int;
+
+ /**
+ * @return int
+ */
+ public function getDetails(): int;
+
+ /**
+ * @param int $details
+ *
+ * @return bool
+ */
+ public function showDetails(int $details): bool;
+
+ /**
+ * @return Circle
+ */
+ public function getFilterCircle(): Circle;
+
+ /**
+ * @return bool
+ */
+ public function hasFilterCircle(): bool;
+
+ /**
+ * @return Member
+ */
+ public function getFilterMember(): Member;
+
+ /**
+ * @return bool
+ */
+ public function hasFilterMember(): bool;
+
+ /**
+ * @return RemoteInstance
+ */
+ public function getFilterRemoteInstance(): RemoteInstance;
+
+ /**
+ * @return bool
+ */
+ public function hasFilterRemoteInstance(): bool;
+
+ /**
+ * @return array
+ */
+ public function getAsOptions(): array;
+}
diff --git a/lib/Listeners/DeprecatedListener.php b/lib/Listeners/DeprecatedListener.php
index 3da31f733..241df229e 100644
--- a/lib/Listeners/DeprecatedListener.php
+++ b/lib/Listeners/DeprecatedListener.php
@@ -31,7 +31,6 @@
namespace OCA\Circles\Listeners;
-use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
use Exception;
use OCA\Circles\Db\CircleRequest;
use OCA\Circles\Exceptions\ContactAddressBookNotFoundException;
@@ -45,6 +44,7 @@
use OCA\Circles\Exceptions\SingleCircleNotFoundException;
use OCA\Circles\FederatedItems\MemberDisplayName;
use OCA\Circles\Model\Federated\FederatedEvent;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\FederatedEventService;
use OCA\Circles\Service\FederatedUserService;
@@ -111,8 +111,12 @@ public function userAccountUpdated(IUser $user) {
$this->circleRequest->updateDisplayName($federatedUser->getSingleId(), $user->getDisplayName());
$this->federatedUserService->setCurrentUser($federatedUser);
- $params = new SimpleDataStore(['includeSystemCircles' => true]);
- $circles = $this->circleService->getCircles(null, null, $params);
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles()
+ ->mustBeMember()
+ ->canBeRequestingMembership();
+
+ $circles = $this->circleService->getCircles($probe);
foreach ($circles as $circle) {
$event = new FederatedEvent(MemberDisplayName::class);
diff --git a/lib/Model/Probes/BasicProbe.php b/lib/Model/Probes/BasicProbe.php
new file mode 100644
index 000000000..ee6a95dab
--- /dev/null
+++ b/lib/Model/Probes/BasicProbe.php
@@ -0,0 +1,272 @@
+
+ * @copyright 2021
+ * @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 .
+ *
+ */
+
+
+namespace OCA\Circles\Model\Probes;
+
+use OCA\Circles\IQueryProbe;
+use OCA\Circles\Model\Circle;
+use OCA\Circles\Model\Federated\RemoteInstance;
+use OCA\Circles\Model\Member;
+
+/**
+ * Class BasicProbe
+ *
+ * @package OCA\Circles\Model\Probes
+ */
+class BasicProbe implements IQueryProbe {
+ public const DETAILS_NONE = 0;
+ public const DETAILS_ALL = 64;
+
+
+ /** @var int */
+ private $itemsOffset = 0;
+
+ /** @var int */
+ private $itemsLimit = -1;
+
+ /** @var int */
+ private $details = 0;
+
+ /** @var Circle */
+ private $filterCircle;
+
+ /** @var Member */
+ private $filterMember;
+
+ /** @var RemoteInstance */
+ private $filterRemoteInstance;
+
+ /** @var array */
+ private $options = [];
+
+
+ /**
+ * @param int $itemsOffset
+ *
+ * @return BasicProbe
+ */
+ public function setItemsOffset(int $itemsOffset): self {
+ $this->itemsOffset = $itemsOffset;
+
+ return $this;
+ }
+
+ /**
+ * @return int
+ */
+ public function getItemsOffset(): int {
+ return $this->itemsOffset;
+ }
+
+
+ /**
+ * @param int $itemsLimit
+ *
+ * @return BasicProbe
+ */
+ public function setItemsLimit(int $itemsLimit): self {
+ $this->itemsLimit = $itemsLimit;
+
+ return $this;
+ }
+
+ /**
+ * @return int
+ */
+ public function getItemsLimit(): int {
+ return $this->itemsLimit;
+ }
+
+
+ /**
+ * @param int $details
+ *
+ * @return $this
+ */
+ public function setDetails(int $details): self {
+ $this->details = $details;
+ }
+
+ /**
+ * @return int
+ */
+ public function getDetails(): int {
+ return $this->details;
+ }
+
+
+ /**
+ * @param int $details
+ *
+ * @return bool
+ */
+ public function showDetails(int $details): bool {
+ return (($this->getDetails() & $details) !== 0);
+ }
+
+
+ /**
+ * @param Circle $filterCircle
+ *
+ * @return CircleProbe
+ */
+ public function setFilterCircle(Circle $filterCircle): self {
+ $this->filterCircle = $filterCircle;
+
+ return $this;
+ }
+
+ /**
+ * @return Circle
+ */
+ public function getFilterCircle(): Circle {
+ return $this->filterCircle;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasFilterCircle(): bool {
+ return !is_null($this->filterCircle);
+ }
+
+
+ /**
+ * @param Member $filterMember
+ *
+ * @return CircleProbe
+ */
+ public function setFilterMember(Member $filterMember): self {
+ $this->filterMember = $filterMember;
+
+ return $this;
+ }
+
+ /**
+ * @return Member
+ */
+ public function getFilterMember(): Member {
+ return $this->filterMember;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasFilterMember(): bool {
+ return !is_null($this->filterMember);
+ }
+
+
+ /**
+ * @param RemoteInstance $filterRemoteInstance
+ *
+ * @return CircleProbe
+ */
+ public function setFilterRemoteInstance(RemoteInstance $filterRemoteInstance): self {
+ $this->filterRemoteInstance = $filterRemoteInstance;
+
+ return $this;
+ }
+
+ /**
+ * @return RemoteInstance
+ */
+ public function getFilterRemoteInstance(): RemoteInstance {
+ return $this->filterRemoteInstance;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasFilterRemoteInstance(): bool {
+ return !is_null($this->filterRemoteInstance);
+ }
+
+
+ /**
+ * @param string $key
+ * @param string $value
+ *
+ * @return $this
+ */
+ public function addOption(string $key, string $value): self {
+ $this->options[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @param string $key
+ * @param int $value
+ *
+ * @return $this
+ */
+ public function addOptionInt(string $key, int $value): self {
+ $this->options[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @param string $key
+ * @param bool $value
+ *
+ * @return $this
+ */
+ public function addOptionBool(string $key, bool $value): self {
+ $this->options[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAsOptions(): array {
+ return array_merge(
+ $this->options,
+ [
+ 'offset' => $this->getItemsOffset(),
+ 'limit' => $this->getItemsLimit(),
+ 'details' => $this->getDetails(),
+ 'detailsAll' => ($this->getDetails() === self::DETAILS_ALL)
+ ]
+ );
+ }
+
+
+ /**
+ * @return array
+ */
+ public function JsonSerialize(): array {
+ return $this->getAsOptions();
+ }
+}
diff --git a/lib/Model/Probes/CircleProbe.php b/lib/Model/Probes/CircleProbe.php
new file mode 100644
index 000000000..7a5a3787f
--- /dev/null
+++ b/lib/Model/Probes/CircleProbe.php
@@ -0,0 +1,180 @@
+
+ * @copyright 2021
+ * @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 .
+ *
+ */
+
+
+namespace OCA\Circles\Model\Probes;
+
+use OCA\Circles\Model\Circle;
+
+/**
+ * Class CircleProbe
+ *
+ * @package OCA\Circles\Model\Probes
+ */
+class CircleProbe extends MemberProbe {
+
+
+ /** @var array */
+ public static $filters = [
+ Circle::CFG_SINGLE,
+ Circle::CFG_HIDDEN,
+ Circle::CFG_BACKEND,
+ ];
+
+ /** @var int */
+ private $include = 0;
+
+
+ /**
+ * @param bool $include
+ *
+ * @return $this
+ */
+ public function includePersonalCircles(bool $include = true): self {
+ $this->include |= Circle::CFG_PERSONAL;
+ if (!$include) {
+ $this->include -= Circle::CFG_PERSONAL;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param bool $include
+ *
+ * @return $this
+ */
+ public function includeSingleCircles(bool $include = true): self {
+ $this->include |= Circle::CFG_SINGLE;
+ if (!$include) {
+ $this->include -= Circle::CFG_SINGLE;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param bool $include
+ *
+ * @return $this
+ */
+ public function includeSystemCircles(bool $include = true): self {
+ $this->include |= Circle::CFG_SYSTEM;
+ if (!$include) {
+ $this->include -= Circle::CFG_SYSTEM;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param bool $include
+ *
+ * @return $this
+ */
+ public function includeHiddenCircles(bool $include = true): self {
+ $this->include |= Circle::CFG_HIDDEN;
+ if (!$include) {
+ $this->include -= Circle::CFG_HIDDEN;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param bool $include
+ *
+ * @return $this
+ */
+ public function includeBackendCircles(bool $include = true): self {
+ $this->include |= Circle::CFG_BACKEND;
+ if (!$include) {
+ $this->include -= Circle::CFG_BACKEND;
+ }
+
+ return $this;
+ }
+
+
+ /**
+ * @return int
+ */
+ public function included(): int {
+ return $this->include;
+ }
+
+ /**
+ * @param int $config
+ *
+ * @return bool
+ */
+ public function isIncluded(int $config): bool {
+ return (($this->included() & $config) !== 0);
+ }
+
+ /**
+ * @return int
+ */
+ public function filtered(): int {
+ $filtered = 0;
+ foreach (self::$filters as $filter) {
+ if ($this->isIncluded($filter)) {
+ continue;
+ }
+ $filtered += $filter;
+ }
+
+ return $filtered;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAsOptions(): array {
+ return array_merge(
+ [
+ 'included' => $this->included(),
+ 'includeHiddenCircles' => $this->isIncluded(Circle::CFG_HIDDEN),
+ 'includeBackendCircles' => $this->isIncluded(Circle::CFG_BACKEND),
+ 'includeSystemCircles' => $this->isIncluded(Circle::CFG_SYSTEM),
+ 'includePersonalCircles' => $this->isIncluded(Circle::CFG_PERSONAL),
+ ],
+ parent::getAsOptions()
+ );
+ }
+
+
+ /**
+ * @return array
+ */
+ public function JsonSerialize(): array {
+ return $this->getAsOptions();
+ }
+}
diff --git a/lib/Model/Probes/MemberProbe.php b/lib/Model/Probes/MemberProbe.php
new file mode 100644
index 000000000..8d3e62934
--- /dev/null
+++ b/lib/Model/Probes/MemberProbe.php
@@ -0,0 +1,160 @@
+
+ * @copyright 2021
+ * @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 .
+ *
+ */
+
+
+namespace OCA\Circles\Model\Probes;
+
+use OCA\Circles\Model\Member;
+
+/**
+ * Class CircleProbe
+ *
+ * @package OCA\Circles\Model\Probes
+ */
+class MemberProbe extends BasicProbe {
+
+
+ /** @var int */
+ private $minimumLevel = Member::LEVEL_NONE;
+
+ /** @var bool */
+ private $emulateVisitor = false;
+
+ /** @var bool */
+ private $requestingMembership = false;
+
+
+ /**
+ * allow the initiator as a requesting member
+ *
+ * @param bool $can
+ *
+ * @return $this
+ */
+ public function canBeRequestingMembership(bool $can = true): self {
+ $this->requestingMembership = $can;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRequestingMembership(): bool {
+ return $this->requestingMembership;
+ }
+
+
+ /**
+ * force the generation an initiator if visitor
+ *
+ * @return $this
+ */
+ public function emulateVisitor(): self {
+ $this->emulateVisitor = true;
+
+ return $this;
+ }
+
+ public function isEmulatingVisitor(): bool {
+ return $this->emulateVisitor;
+ }
+
+
+ /**
+ * @return int
+ */
+ public function getMinimumLevel(): int {
+ return $this->minimumLevel;
+ }
+
+ /**
+ * @return $this
+ */
+ public function mustBeMember(bool $must = true): self {
+ if ($must) {
+ $this->minimumLevel = Member::LEVEL_MEMBER;
+ } else {
+ $this->minimumLevel = Member::LEVEL_NONE;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function mustBeModerator(): self {
+ $this->minimumLevel = Member::LEVEL_MODERATOR;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function mustBeAdmin(): self {
+ $this->minimumLevel = Member::LEVEL_ADMIN;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function mustBeOwner(): self {
+ $this->minimumLevel = Member::LEVEL_OWNER;
+
+ return $this;
+ }
+
+
+ /**
+ * @return array
+ */
+ public function getAsOptions(): array {
+ return array_merge(
+ [
+ 'minimumLevel' => $this->getMinimumLevel(),
+ 'emulateVisitor' => $this->isEmulatingVisitor(),
+ 'allowRequestingMembership' => $this->isRequestingMembership()
+ ],
+ parent::getAsOptions()
+ );
+ }
+
+
+ /**
+ * @return array
+ */
+ public function JsonSerialize(): array {
+ return $this->getAsOptions();
+ }
+}
diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php
index ed3ec359d..969fd28cf 100644
--- a/lib/Notification/Notifier.php
+++ b/lib/Notification/Notifier.php
@@ -42,6 +42,7 @@
use OCA\Circles\Exceptions\MemberNotFoundException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Exceptions\SingleCircleNotFoundException;
+use OCA\Circles\Model\Probes\MemberProbe;
use OCA\Circles\Service\FederatedUserService;
use OCA\Circles\Service\MemberService;
use OCP\Contacts\IManager;
@@ -170,10 +171,12 @@ public function prepare(INotification $notification, string $languageCode): INot
*/
private function prepareMemberNotification(INotification $notification) {
$this->federatedUserService->initCurrentUser();
+ $probe = new MemberProbe();
+
$member = $this->memberService->getMemberById(
$notification->getObjectId(),
'',
- true
+ $probe
);
switch ($notification->getSubject()) {
diff --git a/lib/Service/CircleService.php b/lib/Service/CircleService.php
index 6801ee80d..a91193c62 100644
--- a/lib/Service/CircleService.php
+++ b/lib/Service/CircleService.php
@@ -63,6 +63,8 @@
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\ManagedModel;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\CircleProbe;
+use OCA\Circles\Model\Probes\MemberProbe;
use OCA\Circles\StatusCode;
/**
@@ -426,56 +428,35 @@ public function circleLeave(string $circleId, bool $force = false): array {
*/
public function getCircle(
string $circleId,
- int $filter = Circle::CFG_BACKEND | Circle::CFG_SINGLE | Circle::CFG_HIDDEN
+ ?CircleProbe $probe = null
): Circle {
$this->federatedUserService->mustHaveCurrentUser();
return $this->circleRequest->getCircle(
$circleId,
$this->federatedUserService->getCurrentUser(),
- $this->federatedUserService->getRemoteInstance(),
- $filter
+ $probe
);
}
/**
- * @param Circle|null $circleFilter
- * @param Member|null $memberFilter
- * @param SimpleDataStore|null $params
+ * @param CircleProbe|null $probe
*
* @return Circle[]
* @throws InitiatorNotFoundException
* @throws RequestBuilderException
*/
- public function getCircles(
- ?Circle $circleFilter = null,
- ?Member $memberFilter = null,
- ?SimpleDataStore $params = null
- ): array {
+ public function getCircles(?CircleProbe $probe = null): array {
$this->federatedUserService->mustHaveCurrentUser();
- if ($params === null) {
- $params = new SimpleDataStore();
+ if (is_null($probe)) {
+ $probe = new CircleProbe();
}
- $params->default(
- [
- 'limit' => -1,
- 'offset' => 0,
- 'mustBeMember' => false,
- 'includeHiddenCircles' => false,
- 'includeBackendCircles' => false,
- 'includeSystemCircles' => false,
- 'includePersonalCircles' => false
- ]
- );
return $this->circleRequest->getCircles(
- $circleFilter,
- $memberFilter,
$this->federatedUserService->getCurrentUser(),
- $this->federatedUserService->getRemoteInstance(),
- $params
+ $probe
);
}
@@ -597,9 +578,12 @@ public function confirmCircleNotFull(Circle $circle): void {
* @throws RequestBuilderException
*/
public function isCircleFull(Circle $circle): bool {
- $filter = new Member();
- $filter->setLevel(Member::LEVEL_MEMBER);
- $members = $this->memberRequest->getMembers($circle->getSingleId(), null, null, $filter);
+ $filterMember = new Member();
+ $filterMember->setLevel(Member::LEVEL_MEMBER);
+ $probe = new MemberProbe();
+ $probe->setFilterMember($filterMember);
+
+ $members = $this->memberRequest->getMembers($circle->getSingleId(), null, $probe);
$limit = $this->getInt('members_limit', $circle->getSettings());
if ($limit === 0) {
diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php
index 8628292f3..4aa0ea09f 100644
--- a/lib/Service/ConfigService.php
+++ b/lib/Service/ConfigService.php
@@ -80,6 +80,7 @@ class ConfigService {
public const HARD_MODERATION = 'hard_moderation';
public const FRONTEND_ENABLED = 'frontend_enabled';
+ public const KEYHOLE_CFG_REQUEST = 'keyhole_cfg_request';
public const ROUTE_TO_CIRCLE = 'route_to_circle';
public const EVENT_EXAMPLES = 'event_examples';
@@ -89,6 +90,7 @@ class ConfigService {
public const MIGRATION_BYPASS = 'migration_bypass';
public const MIGRATION_22 = 'migration_22';
+ public const MIGRATION_22_CONFIRMED = 'migration_22_confirmed';
public const MIGRATION_RUN = 'migration_run';
public const MAINTENANCE_UPDATE = 'maintenance_update';
public const MAINTENANCE_RUN = 'maintenance_run';
@@ -142,6 +144,7 @@ class ConfigService {
self::FRONTEND_ENABLED => '1',
self::HARD_MODERATION => '0',
+ self::KEYHOLE_CFG_REQUEST => '0',
self::ROUTE_TO_CIRCLE => 'contacts.contacts.directcircle',
self::EVENT_EXAMPLES => '0',
@@ -150,6 +153,7 @@ class ConfigService {
self::ACTIVITY_ON_NEW_CIRCLE => '1',
self::MIGRATION_BYPASS => '0',
self::MIGRATION_22 => '0',
+ self::MIGRATION_22_CONFIRMED => '0',
self::MIGRATION_RUN => '0',
self::MAINTENANCE_UPDATE => '[]',
self::MAINTENANCE_RUN => '0',
diff --git a/lib/Service/FederatedUserService.php b/lib/Service/FederatedUserService.php
index a90d3d4d2..38381c027 100644
--- a/lib/Service/FederatedUserService.php
+++ b/lib/Service/FederatedUserService.php
@@ -68,6 +68,7 @@
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\ManagedModel;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserManager;
@@ -544,7 +545,10 @@ public function commandLineInitiator(
}
if ($circleId !== '') {
- $localCircle = $this->circleRequest->getCircle($circleId, null, null, 0);
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles()
+ ->canBeRequestingMembership();
+ $localCircle = $this->circleRequest->getCircle($circleId, null, $probe);
if ($this->configService->isLocalInstance($localCircle->getInstance())) {
$this->setCurrentUser($localCircle->getOwner());
diff --git a/lib/Service/MaintenanceService.php b/lib/Service/MaintenanceService.php
index f56bb3209..a927a4d29 100644
--- a/lib/Service/MaintenanceService.php
+++ b/lib/Service/MaintenanceService.php
@@ -31,16 +31,18 @@
namespace OCA\Circles\Service;
-use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Logger;
use Exception;
use OCA\Circles\Db\CircleRequest;
use OCA\Circles\Db\MemberRequest;
+use OCA\Circles\Db\ShareWrapperRequest;
use OCA\Circles\Exceptions\InitiatorNotFoundException;
use OCA\Circles\Exceptions\MaintenanceException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\CircleProbe;
+use OCA\Circles\Model\ShareWrapper;
use OCP\IUserManager;
use Symfony\Component\Console\Output\OutputInterface;
@@ -65,6 +67,9 @@ class MaintenanceService {
/** @var MemberRequest */
private $memberRequest;
+ /** @var ShareWrapperRequest */
+ private $shareWrapperRequest;
+
/** @var SyncService */
private $syncService;
@@ -91,6 +96,7 @@ class MaintenanceService {
* @param IUserManager $userManager
* @param CircleRequest $circleRequest
* @param MemberRequest $memberRequest
+ * @param ShareWrapperRequest $shareWrapperRequest
* @param SyncService $syncService
* @param FederatedUserService $federatedUserService
* @param EventWrapperService $eventWrapperService
@@ -101,6 +107,7 @@ public function __construct(
IUserManager $userManager,
CircleRequest $circleRequest,
MemberRequest $memberRequest,
+ ShareWrapperRequest $shareWrapperRequest,
SyncService $syncService,
FederatedUserService $federatedUserService,
EventWrapperService $eventWrapperService,
@@ -110,6 +117,7 @@ public function __construct(
$this->userManager = $userManager;
$this->circleRequest = $circleRequest;
$this->memberRequest = $memberRequest;
+ $this->shareWrapperRequest = $shareWrapperRequest;
$this->syncService = $syncService;
$this->federatedUserService = $federatedUserService;
$this->eventWrapperService = $eventWrapperService;
@@ -231,8 +239,10 @@ private function runMaintenance4(): void {
}
try {
// TODO: waiting for confirmation of a good migration before cleaning orphan shares
-// $this->output('remove deprecated shares');
-// $this->removeDeprecatedShares();
+ if ($this->configService->getAppValue(ConfigService::MIGRATION_22_CONFIRMED)) {
+ $this->output('remove deprecated shares');
+ $this->removeDeprecatedShares();
+ }
} catch (Exception $e) {
}
@@ -262,7 +272,11 @@ private function runMaintenance5(): void {
* @throws RequestBuilderException
*/
private function removeCirclesWithNoOwner(): void {
- $circles = $this->circleService->getCircles();
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles()
+ ->includeSingleCircles()
+ ->includePersonalCircles();
+ $circles = $this->circleService->getCircles($probe);
foreach ($circles as $circle) {
if (!$circle->hasOwner()) {
$this->circleRequest->delete($circle);
@@ -288,25 +302,29 @@ private function removeMembersWithNoCircles(): void {
private function removeDeprecatedShares(): void {
-// $circles = array_map(
-// function(DeprecatedCircle $circle) {
-// return $circle->getUniqueId();
-// }, $this->circlesRequest->forceGetCircles()
-// );
-//
-// $shares = array_unique(
-// array_map(
-// function($share) {
-// return $share['share_with'];
-// }, $this->fileSharesRequest->getShares()
-// )
-// );
-//
-// foreach ($shares as $share) {
-// if (!in_array($share, $circles)) {
-// $this->fileSharesRequest->removeSharesToCircleId($share);
-// }
-// }
+ $probe = new CircleProbe();
+ $probe->includePersonalCircles()
+ ->includeSystemCircles();
+
+ $circles = array_map(
+ function (Circle $circle) {
+ return $circle->getSingleId();
+ }, $this->circleRequest->getCircles(null, $probe)
+ );
+
+ $shares = array_unique(
+ array_map(
+ function (ShareWrapper $share) {
+ return $share->getSharedWith();
+ }, $this->shareWrapperRequest->getShares()
+ )
+ );
+
+ foreach ($shares as $share) {
+ if (!in_array($share, $circles)) {
+ $this->shareWrapperRequest->deleteFromCircle($share);
+ }
+ }
}
@@ -315,10 +333,16 @@ private function removeDeprecatedShares(): void {
* @throws InitiatorNotFoundException
*/
private function refreshDisplayName(): void {
- $params = new SimpleDataStore(['includeSystemCircles' => true]);
$circleFilter = new Circle();
$circleFilter->setConfig(Circle::CFG_SINGLE);
- $circles = $this->circleService->getCircles($circleFilter, null, $params);
+
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles()
+ ->setFilterCircle($circleFilter)
+ ->mustBeMember()
+ ->canBeRequestingMembership();
+
+ $circles = $this->circleService->getCircles($probe);
foreach ($circles as $circle) {
$owner = $circle->getOwner();
diff --git a/lib/Service/MemberService.php b/lib/Service/MemberService.php
index c6bf0996c..38b81e016 100644
--- a/lib/Service/MemberService.php
+++ b/lib/Service/MemberService.php
@@ -63,6 +63,7 @@
use OCA\Circles\Model\Federated\FederatedEvent;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\MemberProbe;
/**
* Class MemberService
@@ -145,7 +146,7 @@ public function __construct(
public function getMemberById(
string $memberId,
string $circleId = '',
- bool $canBeVisitor = false
+ ?MemberProbe $probe = null
): Member {
$this->federatedUserService->mustHaveCurrentUser();
@@ -153,7 +154,7 @@ public function getMemberById(
$this->memberRequest->getMemberById(
$memberId,
$this->federatedUserService->getCurrentUser(),
- $canBeVisitor
+ $probe
);
if ($circleId !== '' && $member->getCircle()->getSingleId() !== $circleId) {
throw new MemberNotFoundException();
@@ -173,10 +174,16 @@ public function getMemberById(
public function getMembers(string $circleId): array {
$this->federatedUserService->mustHaveCurrentUser();
+ $probe = new MemberProbe();
+ if ($this->federatedUserService->hasRemoteInstance()) {
+ $probe->setFilterRemoteInstance($this->federatedUserService->getRemoteInstance());
+ }
+ $probe->mustBeMember();
+
return $this->memberRequest->getMembers(
$circleId,
$this->federatedUserService->getCurrentUser(),
- $this->federatedUserService->getRemoteInstance()
+ $probe
);
}
diff --git a/lib/Service/MembershipService.php b/lib/Service/MembershipService.php
index dbb07e1aa..55e4c975d 100644
--- a/lib/Service/MembershipService.php
+++ b/lib/Service/MembershipService.php
@@ -32,7 +32,6 @@
namespace OCA\Circles\Service;
use ArtificialOwl\MySmallPhpTools\Exceptions\ItemNotFoundException;
-use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Logger;
use OCA\Circles\Db\CircleRequest;
use OCA\Circles\Db\MemberRequest;
@@ -44,6 +43,7 @@
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
use OCA\Circles\Model\Membership;
+use OCA\Circles\Model\Probes\CircleProbe;
/**
* Class MembershipService
@@ -128,14 +128,9 @@ public function onUpdate(string $singleId): void {
*
*/
public function manageAll(): void {
- $params = new SimpleDataStore(['includeSystemCircles' => true]);
- $circles = $this->circleRequest->getCircles(
- null,
- null,
- null,
- null,
- $params
- );
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles();
+ $circles = $this->circleRequest->getCircles(null, $probe);
$this->outputService->startMigrationProgress(sizeof($circles));
diff --git a/lib/Service/RemoteDownstreamService.php b/lib/Service/RemoteDownstreamService.php
index b4a9cc551..6c40b55dd 100644
--- a/lib/Service/RemoteDownstreamService.php
+++ b/lib/Service/RemoteDownstreamService.php
@@ -53,6 +53,7 @@
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Exceptions\UnknownRemoteException;
use OCA\Circles\Model\Federated\FederatedEvent;
+use OCA\Circles\Model\Probes\CircleProbe;
/**
* Class RemoteDownstreamService
@@ -244,7 +245,10 @@ private function verifyCircle(FederatedEvent $event): bool {
$circle = $event->getCircle();
try {
- $localCircle = $this->circleRequest->getCircle($circle->getSingleId(), null, null, 0);
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles()
+ ->includePersonalCircles();
+ $localCircle = $this->circleRequest->getCircle($circle->getSingleId(), null, $probe);
} catch (CircleNotFoundException $e) {
try {
$this->remoteService->syncRemoteCircle(
diff --git a/lib/Service/ShareWrapperService.php b/lib/Service/ShareWrapperService.php
index b52df30f5..81bd5ece8 100644
--- a/lib/Service/ShareWrapperService.php
+++ b/lib/Service/ShareWrapperService.php
@@ -36,6 +36,7 @@
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Exceptions\ShareWrapperNotFoundException;
use OCA\Circles\Model\FederatedUser;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\ShareWrapper;
use OCP\Files\NotFoundException;
use OCP\Share\IShare;
@@ -166,9 +167,7 @@ public function getShareByToken(string $token, ?FederatedUser $federatedUser = n
/**
* @param FederatedUser $federatedUser
* @param int $nodeId
- * @param int $offset
- * @param int $limit
- * @param bool $getData
+ * @param CircleProbe|null $probe
*
* @return ShareWrapper[]
* @throws RequestBuilderException
@@ -176,11 +175,9 @@ public function getShareByToken(string $token, ?FederatedUser $federatedUser = n
public function getSharedWith(
FederatedUser $federatedUser,
int $nodeId,
- int $offset,
- int $limit,
- bool $getData = false
+ ?CircleProbe $probe
): array {
- return $this->shareWrapperRequest->getSharedWith($federatedUser, $nodeId, $offset, $limit, $getData);
+ return $this->shareWrapperRequest->getSharedWith($federatedUser, $nodeId, $probe);
}
diff --git a/lib/ShareByCircleProvider.php b/lib/ShareByCircleProvider.php
index 11216f976..0a993a4e8 100644
--- a/lib/ShareByCircleProvider.php
+++ b/lib/ShareByCircleProvider.php
@@ -61,6 +61,7 @@
use OCA\Circles\FederatedItems\Files\FileUnshare;
use OCA\Circles\Model\Federated\FederatedEvent;
use OCA\Circles\Model\Helpers\MemberHelper;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\ShareWrapper;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\EventService;
@@ -545,12 +546,16 @@ public function getSharedWith($userId, $shareType, $node, $limit, $offset): arra
}
$federatedUser = $this->federatedUserService->getLocalFederatedUser($userId);
+ $probe = new CircleProbe();
+ $probe->includePersonalCircles()
+ ->mustBeMember()
+ ->setItemsLimit((int)$limit)
+ ->setItemsOffset((int)$offset);
+
$wrappedShares = $this->shareWrapperService->getSharedWith(
$federatedUser,
(!is_null($node)) ? $node->getId() : 0,
- $limit,
- $offset,
- true
+ $probe
);
return array_filter(