-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathapp5.py
More file actions
executable file
·110 lines (102 loc) · 4.51 KB
/
Copy pathapp5.py
File metadata and controls
executable file
·110 lines (102 loc) · 4.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env python
from pyramid.response import Response
from pyramid.view import view_config
from pyramid.config import Configurator
from pyramid.security import Allow, Authenticated, remember, forget
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from waitress import serve
class BlogentryViews(object):
def __init__(self, request):
self.request = request
@view_config(route_name='blogentry_show')
def show(self):
return Response('Shown')
@view_config(route_name='blogentry_delete',
permission='delete')
def delete(self):
return Response('Deleted')
@view_config(route_name='login')
def login(self):
userid = self.request.params.get('userid')
headers = remember(self.request, userid)
return Response(
'Logged in as %s' % userid,
headers=headers
)
@view_config(route_name='logout')
def logout(self):
headers = forget(self.request)
return Response(
'Logged out',
headers=headers
)
# [2]
class RootFactory(object):
def __init__(self, request):
self.__acl__ = [(Allow, Authenticated, 'delete')]
if __name__ == '__main__':
authn_policy = AuthTktAuthenticationPolicy('soseekrit')
authz_policy = ACLAuthorizationPolicy()
# [1]
config = Configurator(
root_factory=RootFactory,
authentication_policy=authn_policy,
authorization_policy=authz_policy
)
config.add_route('blogentry_show', '/blog/{id}')
config.add_route('blogentry_delete', '/blog/{id}/delete')
config.add_route('login', '/login')
config.add_route('logout', '/logout')
config.scan()
app = config.make_wsgi_app()
serve(app)
# Exactly the same as app2.py, app3.py, and app4.py. Basic security; only
# authenticated users can delete blog entries. all others can view blog
# entries.
#
# New features:
#
# [1] We use Pyramid's ACLAuthorizationPolicy instead of our homebrewed
# DumbAuthorizationPolicy. We now pass a "root factory" into our
# configurator. Our ACLAuthorizationPolicy will use instances
# of objects produced by this root factory to determine whether or
# not someone is permitted to execute a view.
# [2] We supply a "RootFactory" class. Instances of this class possess an
# ACL (as ``__acl__``). ACL stands for "Access Control List".
#
# Noteworthy:
#
# - This step is typically where people's brains start to steam. It's
# because we've added yet another layer of abstraction by using the
# ACLAuthorizationPolicy. This abstraction requires us to understand this
# "root factory" thing and what the policy does with the "root" it produces.
#
# - The root object produced by the root factory is a "resource". You can
# think of a resource as a security context. It's called "root" because it's
# presumed that there will be some number of resources arranged in a tree
# with the object produced by the root factory at the root of the resource
# tree. In the above application the root object has no children, so it's
# the *only* resource that the system ever sees when the application is run.
# More complex authorization requirements can make use of children.
#
# - Every authorization policy is passed a *context* argument to its
# ``permits`` method. This argument will be a resource. Our
# DumbAuthorizationPolicy ignored this argument. The ACLAuthorizationPolicy
# does not; it uses the values in the ``__acl__`` attribute of the resource
# its passed to determine whether the user possesses the permission relative
# to this view execution.
#
# - An ACL is an access control list. It is a sequence of ACEs (access control
# entries). ``(Allow, Authenticated, 'edit')`` means Allow people who
# possess the Authenticated principal (you can think of it as a group) to
# edit. Only users who are explicitly allowed a permission in an ACL (by
# mention of their userid or any group they're in such as "Authenticated")
# will be permitted to execute a view protected by that permission.
#
# - The benefit of all this indirection: we no longer own any imperative code
# which does authorization or authentication. Our application uses entirely
# declarative stuff to protect view execution. We only add ACLs and
# permissions, and we have no conditions in our code. Declarative code
# requires less testing, and you can typically be surer of the result as long
# as you understand the abstraction.