mirror of
https://github.com/nextcloud/server.git
synced 2026-06-07 15:53:04 -04:00
Merge pull request #58863 from nextcloud/fix/annotation-attributes-fix
This commit is contained in:
commit
1b504bf4ec
22 changed files with 138 additions and 168 deletions
|
|
@ -11,6 +11,7 @@ namespace OCA\Provisioning_API\Middleware;
|
|||
use OCA\Provisioning_API\Middleware\Exceptions\NotSubAdminException;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\AppFramework\Middleware;
|
||||
use OCP\AppFramework\OCS\OCSException;
|
||||
|
|
@ -40,7 +41,7 @@ class ProvisioningApiMiddleware extends Middleware {
|
|||
*/
|
||||
public function beforeController($controller, $methodName) {
|
||||
// If AuthorizedAdminSetting, the check will be done in the SecurityMiddleware
|
||||
if (!$this->isAdmin && !$this->reflector->hasAnnotation('NoSubAdminRequired') && !$this->isSubAdmin && !$this->reflector->hasAnnotation('AuthorizedAdminSetting')) {
|
||||
if (!$this->isAdmin && !$this->reflector->hasAnnotation('NoSubAdminRequired') && !$this->isSubAdmin && !$this->reflector->hasAnnotationOrAttribute('AuthorizedAdminSetting', AuthorizedAdminSetting::class)) {
|
||||
throw new NotSubAdminException();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,10 +53,14 @@ class ProvisioningApiMiddlewareTest extends TestCase {
|
|||
);
|
||||
|
||||
$this->reflector->method('hasAnnotation')
|
||||
->willReturnCallback(function ($annotation) use ($subadminRequired, $hasSettingAuthorizationAnnotation) {
|
||||
->willReturnCallback(function ($annotation) use ($subadminRequired) {
|
||||
if ($annotation === 'NoSubAdminRequired') {
|
||||
return !$subadminRequired;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$this->reflector->method('hasAnnotationOrAttribute')
|
||||
->willReturnCallback(function ($annotation, $attribute) use ($hasSettingAuthorizationAnnotation) {
|
||||
if ($annotation === 'AuthorizedAdminSetting') {
|
||||
return $hasSettingAuthorizationAnnotation;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use OC\AppFramework\Http;
|
|||
use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException;
|
||||
use OC\AppFramework\Utility\ControllerMethodReflector;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\AppFramework\Middleware;
|
||||
use OCP\Group\ISubAdmin;
|
||||
|
|
@ -44,7 +45,7 @@ class SubadminMiddleware extends Middleware {
|
|||
|
||||
#[Override]
|
||||
public function beforeController(Controller $controller, string $methodName): void {
|
||||
if (!$this->reflector->hasAnnotation('NoSubAdminRequired') && !$this->reflector->hasAnnotation('AuthorizedAdminSetting')) {
|
||||
if (!$this->reflector->hasAnnotation('NoSubAdminRequired') && !$this->reflector->hasAnnotationOrAttribute('AuthorizedAdminSetting', AuthorizedAdminSetting::class)) {
|
||||
if (!$this->isSubAdmin()) {
|
||||
throw new NotAdminException($this->l10n->t('Logged in account must be a sub admin'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException;
|
|||
use OC\AppFramework\Utility\ControllerMethodReflector;
|
||||
use OCA\Settings\Middleware\SubadminMiddleware;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\Group\ISubAdmin;
|
||||
use OCP\IL10N;
|
||||
|
|
@ -62,11 +63,16 @@ class SubadminMiddlewareTest extends \Test\TestCase {
|
|||
$this->expectException(NotAdminException::class);
|
||||
|
||||
$this->reflector
|
||||
->expects($this->exactly(2))
|
||||
->expects($this->exactly(1))
|
||||
->method('hasAnnotation')
|
||||
->willReturnMap([
|
||||
['NoSubAdminRequired', false],
|
||||
['AuthorizedAdminSetting', false],
|
||||
]);
|
||||
$this->reflector
|
||||
->expects($this->exactly(1))
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->willReturnMap([
|
||||
['AuthorizedAdminSetting', AuthorizedAdminSetting::class, false],
|
||||
]);
|
||||
|
||||
$this->subAdminManager
|
||||
|
|
@ -94,11 +100,16 @@ class SubadminMiddlewareTest extends \Test\TestCase {
|
|||
|
||||
public function testBeforeControllerAsSubAdminWithoutAnnotation(): void {
|
||||
$this->reflector
|
||||
->expects($this->exactly(2))
|
||||
->expects($this->exactly(1))
|
||||
->method('hasAnnotation')
|
||||
->willReturnMap([
|
||||
['NoSubAdminRequired', false],
|
||||
['AuthorizedAdminSetting', false],
|
||||
]);
|
||||
$this->reflector
|
||||
->expects($this->exactly(1))
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->willReturnMap([
|
||||
['AuthorizedAdminSetting', AuthorizedAdminSetting::class, false],
|
||||
]);
|
||||
|
||||
$this->subAdminManager
|
||||
|
|
|
|||
|
|
@ -1552,9 +1552,6 @@
|
|||
</DeprecatedMethod>
|
||||
</file>
|
||||
<file src="apps/files_sharing/lib/Middleware/SharingCheckMiddleware.php">
|
||||
<DeprecatedInterface>
|
||||
<code><![CDATA[protected]]></code>
|
||||
</DeprecatedInterface>
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[getAppValue]]></code>
|
||||
<code><![CDATA[getAppValue]]></code>
|
||||
|
|
@ -2097,9 +2094,6 @@
|
|||
</DeprecatedMethod>
|
||||
</file>
|
||||
<file src="apps/provisioning_api/lib/Middleware/ProvisioningApiMiddleware.php">
|
||||
<DeprecatedInterface>
|
||||
<code><![CDATA[IControllerMethodReflector]]></code>
|
||||
</DeprecatedInterface>
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[hasAnnotation]]></code>
|
||||
<code><![CDATA[hasAnnotation]]></code>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ namespace OC\Core\Middleware;
|
|||
|
||||
use Exception;
|
||||
use OC\AppFramework\Http\Attributes\TwoFactorSetUpDoneRequired;
|
||||
use OC\AppFramework\Middleware\MiddlewareUtils;
|
||||
use OC\Authentication\Exceptions\TwoFactorAuthRequiredException;
|
||||
use OC\Authentication\Exceptions\UserAlreadyLoggedInException;
|
||||
use OC\Authentication\TwoFactorAuth\Manager;
|
||||
|
|
@ -23,6 +22,7 @@ use OCP\AppFramework\Controller;
|
|||
use OCP\AppFramework\Http\Attribute\NoTwoFactorRequired;
|
||||
use OCP\AppFramework\Http\RedirectResponse;
|
||||
use OCP\AppFramework\Middleware;
|
||||
use OCP\AppFramework\Utility\IControllerMethodReflector;
|
||||
use OCP\Authentication\TwoFactorAuth\ALoginSetupController;
|
||||
use OCP\IRequest;
|
||||
use OCP\ISession;
|
||||
|
|
@ -36,7 +36,7 @@ class TwoFactorMiddleware extends Middleware {
|
|||
private Session $userSession,
|
||||
private ISession $session,
|
||||
private IURLGenerator $urlGenerator,
|
||||
private MiddlewareUtils $middlewareUtils,
|
||||
private IControllerMethodReflector $reflector,
|
||||
private IRequest $request,
|
||||
) {
|
||||
}
|
||||
|
|
@ -46,9 +46,7 @@ class TwoFactorMiddleware extends Middleware {
|
|||
* @param string $methodName
|
||||
*/
|
||||
public function beforeController($controller, $methodName) {
|
||||
$reflectionMethod = new ReflectionMethod($controller, $methodName);
|
||||
|
||||
if ($this->middlewareUtils->hasAnnotationOrAttribute($reflectionMethod, 'NoTwoFactorRequired', NoTwoFactorRequired::class)) {
|
||||
if ($this->reflector->hasAnnotationOrAttribute('NoTwoFactorRequired', NoTwoFactorRequired::class)) {
|
||||
// Route handler explicitly marked to work without finished 2FA are
|
||||
// not blocked
|
||||
return;
|
||||
|
|
@ -59,6 +57,7 @@ class TwoFactorMiddleware extends Middleware {
|
|||
return;
|
||||
}
|
||||
|
||||
$reflectionMethod = new ReflectionMethod($controller, $methodName);
|
||||
if ($controller instanceof TwoFactorChallengeController
|
||||
&& $this->userSession->getUser() !== null
|
||||
&& !$reflectionMethod->getAttributes(TwoFactorSetUpDoneRequired::class)) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ use OCP\Authentication\TwoFactorAuth\ALoginSetupController;
|
|||
use OCP\ISession;
|
||||
use OCP\IUserSession;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ReflectionMethod;
|
||||
|
||||
// Will close the session if the user session is ephemeral.
|
||||
// Happens when the user logs in via the login flow v2.
|
||||
|
|
@ -61,12 +60,7 @@ class FlowV2EphemeralSessionsMiddleware extends Middleware {
|
|||
return;
|
||||
}
|
||||
|
||||
$reflectionMethod = new ReflectionMethod($controller, $methodName);
|
||||
if (!empty($reflectionMethod->getAttributes(PublicPage::class))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->reflector->hasAnnotation('PublicPage')) {
|
||||
if ($this->reflector->hasAnnotationOrAttribute('PublicPage', PublicPage::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,19 +30,10 @@ class MiddlewareUtils {
|
|||
* @param ReflectionMethod $reflectionMethod
|
||||
* @param ?string $annotationName
|
||||
* @param class-string<T> $attributeClass
|
||||
* @return boolean
|
||||
* @deprecated 34.0.0 call directly on the reflector
|
||||
*/
|
||||
public function hasAnnotationOrAttribute(ReflectionMethod $reflectionMethod, ?string $annotationName, string $attributeClass): bool {
|
||||
if (!empty($reflectionMethod->getAttributes($attributeClass))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($annotationName && $this->reflector->hasAnnotation($annotationName)) {
|
||||
$this->logger->debug($reflectionMethod->getDeclaringClass()->getName() . '::' . $reflectionMethod->getName() . ' uses the @' . $annotationName . ' annotation and should use the #[' . $attributeClass . '] attribute instead');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $this->reflector->hasAnnotationOrAttribute($annotationName, $attributeClass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,9 +46,7 @@ class PasswordConfirmationMiddleware extends Middleware {
|
|||
* @throws NotConfirmedException
|
||||
*/
|
||||
public function beforeController(Controller $controller, string $methodName) {
|
||||
$reflectionMethod = new ReflectionMethod($controller, $methodName);
|
||||
|
||||
if (!$this->needsPasswordConfirmation($reflectionMethod)) {
|
||||
if (!$this->needsPasswordConfirmation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -79,6 +77,7 @@ class PasswordConfirmationMiddleware extends Middleware {
|
|||
return;
|
||||
}
|
||||
|
||||
$reflectionMethod = new ReflectionMethod($controller, $methodName);
|
||||
if ($this->isPasswordConfirmationStrict($reflectionMethod)) {
|
||||
$authHeader = $this->request->getHeader('Authorization');
|
||||
if (!str_starts_with(strtolower($authHeader), 'basic ')) {
|
||||
|
|
@ -101,18 +100,8 @@ class PasswordConfirmationMiddleware extends Middleware {
|
|||
}
|
||||
}
|
||||
|
||||
private function needsPasswordConfirmation(ReflectionMethod $reflectionMethod): bool {
|
||||
$attributes = $reflectionMethod->getAttributes(PasswordConfirmationRequired::class);
|
||||
if (!empty($attributes)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->reflector->hasAnnotation('PasswordConfirmationRequired')) {
|
||||
$this->logger->debug($reflectionMethod->getDeclaringClass()->getName() . '::' . $reflectionMethod->getName() . ' uses the @' . 'PasswordConfirmationRequired' . ' annotation and should use the #[PasswordConfirmationRequired] attribute instead');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
private function needsPasswordConfirmation(): bool {
|
||||
return $this->reflector->hasAnnotationOrAttribute('PasswordConfirmationRequired', PasswordConfirmationRequired::class);
|
||||
}
|
||||
|
||||
private function isPasswordConfirmationStrict(ReflectionMethod $reflectionMethod): bool {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ use OCP\AppFramework\Http\Attribute\UseSession;
|
|||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\AppFramework\Middleware;
|
||||
use OCP\ISession;
|
||||
use ReflectionMethod;
|
||||
|
||||
class SessionMiddleware extends Middleware {
|
||||
public function __construct(
|
||||
|
|
@ -28,18 +27,7 @@ class SessionMiddleware extends Middleware {
|
|||
* @param string $methodName
|
||||
*/
|
||||
public function beforeController($controller, $methodName) {
|
||||
/**
|
||||
* Annotation deprecated with Nextcloud 26
|
||||
*/
|
||||
$hasAnnotation = $this->reflector->hasAnnotation('UseSession');
|
||||
if ($hasAnnotation) {
|
||||
$this->session->reopen();
|
||||
return;
|
||||
}
|
||||
|
||||
$reflectionMethod = new ReflectionMethod($controller, $methodName);
|
||||
$hasAttribute = !empty($reflectionMethod->getAttributes(UseSession::class));
|
||||
if ($hasAttribute) {
|
||||
if ($this->reflector->hasAnnotationOrAttribute('UseSession', UseSession::class)) {
|
||||
$this->session->reopen();
|
||||
}
|
||||
}
|
||||
|
|
@ -51,18 +39,7 @@ class SessionMiddleware extends Middleware {
|
|||
* @return Response
|
||||
*/
|
||||
public function afterController($controller, $methodName, Response $response) {
|
||||
/**
|
||||
* Annotation deprecated with Nextcloud 26
|
||||
*/
|
||||
$hasAnnotation = $this->reflector->hasAnnotation('UseSession');
|
||||
if ($hasAnnotation) {
|
||||
$this->session->close();
|
||||
return $response;
|
||||
}
|
||||
|
||||
$reflectionMethod = new ReflectionMethod($controller, $methodName);
|
||||
$hasAttribute = !empty($reflectionMethod->getAttributes(UseSession::class));
|
||||
if ($hasAttribute) {
|
||||
if ($this->reflector->hasAnnotationOrAttribute('UseSession', UseSession::class)) {
|
||||
$this->session->close();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,28 +9,39 @@ declare(strict_types=1);
|
|||
namespace OC\AppFramework\Utility;
|
||||
|
||||
use OCP\AppFramework\Utility\IControllerMethodReflector;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Reads and parses annotations from doc comments
|
||||
*/
|
||||
class ControllerMethodReflector implements IControllerMethodReflector {
|
||||
public $annotations = [];
|
||||
private $types = [];
|
||||
private $parameters = [];
|
||||
public array $annotations = [];
|
||||
private array $types = [];
|
||||
private array $parameters = [];
|
||||
private array $ranges = [];
|
||||
private int $startLine = 0;
|
||||
private string $file = '';
|
||||
private ?\ReflectionMethod $reflectionMethod = null;
|
||||
|
||||
public function __construct(
|
||||
private readonly LoggerInterface $logger,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $object an object or classname
|
||||
* @param string $method the method which we want to inspect
|
||||
*/
|
||||
public function reflect($object, string $method) {
|
||||
$reflection = new \ReflectionMethod($object, $method);
|
||||
$this->startLine = $reflection->getStartLine();
|
||||
$this->file = $reflection->getFileName();
|
||||
$this->annotations = [];
|
||||
$this->types = [];
|
||||
$this->parameters = [];
|
||||
$this->ranges = [];
|
||||
$this->reflectionMethod = new \ReflectionMethod($object, $method);
|
||||
$this->startLine = $this->reflectionMethod->getStartLine();
|
||||
$this->file = $this->reflectionMethod->getFileName();
|
||||
|
||||
$docs = $reflection->getDocComment();
|
||||
$docs = $this->reflectionMethod->getDocComment();
|
||||
|
||||
if ($docs !== false) {
|
||||
// extract everything prefixed by @ and first letter uppercase
|
||||
|
|
@ -69,7 +80,7 @@ class ControllerMethodReflector implements IControllerMethodReflector {
|
|||
}
|
||||
}
|
||||
|
||||
foreach ($reflection->getParameters() as $param) {
|
||||
foreach ($this->reflectionMethod->getParameters() as $param) {
|
||||
// extract type information from PHP 7 scalar types and prefer them over phpdoc annotations
|
||||
$type = $param->getType();
|
||||
if ($type instanceof \ReflectionNamedType) {
|
||||
|
|
@ -114,6 +125,24 @@ class ControllerMethodReflector implements IControllerMethodReflector {
|
|||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*
|
||||
* @param class-string<T> $attributeClass
|
||||
*/
|
||||
public function hasAnnotationOrAttribute(?string $annotationName, string $attributeClass): bool {
|
||||
if (!empty($this->reflectionMethod->getAttributes($attributeClass))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($annotationName && $this->hasAnnotation($annotationName)) {
|
||||
$this->logger->debug($this->reflectionMethod->getDeclaringClass()->getName() . '::' . $this->reflectionMethod->getName() . ' uses the @' . $annotationName . ' annotation and should use the #[' . $attributeClass . '] attribute instead');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a method contains an annotation
|
||||
* @param string $name the name of the annotation
|
||||
|
|
|
|||
|
|
@ -11,22 +11,13 @@ namespace OCP\AppFramework\Utility;
|
|||
/**
|
||||
* Interface ControllerMethodReflector
|
||||
*
|
||||
* Reads and parses annotations from doc comments
|
||||
* You can inject this interface in your Middleware, and it will be prefilled with information related to the called controller method
|
||||
*
|
||||
* Reads and parses annotations from doc comments (deprecated) and PHP attributes
|
||||
*
|
||||
* @since 8.0.0
|
||||
* @deprecated 22.0.0 will be obsolete with native attributes in PHP8
|
||||
* @see https://help.nextcloud.com/t/how-should-we-use-php8-attributes/104278
|
||||
*/
|
||||
interface IControllerMethodReflector {
|
||||
/**
|
||||
* @param object $object an object or classname
|
||||
* @param string $method the method which we want to inspect
|
||||
* @return void
|
||||
* @since 8.0.0
|
||||
* @deprecated 17.0.0 Reflect should not be called multiple times and only be used internally. This will be removed in Nextcloud 18
|
||||
*/
|
||||
public function reflect($object, string $method);
|
||||
|
||||
/**
|
||||
* Inspects the PHPDoc parameters for types
|
||||
*
|
||||
|
|
@ -56,4 +47,15 @@ interface IControllerMethodReflector {
|
|||
* @see https://help.nextcloud.com/t/how-should-we-use-php8-attributes/104278
|
||||
*/
|
||||
public function hasAnnotation(string $name): bool;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*
|
||||
* Check if a method contains an annotation or an attribute.
|
||||
* Log a debug line if the annotation is used.
|
||||
*
|
||||
* @param class-string<T> $attributeClass
|
||||
* @since 34.0.0
|
||||
*/
|
||||
public function hasAnnotationOrAttribute(?string $annotationName, string $attributeClass): bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ namespace Test\Core\Middleware;
|
|||
|
||||
use OC\AppFramework\Http\Attributes\TwoFactorSetUpDoneRequired;
|
||||
use OC\AppFramework\Http\Request;
|
||||
use OC\AppFramework\Middleware\MiddlewareUtils;
|
||||
use OC\AppFramework\Utility\ControllerMethodReflector;
|
||||
use OC\Authentication\Exceptions\TwoFactorAuthRequiredException;
|
||||
use OC\Authentication\Exceptions\UserAlreadyLoggedInException;
|
||||
|
|
@ -102,7 +101,7 @@ class TwoFactorMiddlewareTest extends TestCase {
|
|||
$this->createMock(IConfig::class)
|
||||
);
|
||||
|
||||
$this->middleware = new TwoFactorMiddleware($this->twoFactorManager, $this->userSession, $this->session, $this->urlGenerator, new MiddlewareUtils($this->reflector, $this->logger), $this->request);
|
||||
$this->middleware = new TwoFactorMiddleware($this->twoFactorManager, $this->userSession, $this->session, $this->urlGenerator, $this->reflector, $this->request);
|
||||
}
|
||||
|
||||
public function testBeforeControllerNotLoggedIn(): void {
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class DispatcherTest extends \Test\TestCase {
|
|||
|
||||
$this->request = $this->createMock(Request::class);
|
||||
|
||||
$this->reflector = new ControllerMethodReflector();
|
||||
$this->reflector = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
|
||||
$this->dispatcher = new Dispatcher(
|
||||
$this->http,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class BruteForceMiddlewareTest extends TestCase {
|
|||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->reflector = new ControllerMethodReflector();
|
||||
$this->reflector = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$this->throttler = $this->createMock(IThrottler::class);
|
||||
$this->request = $this->createMock(IRequest::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class CORSMiddlewareTest extends \Test\TestCase {
|
|||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->reflector = new ControllerMethodReflector();
|
||||
$this->reflector = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$this->session = $this->createMock(Session::class);
|
||||
$this->throttler = $this->createMock(IThrottler::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
|
|
@ -79,6 +79,7 @@ class CORSMiddlewareTest extends \Test\TestCase {
|
|||
$this->createMock(IRequestId::class),
|
||||
$this->createMock(IConfig::class)
|
||||
);
|
||||
$this->reflector->reflect($this->controller, __FUNCTION__);
|
||||
$middleware = new CORSMiddleware($request, new MiddlewareUtils($this->reflector, $this->logger), $this->session, $this->throttler);
|
||||
|
||||
$response = $middleware->afterController($this->controller, __FUNCTION__, new Response());
|
||||
|
|
@ -300,6 +301,7 @@ class CORSMiddlewareTest extends \Test\TestCase {
|
|||
$this->createMock(IRequestId::class),
|
||||
$this->createMock(IConfig::class)
|
||||
);
|
||||
$this->reflector->reflect($this->controller, __FUNCTION__);
|
||||
$middleware = new CORSMiddleware($request, new MiddlewareUtils($this->reflector, $this->logger), $this->session, $this->throttler);
|
||||
$response = $middleware->afterException($this->controller, __FUNCTION__, new SecurityException('A security exception'));
|
||||
|
||||
|
|
@ -316,6 +318,7 @@ class CORSMiddlewareTest extends \Test\TestCase {
|
|||
$this->createMock(IRequestId::class),
|
||||
$this->createMock(IConfig::class)
|
||||
);
|
||||
$this->reflector->reflect($this->controller, __FUNCTION__);
|
||||
$middleware = new CORSMiddleware($request, new MiddlewareUtils($this->reflector, $this->logger), $this->session, $this->throttler);
|
||||
$response = $middleware->afterException($this->controller, __FUNCTION__, new SecurityException('A security exception', 501));
|
||||
|
||||
|
|
@ -335,6 +338,7 @@ class CORSMiddlewareTest extends \Test\TestCase {
|
|||
$this->createMock(IRequestId::class),
|
||||
$this->createMock(IConfig::class)
|
||||
);
|
||||
$this->reflector->reflect($this->controller, __FUNCTION__);
|
||||
$middleware = new CORSMiddleware($request, new MiddlewareUtils($this->reflector, $this->logger), $this->session, $this->throttler);
|
||||
$middleware->afterException($this->controller, __FUNCTION__, new \Exception('A regular exception'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
|
|||
private Manager $userManager;
|
||||
|
||||
protected function setUp(): void {
|
||||
$this->reflector = new ControllerMethodReflector();
|
||||
$this->reflector = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$this->session = $this->createMock(ISession::class);
|
||||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
$this->user = $this->createMock(IUser::class);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class RateLimitingMiddlewareTest extends TestCase {
|
|||
|
||||
$this->request = $this->createMock(IRequest::class);
|
||||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
$this->reflector = new ControllerMethodReflector();
|
||||
$this->reflector = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$this->limiter = $this->createMock(Limiter::class);
|
||||
$this->session = $this->createMock(ISession::class);
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
|
|
|
|||
|
|
@ -61,8 +61,9 @@ class SameSiteCookieMiddlewareTest extends TestCase {
|
|||
$this->request->method('getScriptName')
|
||||
->willReturn('/index.php');
|
||||
|
||||
$this->reflector->method('hasAnnotation')
|
||||
->with('NoSameSiteCookieRequired')
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->with('NoSameSiteCookieRequired', NoSameSiteCookieRequired::class)
|
||||
->willReturn(true);
|
||||
|
||||
$this->middleware->beforeController(new HasAnnotationController('foo', $this->request), 'foo');
|
||||
|
|
@ -73,8 +74,9 @@ class SameSiteCookieMiddlewareTest extends TestCase {
|
|||
$this->request->method('getScriptName')
|
||||
->willReturn('/index.php');
|
||||
|
||||
$this->reflector->method('hasAnnotation')
|
||||
->with('NoSameSiteCookieRequired')
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->with('NoSameSiteCookieRequired', NoSameSiteCookieRequired::class)
|
||||
->willReturn(false);
|
||||
|
||||
$this->request->method('passesLaxCookieCheck')
|
||||
|
|
@ -90,8 +92,9 @@ class SameSiteCookieMiddlewareTest extends TestCase {
|
|||
$this->request->method('getScriptName')
|
||||
->willReturn('/index.php');
|
||||
|
||||
$this->reflector->method('hasAnnotation')
|
||||
->with('NoSameSiteCookieRequired')
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->with('NoSameSiteCookieRequired', NoSameSiteCookieRequired::class)
|
||||
->willReturn(false);
|
||||
|
||||
$this->request->method('passesLaxCookieCheck')
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class SecurityMiddlewareTest extends \Test\TestCase {
|
|||
'test',
|
||||
$this->request
|
||||
);
|
||||
$this->reader = new ControllerMethodReflector();
|
||||
$this->reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->navigationManager = $this->createMock(INavigationManager::class);
|
||||
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
||||
|
|
@ -433,6 +433,7 @@ class SecurityMiddlewareTest extends \Test\TestCase {
|
|||
->willReturn(true);
|
||||
|
||||
$controller = new $controllerClass('test', $this->request);
|
||||
$this->reader->reflect($controller, 'foo');
|
||||
|
||||
try {
|
||||
$this->middleware->beforeController($controller, 'foo');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace Test\AppFramework\Middleware;
|
|||
use OC\AppFramework\Middleware\SessionMiddleware;
|
||||
use OC\AppFramework\Utility\ControllerMethodReflector;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\UseSession;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IRequest;
|
||||
use OCP\ISession;
|
||||
|
|
@ -19,8 +20,8 @@ use Test\AppFramework\Middleware\Mock\UseSessionController;
|
|||
use Test\TestCase;
|
||||
|
||||
class SessionMiddlewareTest extends TestCase {
|
||||
private ControllerMethodReflector|MockObject $reflector;
|
||||
private ISession|MockObject $session;
|
||||
private ControllerMethodReflector&MockObject $reflector;
|
||||
private ISession&MockObject $session;
|
||||
private Controller $controller;
|
||||
private SessionMiddleware $middleware;
|
||||
|
||||
|
|
@ -39,70 +40,39 @@ class SessionMiddlewareTest extends TestCase {
|
|||
public function testSessionNotClosedOnBeforeController(): void {
|
||||
$this->configureSessionMock(0, 1);
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotation')
|
||||
->with('UseSession')
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->with('UseSession', UseSession::class)
|
||||
->willReturn(true);
|
||||
|
||||
$this->middleware->beforeController($this->controller, 'withAnnotation');
|
||||
}
|
||||
|
||||
public function testSessionNotClosedOnBeforeControllerWithAttribute(): void {
|
||||
$this->configureSessionMock(0, 1);
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotation')
|
||||
->with('UseSession')
|
||||
->willReturn(false);
|
||||
|
||||
$this->middleware->beforeController($this->controller, 'withAttribute');
|
||||
}
|
||||
|
||||
public function testSessionClosedOnAfterController(): void {
|
||||
$this->configureSessionMock(1);
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotation')
|
||||
->with('UseSession')
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->with('UseSession', UseSession::class)
|
||||
->willReturn(true);
|
||||
|
||||
$this->middleware->afterController($this->controller, 'withAnnotation', new Response());
|
||||
}
|
||||
|
||||
public function testSessionClosedOnAfterControllerWithAttribute(): void {
|
||||
$this->configureSessionMock(1);
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotation')
|
||||
->with('UseSession')
|
||||
->willReturn(true);
|
||||
|
||||
$this->middleware->afterController($this->controller, 'withAttribute', new Response());
|
||||
}
|
||||
|
||||
public function testSessionReopenedAndClosedOnBeforeController(): void {
|
||||
$this->configureSessionMock(1, 1);
|
||||
$this->reflector->expects(self::exactly(2))
|
||||
->method('hasAnnotation')
|
||||
->with('UseSession')
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->with('UseSession', UseSession::class)
|
||||
->willReturn(true);
|
||||
|
||||
$this->middleware->beforeController($this->controller, 'withAnnotation');
|
||||
$this->middleware->afterController($this->controller, 'withAnnotation', new Response());
|
||||
}
|
||||
|
||||
public function testSessionReopenedAndClosedOnBeforeControllerWithAttribute(): void {
|
||||
$this->configureSessionMock(1, 1);
|
||||
$this->reflector->expects(self::exactly(2))
|
||||
->method('hasAnnotation')
|
||||
->with('UseSession')
|
||||
->willReturn(false);
|
||||
|
||||
$this->middleware->beforeController($this->controller, 'withAttribute');
|
||||
$this->middleware->afterController($this->controller, 'withAttribute', new Response());
|
||||
}
|
||||
|
||||
public function testSessionClosedOnBeforeController(): void {
|
||||
$this->configureSessionMock(0);
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotation')
|
||||
->with('UseSession')
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->with('UseSession', UseSession::class)
|
||||
->willReturn(false);
|
||||
|
||||
$this->middleware->beforeController($this->controller, 'without');
|
||||
|
|
@ -111,8 +81,8 @@ class SessionMiddlewareTest extends TestCase {
|
|||
public function testSessionNotClosedOnAfterController(): void {
|
||||
$this->configureSessionMock(0);
|
||||
$this->reflector->expects(self::once())
|
||||
->method('hasAnnotation')
|
||||
->with('UseSession')
|
||||
->method('hasAnnotationOrAttribute')
|
||||
->with('UseSession', UseSession::class)
|
||||
->willReturn(false);
|
||||
|
||||
$this->middleware->afterController($this->controller, 'without', new Response());
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
namespace Test\AppFramework\Utility;
|
||||
|
||||
use OC\AppFramework\Utility\ControllerMethodReflector;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class BaseController {
|
||||
/**
|
||||
|
|
@ -69,7 +70,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
* @Annotation
|
||||
*/
|
||||
public function testReadAnnotation(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
'\Test\AppFramework\Utility\ControllerMethodReflectorTest',
|
||||
'testReadAnnotation'
|
||||
|
|
@ -82,7 +83,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
* @Annotation(parameter=value)
|
||||
*/
|
||||
public function testGetAnnotationParameterSingle(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
self::class,
|
||||
__FUNCTION__
|
||||
|
|
@ -95,7 +96,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
* @Annotation(parameter1=value1, parameter2=value2,parameter3=value3)
|
||||
*/
|
||||
public function testGetAnnotationParameterMultiple(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
self::class,
|
||||
__FUNCTION__
|
||||
|
|
@ -111,7 +112,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
* @param test
|
||||
*/
|
||||
public function testReadAnnotationNoLowercase(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
'\Test\AppFramework\Utility\ControllerMethodReflectorTest',
|
||||
'testReadAnnotationNoLowercase'
|
||||
|
|
@ -127,7 +128,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
* @param int $test
|
||||
*/
|
||||
public function testReadTypeIntAnnotations(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
'\Test\AppFramework\Utility\ControllerMethodReflectorTest',
|
||||
'testReadTypeIntAnnotations'
|
||||
|
|
@ -145,7 +146,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
public function testReadTypeIntAnnotationsScalarTypes(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
'\Test\AppFramework\Utility\ControllerMethodReflectorTest',
|
||||
'arguments3'
|
||||
|
|
@ -163,7 +164,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
* @param double $test something special
|
||||
*/
|
||||
public function testReadTypeDoubleAnnotations(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
'\Test\AppFramework\Utility\ControllerMethodReflectorTest',
|
||||
'testReadTypeDoubleAnnotations'
|
||||
|
|
@ -177,7 +178,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
* @param string $foo
|
||||
*/
|
||||
public function testReadTypeWhitespaceAnnotations(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
'\Test\AppFramework\Utility\ControllerMethodReflectorTest',
|
||||
'testReadTypeWhitespaceAnnotations'
|
||||
|
|
@ -190,7 +191,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
public function arguments($arg, $arg2 = 'hi') {
|
||||
}
|
||||
public function testReflectParameters(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
'\Test\AppFramework\Utility\ControllerMethodReflectorTest',
|
||||
'arguments'
|
||||
|
|
@ -203,7 +204,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
public function arguments2($arg) {
|
||||
}
|
||||
public function testReflectParameters2(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect(
|
||||
'\Test\AppFramework\Utility\ControllerMethodReflectorTest',
|
||||
'arguments2'
|
||||
|
|
@ -214,7 +215,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
|
||||
|
||||
public function testInheritance(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect('Test\AppFramework\Utility\EndController', 'test');
|
||||
|
||||
$this->assertTrue($reader->hasAnnotation('Annotation'));
|
||||
|
|
@ -222,7 +223,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
|
||||
|
||||
public function testInheritanceOverride(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect('Test\AppFramework\Utility\EndController', 'test2');
|
||||
|
||||
$this->assertTrue($reader->hasAnnotation('NoAnnotation'));
|
||||
|
|
@ -231,14 +232,14 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
|
||||
|
||||
public function testInheritanceOverrideNoDocblock(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect('Test\AppFramework\Utility\EndController', 'test3');
|
||||
|
||||
$this->assertFalse($reader->hasAnnotation('Annotation'));
|
||||
}
|
||||
|
||||
public function testRangeDetectionPsalm(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect('Test\AppFramework\Utility\EndController', 'test4');
|
||||
|
||||
$rangeInfo1 = $reader->getRange('rangedOne');
|
||||
|
|
@ -259,7 +260,7 @@ class ControllerMethodReflectorTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
public function testRangeDetectionNative(): void {
|
||||
$reader = new ControllerMethodReflector();
|
||||
$reader = new ControllerMethodReflector(\OCP\Server::get(LoggerInterface::class));
|
||||
$reader->reflect('Test\AppFramework\Utility\EndController', 'test5');
|
||||
|
||||
$rangeInfo1 = $reader->getRange('rangedOne');
|
||||
|
|
|
|||
Loading…
Reference in a new issue