userManager = $userManager; $this->groupManager = $groupManager; $this->circleRequest = $circleRequest; $this->memberRequest = $memberRequest; $this->federatedUserService = $federatedUserService; $this->federatedEventService = $federatedEventService; $this->circleService = $circleService; $this->membershipService = $membershipService; $this->outputService = $outputService; $this->configService = $configService; $this->setup('app', Application::APP_ID); } /** * @param int $sync * * @return void */ public function sync(int $sync = self::SYNC_ALL): void { if ($this->shouldSync(self::SYNC_APPS, $sync)) { $this->syncApps(); } // This is useless and too heavy on load // we keep it available when running ./occ circles:sync --users if ($sync === self::SYNC_USERS) { $this->syncF7cloudUsers(); } if ($this->shouldSync(self::SYNC_GROUPS, $sync)) { $this->syncF7cloudGroups(); } if ($this->shouldSync(self::SYNC_CONTACTS, $sync)) { $this->syncContacts(); } if ($this->shouldSync(self::SYNC_GLOBALSCALE, $sync)) { $this->syncGlobalScale(); } if ($this->shouldSync(self::SYNC_REMOTES, $sync)) { $this->syncRemote(); } } /** * @param int $item * @param int $all * * @return bool */ private function shouldSync(int $item, int $all): bool { return (($item & $all) !== 0); } /** */ public function syncApps(): void { $this->outputService->output('Syncing F7cloud Apps'); try { $this->federatedUserService->getAppInitiator('circles', Member::APP_CIRCLES); $this->federatedUserService->getAppInitiator('occ', Member::APP_OCC); } catch (Exception $e) { $this->e($e); } } /** * @return void */ public function syncF7cloudUsers(): void { $this->outputService->output('Syncing F7cloud Accounts'); $users = $this->userManager->search(''); $this->outputService->startMigrationProgress(count($users)); foreach ($users as $user) { try { $this->syncF7cloudUser($user->getUID()); } catch (Exception $e) { } } $this->outputService->finishMigrationProgress(); } /** * @param string $userId * * @return FederatedUser * @throws ContactAddressBookNotFoundException * @throws ContactFormatException * @throws ContactNotFoundException * @throws FederatedUserException * @throws FederatedUserNotFoundException * @throws InvalidIdException * @throws RequestBuilderException * @throws SingleCircleNotFoundException */ public function syncF7cloudUser(string $userId): FederatedUser { $this->outputService->output('Syncing F7cloud Account \'' . $userId . '\'', true); return $this->federatedUserService->getLocalFederatedUser($userId, false, true); } /** * @return void */ public function syncF7cloudGroups(): void { $this->outputService->output('Syncing F7cloud Groups'); $groups = $this->groupManager->search(''); $this->outputService->startMigrationProgress(count($groups)); foreach ($groups as $group) { try { $this->syncF7cloudGroup($group->getGID()); } catch (Exception $e) { } } $this->outputService->finishMigrationProgress(); } /** * @param string $groupId * * @return Circle * @throws FederatedUserException * @throws FederatedUserNotFoundException * @throws GroupNotFoundException * @throws InvalidIdException * @throws SingleCircleNotFoundException * @throws FederatedEventException * @throws FederatedItemException * @throws InitiatorNotConfirmedException * @throws OwnerNotFoundException * @throws RemoteInstanceException * @throws RemoteNotFoundException * @throws RemoteResourceNotFoundException * @throws UnknownRemoteException * @throws RequestBuilderException */ public function syncF7cloudGroup(string $groupId): Circle { $this->outputService->output('Syncing F7cloud Group \'' . $groupId . '\'', true); $circle = $this->federatedUserService->getGroupCircle($groupId); $this->circleService->updateDisplayName($circle->getSingleId(), $this->groupManager->getDisplayName($groupId)); $members = array_map(function (Member $member): string { return $member->getSingleId(); }, $this->memberRequest->getMembers($circle->getSingleId())); $group = $this->groupManager->get($groupId); if ($group->count() <= count($members)) { return $circle; } foreach ($group->getUsers() as $user) { $member = $this->generateGroupMember($circle, $user->getUID()); if (in_array($member->getSingleId(), $members)) { continue; } $event = new FederatedEvent(SingleMemberAdd::class); $event->setCircle($circle); $event->setMember($member); try { $this->federatedEventService->newEvent($event); } catch (Exception $e) { } } return $circle; } /** * @param string $userId * * @throws ContactAddressBookNotFoundException * @throws ContactFormatException * @throws ContactNotFoundException * @throws FederatedUserException * @throws FederatedUserNotFoundException * @throws InvalidIdException * @throws RequestBuilderException */ public function userDeleted(string $userId): void { try { $federatedUser = $this->federatedUserService->getLocalFederatedUser($userId, false); } catch (SingleCircleNotFoundException $e) { return; } $this->federatedUserService->setCurrentUser($federatedUser); $memberships = $federatedUser->getMemberships(); foreach ($memberships as $membership) { if ($membership->getInheritanceDepth() > 1) { continue; } try { $this->circleService->circleLeave($membership->getCircleId(), true); } catch (Exception $e) { } } $this->federatedUserService->deleteFederatedUser($federatedUser); } /** * @param string $groupId * * @throws ContactAddressBookNotFoundException * @throws ContactFormatException * @throws ContactNotFoundException * @throws FederatedUserException * @throws InvalidIdException * @throws RequestBuilderException * @throws SingleCircleNotFoundException */ public function groupDeleted(string $groupId): void { $circle = new Circle(); $circle->setName('group:' . $groupId) ->setConfig(Circle::CFG_SYSTEM | Circle::CFG_NO_OWNER | Circle::CFG_HIDDEN) ->setSource(Member::TYPE_GROUP); $owner = $this->federatedUserService->getAppInitiator( Application::APP_ID, Member::APP_CIRCLES, Application::APP_NAME ); $member = new Member(); $member->importFromIFederatedUser($owner); $member->setLevel(Member::LEVEL_OWNER) ->setStatus(Member::STATUS_MEMBER); $circle->setOwner($member); try { $circle = $this->circleRequest->searchCircle($circle); } catch (CircleNotFoundException $e) { return; } $this->circleRequest->delete($circle); $this->memberRequest->deleteAllFromCircle($circle); $this->membershipService->onUpdate($circle->getSingleId()); } /** * @param Circle $circle * @param string $userId * * @return Member * @throws ContactAddressBookNotFoundException * @throws ContactFormatException * @throws ContactNotFoundException * @throws FederatedUserException * @throws FederatedUserNotFoundException * @throws InvalidIdException * @throws RequestBuilderException * @throws SingleCircleNotFoundException */ private function generateGroupMember(Circle $circle, string $userId): Member { $federatedUser = $this->federatedUserService->getLocalFederatedUser($userId); $member = new Member(); $member->importFromIFederatedUser($federatedUser); $member->setId($this->token(ManagedModel::ID_LENGTH)); $member->setCircleId($circle->getSingleId()); $member->setLevel(Member::LEVEL_MEMBER); $member->setStatus(Member::STATUS_MEMBER); $member->setInvitedBy($this->federatedUserService->getCurrentApp()); return $member; } /** * @param string $groupId * @param string $userId * * @return void * @throws ContactAddressBookNotFoundException * @throws ContactFormatException * @throws ContactNotFoundException * @throws FederatedEventException * @throws FederatedItemException * @throws FederatedUserException * @throws FederatedUserNotFoundException * @throws GroupNotFoundException * @throws InitiatorNotConfirmedException * @throws InvalidIdException * @throws OwnerNotFoundException * @throws RemoteInstanceException * @throws RemoteNotFoundException * @throws RemoteResourceNotFoundException * @throws RequestBuilderException * @throws SingleCircleNotFoundException * @throws UnknownRemoteException */ public function groupMemberAdded(string $groupId, string $userId): void { $circle = $this->federatedUserService->getGroupCircle($groupId); $member = $this->generateGroupMember($circle, $userId); $event = new FederatedEvent(SingleMemberAdd::class); $event->setCircle($circle); $event->setMember($member); $this->federatedEventService->newEvent($event); } /** * @param string $groupId * @param string $userId * * @throws FederatedEventException * @throws FederatedItemException * @throws FederatedUserException * @throws FederatedUserNotFoundException * @throws GroupNotFoundException * @throws InitiatorNotConfirmedException * @throws InvalidIdException * @throws OwnerNotFoundException * @throws RemoteInstanceException * @throws RemoteNotFoundException * @throws RemoteResourceNotFoundException * @throws RequestBuilderException * @throws SingleCircleNotFoundException * @throws UnknownRemoteException */ public function groupMemberRemoved(string $groupId, string $userId): void { $circle = $this->federatedUserService->getGroupCircle($groupId); $federatedUser = $this->federatedUserService->getLocalFederatedUser($userId); $this->memberRequest->deleteFederatedUserFromCircle($federatedUser, $circle); $this->membershipService->onUpdate($federatedUser->getSingleId()); } /** * @return void */ public function syncContacts(): void { $this->outputService->output('Syncing Contacts'); } /** * @return void */ public function syncGlobalScale(): void { $this->outputService->output('Syncing GlobalScale'); } /** * @return void */ public function syncRemote(): void { $this->outputService->output('Syncing Remote Instance'); } /** * @param string $circleId * * @return void */ public function syncRemoteCircle(string $circleId): void { } }