Signed-off-by: Julius Härtl <jus@bitgrid.net>tags/v29.0.0beta1
@@ -0,0 +1,97 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2024 Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @author Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @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 OC\Core\Controller; | |||
use OCA\Core\ResponseDefinitions; | |||
use OCP\AppFramework\Http; | |||
use OCP\AppFramework\Http\Attribute\ApiRoute; | |||
use OCP\AppFramework\Http\Attribute\NoAdminRequired; | |||
use OCP\AppFramework\Http\DataResponse; | |||
use OCP\IRequest; | |||
use OCP\Teams\ITeamManager; | |||
use OCP\Teams\Team; | |||
/** | |||
* @psalm-import-type CoreTeamResource from ResponseDefinitions | |||
* @psalm-import-type CoreTeam from ResponseDefinitions | |||
* @property $userId string | |||
*/ | |||
class TeamsApiController extends \OCP\AppFramework\OCSController { | |||
public function __construct( | |||
string $appName, | |||
IRequest $request, | |||
private ITeamManager $teamManager, | |||
private ?string $userId, | |||
) { | |||
parent::__construct($appName, $request); | |||
} | |||
/** | |||
* Get all resources of a team | |||
* | |||
* @param string $teamId Unique id of the team | |||
* @return DataResponse<Http::STATUS_OK, array{resources: CoreTeamResource[]}, array{}> | |||
* | |||
* 200: Resources returned | |||
*/ | |||
#[NoAdminRequired] | |||
#[ApiRoute(verb: 'GET', url: '/{teamId}/resources', root: '/teams')] | |||
public function resolveOne(string $teamId): DataResponse { | |||
/** | |||
* @var CoreTeamResource[] $resolvedResources | |||
* @psalm-suppress PossiblyNullArgument The route is limited to logged-in users | |||
*/ | |||
$resolvedResources = $this->teamManager->getSharedWith($teamId, $this->userId); | |||
return new DataResponse(['resources' => $resolvedResources]); | |||
} | |||
/** | |||
* Get all teams of a resource | |||
* | |||
* @param string $providerId Identifier of the provider (e.g. deck, talk, collectives) | |||
* @param string $resourceId Unique id of the resource to list teams for (e.g. deck board id) | |||
* @return DataResponse<Http::STATUS_OK, array{teams: CoreTeam[]}, array{}> | |||
* | |||
* 200: Teams returned | |||
*/ | |||
#[NoAdminRequired] | |||
#[ApiRoute(verb: 'GET', url: '/resources/{providerId}/{resourceId}', root: '/teams')] | |||
public function listTeams(string $providerId, string $resourceId): DataResponse { | |||
/** @psalm-suppress PossiblyNullArgument The route is limited to logged-in users */ | |||
$teams = $this->teamManager->getTeamsForResource($providerId, $resourceId, $this->userId); | |||
/** @var CoreTeam[] $teams */ | |||
$teams = array_map(function (Team $team) { | |||
$response = $team->jsonSerialize(); | |||
/** @psalm-suppress PossiblyNullArgument The route is limited to logged in users */ | |||
$response['resources'] = $this->teamManager->getSharedWith($team->getId(), $this->userId); | |||
return $response; | |||
}, $teams); | |||
return new DataResponse([ | |||
'teams' => $teams, | |||
]); | |||
} | |||
} |
@@ -161,6 +161,21 @@ namespace OCA\Core; | |||
* numberOfImages: int, | |||
* completionExpectedAt: ?int, | |||
* } | |||
* | |||
* @psalm-type CoreTeam = array{ | |||
* id: string, | |||
* name: string, | |||
* icon: string, | |||
* } | |||
* | |||
* @psalm-type CoreTeamResource = array{ | |||
* id: int, | |||
* label: string, | |||
* url: string, | |||
* iconSvg: ?string, | |||
* iconURL: ?string, | |||
* iconEmoji: ?string, | |||
* } | |||
*/ | |||
class ResponseDefinitions { | |||
} |
@@ -406,6 +406,60 @@ | |||
} | |||
} | |||
}, | |||
"Team": { | |||
"type": "object", | |||
"required": [ | |||
"id", | |||
"name", | |||
"icon" | |||
], | |||
"properties": { | |||
"id": { | |||
"type": "string" | |||
}, | |||
"name": { | |||
"type": "string" | |||
}, | |||
"icon": { | |||
"type": "string" | |||
} | |||
} | |||
}, | |||
"TeamResource": { | |||
"type": "object", | |||
"required": [ | |||
"id", | |||
"label", | |||
"url", | |||
"iconSvg", | |||
"iconURL", | |||
"iconEmoji" | |||
], | |||
"properties": { | |||
"id": { | |||
"type": "integer", | |||
"format": "int64" | |||
}, | |||
"label": { | |||
"type": "string" | |||
}, | |||
"url": { | |||
"type": "string" | |||
}, | |||
"iconSvg": { | |||
"type": "string", | |||
"nullable": true | |||
}, | |||
"iconURL": { | |||
"type": "string", | |||
"nullable": true | |||
}, | |||
"iconEmoji": { | |||
"type": "string", | |||
"nullable": true | |||
} | |||
} | |||
}, | |||
"TextProcessingTask": { | |||
"type": "object", | |||
"required": [ | |||
@@ -3009,6 +3063,177 @@ | |||
} | |||
} | |||
}, | |||
"/ocs/v2.php/teams/{teamId}/resources": { | |||
"get": { | |||
"operationId": "teams_api-resolve-one", | |||
"summary": "Get all resources of a team", | |||
"tags": [ | |||
"teams_api" | |||
], | |||
"security": [ | |||
{ | |||
"bearer_auth": [] | |||
}, | |||
{ | |||
"basic_auth": [] | |||
} | |||
], | |||
"parameters": [ | |||
{ | |||
"name": "teamId", | |||
"in": "path", | |||
"description": "Unique id of the team", | |||
"required": true, | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
{ | |||
"name": "OCS-APIRequest", | |||
"in": "header", | |||
"description": "Required to be true for the API request to pass", | |||
"required": true, | |||
"schema": { | |||
"type": "boolean", | |||
"default": true | |||
} | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "Resources returned", | |||
"content": { | |||
"application/json": { | |||
"schema": { | |||
"type": "object", | |||
"required": [ | |||
"ocs" | |||
], | |||
"properties": { | |||
"ocs": { | |||
"type": "object", | |||
"required": [ | |||
"meta", | |||
"data" | |||
], | |||
"properties": { | |||
"meta": { | |||
"$ref": "#/components/schemas/OCSMeta" | |||
}, | |||
"data": { | |||
"type": "object", | |||
"required": [ | |||
"resources" | |||
], | |||
"properties": { | |||
"resources": { | |||
"type": "array", | |||
"items": { | |||
"$ref": "#/components/schemas/TeamResource" | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/ocs/v2.php/teams/resources/{providerId}/{resourceId}": { | |||
"get": { | |||
"operationId": "teams_api-list-teams", | |||
"summary": "Get all teams of a resource", | |||
"tags": [ | |||
"teams_api" | |||
], | |||
"security": [ | |||
{ | |||
"bearer_auth": [] | |||
}, | |||
{ | |||
"basic_auth": [] | |||
} | |||
], | |||
"parameters": [ | |||
{ | |||
"name": "providerId", | |||
"in": "path", | |||
"description": "Identifier of the provider (e.g. deck, talk, collectives)", | |||
"required": true, | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
{ | |||
"name": "resourceId", | |||
"in": "path", | |||
"description": "Unique id of the resource to list teams for (e.g. deck board id)", | |||
"required": true, | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
{ | |||
"name": "OCS-APIRequest", | |||
"in": "header", | |||
"description": "Required to be true for the API request to pass", | |||
"required": true, | |||
"schema": { | |||
"type": "boolean", | |||
"default": true | |||
} | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "Teams returned", | |||
"content": { | |||
"application/json": { | |||
"schema": { | |||
"type": "object", | |||
"required": [ | |||
"ocs" | |||
], | |||
"properties": { | |||
"ocs": { | |||
"type": "object", | |||
"required": [ | |||
"meta", | |||
"data" | |||
], | |||
"properties": { | |||
"meta": { | |||
"$ref": "#/components/schemas/OCSMeta" | |||
}, | |||
"data": { | |||
"type": "object", | |||
"required": [ | |||
"teams" | |||
], | |||
"properties": { | |||
"teams": { | |||
"type": "array", | |||
"items": { | |||
"$ref": "#/components/schemas/Team" | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/ocs/v2.php/textprocessing/tasktypes": { | |||
"get": { | |||
"operationId": "text_processing_api-task-types", |
@@ -1,3 +1,4 @@ | |||
Copyright (c) Nils Adermann, Jordi Boggiano | |||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||
@@ -17,3 +18,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
THE SOFTWARE. | |||
@@ -691,6 +691,10 @@ return array( | |||
'OCP\\Talk\\IConversation' => $baseDir . '/lib/public/Talk/IConversation.php', | |||
'OCP\\Talk\\IConversationOptions' => $baseDir . '/lib/public/Talk/IConversationOptions.php', | |||
'OCP\\Talk\\ITalkBackend' => $baseDir . '/lib/public/Talk/ITalkBackend.php', | |||
'OCP\\Teams\\ITeamManager' => $baseDir . '/lib/public/Teams/ITeamManager.php', | |||
'OCP\\Teams\\ITeamResourceProvider' => $baseDir . '/lib/public/Teams/ITeamResourceProvider.php', | |||
'OCP\\Teams\\Team' => $baseDir . '/lib/public/Teams/Team.php', | |||
'OCP\\Teams\\TeamResource' => $baseDir . '/lib/public/Teams/TeamResource.php', | |||
'OCP\\Template' => $baseDir . '/lib/public/Template.php', | |||
'OCP\\TextProcessing\\Events\\AbstractTextProcessingEvent' => $baseDir . '/lib/public/TextProcessing/Events/AbstractTextProcessingEvent.php', | |||
'OCP\\TextProcessing\\Events\\TaskFailedEvent' => $baseDir . '/lib/public/TextProcessing/Events/TaskFailedEvent.php', | |||
@@ -1158,6 +1162,7 @@ return array( | |||
'OC\\Core\\Controller\\ReferenceController' => $baseDir . '/core/Controller/ReferenceController.php', | |||
'OC\\Core\\Controller\\SearchController' => $baseDir . '/core/Controller/SearchController.php', | |||
'OC\\Core\\Controller\\SetupController' => $baseDir . '/core/Controller/SetupController.php', | |||
'OC\\Core\\Controller\\TeamsApiController' => $baseDir . '/core/Controller/TeamsApiController.php', | |||
'OC\\Core\\Controller\\TextProcessingApiController' => $baseDir . '/core/Controller/TextProcessingApiController.php', | |||
'OC\\Core\\Controller\\TextToImageApiController' => $baseDir . '/core/Controller/TextToImageApiController.php', | |||
'OC\\Core\\Controller\\TranslationApiController' => $baseDir . '/core/Controller/TranslationApiController.php', | |||
@@ -1794,6 +1799,7 @@ return array( | |||
'OC\\Tags' => $baseDir . '/lib/private/Tags.php', | |||
'OC\\Talk\\Broker' => $baseDir . '/lib/private/Talk/Broker.php', | |||
'OC\\Talk\\ConversationOptions' => $baseDir . '/lib/private/Talk/ConversationOptions.php', | |||
'OC\\Teams\\TeamManager' => $baseDir . '/lib/private/Teams/TeamManager.php', | |||
'OC\\TempManager' => $baseDir . '/lib/private/TempManager.php', | |||
'OC\\TemplateLayout' => $baseDir . '/lib/private/TemplateLayout.php', | |||
'OC\\Template\\Base' => $baseDir . '/lib/private/Template/Base.php', |
@@ -724,6 +724,10 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 | |||
'OCP\\Talk\\IConversation' => __DIR__ . '/../../..' . '/lib/public/Talk/IConversation.php', | |||
'OCP\\Talk\\IConversationOptions' => __DIR__ . '/../../..' . '/lib/public/Talk/IConversationOptions.php', | |||
'OCP\\Talk\\ITalkBackend' => __DIR__ . '/../../..' . '/lib/public/Talk/ITalkBackend.php', | |||
'OCP\\Teams\\ITeamManager' => __DIR__ . '/../../..' . '/lib/public/Teams/ITeamManager.php', | |||
'OCP\\Teams\\ITeamResourceProvider' => __DIR__ . '/../../..' . '/lib/public/Teams/ITeamResourceProvider.php', | |||
'OCP\\Teams\\Team' => __DIR__ . '/../../..' . '/lib/public/Teams/Team.php', | |||
'OCP\\Teams\\TeamResource' => __DIR__ . '/../../..' . '/lib/public/Teams/TeamResource.php', | |||
'OCP\\Template' => __DIR__ . '/../../..' . '/lib/public/Template.php', | |||
'OCP\\TextProcessing\\Events\\AbstractTextProcessingEvent' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Events/AbstractTextProcessingEvent.php', | |||
'OCP\\TextProcessing\\Events\\TaskFailedEvent' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Events/TaskFailedEvent.php', | |||
@@ -1191,6 +1195,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 | |||
'OC\\Core\\Controller\\ReferenceController' => __DIR__ . '/../../..' . '/core/Controller/ReferenceController.php', | |||
'OC\\Core\\Controller\\SearchController' => __DIR__ . '/../../..' . '/core/Controller/SearchController.php', | |||
'OC\\Core\\Controller\\SetupController' => __DIR__ . '/../../..' . '/core/Controller/SetupController.php', | |||
'OC\\Core\\Controller\\TeamsApiController' => __DIR__ . '/../../..' . '/core/Controller/TeamsApiController.php', | |||
'OC\\Core\\Controller\\TextProcessingApiController' => __DIR__ . '/../../..' . '/core/Controller/TextProcessingApiController.php', | |||
'OC\\Core\\Controller\\TextToImageApiController' => __DIR__ . '/../../..' . '/core/Controller/TextToImageApiController.php', | |||
'OC\\Core\\Controller\\TranslationApiController' => __DIR__ . '/../../..' . '/core/Controller/TranslationApiController.php', | |||
@@ -1827,6 +1832,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 | |||
'OC\\Tags' => __DIR__ . '/../../..' . '/lib/private/Tags.php', | |||
'OC\\Talk\\Broker' => __DIR__ . '/../../..' . '/lib/private/Talk/Broker.php', | |||
'OC\\Talk\\ConversationOptions' => __DIR__ . '/../../..' . '/lib/private/Talk/ConversationOptions.php', | |||
'OC\\Teams\\TeamManager' => __DIR__ . '/../../..' . '/lib/private/Teams/TeamManager.php', | |||
'OC\\TempManager' => __DIR__ . '/../../..' . '/lib/private/TempManager.php', | |||
'OC\\TemplateLayout' => __DIR__ . '/../../..' . '/lib/private/TemplateLayout.php', | |||
'OC\\Template\\Base' => __DIR__ . '/../../..' . '/lib/private/Template/Base.php', |
@@ -1,5 +1,68 @@ | |||
{ | |||
"packages": [], | |||
"dev": false, | |||
"dev-package-names": [] | |||
"packages": [ | |||
{ | |||
"name": "bamarni/composer-bin-plugin", | |||
"version": "1.8.2", | |||
"version_normalized": "1.8.2.0", | |||
"source": { | |||
"type": "git", | |||
"url": "https://github.com/bamarni/composer-bin-plugin.git", | |||
"reference": "92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880" | |||
}, | |||
"dist": { | |||
"type": "zip", | |||
"url": "https://api.github.com/repos/bamarni/composer-bin-plugin/zipball/92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880", | |||
"reference": "92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880", | |||
"shasum": "" | |||
}, | |||
"require": { | |||
"composer-plugin-api": "^2.0", | |||
"php": "^7.2.5 || ^8.0" | |||
}, | |||
"require-dev": { | |||
"composer/composer": "^2.0", | |||
"ext-json": "*", | |||
"phpstan/extension-installer": "^1.1", | |||
"phpstan/phpstan": "^1.8", | |||
"phpstan/phpstan-phpunit": "^1.1", | |||
"phpunit/phpunit": "^8.5 || ^9.5", | |||
"symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", | |||
"symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", | |||
"symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0" | |||
}, | |||
"time": "2022-10-31T08:38:03+00:00", | |||
"type": "composer-plugin", | |||
"extra": { | |||
"class": "Bamarni\\Composer\\Bin\\BamarniBinPlugin" | |||
}, | |||
"installation-source": "dist", | |||
"autoload": { | |||
"psr-4": { | |||
"Bamarni\\Composer\\Bin\\": "src" | |||
} | |||
}, | |||
"notification-url": "https://packagist.org/downloads/", | |||
"license": [ | |||
"MIT" | |||
], | |||
"description": "No conflicts for your bin dependencies", | |||
"keywords": [ | |||
"composer", | |||
"conflict", | |||
"dependency", | |||
"executable", | |||
"isolation", | |||
"tool" | |||
], | |||
"support": { | |||
"issues": "https://github.com/bamarni/composer-bin-plugin/issues", | |||
"source": "https://github.com/bamarni/composer-bin-plugin/tree/1.8.2" | |||
}, | |||
"install-path": "../bamarni/composer-bin-plugin" | |||
} | |||
], | |||
"dev": true, | |||
"dev-package-names": [ | |||
"bamarni/composer-bin-plugin" | |||
] | |||
} |
@@ -3,21 +3,30 @@ | |||
'name' => '__root__', | |||
'pretty_version' => 'dev-master', | |||
'version' => 'dev-master', | |||
'reference' => '559a758533026559cf632ed1b3d74f6b1ebfb481', | |||
'reference' => 'b6abfc4cba2d1ef4fdd8f2c22bbff46796b9485e', | |||
'type' => 'library', | |||
'install_path' => __DIR__ . '/../../../', | |||
'aliases' => array(), | |||
'dev' => false, | |||
'dev' => true, | |||
), | |||
'versions' => array( | |||
'__root__' => array( | |||
'pretty_version' => 'dev-master', | |||
'version' => 'dev-master', | |||
'reference' => '559a758533026559cf632ed1b3d74f6b1ebfb481', | |||
'reference' => 'b6abfc4cba2d1ef4fdd8f2c22bbff46796b9485e', | |||
'type' => 'library', | |||
'install_path' => __DIR__ . '/../../../', | |||
'aliases' => array(), | |||
'dev_requirement' => false, | |||
), | |||
'bamarni/composer-bin-plugin' => array( | |||
'pretty_version' => '1.8.2', | |||
'version' => '1.8.2.0', | |||
'reference' => '92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880', | |||
'type' => 'composer-plugin', | |||
'install_path' => __DIR__ . '/../bamarni/composer-bin-plugin', | |||
'aliases' => array(), | |||
'dev_requirement' => true, | |||
), | |||
), | |||
); |
@@ -54,6 +54,7 @@ use OCP\Share\IPublicShareTemplateProvider; | |||
use OCP\SpeechToText\ISpeechToTextProvider; | |||
use OCP\Support\CrashReport\IReporter; | |||
use OCP\Talk\ITalkBackend; | |||
use OCP\Teams\ITeamResourceProvider; | |||
use OCP\TextProcessing\IProvider as ITextProcessingProvider; | |||
use OCP\Translation\ITranslationProvider; | |||
use OCP\UserMigration\IMigrator as IUserMigrator; | |||
@@ -158,6 +159,9 @@ class RegistrationContext { | |||
/** @var PreviewProviderRegistration[] */ | |||
private array $previewProviders = []; | |||
/** @var ServiceRegistration<ITeamResourceProvider>[] */ | |||
private array $teamResourceProviders = []; | |||
public function __construct(LoggerInterface $logger) { | |||
$this->logger = $logger; | |||
} | |||
@@ -357,6 +361,13 @@ class RegistrationContext { | |||
); | |||
} | |||
public function registerTeamResourceProvider(string $class) : void { | |||
$this->context->registerTeamResourceProvider( | |||
$this->appId, | |||
$class | |||
); | |||
} | |||
public function registerCalendarRoomBackend(string $class): void { | |||
$this->context->registerCalendarRoomBackend( | |||
$this->appId, | |||
@@ -531,6 +542,17 @@ class RegistrationContext { | |||
); | |||
} | |||
/** | |||
* @psalm-param class-string<ITeamResourceProvider> $class | |||
*/ | |||
public function registerTeamResourceProvider(string $appId, string $class) { | |||
$this->teamResourceProviders[] = new ServiceRegistration( | |||
$appId, | |||
$class | |||
); | |||
} | |||
/** | |||
* @psalm-param class-string<IUserMigrator> $migratorClass | |||
*/ | |||
@@ -870,4 +892,12 @@ class RegistrationContext { | |||
public function getSetupChecks(): array { | |||
return $this->setupChecks; | |||
} | |||
/** | |||
* @return ServiceRegistration<ITeamResourceProvider>[] | |||
*/ | |||
public function getTeamResourceProviders(): array { | |||
return $this->teamResourceProviders; | |||
} | |||
} |
@@ -158,6 +158,7 @@ use OC\SpeechToText\SpeechToTextManager; | |||
use OC\SystemTag\ManagerFactory as SystemTagManagerFactory; | |||
use OC\Tagging\TagMapper; | |||
use OC\Talk\Broker; | |||
use OC\Teams\TeamManager; | |||
use OC\Template\JSCombiner; | |||
use OC\Translation\TranslationManager; | |||
use OC\User\AvailabilityCoordinator; | |||
@@ -265,6 +266,7 @@ use OCP\SpeechToText\ISpeechToTextManager; | |||
use OCP\SystemTag\ISystemTagManager; | |||
use OCP\SystemTag\ISystemTagObjectMapper; | |||
use OCP\Talk\IBroker; | |||
use OCP\Teams\ITeamManager; | |||
use OCP\Translation\ITranslationManager; | |||
use OCP\User\Events\BeforeUserDeletedEvent; | |||
use OCP\User\Events\BeforeUserLoggedInEvent; | |||
@@ -1297,6 +1299,7 @@ class Server extends ServerContainer implements IServerContainer { | |||
$this->registerAlias(\OCP\Collaboration\Resources\IManager::class, \OC\Collaboration\Resources\Manager::class); | |||
$this->registerAlias(IReferenceManager::class, ReferenceManager::class); | |||
$this->registerAlias(ITeamManager::class, TeamManager::class); | |||
$this->registerDeprecatedAlias('SettingsManager', \OC\Settings\Manager::class); | |||
$this->registerAlias(\OCP\Settings\IManager::class, \OC\Settings\Manager::class); |
@@ -0,0 +1,119 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2024 Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @author Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @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 OC\Teams; | |||
use OC\AppFramework\Bootstrap\Coordinator; | |||
use OCA\Circles\CirclesManager; | |||
use OCA\Circles\Exceptions\CircleNotFoundException; | |||
use OCA\Circles\Model\Circle; | |||
use OCA\Circles\Model\Member; | |||
use OCP\IURLGenerator; | |||
use OCP\Server; | |||
use OCP\Teams\ITeamManager; | |||
use OCP\Teams\ITeamResourceProvider; | |||
use OCP\Teams\Team; | |||
use Psr\Container\ContainerExceptionInterface; | |||
use Psr\Container\NotFoundExceptionInterface; | |||
class TeamManager implements ITeamManager { | |||
/** @var ?ITeamResourceProvider[] */ | |||
private ?array $providers = null; | |||
public function __construct( | |||
private Coordinator $bootContext, | |||
private IURLGenerator $urlGenerator, | |||
private ?CirclesManager $circlesManager, | |||
) { | |||
} | |||
public function hasTeamSupport(): bool { | |||
return $this->circlesManager !== null; | |||
} | |||
public function getProviders(): array { | |||
if ($this->providers !== null) { | |||
return $this->providers; | |||
} | |||
$this->providers = []; | |||
foreach ($this->bootContext->getRegistrationContext()->getTeamResourceProviders() as $providerRegistration) { | |||
try { | |||
/** @var ITeamResourceProvider $provider */ | |||
$provider = Server::get($providerRegistration->getService()); | |||
$this->providers[$provider->getId()] = $provider; | |||
} catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) { | |||
} | |||
} | |||
return $this->providers; | |||
} | |||
public function getProvider(string $providerId): ITeamResourceProvider { | |||
$providers = $this->getProviders(); | |||
if (isset($providers[$providerId])) { | |||
return $providers[$providerId]; | |||
} | |||
throw new \RuntimeException('No provider found for id ' .$providerId); | |||
} | |||
public function getSharedWith(string $teamId, string $userId): array { | |||
if ($this->getTeam($teamId, $userId) === null) { | |||
return []; | |||
} | |||
$resources = []; | |||
foreach ($this->getProviders() as $provider) { | |||
array_push($resources, ...$provider->getSharedWith($teamId)); | |||
} | |||
return $resources; | |||
} | |||
public function getTeamsForResource(string $providerId, string $resourceId, string $userId): array { | |||
$provider = $this->getProvider($providerId); | |||
return array_values(array_filter(array_map(function ($teamId) use ($userId) { | |||
$team = $this->getTeam($teamId, $userId); | |||
if ($team === null) { | |||
return null; | |||
} | |||
return new Team( | |||
$teamId, | |||
$team->getDisplayName(), | |||
$this->urlGenerator->linkToRouteAbsolute('contacts.contacts.directcircle', ['singleId' => $teamId]), | |||
); | |||
}, $provider->getTeamsForResource($resourceId)))); | |||
} | |||
private function getTeam(string $teamId, string $userId): ?Circle { | |||
try { | |||
$federatedUser = $this->circlesManager->getFederatedUser($userId, Member::TYPE_USER); | |||
$this->circlesManager->startSession($federatedUser); | |||
return $this->circlesManager->getCircle($teamId); | |||
} catch (CircleNotFoundException) { | |||
return null; | |||
} | |||
} | |||
} |
@@ -351,6 +351,14 @@ interface IRegistrationContext { | |||
*/ | |||
public function registerCalendarRoomBackend(string $class): void; | |||
/** | |||
* @param string $class | |||
* @psalm-param class-string<\OCP\Calendar\Room\IBackend> $actionClass | |||
* @return void | |||
* @since 29.0.0 | |||
*/ | |||
public function registerTeamResourceProvider(string $class): void; | |||
/** | |||
* Register an implementation of \OCP\UserMigration\IMigrator that | |||
* will handle the implementation of a migrator |
@@ -0,0 +1,58 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2024 Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @author Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @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 OCP\Teams; | |||
/** | |||
* @since 29.0.0 | |||
*/ | |||
interface ITeamManager { | |||
/** | |||
* Get all providers that have registered as a team resource provider | |||
* | |||
* @return ITeamResourceProvider[] | |||
* @since 29.0.0 | |||
*/ | |||
public function getProviders(): array; | |||
/** | |||
* Get a specific team resource provider by its id | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getProvider(string $providerId): ITeamResourceProvider; | |||
/** | |||
* Returns all team resources for a given team and user | |||
* | |||
* @return TeamResource[] | |||
* @since 29.0.0 | |||
*/ | |||
public function getSharedWith(string $teamId, string $userId): array; | |||
/** | |||
* Returns all teams for a given resource and user | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getTeamsForResource(string $providerId, string $resourceId, string $userId): array; | |||
} |
@@ -0,0 +1,76 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2024 Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @author Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @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 OCP\Teams; | |||
/** | |||
* Implement a provider of resources that are shared or owned by a team | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
interface ITeamResourceProvider { | |||
/** | |||
* Unique identifier used to identify the provider (app id) | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getId(): string; | |||
/** | |||
* User visible name of the provider (app name) | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getName(): string; | |||
/** | |||
* Svg icon to show next to the provider (app icon) | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getIconSvg(): string; | |||
/** | |||
* Return all resources that are shared to the given team id for the current provider | |||
* | |||
* @param string $teamId | |||
* @return TeamResource[] | |||
* @since 29.0.0 | |||
*/ | |||
public function getSharedWith(string $teamId): array; | |||
/** | |||
* Check if a resource is shared with the given team | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function isSharedWithTeam(string $teamId, string $resourceId): bool; | |||
/** | |||
* Return team ids that a resource is shared with or owned by | |||
* | |||
* @return string[] | |||
* @since 29.0.0 | |||
*/ | |||
public function getTeamsForResource(string $resourceId): array; | |||
} |
@@ -0,0 +1,73 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2024 Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @author Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @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 OCP\Teams; | |||
/** | |||
* Simple abstraction to represent a team in the public API | |||
* | |||
* In the backend a team is a circle identified by the circles singleId | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
class Team implements \JsonSerializable { | |||
/** | |||
* @since 29.0.0 | |||
*/ | |||
public function __construct(private string $teamId, private string $displayName, private ?string $link) { | |||
} | |||
/** | |||
* Unique identifier of the team (singleId of the circle) | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getId(): string { | |||
return $this->teamId; | |||
} | |||
/** | |||
* @since 29.0.0 | |||
*/ | |||
public function getDisplayName(): string { | |||
return $this->displayName; | |||
} | |||
/** | |||
* @since 29.0.0 | |||
*/ | |||
public function getLink(): ?string { | |||
return $this->link; | |||
} | |||
/** | |||
* @since 29.0.0 | |||
*/ | |||
public function jsonSerialize(): array { | |||
return [ | |||
'teamId' => $this->teamId, | |||
'displayName' => $this->displayName, | |||
'link' => $this->link, | |||
]; | |||
} | |||
} |
@@ -0,0 +1,129 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2024 Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @author Julius Härtl <jus@bitgrid.net> | |||
* | |||
* @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 OCP\Teams; | |||
/** | |||
* @since 29.0.0 | |||
*/ | |||
class TeamResource implements \JsonSerializable { | |||
/** | |||
* @since 29.0.0 | |||
*/ | |||
public function __construct( | |||
private ITeamResourceProvider $teamResourceProvider, | |||
private string $resourceId, | |||
private string $label, | |||
private string $url, | |||
private ?string $iconSvg = null, | |||
private ?string $iconURL = null, | |||
private ?string $iconEmoji = null, | |||
) { | |||
} | |||
/** | |||
* Returns the provider details for the current resource | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getProvider(): ITeamResourceProvider { | |||
return $this->teamResourceProvider; | |||
} | |||
/** | |||
* Unique id of the resource (e.g. primary key id) | |||
* @since 29.0.0 | |||
*/ | |||
public function getId(): string { | |||
return $this->resourceId; | |||
} | |||
/** | |||
* User visible label when listing resources | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getLabel(): string { | |||
return $this->label; | |||
} | |||
/** | |||
* Absolute url to navigate the user to the resource | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getUrl(): string { | |||
return $this->url; | |||
} | |||
/** | |||
* Svg icon to show next to the name for the resource | |||
* | |||
* From all icons the first one returning not null will be picked in order: iconEmoji, iconSvg, iconUrl | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getIconSvg(): ?string { | |||
return $this->iconSvg; | |||
} | |||
/** | |||
* Image url of the icon to show next to the name for the resource | |||
* | |||
* From all icons the first one returning not null will be picked in order: iconEmoji, iconSvg, iconUrl | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getIconURL(): ?string { | |||
return $this->iconURL; | |||
} | |||
/** | |||
* Emoji show next to the name for the resource | |||
* | |||
* From all icons the first one returning not null will be picked in order: iconEmoji, iconSvg, iconUrl | |||
* | |||
* @since 29.0.0 | |||
*/ | |||
public function getIconEmoji(): ?string { | |||
return $this->iconEmoji; | |||
} | |||
/** | |||
* @since 29.0.0 | |||
*/ | |||
public function jsonSerialize(): array { | |||
return [ | |||
'id' => $this->resourceId, | |||
'label' => $this->label, | |||
'url' => $this->url, | |||
'iconSvg' => $this->iconSvg, | |||
'iconURL' => $this->iconURL, | |||
'iconEmoji' => $this->iconEmoji, | |||
'provider' => [ | |||
'id' => $this->teamResourceProvider->getId(), | |||
'name' => $this->teamResourceProvider->getName(), | |||
'icon' => $this->teamResourceProvider->getIconSvg(), | |||
] | |||
]; | |||
} | |||
} |
@@ -91,6 +91,10 @@ | |||
<MoreSpecificReturnType errorLevel="error"/> | |||
<UndefinedClass> | |||
<errorLevel type="suppress"> | |||
<referencedClass name="OCA\Circles\CirclesManager"/> | |||
<referencedClass name="OCA\Circles\Exceptions\CircleNotFoundException"/> | |||
<referencedClass name="OCA\Circles\Model\Circle"/> | |||
<referencedClass name="OCA\Circles\Model\Member"/> | |||
<referencedClass name="OCA\GroupFolders\Mount\GroupFolderStorage"/> | |||
<referencedClass name="OCA\TwoFactorNextcloudNotification\Controller\APIController"/> | |||
<referencedClass name="OCA\GlobalSiteSelector\Service\SlaveService"/> |