Skip to content

Commit f8dcc4a

Browse files
lysylorenasvetlov
authored andcommitted
Rewrite 'simple example' in docs, added it to demo dir (#154)
1 parent 27ffe6d commit f8dcc4a

File tree

2 files changed

+182
-56
lines changed

2 files changed

+182
-56
lines changed

demo/simple_example_auth.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from aiohttp import web
2+
from aiohttp_session import SimpleCookieStorage, session_middleware
3+
from aiohttp_security import has_permission, \
4+
is_anonymous, remember, forget, \
5+
setup as setup_security, SessionIdentityPolicy
6+
from aiohttp_security.abc import AbstractAuthorizationPolicy
7+
8+
9+
# Demo authorization policy for only one user.
10+
# User 'jack' has only 'listen' permission.
11+
# For more complicated authorization policies see examples
12+
# in the 'demo' directory.
13+
class SimpleJack_AuthorizationPolicy(AbstractAuthorizationPolicy):
14+
async def authorized_userid(self, identity):
15+
"""Retrieve authorized user id.
16+
Return the user_id of the user identified by the identity
17+
or 'None' if no user exists related to the identity.
18+
"""
19+
if identity == 'jack':
20+
return identity
21+
22+
async def permits(self, identity, permission, context=None):
23+
"""Check user permissions.
24+
Return True if the identity is allowed the permission
25+
in the current context, else return False.
26+
"""
27+
return identity == 'jack' and permission in ('listen',)
28+
29+
30+
async def handler_root(request):
31+
is_logged = not await is_anonymous(request)
32+
return web.Response(text='''<html><head></head><body>
33+
Hello, I'm Jack, I'm {logged} logged in.<br /><br />
34+
<a href="/login">Log me in</a><br />
35+
<a href="/logout">Log me out</a><br /><br />
36+
Check my permissions,
37+
when i'm logged in and logged out.<br />
38+
<a href="/listen">Can I listen?</a><br />
39+
<a href="/speak">Can I speak?</a><br />
40+
</body></html>'''.format(
41+
logged='' if is_logged else 'NOT',
42+
), content_type='text/html')
43+
44+
45+
async def handler_login_jack(request):
46+
redirect_response = web.HTTPFound('/')
47+
await remember(request, redirect_response, 'jack')
48+
raise redirect_response
49+
50+
51+
async def handler_logout(request):
52+
redirect_response = web.HTTPFound('/')
53+
await forget(request, redirect_response)
54+
raise redirect_response
55+
56+
57+
@has_permission('listen')
58+
async def handler_listen(request):
59+
return web.Response(body="I can listen!")
60+
61+
62+
@has_permission('speak')
63+
async def handler_speak(request):
64+
return web.Response(body="I can speak!")
65+
66+
67+
async def make_app():
68+
#
69+
# WARNING!!!
70+
# Never use SimpleCookieStorage on production!!!
71+
# It’s highly insecure!!!
72+
#
73+
74+
# make app
75+
middleware = session_middleware(SimpleCookieStorage())
76+
app = web.Application(middlewares=[middleware])
77+
78+
# add the routes
79+
app.router.add_route('GET', '/', handler_root)
80+
app.router.add_route('GET', '/login', handler_login_jack)
81+
app.router.add_route('GET', '/logout', handler_logout)
82+
app.router.add_route('GET', '/listen', handler_listen)
83+
app.router.add_route('GET', '/speak', handler_speak)
84+
85+
# set up policies
86+
policy = SessionIdentityPolicy()
87+
setup_security(app, policy, SimpleJack_AuthorizationPolicy())
88+
89+
return app
90+
91+
92+
if __name__ == '__main__':
93+
web.run_app(make_app(), port=9000)

docs/example.rst

Lines changed: 89 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,63 +7,96 @@ How to Make a Simple Server With Authorization
77

88
Simple example::
99

10-
import asyncio
1110
from aiohttp import web
11+
from aiohttp_session import SimpleCookieStorage, session_middleware
12+
from aiohttp_security import has_permission, \
13+
is_anonymous, remember, forget, \
14+
setup as setup_security, SessionIdentityPolicy
15+
from aiohttp_security.abc import AbstractAuthorizationPolicy
1216

13-
async def root_handler(request):
14-
text = "Alive and kicking!"
15-
return web.Response(body=text.encode('utf-8'))
16-
17-
# option 2: auth at a higher level?
18-
# set user_id and allowed in the wsgi handler
19-
@protect('view_user')
20-
async def user_handler(request):
21-
name = request.match_info.get('name', "Anonymous")
22-
text = "Hello, " + name
23-
return web.Response(body=text.encode('utf-8'))
24-
25-
26-
# option 3: super low
27-
# wsgi doesn't do anything
28-
async def user_update_handler(request):
29-
# identity, asked_permission
30-
user_id = await identity_policy.identify(request)
31-
identity = await auth_policy.authorized_userid(user_id)
32-
allowed = await request.auth_policy.permits(
33-
identity, asked_permission)
34-
if not allowed:
35-
# how is this pluggable as well?
36-
# ? return NotAllowedStream()
37-
raise NotAllowedResponse()
38-
39-
update_user()
40-
41-
async def init(loop):
42-
# set up identity and auth
43-
auth_policy = DictionaryAuthorizationPolicy({'me': ('view_user',),
44-
'you': ('view_user',
45-
'edit_user',)})
46-
identity_policy = CookieIdentityPolicy()
47-
auth = authorization_middleware(auth_policy, identity_policy)
48-
49-
# wsgi app
50-
app = web.Application(loop=loop, middlewares=*auth)
17+
18+
# Demo authorization policy for only one user.
19+
# User 'jack' has only 'listen' permission.
20+
# For more complicated authorization policies see examples
21+
# in the 'demo' directory.
22+
class SimpleJack_AuthorizationPolicy(AbstractAuthorizationPolicy):
23+
async def authorized_userid(self, identity):
24+
"""Retrieve authorized user id.
25+
Return the user_id of the user identified by the identity
26+
or 'None' if no user exists related to the identity.
27+
"""
28+
if identity == 'jack':
29+
return identity
30+
31+
async def permits(self, identity, permission, context=None):
32+
"""Check user permissions.
33+
Return True if the identity is allowed the permission
34+
in the current context, else return False.
35+
"""
36+
return identity == 'jack' and permission in ('listen',)
37+
38+
39+
async def handler_root(request):
40+
is_logged = not await is_anonymous(request)
41+
return web.Response(text='''<html><head></head><body>
42+
Hello, I'm Jack, I'm {logged} logged in.<br /><br />
43+
<a href="/login">Log me in</a><br />
44+
<a href="/logout">Log me out</a><br /><br />
45+
Check my permissions,
46+
when i'm logged in and logged out.<br />
47+
<a href="/listen">Can I listen?</a><br />
48+
<a href="/speak">Can I speak?</a><br />
49+
</body></html>'''.format(
50+
logged='' if is_logged else 'NOT',
51+
), content_type='text/html')
52+
53+
54+
async def handler_login_jack(request):
55+
redirect_response = web.HTTPFound('/')
56+
await remember(request, redirect_response, 'jack')
57+
raise redirect_response
58+
59+
60+
async def handler_logout(request):
61+
redirect_response = web.HTTPFound('/')
62+
await forget(request, redirect_response)
63+
raise redirect_response
64+
65+
66+
@has_permission('listen')
67+
async def handler_listen(request):
68+
return web.Response(body="I can listen!")
69+
70+
71+
@has_permission('speak')
72+
async def handler_speak(request):
73+
return web.Response(body="I can speak!")
74+
75+
76+
async def make_app():
77+
#
78+
# WARNING!!!
79+
# Never use SimpleCookieStorage on production!!!
80+
# It’s highly insecure!!!
81+
#
82+
83+
# make app
84+
middleware = session_middleware(SimpleCookieStorage())
85+
app = web.Application(middlewares=[middleware])
5186

5287
# add the routes
53-
app.router.add_route('GET', '/', root_handler)
54-
app.router.add_route('GET', '/{user}', user_handler)
55-
app.router.add_route('GET', '/{user}/edit', user_update_handler)
56-
57-
# get it started
58-
srv = await loop.create_server(app.make_handler(),
59-
'127.0.0.1', 8080)
60-
print("Server started at http://127.0.0.1:8080")
61-
return srv
62-
63-
64-
loop = asyncio.get_event_loop()
65-
loop.run_until_complete(init(loop))
66-
try:
67-
loop.run_forever()
68-
except KeyboardInterrupt:
69-
pass # TODO put handler cleanup here
88+
app.router.add_route('GET', '/', handler_root)
89+
app.router.add_route('GET', '/login', handler_login_jack)
90+
app.router.add_route('GET', '/logout', handler_logout)
91+
app.router.add_route('GET', '/listen', handler_listen)
92+
app.router.add_route('GET', '/speak', handler_speak)
93+
94+
# set up policies
95+
policy = SessionIdentityPolicy()
96+
setup_security(app, policy, SimpleJack_AuthorizationPolicy())
97+
98+
return app
99+
100+
101+
if __name__ == '__main__':
102+
web.run_app(make_app(), port=9000)

0 commit comments

Comments
 (0)