Switch to async/await syntax

This commit is contained in:
Andrew Svetlov
2017-12-13 16:51:46 +02:00
parent b9dee120c3
commit 5b2ff779c3
16 changed files with 257 additions and 393 deletions

View File

@@ -1,21 +1,18 @@
import abc
import asyncio
# see http://plope.com/pyramid_auth_design_api_postmortem
class AbstractIdentityPolicy(metaclass=abc.ABCMeta):
@asyncio.coroutine
@abc.abstractmethod
def identify(self, request):
async def identify(self, request):
"""Return the claimed identity of the user associated request or
``None`` if no identity can be found associated with the request."""
pass
@asyncio.coroutine
@abc.abstractmethod
def remember(self, request, response, identity, **kwargs):
async def remember(self, request, response, identity, **kwargs):
"""Remember identity.
Modify response object by filling it's headers with remembered user.
@@ -25,9 +22,8 @@ class AbstractIdentityPolicy(metaclass=abc.ABCMeta):
"""
pass
@asyncio.coroutine
@abc.abstractmethod
def forget(self, request, response):
async def forget(self, request, response):
""" Modify response which can be used to 'forget' the
current identity on subsequent requests."""
pass
@@ -35,9 +31,8 @@ class AbstractIdentityPolicy(metaclass=abc.ABCMeta):
class AbstractAuthorizationPolicy(metaclass=abc.ABCMeta):
@asyncio.coroutine
@abc.abstractmethod
def permits(self, identity, permission, context=None):
async def permits(self, identity, permission, context=None):
"""Check user permissions.
Return True if the identity is allowed the permission in the
@@ -45,9 +40,8 @@ class AbstractAuthorizationPolicy(metaclass=abc.ABCMeta):
"""
pass
@asyncio.coroutine
@abc.abstractmethod
def authorized_userid(self, identity):
async def authorized_userid(self, identity):
"""Retrieve authorized user id.
Return the user_id of the user identified by the identity

View File

@@ -1,4 +1,3 @@
import asyncio
import enum
from aiohttp import web
from aiohttp_security.abc import (AbstractIdentityPolicy,
@@ -9,8 +8,7 @@ IDENTITY_KEY = 'aiohttp_security_identity_policy'
AUTZ_KEY = 'aiohttp_security_autz_policy'
@asyncio.coroutine
def remember(request, response, identity, **kwargs):
async def remember(request, response, identity, **kwargs):
"""Remember identity into response.
The action is performed by identity_policy.remember()
@@ -28,11 +26,10 @@ def remember(request, response, identity, **kwargs):
# output and rendered page we add same message to *reason* and
# *text* arguments.
raise web.HTTPInternalServerError(reason=text, text=text)
yield from identity_policy.remember(request, response, identity, **kwargs)
await identity_policy.remember(request, response, identity, **kwargs)
@asyncio.coroutine
def forget(request, response):
async def forget(request, response):
"""Forget previously remembered identity.
Usually it clears cookie or server-side storage to forget user
@@ -46,38 +43,35 @@ def forget(request, response):
# output and rendered page we add same message to *reason* and
# *text* arguments.
raise web.HTTPInternalServerError(reason=text, text=text)
yield from identity_policy.forget(request, response)
await identity_policy.forget(request, response)
@asyncio.coroutine
def authorized_userid(request):
async def authorized_userid(request):
identity_policy = request.app.get(IDENTITY_KEY)
autz_policy = request.app.get(AUTZ_KEY)
if identity_policy is None or autz_policy is None:
return None
identity = yield from identity_policy.identify(request)
identity = await identity_policy.identify(request)
if identity is None:
return None # non-registered user has None user_id
user_id = yield from autz_policy.authorized_userid(identity)
user_id = await autz_policy.authorized_userid(identity)
return user_id
@asyncio.coroutine
def permits(request, permission, context=None):
async def permits(request, permission, context=None):
assert isinstance(permission, (str, enum.Enum)), permission
assert permission
identity_policy = request.app.get(IDENTITY_KEY)
autz_policy = request.app.get(AUTZ_KEY)
if identity_policy is None or autz_policy is None:
return True
identity = yield from identity_policy.identify(request)
identity = await identity_policy.identify(request)
# non-registered user still may has some permissions
access = yield from autz_policy.permits(identity, permission, context)
access = await autz_policy.permits(identity, permission, context)
return access
@asyncio.coroutine
def is_anonymous(request):
async def is_anonymous(request):
"""Check if user is anonymous.
User is considered anonymous if there is not identity
@@ -86,7 +80,7 @@ def is_anonymous(request):
identity_policy = request.app.get(IDENTITY_KEY)
if identity_policy is None:
return True
identity = yield from identity_policy.identify(request)
identity = await identity_policy.identify(request)
if identity is None:
return True
return False
@@ -98,9 +92,8 @@ def login_required(fn):
User is considered authorized if authorized_userid
returns some value.
"""
@asyncio.coroutine
@wraps(fn)
def wrapped(*args, **kwargs):
async def wrapped(*args, **kwargs):
request = args[-1]
if not isinstance(request, web.BaseRequest):
msg = ("Incorrect decorator usage. "
@@ -108,11 +101,11 @@ def login_required(fn):
"or `def handler(self, request)`.")
raise RuntimeError(msg)
userid = yield from authorized_userid(request)
userid = await authorized_userid(request)
if userid is None:
raise web.HTTPUnauthorized
ret = yield from fn(*args, **kwargs)
ret = await fn(*args, **kwargs)
return ret
return wrapped
@@ -130,9 +123,8 @@ def has_permission(
raises HTTPForbidden.
"""
def wrapper(fn):
@asyncio.coroutine
@wraps(fn)
def wrapped(*args, **kwargs):
async def wrapped(*args, **kwargs):
request = args[-1]
if not isinstance(request, web.BaseRequest):
msg = ("Incorrect decorator usage. "
@@ -140,14 +132,14 @@ def has_permission(
"or `def handler(self, request)`.")
raise RuntimeError(msg)
userid = yield from authorized_userid(request)
userid = await authorized_userid(request)
if userid is None:
raise web.HTTPUnauthorized
allowed = yield from permits(request, permission, context)
allowed = await permits(request, permission, context)
if not allowed:
raise web.HTTPForbidden
ret = yield from fn(*args, **kwargs)
ret = await fn(*args, **kwargs)
return ret
return wrapped

View File

@@ -5,8 +5,6 @@ more handy.
"""
import asyncio
from .abc import AbstractIdentityPolicy
@@ -19,19 +17,16 @@ class CookiesIdentityPolicy(AbstractIdentityPolicy):
self._cookie_name = 'AIOHTTP_SECURITY'
self._max_age = 30 * 24 * 3600
@asyncio.coroutine
def identify(self, request):
async def identify(self, request):
identity = request.cookies.get(self._cookie_name)
return identity
@asyncio.coroutine
def remember(self, request, response, identity, max_age=sentinel,
**kwargs):
async def remember(self, request, response, identity, max_age=sentinel,
**kwargs):
if max_age is sentinel:
max_age = self._max_age
response.set_cookie(self._cookie_name, identity,
max_age=max_age, **kwargs)
@asyncio.coroutine
def forget(self, request, response):
async def forget(self, request, response):
response.del_cookie(self._cookie_name)

View File

@@ -4,8 +4,6 @@ aiohttp_session.setup() should be called on application initialization
to configure aiohttp_session properly.
"""
import asyncio
try:
from aiohttp_session import get_session
HAS_AIOHTTP_SESSION = True
@@ -24,17 +22,14 @@ class SessionIdentityPolicy(AbstractIdentityPolicy):
raise ImportError(
'SessionIdentityPolicy requires `aiohttp_session`')
@asyncio.coroutine
def identify(self, request):
session = yield from get_session(request)
async def identify(self, request):
session = await get_session(request)
return session.get(self._session_key)
@asyncio.coroutine
def remember(self, request, response, identity, **kwargs):
session = yield from get_session(request)
async def remember(self, request, response, identity, **kwargs):
session = await get_session(request)
session[self._session_key] = identity
@asyncio.coroutine
def forget(self, request, response):
session = yield from get_session(request)
async def forget(self, request, response):
session = await get_session(request)
session.pop(self._session_key, None)