Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a getAttributes to IControllerMethodReflector #37279

Closed

Conversation

nickvergessen
Copy link
Member

As discussed in #36928 (comment)

Looking at the diff, I'm not sure it's worth it.

Checklist

Signed-off-by: Joas Schilling <coding@schilljs.com>
@ChristophWurst
Copy link
Member

I'm on the fence here. It's a small enhancement in all fairness.

@@ -69,15 +68,11 @@
$action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action');
$this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $action);
} else {
$reflectionMethod = new ReflectionMethod($controller, $methodName);
$attributes = $reflectionMethod->getAttributes(BruteForceProtection::class);
$attributes = $this->reflector->getAttributes(BruteForceProtection::class);

Check failure

Code scanning / Psalm

InvalidArgument

Argument 1 of OC\AppFramework\Utility\ControllerMethodReflector::getAttributes expects class-string<Attribute>, but OCP\AppFramework\Http\Attribute\BruteForceProtection::class provided
@@ -96,16 +91,13 @@
$this->throttler->sleepDelay($ip, $action);
$this->throttler->registerAttempt($action, $ip, $response->getThrottleMetadata());
} else {
$reflectionMethod = new ReflectionMethod($controller, $methodName);
$attributes = $reflectionMethod->getAttributes(BruteForceProtection::class);
$attributes = $this->reflector->getAttributes(BruteForceProtection::class);

Check failure

Code scanning / Psalm

InvalidArgument

Argument 1 of OC\AppFramework\Utility\ControllerMethodReflector::getAttributes expects class-string<Attribute>, but OCP\AppFramework\Http\Attribute\BruteForceProtection::class provided
@@ -63,8 +62,7 @@
return;
}

$reflectionMethod = new ReflectionMethod($controller, $methodName);
$hasAttribute = !empty($reflectionMethod->getAttributes(UseSession::class));
$hasAttribute = !empty($this->reflector->getAttributes(UseSession::class));

Check failure

Code scanning / Psalm

InvalidArgument

Argument 1 of OC\AppFramework\Utility\ControllerMethodReflector::getAttributes expects class-string<Attribute>, but OCP\AppFramework\Http\Attribute\UseSession::class provided
@@ -86,8 +84,7 @@
return $response;
}

$reflectionMethod = new ReflectionMethod($controller, $methodName);
$hasAttribute = !empty($reflectionMethod->getAttributes(UseSession::class));
$hasAttribute = !empty($this->reflector->getAttributes(UseSession::class));

Check failure

Code scanning / Psalm

InvalidArgument

Argument 1 of OC\AppFramework\Utility\ControllerMethodReflector::getAttributes expects class-string<Attribute>, but OCP\AppFramework\Http\Attribute\UseSession::class provided
use OCP\AppFramework\Utility\IControllerMethodReflector;

/**
* Reads and parses annotations from doc comments
*/
class ControllerMethodReflector implements IControllerMethodReflector {

protected ?\ReflectionMethod $reflection;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be more specific because exist other types of reflections:

Suggested change
protected ?\ReflectionMethod $reflection;
protected ?\ReflectionMethod $reflectionMethod;

Copy link
Contributor

@come-nc come-nc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I like it

@@ -138,4 +141,18 @@ public function getAnnotationParameter(string $name, string $key): string {

return '';
}

/**
* @template T of Attribute
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attribute classes do not extend Attribute class, which is final. So you cannot do that.

@ChristophWurst
Copy link
Member

Subjectively what I don't like about the controller method reflector is that is so stateful. There are two methods to work with it. One analyzes a controller method, another one allows you to test for specific attributes. It sounds a bit artificial but there is no guarantee that at the point of asking for an attribute, nobody else called the reflect method.

In that sense, and with the way PHP reflection works anyway, I would prefer to make the service stateless and pass the controller object and method name into hasAttribute. It ensures that the result you get is only based on what you pass it, not what someone called before.

This remark is not new with attributes. The problem was there with annotations as well. It is just that parsing phpdoc annotations is expensive and there the state for caching makes sense for better performance.

@nickvergessen
Copy link
Member Author

Exactly my thoughts after seeing the resulting PR.
So also tend to close it now and continue as before

@nickvergessen nickvergessen marked this pull request as draft March 20, 2023 11:08
@nickvergessen nickvergessen deleted the techdebt/noid/bruteforce-protection-attribute branch April 14, 2023 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants