-
Notifications
You must be signed in to change notification settings - Fork 1k
Refactor: Migrate to 2.0-style security policies #11218
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
Merged
Merged
Changes from 8 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
bba2796
warehouse: begin using security policies
woodruffw 7bc9904
Merge remote-tracking branch 'origin/main' into tob-pyramid-2-securit…
woodruffw 03ffbc3
Remove pyramid-multiauth, begin switching to security policies
woodruffw 6beb4dd
migrations: remove incorrectly checked in migrations
woodruffw 4efbccf
warehouse: fix principals a little bit
woodruffw 9da307d
warehouse: begin using real security policies
woodruffw 00afa6e
warehouse: port basic auth
woodruffw a211e35
warehouse: port macaroon policy, remove transition shim
woodruffw 1be99d8
utils/security_policy: fix principals
woodruffw 936b633
warehouse: fix lint
woodruffw 8f95b0e
tests/unit: rename-o-rama
woodruffw 090ef01
Improve the readabililty of the overall diff
di 0b788d9
warehouse: refactor security policies
woodruffw 0bc2083
macaroons/security_policy: remove redundant route check
woodruffw 8f858e3
Merge remote-tracking branch 'upstream/main' into tob-pyramid-2-secur…
woodruffw 231a46d
accounts/security_policy: lint
woodruffw e2242ec
Update warehouse/utils/security_policy.py
woodruffw 5cdb53a
macaroons/security_policy: avoid a DB roundtrip
woodruffw 593d199
utils/security_policy: simplify principals, add comment
woodruffw 44d1463
utils/security_policy: re-add id principal
woodruffw 3e0c525
warehouse: disambiguate user IDs inside the principal set
woodruffw 366b5e3
Merge remote-tracking branch 'upstream/main' into tob-pyramid-2-secur…
woodruffw 6be5ae7
Merge remote-tracking branch 'upstream/main' into tob-pyramid-2-secur…
woodruffw 840c301
packaging/models: blacken
woodruffw 52c3120
tests, warehouse: the long and winding road
woodruffw 9c7f8cd
tests/packaging: fix ACL tests
woodruffw f4f608b
tests, warehouse: rewrite account security policy tests
woodruffw 5db0a10
macaroons: make the tests pass
woodruffw ab12fd3
tests: finish tests
woodruffw 29b40f9
warehouse: move session invalidation to session authn
woodruffw f2ee9e9
tests, warehouse: update tests
woodruffw 250a2a7
Merge remote-tracking branch 'upstream/main' into tob-pyramid-2-secur…
woodruffw 42f7beb
Merge remote-tracking branch 'upstream/main' into tob-pyramid-2-secur…
woodruffw 222b293
Merge remote-tracking branch 'upstream/main' into tob-pyramid-2-secur…
woodruffw ec2c563
utils/security_policy: authenticated_userid only works for user ident…
woodruffw 8cb31c8
tests: update utils/security_policy tests
woodruffw 6e6d039
Merge branch 'main' into tob-pyramid-2-security-policies
di File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from pyramid.authorization import Authenticated, Everyone | ||
from pyramid.interfaces import ISecurityPolicy | ||
from zope.interface import implementer | ||
|
||
from warehouse.accounts.interfaces import IUserService | ||
|
||
|
||
class SecurityPolicy: | ||
def __init__(self, callback=None): | ||
self._callback = callback | ||
|
||
def identity(self, request): | ||
woodruffw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
login_service = request.find_service(IUserService, context=None) | ||
user = login_service.get_user(self.unauthenticated_userid(request)) | ||
woodruffw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if user is None: | ||
return None | ||
|
||
principals = [] | ||
if self._callback is not None: | ||
principals = self._callback(user.id, request) | ||
if principals is None: | ||
return None | ||
|
||
return {"entity": user, "principals": principals} | ||
woodruffw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def permits(self, request, context, permission): | ||
return NotImplemented | ||
woodruffw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
@implementer(ISecurityPolicy) | ||
class MultiSecurityPolicy: | ||
""" | ||
A wrapper for multiple Pyramid 2.0-style "security policies", which replace | ||
Pyramid 1.0's separate AuthN and AuthZ APIs. | ||
|
||
Security policies are checked in the order provided during initialization, | ||
with the following semantics: | ||
|
||
* `identity`: Selected from the first policy to return non-`None` | ||
* `authenticated_userid`: Selected from the request identity, if present | ||
* `forget`: Combined from all policies | ||
* `remember`: Combined from all policies | ||
* `permits`: Uses the AuthZ policy passed during initialization | ||
|
||
These semantics mostly mirror those of `pyramid-multiauth`. | ||
""" | ||
|
||
def __init__(self, policies, authz): | ||
self._policies = policies | ||
self._authz = authz | ||
woodruffw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def identity(self, request): | ||
for policy in self._policies: | ||
if ident := policy.identity(request): | ||
return ident | ||
|
||
return None | ||
|
||
def authenticated_userid(self, request): | ||
if request.identity: | ||
return str(request.identity["entity"].id) | ||
return None | ||
|
||
def forget(self, request, **kw): | ||
headers = [] | ||
for policy in self._policies: | ||
headers.extend(policy.forget(request, **kw)) | ||
return headers | ||
|
||
def remember(self, request, userid, **kw): | ||
headers = [] | ||
for policy in self._policies: | ||
headers.extend(policy.remember(request, userid, **kw)) | ||
return headers | ||
|
||
def permits(self, request, context, permission): | ||
identity = request.identity | ||
principals = [Everyone] | ||
woodruffw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if identity is not None: | ||
principals.extend( | ||
[Authenticated, str(identity["entity"].id), identity["principals"]] | ||
) | ||
return self._authz.permits(context, principals, permission) | ||
woodruffw marked this conversation as resolved.
Show resolved
Hide resolved
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.