diff options
author | Joas Schilling <213943+nickvergessen@users.noreply.github.com> | 2023-04-25 17:13:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-25 17:13:53 +0200 |
commit | 75f17b60945e15effc3eea41393eef2b13937226 (patch) | |
tree | b120f563285dc47585fa27b8829347ffec8b4510 /lib | |
parent | d60172567f7b45eade2d5ddc3a2b5a5d0fdca69d (diff) | |
parent | ecb8b55c5c01ca5cfbf23ef241536ef76c8f277d (diff) | |
download | nextcloud-server-75f17b60945e15effc3eea41393eef2b13937226.tar.gz nextcloud-server-75f17b60945e15effc3eea41393eef2b13937226.zip |
Merge pull request #37905 from nextcloud/techdebt/noid/add-attributes-for-remaining-security-annotations
feat(security): Add PHP \Attribute for remaining security annotations
Diffstat (limited to 'lib')
16 files changed, 477 insertions, 28 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 40fe5e431aa..eb2f3e46354 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -37,7 +37,15 @@ return array( 'OCP\\AppFramework\\Http' => $baseDir . '/lib/public/AppFramework/Http.php', 'OCP\\AppFramework\\Http\\Attribute\\ARateLimit' => $baseDir . '/lib/public/AppFramework/Http/Attribute/ARateLimit.php', 'OCP\\AppFramework\\Http\\Attribute\\AnonRateLimit' => $baseDir . '/lib/public/AppFramework/Http/Attribute/AnonRateLimit.php', + 'OCP\\AppFramework\\Http\\Attribute\\AuthorizedAdminSetting' => $baseDir . '/lib/public/AppFramework/Http/Attribute/AuthorizedAdminSetting.php', 'OCP\\AppFramework\\Http\\Attribute\\BruteForceProtection' => $baseDir . '/lib/public/AppFramework/Http/Attribute/BruteForceProtection.php', + 'OCP\\AppFramework\\Http\\Attribute\\CORS' => $baseDir . '/lib/public/AppFramework/Http/Attribute/CORS.php', + 'OCP\\AppFramework\\Http\\Attribute\\NoAdminRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/NoAdminRequired.php', + 'OCP\\AppFramework\\Http\\Attribute\\NoCSRFRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/NoCSRFRequired.php', + 'OCP\\AppFramework\\Http\\Attribute\\PasswordConfirmationRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php', + 'OCP\\AppFramework\\Http\\Attribute\\PublicPage' => $baseDir . '/lib/public/AppFramework/Http/Attribute/PublicPage.php', + 'OCP\\AppFramework\\Http\\Attribute\\StrictCookiesRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php', + 'OCP\\AppFramework\\Http\\Attribute\\SubAdminRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php', 'OCP\\AppFramework\\Http\\Attribute\\UseSession' => $baseDir . '/lib/public/AppFramework/Http/Attribute/UseSession.php', 'OCP\\AppFramework\\Http\\Attribute\\UserRateLimit' => $baseDir . '/lib/public/AppFramework/Http/Attribute/UserRateLimit.php', 'OCP\\AppFramework\\Http\\ContentSecurityPolicy' => $baseDir . '/lib/public/AppFramework/Http/ContentSecurityPolicy.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 93e91bb1641..9343231a55b 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -70,7 +70,15 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\AppFramework\\Http' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http.php', 'OCP\\AppFramework\\Http\\Attribute\\ARateLimit' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/ARateLimit.php', 'OCP\\AppFramework\\Http\\Attribute\\AnonRateLimit' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/AnonRateLimit.php', + 'OCP\\AppFramework\\Http\\Attribute\\AuthorizedAdminSetting' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/AuthorizedAdminSetting.php', 'OCP\\AppFramework\\Http\\Attribute\\BruteForceProtection' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/BruteForceProtection.php', + 'OCP\\AppFramework\\Http\\Attribute\\CORS' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/CORS.php', + 'OCP\\AppFramework\\Http\\Attribute\\NoAdminRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/NoAdminRequired.php', + 'OCP\\AppFramework\\Http\\Attribute\\NoCSRFRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/NoCSRFRequired.php', + 'OCP\\AppFramework\\Http\\Attribute\\PasswordConfirmationRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php', + 'OCP\\AppFramework\\Http\\Attribute\\PublicPage' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/PublicPage.php', + 'OCP\\AppFramework\\Http\\Attribute\\StrictCookiesRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php', + 'OCP\\AppFramework\\Http\\Attribute\\SubAdminRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php', 'OCP\\AppFramework\\Http\\Attribute\\UseSession' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/UseSession.php', 'OCP\\AppFramework\\Http\\Attribute\\UserRateLimit' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/UserRateLimit.php', 'OCP\\AppFramework\\Http\\ContentSecurityPolicy' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/ContentSecurityPolicy.php', diff --git a/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php index 30ba8d8d6e4..e177a612d96 100644 --- a/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php @@ -33,10 +33,13 @@ use OC\Security\Bruteforce\Throttler; use OC\User\Session; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\CORS; +use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Middleware; use OCP\IRequest; +use ReflectionMethod; /** * This middleware sets the correct CORS headers on a response if the @@ -81,9 +84,12 @@ class CORSMiddleware extends Middleware { * @since 6.0.0 */ public function beforeController($controller, $methodName) { + $reflectionMethod = new ReflectionMethod($controller, $methodName); + // ensure that @CORS annotated API routes are not used in conjunction // with session authentication since this enables CSRF attack vectors - if ($this->reflector->hasAnnotation('CORS') && (!$this->reflector->hasAnnotation('PublicPage') || $this->session->isLoggedIn())) { + if ($this->hasAnnotationOrAttribute($reflectionMethod, 'CORS', CORS::class) && + (!$this->hasAnnotationOrAttribute($reflectionMethod, 'PublicPage', PublicPage::class) || $this->session->isLoggedIn())) { $user = array_key_exists('PHP_AUTH_USER', $this->request->server) ? $this->request->server['PHP_AUTH_USER'] : null; $pass = array_key_exists('PHP_AUTH_PW', $this->request->server) ? $this->request->server['PHP_AUTH_PW'] : null; @@ -103,7 +109,28 @@ class CORSMiddleware extends Middleware { } /** - * This is being run after a successful controllermethod call and allows + * @template T + * + * @param ReflectionMethod $reflectionMethod + * @param string $annotationName + * @param class-string<T> $attributeClass + * @return boolean + */ + protected function hasAnnotationOrAttribute(ReflectionMethod $reflectionMethod, string $annotationName, string $attributeClass): bool { + if ($this->reflector->hasAnnotation($annotationName)) { + return true; + } + + + if (!empty($reflectionMethod->getAttributes($attributeClass))) { + return true; + } + + return false; + } + + /** + * This is being run after a successful controller method call and allows * the manipulation of a Response object. The middleware is run in reverse order * * @param Controller $controller the controller that is being called @@ -114,23 +141,25 @@ class CORSMiddleware extends Middleware { * @throws SecurityException */ public function afterController($controller, $methodName, Response $response) { - // only react if its a CORS request and if the request sends origin and + // only react if it's a CORS request and if the request sends origin and - if (isset($this->request->server['HTTP_ORIGIN']) && - $this->reflector->hasAnnotation('CORS')) { - // allow credentials headers must not be true or CSRF is possible - // otherwise - foreach ($response->getHeaders() as $header => $value) { - if (strtolower($header) === 'access-control-allow-credentials' && - strtolower(trim($value)) === 'true') { - $msg = 'Access-Control-Allow-Credentials must not be '. - 'set to true in order to prevent CSRF'; - throw new SecurityException($msg); + if (isset($this->request->server['HTTP_ORIGIN'])) { + $reflectionMethod = new ReflectionMethod($controller, $methodName); + if ($this->hasAnnotationOrAttribute($reflectionMethod, 'CORS', CORS::class)) { + // allow credentials headers must not be true or CSRF is possible + // otherwise + foreach ($response->getHeaders() as $header => $value) { + if (strtolower($header) === 'access-control-allow-credentials' && + strtolower(trim($value)) === 'true') { + $msg = 'Access-Control-Allow-Credentials must not be '. + 'set to true in order to prevent CSRF'; + throw new SecurityException($msg); + } } - } - $origin = $this->request->server['HTTP_ORIGIN']; - $response->addHeader('Access-Control-Allow-Origin', $origin); + $origin = $this->request->server['HTTP_ORIGIN']; + $response->addHeader('Access-Control-Allow-Origin', $origin); + } } return $response; } diff --git a/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php b/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php index 0ee9fdff881..a72a7a40016 100644 --- a/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php @@ -26,11 +26,13 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Middleware\Security\Exceptions\NotConfirmedException; use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired; use OCP\AppFramework\Middleware; use OCP\AppFramework\Utility\ITimeFactory; use OCP\ISession; use OCP\IUserSession; use OCP\User\Backend\IPasswordConfirmationBackend; +use ReflectionMethod; class PasswordConfirmationMiddleware extends Middleware { /** @var ControllerMethodReflector */ @@ -68,7 +70,9 @@ class PasswordConfirmationMiddleware extends Middleware { * @throws NotConfirmedException */ public function beforeController($controller, $methodName) { - if ($this->reflector->hasAnnotation('PasswordConfirmationRequired')) { + $reflectionMethod = new ReflectionMethod($controller, $methodName); + + if ($this->hasAnnotationOrAttribute($reflectionMethod, 'PasswordConfirmationRequired', PasswordConfirmationRequired::class)) { $user = $this->userSession->getUser(); $backendClassName = ''; if ($user !== null) { @@ -89,4 +93,24 @@ class PasswordConfirmationMiddleware extends Middleware { } } } + + /** + * @template T + * + * @param ReflectionMethod $reflectionMethod + * @param string $annotationName + * @param class-string<T> $attributeClass + * @return boolean + */ + protected function hasAnnotationOrAttribute(ReflectionMethod $reflectionMethod, string $annotationName, string $attributeClass): bool { + if (!empty($reflectionMethod->getAttributes($attributeClass))) { + return true; + } + + if ($this->reflector->hasAnnotation($annotationName)) { + return true; + } + + return false; + } } diff --git a/lib/private/AppFramework/Middleware/Security/ReloadExecutionMiddleware.php b/lib/private/AppFramework/Middleware/Security/ReloadExecutionMiddleware.php index 5a635e3f284..a6a07538345 100644 --- a/lib/private/AppFramework/Middleware/Security/ReloadExecutionMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/ReloadExecutionMiddleware.php @@ -58,7 +58,7 @@ class ReloadExecutionMiddleware extends Middleware { return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute( 'core.login.showLoginForm', - ['clear' => true] // this param the the code in login.js may be removed when the "Clear-Site-Data" is working in the browsers + ['clear' => true] // this param the code in login.js may be removed when the "Clear-Site-Data" is working in the browsers )); } diff --git a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php index eb8c1b8dc43..8e0794f9645 100644 --- a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php @@ -48,6 +48,12 @@ use OC\Settings\AuthorizedGroupMapper; use OCP\App\AppPathNotFoundException; use OCP\App\IAppManager; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting; +use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\PublicPage; +use OCP\AppFramework\Http\Attribute\StrictCookiesRequired; +use OCP\AppFramework\Http\Attribute\SubAdminRequired; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\Response; @@ -61,6 +67,7 @@ use OCP\IURLGenerator; use OCP\IUserSession; use OCP\Util; use Psr\Log\LoggerInterface; +use ReflectionMethod; /** * Used to do all the authentication and checking stuff for a controller method @@ -145,22 +152,24 @@ class SecurityMiddleware extends Middleware { $this->navigationManager->setActiveEntry('spreed'); } + $reflectionMethod = new ReflectionMethod($controller, $methodName); + // security checks - $isPublicPage = $this->reflector->hasAnnotation('PublicPage'); + $isPublicPage = $this->hasAnnotationOrAttribute($reflectionMethod, 'PublicPage', PublicPage::class); if (!$isPublicPage) { if (!$this->isLoggedIn) { throw new NotLoggedInException(); } $authorized = false; - if ($this->reflector->hasAnnotation('AuthorizedAdminSetting')) { + if ($this->hasAnnotationOrAttribute($reflectionMethod, 'AuthorizedAdminSetting', AuthorizedAdminSetting::class)) { $authorized = $this->isAdminUser; - if (!$authorized && $this->reflector->hasAnnotation('SubAdminRequired')) { + if (!$authorized && $this->hasAnnotationOrAttribute($reflectionMethod, 'SubAdminRequired', SubAdminRequired::class)) { $authorized = $this->isSubAdmin; } if (!$authorized) { - $settingClasses = explode(';', $this->reflector->getAnnotationParameter('AuthorizedAdminSetting', 'settings')); + $settingClasses = $this->getAuthorizedAdminSettingClasses($reflectionMethod); $authorizedClasses = $this->groupAuthorizationMapper->findAllClassesForUser($this->userSession->getUser()); foreach ($settingClasses as $settingClass) { $authorized = in_array($settingClass, $authorizedClasses, true); @@ -174,14 +183,14 @@ class SecurityMiddleware extends Middleware { throw new NotAdminException($this->l10n->t('Logged in user must be an admin, a sub admin or gotten special right to access this setting')); } } - if ($this->reflector->hasAnnotation('SubAdminRequired') + if ($this->hasAnnotationOrAttribute($reflectionMethod, 'SubAdminRequired', SubAdminRequired::class) && !$this->isSubAdmin && !$this->isAdminUser && !$authorized) { throw new NotAdminException($this->l10n->t('Logged in user must be an admin or sub admin')); } - if (!$this->reflector->hasAnnotation('SubAdminRequired') - && !$this->reflector->hasAnnotation('NoAdminRequired') + if (!$this->hasAnnotationOrAttribute($reflectionMethod, 'SubAdminRequired', SubAdminRequired::class) + && !$this->hasAnnotationOrAttribute($reflectionMethod, 'NoAdminRequired', NoAdminRequired::class) && !$this->isAdminUser && !$authorized) { throw new NotAdminException($this->l10n->t('Logged in user must be an admin')); @@ -189,14 +198,15 @@ class SecurityMiddleware extends Middleware { } // Check for strict cookie requirement - if ($this->reflector->hasAnnotation('StrictCookieRequired') || !$this->reflector->hasAnnotation('NoCSRFRequired')) { + if ($this->hasAnnotationOrAttribute($reflectionMethod, 'StrictCookieRequired', StrictCookiesRequired::class) || + !$this->hasAnnotationOrAttribute($reflectionMethod, 'NoCSRFRequired', NoCSRFRequired::class)) { if (!$this->request->passesStrictCookieCheck()) { throw new StrictCookieMissingException(); } } // CSRF check - also registers the CSRF token since the session may be closed later Util::callRegister(); - if (!$this->reflector->hasAnnotation('NoCSRFRequired')) { + if (!$this->hasAnnotationOrAttribute($reflectionMethod, 'NoCSRFRequired', NoCSRFRequired::class)) { /* * Only allow the CSRF check to fail on OCS Requests. This kind of * hacks around that we have no full token auth in place yet and we @@ -233,6 +243,48 @@ class SecurityMiddleware extends Middleware { } /** + * @template T + * + * @param ReflectionMethod $reflectionMethod + * @param string $annotationName + * @param class-string<T> $attributeClass + * @return boolean + */ + protected function hasAnnotationOrAttribute(ReflectionMethod $reflectionMethod, string $annotationName, string $attributeClass): bool { + if (!empty($reflectionMethod->getAttributes($attributeClass))) { + return true; + } + + if ($this->reflector->hasAnnotation($annotationName)) { + return true; + } + + return false; + } + + /** + * @param ReflectionMethod $reflectionMethod + * @return string[] + */ + protected function getAuthorizedAdminSettingClasses(ReflectionMethod $reflectionMethod): array { + $classes = []; + if ($this->reflector->hasAnnotation('AuthorizedAdminSetting')) { + $classes = explode(';', $this->reflector->getAnnotationParameter('AuthorizedAdminSetting', 'settings')); + } + + $attributes = $reflectionMethod->getAttributes(AuthorizedAdminSetting::class); + if (!empty($attributes)) { + foreach ($attributes as $attribute) { + /** @var AuthorizedAdminSetting $setting */ + $setting = $attribute->newInstance(); + $classes[] = $setting->getSettings(); + } + } + + return $classes; + } + + /** * If an SecurityException is being caught, ajax requests return a JSON error * response and non ajax requests redirect to the index * diff --git a/lib/public/AppFramework/ApiController.php b/lib/public/AppFramework/ApiController.php index 83dfaf93bc6..66c278e62d8 100644 --- a/lib/public/AppFramework/ApiController.php +++ b/lib/public/AppFramework/ApiController.php @@ -23,6 +23,8 @@ */ namespace OCP\AppFramework; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\Response; use OCP\IRequest; @@ -70,6 +72,8 @@ abstract class ApiController extends Controller { * @PublicPage * @since 7.0.0 */ + #[NoCSRFRequired] + #[PublicPage] public function preflightedCors() { if (isset($this->request->server['HTTP_ORIGIN'])) { $origin = $this->request->server['HTTP_ORIGIN']; diff --git a/lib/public/AppFramework/AuthPublicShareController.php b/lib/public/AppFramework/AuthPublicShareController.php index 00834506b05..78dd45551ed 100644 --- a/lib/public/AppFramework/AuthPublicShareController.php +++ b/lib/public/AppFramework/AuthPublicShareController.php @@ -28,6 +28,10 @@ declare(strict_types=1); */ namespace OCP\AppFramework; +use OCP\AppFramework\Http\Attribute\BruteForceProtection; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\PublicPage; +use OCP\AppFramework\Http\Attribute\UseSession; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\IRequest; @@ -70,6 +74,8 @@ abstract class AuthPublicShareController extends PublicShareController { * * @since 14.0.0 */ + #[NoCSRFRequired] + #[PublicPage] public function showAuthenticate(): TemplateResponse { return new TemplateResponse('core', 'publicshareauth', [], 'guest'); } @@ -129,7 +135,7 @@ abstract class AuthPublicShareController extends PublicShareController { } /** - * Function called after successfull authentication + * Function called after successful authentication * * You can use this to do some logging for example * @@ -147,6 +153,9 @@ abstract class AuthPublicShareController extends PublicShareController { * * @since 14.0.0 */ + #[BruteForceProtection(action: 'publicLinkAuth')] + #[PublicPage] + #[UseSession] final public function authenticate(string $password = '', string $passwordRequest = 'no', string $identityToken = '') { // Already authenticated if ($this->isAuthenticated()) { diff --git a/lib/public/AppFramework/Http/Attribute/AuthorizedAdminSetting.php b/lib/public/AppFramework/Http/Attribute/AuthorizedAdminSetting.php new file mode 100644 index 00000000000..724e78a1958 --- /dev/null +++ b/lib/public/AppFramework/Http/Attribute/AuthorizedAdminSetting.php @@ -0,0 +1,56 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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\AppFramework\Http\Attribute; + +use Attribute; +use OCP\Settings\IDelegatedSettings; + +/** + * Attribute for controller methods that should be only accessible with + * full admin or partial admin permissions. + * + * @since 27.0.0 + */ +#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] +class AuthorizedAdminSetting { + /** + * @param class-string<IDelegatedSettings> $settings A settings section the user needs to be able to access + * @since 27.0.0 + */ + public function __construct( + protected string $settings + ) { + } + + /** + * + * @return class-string<IDelegatedSettings> + * @since 27.0.0 + */ + public function getSettings(): string { + return $this->settings; + } +} diff --git a/lib/public/AppFramework/Http/Attribute/CORS.php b/lib/public/AppFramework/Http/Attribute/CORS.php new file mode 100644 index 00000000000..2d87c91ccab --- /dev/null +++ b/lib/public/AppFramework/Http/Attribute/CORS.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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\AppFramework\Http\Attribute; + +use Attribute; + +/** + * Attribute for controller methods that can also be accessed by not logged-in user + * + * @since 27.0.0 + */ +#[Attribute] +class CORS { +} diff --git a/lib/public/AppFramework/Http/Attribute/NoAdminRequired.php b/lib/public/AppFramework/Http/Attribute/NoAdminRequired.php new file mode 100644 index 00000000000..5e7164523a2 --- /dev/null +++ b/lib/public/AppFramework/Http/Attribute/NoAdminRequired.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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\AppFramework\Http\Attribute; + +use Attribute; + +/** + * Attribute for controller methods that can be accessed by any logged-in user + * + * @since 27.0.0 + */ +#[Attribute] +class NoAdminRequired { +} diff --git a/lib/public/AppFramework/Http/Attribute/NoCSRFRequired.php b/lib/public/AppFramework/Http/Attribute/NoCSRFRequired.php new file mode 100644 index 00000000000..247cb5c55b5 --- /dev/null +++ b/lib/public/AppFramework/Http/Attribute/NoCSRFRequired.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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\AppFramework\Http\Attribute; + +use Attribute; + +/** + * Attribute for controller methods that are not CSRF protected + * + * @since 27.0.0 + */ +#[Attribute] +class NoCSRFRequired { +} diff --git a/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php b/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php new file mode 100644 index 00000000000..49fc290be1c --- /dev/null +++ b/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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\AppFramework\Http\Attribute; + +use Attribute; + +/** + * Attribute for controller methods that require the password to be confirmed with in the last 30 minutes + * + * @since 27.0.0 + */ +#[Attribute] +class PasswordConfirmationRequired { +} diff --git a/lib/public/AppFramework/Http/Attribute/PublicPage.php b/lib/public/AppFramework/Http/Attribute/PublicPage.php new file mode 100644 index 00000000000..14e7a93b981 --- /dev/null +++ b/lib/public/AppFramework/Http/Attribute/PublicPage.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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\AppFramework\Http\Attribute; + +use Attribute; + +/** + * Attribute for controller methods that can also be accessed by not logged-in user + * + * @since 27.0.0 + */ +#[Attribute] +class PublicPage { +} diff --git a/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php b/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php new file mode 100644 index 00000000000..075a1b13c13 --- /dev/null +++ b/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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\AppFramework\Http\Attribute; + +use Attribute; + +/** + * Attribute for controller methods that require strict cookies + * + * @since 27.0.0 + */ +#[Attribute] +class StrictCookiesRequired { +} diff --git a/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php b/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php new file mode 100644 index 00000000000..dd34ce73c01 --- /dev/null +++ b/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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\AppFramework\Http\Attribute; + +use Attribute; + +/** + * Attribute for controller methods that can be accessed by sub-admins + * + * @since 27.0.0 + */ +#[Attribute] +class SubAdminRequired { +} |