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
Security policy implementation #3465
Conversation
Deprecate IAuthenticationPolicy and IAuthorizationPolicy.
Also mark authn/authz as deprecatd.
b7b2223
to
a6234e4
Compare
Please include a signed |
70fa2c1
to
f1709eb
Compare
Deleted AuthorizationAPIMixin
Some tests still need fixing.
This breaks some more tests.
Security policies are working! Please review. Tests are passing locally, but it doesn't look like CI got triggered? Test coverage is 100% except for this line. Looks like it's from the repoze.bfg days. Still necessary in Pyramid 2.0, or can I delete it? I think I should add an integration test for security policies and legacy policies. Also update the other integration tests to use security policies. I still need to implement built-in policies and helpers, which hasn't been discussed much:
|
The issue with shipping security policy classes is that they tie together a lot of decisions into one class. We should not add any without first having the building blocks and at least testing out the class in the existing tutorial (probably in the wiki2 tutorial like https://docs.pylonsproject.org/projects/pyramid/en/1.10-branch/tutorials/wiki2/authentication.html). |
Mixins work for some things but we're actively trying to reduce the usage of things like the |
I added a bullet for deprecations. Anywhere that you're putting into the docs that something is deprecated should be followed by calls to |
Related to my question above, I realize Other than that, I've reviewed the code and everything looks good AFAICT. Please review yourselves and let me know if anything needs to change. |
I need this PR to land and a new release of Pyramid, like yesterday ;-) This would solve some problems I am currently working on. I'll review in a second, but changing "userid" to "identity" may make sense, but I'd like @mmerickel's opinion on that. |
I think the api for remember/forget should remain a userid and not an opaque object. The identity object is opaque and is meant for exposing data to permits but there's no standard way to load one outside of the policy in order to pass it in. I think |
Since we're still using userid, should I undo the deprecation of |
@luhn that’s my feeling right now. Definitely open to alternative opinions though. I think it’s important to maintain a bidirectional identifier for the authenticated payload maintained by the policy. |
Done! |
I confirmed over the weekend that some $work apps continue to function unchanged using this branch which is great. I'm planning to get into the rest of the details more this week and try to get this merged. |
Co-Authored-By: Michael Merickel <github@m.merickel.org>
Co-Authored-By: Michael Merickel <github@m.merickel.org>
Thanks @mmerickel! I've applied the suggestions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luhn can you do me a tiny favor and rename this PR to remove the WIP just to make sure you're happy with things before I merge? |
👍 |
Excited to see this merged! Thanks to everyone for working with me on this. Cheers! 🍻 |
identity | ||
An identity is an object identifying the user associated with the | ||
current request. The identity can be any object, but should implement a | ||
``__str__`` method that outputs a corresponding :term:`userid`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! Sorry to comment after this is merged, but I was following the issue and not aware of this PR.
I don’t understand the reason for using __str__
as the method to convert Identity to user ID.
__str__
is meant to control what happens withprint
,%s
formatting, etc.- IMO it is good practice to have
__str__
fast, without side effects, without possibility of failure (so no parsing, casting, etc) repr
uses__str__
if the class doesn’t define__repr__
- REPL, logging, others use repr or str, so seeing something that’s a user ID instead of custom str/repr output (like
<SomeIdentityClass id=blah source=value>
) in debug logs, etc. could make inspection harder - depending on the system, user ID may not be a string
- calling
str(identity)
instead ofidentity.some_explicit_method()
seems a bit obscure (not discoverable)
If people agree with the disadvantages here, could this API decision be reconsidered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a discussion I'm happy to have. I'm not in love with __str__
myself. I'd ask that since this is merged we open a new issue to talk about it though, instead of here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are 2 good options that come to my mind: either return storable_id, IdentityClass
tuple or have another function in the policy that derives the serializable id from the identity class...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's been some discussion on this, I dug up what I could find:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened an issue over at #3520
object representing the user associated with the current request. The identity | ||
can be accessed via :attr:`pyramid.request.Request.authenticated_identity`. | ||
The object can be of any shape, such as a simple ID string or an ORM object, | ||
but should implement a ``__str__`` method that outputs a string identifying the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: using outputs
here (and other parts of this PR) could be misleading (does it mean print
?), compared to returns
if authn is not None: | ||
return authn.authenticated_userid(self) | ||
elif security is not None: | ||
return str(security.identify(self)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luhn can I ask why this method checks old-style authn policy before security policy?
The other methods in the mixin only work with security policy, without falling back on (or checking first!) an authentication policy.
Is there a goal to support a config with security policy + authentication policy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually we just let LegacySecurityPolicy handle the bw compat, but in this case we need to circumvent the str(security.identify(self))
, otherwise we'd be changing the behavior of the legacy method.
Now that str(identity)
is out and authenticated_userid is back, we should be able to just reference the security policy and let LegacySecurityPolicy work its magic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! ✨
|
||
``hashalg`` | ||
|
||
Default: ``sha512`` (the literal string). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noticed today that the actual default is md5
: https://github.com/Pylons/pyramid/pull/3465/files#diff-00f789cd007443672848b9eb23973a86R861
Ping @mmerickel this could be changed in your doc PR too? Fix the default to match the doc (as this is a new class for Pyramid 2), then the docs examples can remove the explicit hashalg
parameter!
For the backward-compatible authn policy, its constructor could be kept to md5
(if that is indeed the previous behaviour).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this class is not new.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't believe we forgot to fix it when we changed it on the policy. I'm changing it now and we'll just release a deprecation in 1.10.5.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright then I should send a doc PR for 1.x / stable branch?
(not sure how many versions of Pyramid are maintained and how backports work)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did it yesterday in #3558
These are significant changes! |
@invisibleroads you can continue to use existing auth policy stuff, too. See the What's New in Pyramid 2.0 document for details in the blue box. |
Pyramid 2.0 is big news. I am very happy to see that Pyramid is still very alive after 10+ years thanks to lots of work from all of you. |
ISecurityPolicy
Configurator.set_security_policy
DeprecationWarning
/zope.deprecation
Closes #3422