From be840e77c02709517736d5df29d1357d8b534c94 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Mar 2024 13:11:41 +0100 Subject: [PATCH] feat(avatar): Allow logged-in users to proxy avatars without a token Signed-off-by: Joas Schilling --- appinfo/routes/routesAvatarController.php | 8 ++ lib/Controller/AvatarController.php | 38 +++++ openapi-federation.json | 167 ++++++++++++++++++++++ openapi-full.json | 167 ++++++++++++++++++++++ src/types/openapi/openapi-federation.ts | 62 ++++++++ src/types/openapi/openapi-full.ts | 62 ++++++++ 6 files changed, 504 insertions(+) diff --git a/appinfo/routes/routesAvatarController.php b/appinfo/routes/routesAvatarController.php index 688dc1a280b..35e76a6f74f 100644 --- a/appinfo/routes/routesAvatarController.php +++ b/appinfo/routes/routesAvatarController.php @@ -32,6 +32,10 @@ 'token' => '^[a-z0-9]{4,30}$', 'size' => '(64|512)', ]; +$requirementsNewWithSize = [ + 'apiVersion' => '(v1)', + 'size' => '(64|512)', +]; return [ 'ocs' => [ @@ -45,6 +49,10 @@ ['name' => 'Avatar#getAvatarDark', 'url' => '/api/{apiVersion}/room/{token}/avatar/dark', 'verb' => 'GET', 'requirements' => $requirements], /** @see \OCA\Talk\Controller\AvatarController::deleteAvatar() */ ['name' => 'Avatar#deleteAvatar', 'url' => '/api/{apiVersion}/room/{token}/avatar', 'verb' => 'DELETE', 'requirements' => $requirements], + /** @see \OCA\Talk\Controller\AvatarController::getUserProxyAvatarWithoutRoom() */ + ['name' => 'Avatar#getUserProxyAvatarWithoutRoom', 'url' => '/api/{apiVersion}/proxy/new/user-avatar/{size}', 'verb' => 'GET', 'requirements' => $requirementsNewWithSize], + /** @see \OCA\Talk\Controller\AvatarController::getUserProxyAvatarDarkWithoutRoom() */ + ['name' => 'Avatar#getUserProxyAvatarDarkWithoutRoom', 'url' => '/api/{apiVersion}/proxy/new/user-avatar/{size}/dark', 'verb' => 'GET', 'requirements' => $requirementsNewWithSize], /** @see \OCA\Talk\Controller\AvatarController::getUserProxyAvatar() */ ['name' => 'Avatar#getUserProxyAvatar', 'url' => '/api/{apiVersion}/proxy/{token}/user-avatar/{size}', 'verb' => 'GET', 'requirements' => $requirementsWithSize], /** @see \OCA\Talk\Controller\AvatarController::getUserProxyAvatarDark() */ diff --git a/lib/Controller/AvatarController.php b/lib/Controller/AvatarController.php index b6ec9521fba..ad90363953d 100644 --- a/lib/Controller/AvatarController.php +++ b/lib/Controller/AvatarController.php @@ -39,6 +39,7 @@ use OCA\Talk\Service\RoomFormatter; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\BruteForceProtection; +use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\Attribute\PublicPage; @@ -183,6 +184,43 @@ public function getAvatarDark(): FileDisplayResponse { return $this->getAvatar(true); } + /** + * Get the avatar of a cloudId user when inviting users while creating a conversation + * + * @param int $size Avatar size + * @psalm-param 64|512 $size + * @param string $cloudId Federation CloudID to get the avatar for + * @param bool $darkTheme Theme used for background + * @return FileDisplayResponse + * + * 200: User avatar returned + */ + #[FederationSupported] + #[OpenAPI(scope: OpenAPI::SCOPE_FEDERATION)] + #[NoAdminRequired] + #[NoCSRFRequired] + public function getUserProxyAvatarWithoutRoom(int $size, string $cloudId, bool $darkTheme = false): FileDisplayResponse { + return $this->getUserProxyAvatar($size, $cloudId, $darkTheme); + } + + /** + * Get the dark mode avatar of a cloudId user when inviting users while creating a conversation + * + * @param int $size Avatar size + * @psalm-param 64|512 $size + * @param string $cloudId Federation CloudID to get the avatar for + * @return FileDisplayResponse + * + * 200: User avatar returned + */ + #[FederationSupported] + #[OpenAPI(scope: OpenAPI::SCOPE_FEDERATION)] + #[NoAdminRequired] + #[NoCSRFRequired] + public function getUserProxyAvatarDarkWithoutRoom(int $size, string $cloudId): FileDisplayResponse { + return $this->getUserProxyAvatar($size, $cloudId, true); + } + /** * Get the avatar of a cloudId user * diff --git a/openapi-federation.json b/openapi-federation.json index 73c52570625..26404c9559d 100644 --- a/openapi-federation.json +++ b/openapi-federation.json @@ -816,6 +816,173 @@ } }, "paths": { + "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/new/user-avatar/{size}": { + "get": { + "operationId": "avatar-get-user-proxy-avatar-without-room", + "summary": "Get the avatar of a cloudId user when inviting users while creating a conversation", + "tags": [ + "avatar" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "cloudId", + "in": "query", + "description": "Federation CloudID to get the avatar for", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "darkTheme", + "in": "query", + "description": "Theme used for background", + "schema": { + "type": "integer", + "default": 0, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "apiVersion", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": [ + "v1" + ], + "default": "v1" + } + }, + { + "name": "size", + "in": "path", + "description": "Avatar size", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "enum": [ + 64, + 512 + ] + } + }, + { + "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": "User avatar returned", + "content": { + "*/*": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/new/user-avatar/{size}/dark": { + "get": { + "operationId": "avatar-get-user-proxy-avatar-dark-without-room", + "summary": "Get the dark mode avatar of a cloudId user when inviting users while creating a conversation", + "tags": [ + "avatar" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "cloudId", + "in": "query", + "description": "Federation CloudID to get the avatar for", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "apiVersion", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": [ + "v1" + ], + "default": "v1" + } + }, + { + "name": "size", + "in": "path", + "description": "Avatar size", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "enum": [ + 64, + 512 + ] + } + }, + { + "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": "User avatar returned", + "content": { + "*/*": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + } + } + }, "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/{token}/user-avatar/{size}": { "get": { "operationId": "avatar-get-user-proxy-avatar", diff --git a/openapi-full.json b/openapi-full.json index 7c4ff1ff372..b43018ef755 100644 --- a/openapi-full.json +++ b/openapi-full.json @@ -16220,6 +16220,173 @@ } } }, + "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/new/user-avatar/{size}": { + "get": { + "operationId": "avatar-get-user-proxy-avatar-without-room", + "summary": "Get the avatar of a cloudId user when inviting users while creating a conversation", + "tags": [ + "avatar" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "cloudId", + "in": "query", + "description": "Federation CloudID to get the avatar for", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "darkTheme", + "in": "query", + "description": "Theme used for background", + "schema": { + "type": "integer", + "default": 0, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "apiVersion", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": [ + "v1" + ], + "default": "v1" + } + }, + { + "name": "size", + "in": "path", + "description": "Avatar size", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "enum": [ + 64, + 512 + ] + } + }, + { + "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": "User avatar returned", + "content": { + "*/*": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/new/user-avatar/{size}/dark": { + "get": { + "operationId": "avatar-get-user-proxy-avatar-dark-without-room", + "summary": "Get the dark mode avatar of a cloudId user when inviting users while creating a conversation", + "tags": [ + "avatar" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "cloudId", + "in": "query", + "description": "Federation CloudID to get the avatar for", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "apiVersion", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": [ + "v1" + ], + "default": "v1" + } + }, + { + "name": "size", + "in": "path", + "description": "Avatar size", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "enum": [ + 64, + 512 + ] + } + }, + { + "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": "User avatar returned", + "content": { + "*/*": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + } + } + }, "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/{token}/user-avatar/{size}": { "get": { "operationId": "avatar-get-user-proxy-avatar", diff --git a/src/types/openapi/openapi-federation.ts b/src/types/openapi/openapi-federation.ts index ea46a31bb16..e971f60d30b 100644 --- a/src/types/openapi/openapi-federation.ts +++ b/src/types/openapi/openapi-federation.ts @@ -10,6 +10,14 @@ type XOR = (T | U) extends object ? (Without & U) | (Without & type OneOf = T extends [infer Only] ? Only : T extends [infer A, infer B, ...infer Rest] ? OneOf<[XOR, ...Rest]> : never; export type paths = { + "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/new/user-avatar/{size}": { + /** Get the avatar of a cloudId user when inviting users while creating a conversation */ + get: operations["avatar-get-user-proxy-avatar-without-room"]; + }; + "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/new/user-avatar/{size}/dark": { + /** Get the dark mode avatar of a cloudId user when inviting users while creating a conversation */ + get: operations["avatar-get-user-proxy-avatar-dark-without-room"]; + }; "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/{token}/user-avatar/{size}": { /** Get the avatar of a cloudId user */ get: operations["avatar-get-user-proxy-avatar"]; @@ -297,6 +305,60 @@ export type external = Record; export type operations = { + /** Get the avatar of a cloudId user when inviting users while creating a conversation */ + "avatar-get-user-proxy-avatar-without-room": { + parameters: { + query: { + /** @description Federation CloudID to get the avatar for */ + cloudId: string; + /** @description Theme used for background */ + darkTheme?: 0 | 1; + }; + header: { + /** @description Required to be true for the API request to pass */ + "OCS-APIRequest": boolean; + }; + path: { + apiVersion: "v1"; + /** @description Avatar size */ + size: 64 | 512; + }; + }; + responses: { + /** @description User avatar returned */ + 200: { + content: { + "*/*": string; + }; + }; + }; + }; + /** Get the dark mode avatar of a cloudId user when inviting users while creating a conversation */ + "avatar-get-user-proxy-avatar-dark-without-room": { + parameters: { + query: { + /** @description Federation CloudID to get the avatar for */ + cloudId: string; + }; + header: { + /** @description Required to be true for the API request to pass */ + "OCS-APIRequest": boolean; + }; + path: { + apiVersion: "v1"; + /** @description Avatar size */ + size: 64 | 512; + }; + }; + responses: { + /** @description User avatar returned */ + 200: { + content: { + "*/*": string; + }; + }; + }; + }; /** Get the avatar of a cloudId user */ "avatar-get-user-proxy-avatar": { parameters: { diff --git a/src/types/openapi/openapi-full.ts b/src/types/openapi/openapi-full.ts index 90ec9bcd5f4..6906320f9f4 100644 --- a/src/types/openapi/openapi-full.ts +++ b/src/types/openapi/openapi-full.ts @@ -372,6 +372,14 @@ export type paths = { /** Delete your avatar as a user */ delete: operations["user_avatar-delete-avatar"]; }; + "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/new/user-avatar/{size}": { + /** Get the avatar of a cloudId user when inviting users while creating a conversation */ + get: operations["avatar-get-user-proxy-avatar-without-room"]; + }; + "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/new/user-avatar/{size}/dark": { + /** Get the dark mode avatar of a cloudId user when inviting users while creating a conversation */ + get: operations["avatar-get-user-proxy-avatar-dark-without-room"]; + }; "/ocs/v2.php/apps/spreed/api/{apiVersion}/proxy/{token}/user-avatar/{size}": { /** Get the avatar of a cloudId user */ get: operations["avatar-get-user-proxy-avatar"]; @@ -5537,6 +5545,60 @@ export type operations = { }; }; }; + /** Get the avatar of a cloudId user when inviting users while creating a conversation */ + "avatar-get-user-proxy-avatar-without-room": { + parameters: { + query: { + /** @description Federation CloudID to get the avatar for */ + cloudId: string; + /** @description Theme used for background */ + darkTheme?: 0 | 1; + }; + header: { + /** @description Required to be true for the API request to pass */ + "OCS-APIRequest": boolean; + }; + path: { + apiVersion: "v1"; + /** @description Avatar size */ + size: 64 | 512; + }; + }; + responses: { + /** @description User avatar returned */ + 200: { + content: { + "*/*": string; + }; + }; + }; + }; + /** Get the dark mode avatar of a cloudId user when inviting users while creating a conversation */ + "avatar-get-user-proxy-avatar-dark-without-room": { + parameters: { + query: { + /** @description Federation CloudID to get the avatar for */ + cloudId: string; + }; + header: { + /** @description Required to be true for the API request to pass */ + "OCS-APIRequest": boolean; + }; + path: { + apiVersion: "v1"; + /** @description Avatar size */ + size: 64 | 512; + }; + }; + responses: { + /** @description User avatar returned */ + 200: { + content: { + "*/*": string; + }; + }; + }; + }; /** Get the avatar of a cloudId user */ "avatar-get-user-proxy-avatar": { parameters: {