Skip to content

Commit 9b1d08c

Browse files
committed
Update to 0.3.0
1 parent 097f7ec commit 9b1d08c

23 files changed

+418
-177
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,5 @@ docs/_build/
5555
# PyBuilder
5656
target/
5757

58-
coverage
58+
coverage
59+
.pytest_cache

CHANGES.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
Changes
22
=======
33

4+
0.3.0 (2018-09-06)
5+
------------------
6+
7+
- Deprecate ``login_required`` and ``has_permission`` decorators.
8+
Use ``check_authorized`` and ``check_permission`` helper functions instead.
9+
10+
- Bump supported ``aiohttp`` version to 3.0+
11+
12+
- Enable strong warnings mode for test suite, clean-up all deprecation
13+
warnings.
14+
15+
- Polish documentation
16+
417
0.2.0 (2017-11-17)
518
------------------
619

7-
- Add `is_anonymous`, `login_required`, `has_permission` helpers (#114)
20+
- Add ``is_anonymous``, ``login_required``, ``has_permission`` helpers (#114)
821

922
0.1.2 (2017-10-17)
1023
------------------

aiohttp_security/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
from .abc import AbstractAuthorizationPolicy, AbstractIdentityPolicy
2-
from .api import (authorized_userid, forget, has_permission, is_anonymous,
3-
login_required, permits, remember, setup)
2+
from .api import (authorized_userid, forget, has_permission,
3+
is_anonymous, login_required, permits, remember,
4+
setup, check_authorized, check_permission)
45
from .cookies_identity import CookiesIdentityPolicy
56
from .session_identity import SessionIdentityPolicy
67
from .jwt_identity import JWTIdentityPolicy
78

8-
__version__ = '0.2.0'
9+
__version__ = '0.3.0'
910

1011

1112
__all__ = ('AbstractIdentityPolicy', 'AbstractAuthorizationPolicy',
1213
'CookiesIdentityPolicy', 'SessionIdentityPolicy',
1314
'JWTIdentityPolicy',
1415
'remember', 'forget', 'authorized_userid',
1516
'permits', 'setup', 'is_anonymous',
16-
'login_required', 'has_permission')
17+
'login_required', 'has_permission',
18+
'check_authorized', 'check_permission')

aiohttp_security/api.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import enum
2+
import warnings
23
from aiohttp import web
34
from aiohttp_security.abc import (AbstractIdentityPolicy,
45
AbstractAuthorizationPolicy)
@@ -86,6 +87,15 @@ async def is_anonymous(request):
8687
return False
8788

8889

90+
async def check_authorized(request):
91+
"""Checker that raises HTTPUnauthorized for anonymous users.
92+
"""
93+
userid = await authorized_userid(request)
94+
if userid is None:
95+
raise web.HTTPUnauthorized()
96+
return userid
97+
98+
8999
def login_required(fn):
90100
"""Decorator that restrict access only for authorized users.
91101
@@ -101,21 +111,34 @@ async def wrapped(*args, **kwargs):
101111
"or `def handler(self, request)`.")
102112
raise RuntimeError(msg)
103113

104-
userid = await authorized_userid(request)
105-
if userid is None:
106-
raise web.HTTPUnauthorized
107-
108-
ret = await fn(*args, **kwargs)
109-
return ret
114+
await check_authorized(request)
115+
return await fn(*args, **kwargs)
110116

117+
warnings.warn("login_required decorator is deprecated, "
118+
"use check_authorized instead",
119+
DeprecationWarning)
111120
return wrapped
112121

113122

123+
async def check_permission(request, permission, context=None):
124+
"""Checker that passes only to authoraised users with given permission.
125+
126+
If user is not authorized - raises HTTPUnauthorized,
127+
if user is authorized and does not have permission -
128+
raises HTTPForbidden.
129+
"""
130+
131+
await check_authorized(request)
132+
allowed = await permits(request, permission, context)
133+
if not allowed:
134+
raise web.HTTPForbidden()
135+
136+
114137
def has_permission(
115138
permission,
116139
context=None,
117140
):
118-
"""Decorator that restrict access only for authorized users
141+
"""Decorator that restricts access only for authorized users
119142
with correct permissions.
120143
121144
If user is not authorized - raises HTTPUnauthorized,
@@ -132,18 +155,14 @@ async def wrapped(*args, **kwargs):
132155
"or `def handler(self, request)`.")
133156
raise RuntimeError(msg)
134157

135-
userid = await authorized_userid(request)
136-
if userid is None:
137-
raise web.HTTPUnauthorized
138-
139-
allowed = await permits(request, permission, context)
140-
if not allowed:
141-
raise web.HTTPForbidden
142-
ret = await fn(*args, **kwargs)
143-
return ret
158+
await check_permission(request, permission, context)
159+
return await fn(*args, **kwargs)
144160

145161
return wrapped
146162

163+
warnings.warn("has_permission decorator is deprecated, "
164+
"use check_permission instead",
165+
DeprecationWarning)
147166
return wrapper
148167

149168

aiohttp_security/jwt_identity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ async def identify(self, request):
3535

3636
identity = jwt.decode(token,
3737
self.secret,
38-
algorithm=self.algorithm)
38+
algorithms=[self.algorithm])
3939
return identity
4040

4141
async def remember(self, *args, **kwargs): # pragma: no cover

demo/database_auth/handlers.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from aiohttp_security import (
66
remember, forget, authorized_userid,
7-
has_permission, login_required,
7+
check_permission, check_authorized,
88
)
99

1010
from .db_auth import check_credentials
@@ -45,25 +45,25 @@ async def login(self, request):
4545
db_engine = request.app.db_engine
4646
if await check_credentials(db_engine, login, password):
4747
await remember(request, response, login)
48-
return response
48+
raise response
4949

50-
return web.HTTPUnauthorized(
50+
raise web.HTTPUnauthorized(
5151
body=b'Invalid username/password combination')
5252

53-
@login_required
5453
async def logout(self, request):
54+
await check_authorized(request)
5555
response = web.Response(body=b'You have been logged out')
5656
await forget(request, response)
5757
return response
5858

59-
@has_permission('public')
6059
async def internal_page(self, request):
60+
await check_permission(request, 'public')
6161
response = web.Response(
6262
body=b'This page is visible for all registered users')
6363
return response
6464

65-
@has_permission('protected')
6665
async def protected_page(self, request):
66+
await check_permission(request, 'protected')
6767
response = web.Response(body=b'You are on protected page')
6868
return response
6969

demo/database_auth/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ async def init(loop):
1919
password='aiohttp_security',
2020
database='aiohttp_security',
2121
host='127.0.0.1')
22-
app = web.Application(loop=loop)
22+
app = web.Application()
2323
app.db_engine = db_engine
2424
setup_session(app, RedisStorage(redis_pool))
2525
setup_security(app,

demo/dictionary_auth/handlers.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from aiohttp_security import (
66
remember, forget, authorized_userid,
7-
has_permission, login_required,
7+
check_permission, check_authorized,
88
)
99

1010
from .authz import check_credentials
@@ -55,8 +55,8 @@ async def login(request):
5555
return web.HTTPUnauthorized(body='Invalid username / password combination')
5656

5757

58-
@login_required
5958
async def logout(request):
59+
await check_authorized(request)
6060
response = web.Response(
6161
text='You have been logged out',
6262
content_type='text/html',
@@ -65,19 +65,17 @@ async def logout(request):
6565
return response
6666

6767

68-
@has_permission('public')
6968
async def internal_page(request):
70-
# pylint: disable=unused-argument
69+
await check_permission(request, 'public')
7170
response = web.Response(
7271
text='This page is visible for all registered users',
7372
content_type='text/html',
7473
)
7574
return response
7675

7776

78-
@has_permission('protected')
7977
async def protected_page(request):
80-
# pylint: disable=unused-argument
78+
await check_permission(request, 'protected')
8179
response = web.Response(
8280
text='You are on protected page',
8381
content_type='text/html',

demo/simple_example_auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from aiohttp import web
22
from aiohttp_session import SimpleCookieStorage, session_middleware
3-
from aiohttp_security import has_permission, \
3+
from aiohttp_security import check_permission, \
44
is_anonymous, remember, forget, \
55
setup as setup_security, SessionIdentityPolicy
66
from aiohttp_security.abc import AbstractAuthorizationPolicy
@@ -54,13 +54,13 @@ async def handler_logout(request):
5454
raise redirect_response
5555

5656

57-
@has_permission('listen')
5857
async def handler_listen(request):
58+
await check_permission(request, 'listen')
5959
return web.Response(body="I can listen!")
6060

6161

62-
@has_permission('speak')
6362
async def handler_speak(request):
63+
await check_permission(request, 'speak')
6464
return web.Response(body="I can speak!")
6565

6666

docs/example.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Simple example::
99

1010
from aiohttp import web
1111
from aiohttp_session import SimpleCookieStorage, session_middleware
12-
from aiohttp_security import has_permission, \
12+
from aiohttp_security import check_permission, \
1313
is_anonymous, remember, forget, \
1414
setup as setup_security, SessionIdentityPolicy
1515
from aiohttp_security.abc import AbstractAuthorizationPolicy
@@ -63,13 +63,13 @@ Simple example::
6363
raise redirect_response
6464

6565

66-
@has_permission('listen')
6766
async def handler_listen(request):
67+
await check_permission(request, 'listen')
6868
return web.Response(body="I can listen!")
6969

7070

71-
@has_permission('speak')
7271
async def handler_speak(request):
72+
await check_permission(request, 'speak')
7373
return web.Response(body="I can speak!")
7474

7575

@@ -85,11 +85,12 @@ Simple example::
8585
app = web.Application(middlewares=[middleware])
8686

8787
# add the routes
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)
88+
app.add_routes([
89+
web.get('/', handler_root),
90+
web.get('/login', handler_login_jack),
91+
web.get('/logout', handler_logout),
92+
web.get('/listen', handler_listen),
93+
web.get('/speak', handler_speak)])
9394

9495
# set up policies
9596
policy = SessionIdentityPolicy()

0 commit comments

Comments
 (0)