Skip to content

Commit 27ffe6d

Browse files
alexpantyukhinasvetlov
authored andcommitted
init for jwt identity (#147)
1 parent 29166f4 commit 27ffe6d

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

aiohttp_security/jwt_identity.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""Identity policy for storing info in the jwt token.
2+
3+
"""
4+
5+
from .abc import AbstractIdentityPolicy
6+
try:
7+
import jwt
8+
except ImportError: # pragma: no cover
9+
jwt = None
10+
11+
12+
AUTH_HEADER_NAME = 'Authorization'
13+
14+
15+
class JWTIdentityPolicy(AbstractIdentityPolicy):
16+
def __init__(self, secret, algorithm=None):
17+
if jwt is None:
18+
raise RuntimeError("Please install pyjwt")
19+
self.secret = secret
20+
self.algorithm = 'HS256' if algorithm is None else algorithm
21+
22+
async def identify(self, request):
23+
header_identity = request.headers.get(AUTH_HEADER_NAME)
24+
identity = jwt.decode(header_identity,
25+
self.secret,
26+
algorithm=self.algorithm)
27+
28+
return identity['identity']
29+
30+
async def remember(self, *args, **kwargs): # pragma: no cover
31+
pass
32+
33+
async def forget(self, request, response): # pragma: no cover
34+
pass

requirements-dev.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
flake8==3.5.0
33
pytest==3.5.0
44
pytest-cov==2.5.1
5+
pytest-mock==1.6.3
56
coverage==4.5.1
67
sphinx==1.7.3
78
pep257==0.7.0
@@ -13,3 +14,4 @@ passlib==1.7.1
1314
cryptography==2.2.2
1415
aiohttp==3.1.3
1516
pytest-aiohttp==0.3.0
17+
pyjwt

tests/test_jwt_identity.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import pytest
2+
from aiohttp import web
3+
from aiohttp_security import AbstractAuthorizationPolicy
4+
from aiohttp_security import setup as _setup
5+
from aiohttp_security.jwt_identity import JWTIdentityPolicy
6+
from aiohttp_security.api import IDENTITY_KEY
7+
import jwt
8+
9+
10+
class Autz(AbstractAuthorizationPolicy):
11+
12+
async def permits(self, identity, permission, context=None):
13+
pass
14+
15+
async def authorized_userid(self, identity):
16+
pass
17+
18+
19+
async def test_no_pyjwt_installed(mocker):
20+
mocker.patch('aiohttp_security.jwt_identity.jwt', None)
21+
with pytest.raises(RuntimeError):
22+
JWTIdentityPolicy('secret')
23+
24+
25+
async def test_identify(loop, test_client):
26+
kwt_secret_key = 'Key'
27+
28+
async def create(request):
29+
response = web.Response()
30+
data = await request.post()
31+
32+
encoded_identity = jwt.encode({'identity': data['login']},
33+
kwt_secret_key,
34+
algorithm='HS256')
35+
36+
response.text = encoded_identity.decode('utf-8')
37+
return response
38+
39+
async def check(request):
40+
policy = request.app[IDENTITY_KEY]
41+
user_id = await policy.identify(request)
42+
assert 'Andrew' == user_id
43+
return web.Response()
44+
45+
app = web.Application(loop=loop)
46+
_setup(app, JWTIdentityPolicy(kwt_secret_key), Autz())
47+
app.router.add_route('GET', '/', check)
48+
app.router.add_route('POST', '/', create)
49+
client = await test_client(app)
50+
resp = await client.post('/', data={'login': 'Andrew'})
51+
jwt_token = await resp.content.read()
52+
assert 200 == resp.status
53+
await resp.release()
54+
headers = {'Authorization': str(jwt_token.decode('utf-8'))}
55+
resp = await client.get('/', headers=headers)
56+
assert 200 == resp.status

0 commit comments

Comments
 (0)