Skip to content
Draft

API v2 #1890

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Those groups of people can then be used by any other app for sharing purpose.
]]>
</description>
<version>32.0.0-dev.0</version>
<version>31.0.0-dev.1</version>
<licence>agpl</licence>
<author>Maxence Lange</author>
<types>
Expand All @@ -31,7 +31,7 @@ Those groups of people can then be used by any other app for sharing purpose.
<repository>https://github.com/nextcloud/circles.git</repository>
<screenshot>https://raw.githubusercontent.com/nextcloud/circles/master/screenshots/0.12.0.png</screenshot>
<dependencies>
<nextcloud min-version="32" max-version="32"/>
<nextcloud min-version="31" max-version="32"/>
</dependencies>
<default_enable/>
<background-jobs>
Expand All @@ -45,6 +45,7 @@ Those groups of people can then be used by any other app for sharing purpose.
</repair-steps>

<commands>
<command>OCA\Circles\Command\Test</command>
<command>OCA\Circles\Command\CirclesCreate</command>
<command>OCA\Circles\Command\MembersAdd</command>
<command>OCA\Circles\Command\CirclesJoin</command>
Expand Down
21 changes: 21 additions & 0 deletions lib/Api/v2/ITeamEntityOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2;

use OCA\Circles\Model\TeamEntity;
use OCP\IUser;

interface ITeamEntityOperation {
public function getFromLocalUser(string $userId): TeamEntity;
public function getFromTeam(string $singleId): TeamEntity;
public function getFromApp(string $appId): TeamEntity;
public function getFromOcc(): TeamEntity;
public function getFromSuperAdmin(): TeamEntity;
public function getFromUser(IUser $user): TeamEntity;
}
13 changes: 13 additions & 0 deletions lib/Api/v2/ITeamMemberOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2;

interface ITeamMemberOperation {
public function getTeamMembers(string $singleId): array;
}
22 changes: 22 additions & 0 deletions lib/Api/v2/ITeamMembershipOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2;

/**
* TeamMemberships is a caching system to help managing direct and inherited memberships
* to lighten database request.
*/
interface ITeamMembershipOperation {
/**
* create/remove entries in database using Teams and Teams' Members to keep Memberships up-to-date
*
* @param string $singleId
*/
public function syncTeamMemberships(string $singleId): void;
}
31 changes: 31 additions & 0 deletions lib/Api/v2/ITeamOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2;

use OCA\Circles\Exceptions\TeamEntityNotFoundException;
use OCA\Circles\Model\Team;
use OCA\Circles\Model\TeamEntity;
use OCA\Circles\Model\TeamMember;

interface ITeamOperation {

/**
* @throws TeamEntityNotFoundException
*/
public function createTeam(string $teamName, ?TeamEntity $realOwner = null): Team;

/**
* get list of teams current entity is member of
*
* @return TeamMember[]
*/
public function getTeams(): array;
public function getAvailableTeams(): array;
public function getTeam(string $singleId): Team;
}
49 changes: 49 additions & 0 deletions lib/Api/v2/ITeamSession.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
/*
* 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 2017
* @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/>.
*
*/

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2;

use OCA\Circles\Model\TeamEntity;
use OCP\IUser;

interface ITeamSession {
public function sessionAsCurrentUser(): self;
public function sessionAsUser(IUser $user): self;
public function sessionAsLocalUser(string $userId): self;
public function sessionAsApp(string $appId): self;
public function sessionAsSuperAdmin(): self;
public function sessionAsEntity(TeamEntity $entity): self;
public function hasEntity(): bool;
public function getEntity(): TeamEntity;
public function performTeamOperation(): ITeamOperation;
public function performTeamMemberOperation(): ITeamMemberOperation;
}
13 changes: 13 additions & 0 deletions lib/Api/v2/ITeamSuperOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2;

interface ITeamSuperOperation {
public function dropAllData(): void;
}
80 changes: 80 additions & 0 deletions lib/Api/v2/Operation/CoreOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2\Operation;

use OCA\Circles\Api\v2\TeamSession;
use OCA\Circles\Enum\TeamEntityType;
use OCA\Circles\Model\TeamEntity;

