Skip to content

Instantly share code, notes, and snippets.

@pelson
Last active February 1, 2018 08:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pelson/246ceff7c980fcfeb4b8e75bde5d6db0 to your computer and use it in GitHub Desktop.
Save pelson/246ceff7c980fcfeb4b8e75bde5d6db0 to your computer and use it in GitHub Desktop.
aiohttp security authorization for StaticResource (or any aiohttp resource)
from aiohttp import web
from functools import wraps
from logging import getLogger
from types import MethodType
_LOGGER = getLogger(__name__)
AUTH_USER = 'authenticated_user'
def permits(user, required_permission):
if user == 123:
return True
else:
return False
def require_permission(required_permission):
def authorize_handler_decorator(handler):
@wraps(handler)
async def new_handler(request):
if AUTH_USER not in request:
_LOGGER.error("Please install the authorization middleware.")
raise web.HTTPInternalServerError
if permits(request[AUTH_USER], required_permission):
return await handler(request)
else:
raise web.HTTPForbidden
return new_handler
return authorize_handler_decorator
def authorize_resource(resource, required_permission):
"""Modify the resource to ensure authorization against the requested permissions."""
orig_resolve = resource.resolve
async def new_resolve(self, request):
resolved = await orig_resolve(request)
url_mapping, allowed = resolved
if url_mapping and authorization:
# Wrap the mapping's _handler
url_mapping.route._handler = require_permission(required_permission)(
url_mapping.route._handler)
return url_mapping, allowed
resource.resolve = MethodType(new_resolve, resource)
return resource
@require_permission('view')
async def test(request):
print('Handler function called')
return web.Response(text="Hello")
@web.middleware
async def auth_middleware(request, handler):
request[AUTH_USER] = 123
response = await handler(request)
return response
app = web.Application(middlewares=[auth_middleware])
app.router.add_get('/', test)
resource = web.StaticResource('/static', './', show_index=True)
resource = authorize_resource(resource, required_permission='view_static')
app.router.register_resource(resource)
web.run_app(app)
@pelson
Copy link
Author

pelson commented Feb 1, 2018

The fact that one would almost always use aiohttp-session to do the authentication is not really that important here. I wanted to see how the authorization looked - especially for web.StaticResource instances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment