using probes

Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
This commit is contained in:
Maxence Lange 2021-07-17 00:31:51 -01:00
parent 7c1a51fca8
commit 1aa24e3bae
29 changed files with 1126 additions and 237 deletions

View file

@ -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\RequestBuilderException;
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 @@ class Circles {
/** @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 @@ class Circles {
/** @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);
}

View file

@ -33,6 +33,9 @@ namespace OCA\Circles;
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\InitiatorNotConfirmedException;
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\Exceptions\UserTypeNotFoundException;
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 @@ class CirclesManager {
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 @@ class CirclesManager {
* @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 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 getAllCircles(): array {
// $this->federatedUserService->bypassCurrentUserCondition(true);
// $this->circleService->getCircles();
// }
public function getLink(string $circleId, string $singleId): Membership {
return $this->membershipService->getMembership($circleId, $singleId);
}
/**

View file

@ -37,6 +37,7 @@ use OCA\Circles\Exceptions\CircleNotFoundException;
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 @@ class CirclesQueryHelper {
[CoreQueryBuilder::HELPER],
[
'getData' => $fullDetails,
'mustBeMember' => true
'minimumLevel' => Member::LEVEL_MEMBER
]
);
@ -141,7 +142,7 @@ class CirclesQueryHelper {
[CoreQueryBuilder::HELPER],
[
'getData' => $fullDetails,
'mustBeMember' => true
'minimumLevel' => Member::LEVEL_MEMBER
]
);

View file

@ -31,10 +31,10 @@ declare(strict_types=1);
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 @@ class CollaboratorSearchPlugin implements ISearchPlugin {
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;
}

View file

@ -33,7 +33,6 @@ namespace OCA\Circles\Command;
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\Exceptions\UserTypeNotFoundException;
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 @@ class CirclesList extends Base {
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') {

View file

@ -61,6 +61,7 @@ use OCA\Circles\Exceptions\UserTypeNotFoundException;
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;
@ -273,8 +274,8 @@ class CirclesMemberships extends Base {
$item = new NC22TreeNode(
$tree, new SimpleDataStore(
[
'member' => $member,
'cycling' => in_array($member->getCircleId(), $knownIds)
'member' => $member,
'cycling' => in_array($member->getCircleId(), $knownIds)
]
)
);
@ -366,8 +367,10 @@ class CirclesMemberships extends Base {
$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();

View file

@ -46,6 +46,7 @@ use OCA\Circles\Model\Federated\RemoteInstance;
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 +174,9 @@ class CirclesReport extends Base implements IInteractiveShellClient {
$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) {

View file

@ -39,6 +39,7 @@ use OCA\Circles\Exceptions\InvalidIdException;
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;
@ -236,11 +237,11 @@ class SharesFiles extends Base {
if (!$filterRecipient) {
$row = array_merge(
$row, [
$sharedTo . ' (' . $recipient->getSingleId() . ', '
. Circle::$DEF_SOURCE[$recipient->getBasedOn()->getSource()] . ')',
(($share->getChildId() > 0) ? $share->getChildFileTarget(
) : $share->getFileTarget()),
]
$sharedTo . ' (' . $recipient->getSingleId() . ', '
. Circle::$DEF_SOURCE[$recipient->getBasedOn()->getSource()] . ')',
(($share->getChildId() > 0) ? $share->getChildFileTarget(
) : $share->getFileTarget()),
]
);
}
@ -302,12 +303,13 @@ class SharesFiles extends Base {
}
if ($with !== '') {
$probe = new CircleProbe();
$probe->includePersonalCircles();
return $this->shareWrapperService->getSharedWith(
$this->federatedUserService->getLocalFederatedUser($with),
$fileId,
-1,
0,
true
$probe
);
}

View file

@ -148,11 +148,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());
}
@ -209,11 +209,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());
}

View file

@ -55,6 +55,7 @@ use OCA\Circles\Model\Federated\FederatedEvent;
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 @@ class RemoteController extends Controller {
$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) {

View file

@ -31,7 +31,6 @@ declare(strict_types=1);
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\RequestBuilderException;
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 @@ class CircleRequest extends CircleRequestBuilder {
/**
* @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 @@ class CircleRequest extends CircleRequestBuilder {
*/
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 @@ class CircleRequest extends CircleRequestBuilder {
/**
* @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 @@ class CircleRequest extends CircleRequestBuilder {
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);

View file

@ -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 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
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 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
);
$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 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
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 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
// - 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 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
);
}
$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 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
/**
* 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;
}

View file

@ -36,9 +36,9 @@ use OCA\Circles\Exceptions\MemberNotFoundException;
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 @@ class MemberRequest extends MemberRequestBuilder {
/**
* @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 @@ class MemberRequest extends MemberRequestBuilder {
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 @@ class MemberRequest extends MemberRequestBuilder {
/**
* @param string $memberId
* @param FederatedUser|null $initiator
* @param bool $canBeVisitor
* @param MemberProbe|null $probe
*
* @return Member
* @throws MemberNotFoundException
@ -299,13 +314,17 @@ class MemberRequest extends MemberRequestBuilder {
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);
}

View file

@ -35,6 +35,7 @@ use OCA\Circles\Exceptions\RequestBuilderException;
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 @@ class ShareWrapperRequest extends ShareWrapperRequestBuilder {
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 @@ class ShareWrapperRequest extends ShareWrapperRequestBuilder {
$qb->limitToFileSource($nodeId);
}
$qb->chunk($offset, $limit);
$qb->chunk($probe->getItemsOffset(), $probe->getItemsLimit());
return $this->getItemsFromRequest($qb);
}
@ -450,4 +457,15 @@ class ShareWrapperRequest extends ShareWrapperRequestBuilder {
$qb->execute();
}
/**
* @param string $circleId
*/
public function deleteFromCircle(string $circleId): void {
$qb = $this->getShareDeleteSql();
$qb->andWhere($qb->exprLimit('share_with', $circleId));
$qb->execute();
}
}

103
lib/IQueryProbe.php Normal file
View file

@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @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 <http://www.gnu.org/licenses/>.
*
*/
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;
}