class CoreOperation {
// private ?TeamEntity $entity = null;
private ?TeamSession $session = null;

final public function fromSession(TeamSession $session): void {
if ($this->session !== null) {
throw new \Exception('cannot overwrite session'); // TODO specific Exception
}
if (!$session->hasEntity()) {
throw new \Exception('entity must be set'); // TODO: specific exception
}
$this->session = $session;
}

final public function getSession(): TeamSession {
return $this->session;
}

final public function hasEntity(): bool {
return $this->session->hasEntity();
}

final public function getEntity(): TeamEntity {
return $this->session->getEntity();
}
//
//
// final public function asEntity(TeamEntity $entity): void {
// if ($this->entity !== null) {
// throw new \Exception('cannot overwrite initiator'); // TODO specific Exception
// }
// $this->entity = $entity;
// }

/**
* @param TeamEntityType|TeamEntityType[] $limitToEntities
*/
final public function confirmSessionInitialized(TeamEntityType|array $limitToEntities = []): void {
if ($this->session === null) {
throw new \Exception('session/entity not initialized'); // TODO specific Exception
}

if (!empty($limitToEntities)
&& !in_array($this->getEntity()->getTeamEntityType(), $limitToEntities)) {
throw new \Exception('entity cannot execute this operation'); // TODO specific Exception
}

}

/**
* @param TeamEntityType|TeamEntityType[] $limitToEntities
*/
final protected function lowPriorityProcess(TeamEntityType|array $limitToEntities = []): void {
$this->confirmSessionInitialized($limitToEntities);
// TODO: detect type of process and filters it
// if (!in_array(
// $this->entity->getTeamEntityType(),
// TeamEntityType::OCC,
// TeamEntityType::CRON,
// TeamEntityType::ASYNC,
// )) {
// throw new \Exception('cannot be executed on main process');
// }
}

}
45 changes: 45 additions & 0 deletions lib/Api/v2/Operation/TeamEntityOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2\Operation;

use OCA\Circles\Api\v2\ITeamEntityOperation;
use OCA\Circles\Model\TeamEntity;
use OCA\Circles\Service\TeamEntityService;
use OCP\IUser;

class TeamEntityOperation extends CoreOperation implements ITeamEntityOperation {
public function __construct(
private readonly TeamEntityService $teamEntityService,
) {
}

public function getFromLocalUser(string $userId): TeamEntity {
return $this->teamEntityService->generateTeamEntityFromLocalUser($userId);
}

public function getFromTeam(string $singleId): TeamEntity {
return $this->teamEntityService->generateTeamEntityFromTeam($singleId);
}

public function getFromApp(string $appId): TeamEntity {
return $this->teamEntityService->generateTeamEntityFromApp($appId);
}

public function getFromOcc(): TeamEntity {
return $this->teamEntityService->generateTeamEntityFromOcc();
}

public function getFromSuperAdmin(): TeamEntity {
return $this->teamEntityService->generateTeamEntityFromSuperAdmin();
}

public function getFromUser(IUser $user): TeamEntity {
return $this->teamEntityService->generateTeamEntityFromUser($user);
}
}
53 changes: 53 additions & 0 deletions lib/Api/v2/Operation/TeamMemberOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2\Operation;

use OCA\Circles\Api\v2\ITeamMemberOperation;
use OCA\Circles\Managers\TeamMemberManager;
use OCA\Circles\Model\Team;
use OCA\Circles\Model\TeamEntity;
use OCA\Circles\Model\TeamMember;
use OCA\Circles\Service\TeamEntityService;
use OCA\Circles\Service\TeamMemberService;
use OCA\Circles\Service\TeamService;

/**
* TeamMemberOperation uses heavier process to verify permissions when accessing data.
*
* It is strongly advised to use TeamMembershipOperation for most of your actions
* as it manage direct and inherited memberships only.
*
*/
class TeamMemberOperation extends CoreOperation implements ITeamMemberOperation {
public function __construct(
private readonly TeamService $teamService,
private readonly TeamEntityService $teamEntityService,
private readonly TeamMemberService $teamMemberService,
private readonly TeamMemberManager $teamMemberManager,
) {
}

public function getTeamMembers(string $singleId): array {
$this->confirmSessionInitialized();
return $this->teamMemberManager->getMembersFromTeam($this->getEntity(), $singleId);
}

public function addMember(Team|string $team, TeamEntity|string $entity): TeamMember {
$this->confirmSessionInitialized();

if (!($team instanceof Team)) {
$team = $this->teamService->getTeam($this->getEntity(), $team);
}
if (!($entity instanceof TeamEntity)) {
$entity = $this->teamEntityService->getTeamEntity($entity);
}

return $this->teamMemberService->addMember($this->getEntity(), $team, $entity);
}
}
28 changes: 28 additions & 0 deletions lib/Api/v2/Operation/TeamMembershipOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Api\v2\Operation;

use OCA\Circles\Api\v2\ITeamMembershipOperation;
use OCA\Circles\Managers\TeamMembershipManager;
use OCA\Circles\Service\TeamMembershipService;

class TeamMembershipOperation extends CoreOperation implements ITeamMembershipOperation {
public function __construct(
private readonly TeamMembershipService $teamMembershipService,
private readonly TeamMembershipManager $teamMembershipManager,
) {
}

public function syncTeamMemberships(string $singleId): void {
$this->lowPriorityProcess();
$this->teamMembershipService->syncTeamMemberships($this->getSession(), $singleId);
}


}
Loading