View file

@ -31,7 +31,6 @@ declare(strict_types=1);
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\RequestBuilderException;
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 @@ class DeprecatedListener {
$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);

View file

@ -0,0 +1,277 @@
<?php
declare(strict_types=1);
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @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 <http://www.gnu.org/licenses/>.
*
*/
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 {
const DETAILS_NONE = 0;
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();
}
}

View file

@ -0,0 +1,182 @@
<?php
declare(strict_types=1);
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @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 <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Circles\Model\Probes;
use OCA\Circles\Model\Circle;
/**
* Class CircleProbe
*
* @package OCA\Circles\Model\Probes
*/
class CircleProbe extends MemberProbe {
/** @var array */
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();
}
}

View file

@ -0,0 +1,162 @@
<?php
declare(strict_types=1);
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @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 <http://www.gnu.org/licenses/>.
*
*/
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();
}
}

View file

@ -42,6 +42,7 @@ use OCA\Circles\Exceptions\InvalidIdException;
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 @@ class Notifier implements INotifier {
*/
private function prepareMemberNotification(INotification $notification) {
$this->federatedUserService->initCurrentUser();
$probe = new MemberProbe();
$member = $this->memberService->getMemberById(
$notification->getObjectId(),
'',
true
$probe
);
switch ($notification->getSubject()) {

View file

@ -63,6 +63,8 @@ use OCA\Circles\Model\Federated\FederatedEvent;
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 @@ class CircleService {
*/
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 @@ class CircleService {
* @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) {

View file

@ -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',

View file

@ -68,6 +68,7 @@ use OCA\Circles\Model\Federated\RemoteInstance;
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 @@ class FederatedUserService {
}
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());

View file

@ -31,16 +31,18 @@ declare(strict_types=1);
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 @@ class MaintenanceService {
IUserManager $userManager,
CircleRequest $circleRequest,
MemberRequest $memberRequest,
ShareWrapperRequest $shareWrapperRequest,
SyncService $syncService,
FederatedUserService $federatedUserService,
EventWrapperService $eventWrapperService,
@ -110,6 +117,7 @@ class MaintenanceService {
$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 @@ class MaintenanceService {
}
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 @@ class MaintenanceService {
* @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 @@ class MaintenanceService {
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 @@ class MaintenanceService {
* @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();

View file

@ -63,6 +63,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\Probes\MemberProbe;
/**
* Class MemberService
@ -145,7 +146,7 @@ class MemberService {
public function getMemberById(
string $memberId,
string $circleId = '',
bool $canBeVisitor = false
?MemberProbe $probe = null
): Member {
$this->federatedUserService->mustHaveCurrentUser();
@ -153,7 +154,7 @@ class MemberService {
$this->memberRequest->getMemberById(
$memberId,
$this->federatedUserService->getCurrentUser(),
$canBeVisitor
$probe
);
if ($circleId !== '' && $member->getCircle()->getSingleId() !== $circleId) {
throw new MemberNotFoundException();
@ -173,10 +174,16 @@ class MemberService {
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
);
}

View file

@ -32,7 +32,6 @@ declare(strict_types=1);
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\Exceptions\RequestBuilderException;
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 @@ class MembershipService {
*
*/
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));

View file

@ -53,6 +53,7 @@ use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
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 @@ class RemoteDownstreamService {
$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(

View file

@ -36,6 +36,7 @@ use OCA\Circles\Db\ShareWrapperRequest;
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 @@ class ShareWrapperService {
/**
* @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 @@ class ShareWrapperService {
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);
}

View file

@ -61,6 +61,7 @@ use OCA\Circles\FederatedItems\Files\FileShare;
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 @@ class ShareByCircleProvider implements IShareProvider {
}
$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(