auth: Allow Python classes as request validators (see #4)

In addition to setuptools entry point names, the authentication subsystem now
accepts Python classes directly as the value of the `milla.request_validator`
configuration setting. This removes the dependency on setuptools for
authentication, and allows more flexibility in application configuration.
master
Dustin 2015-04-15 19:47:24 -05:00
parent 86b19bb9e7
commit 94b98a0620
1 changed files with 28 additions and 13 deletions

View File

@ -18,9 +18,12 @@
'''
from functools import wraps
from milla.auth import RequestValidator, NotAuthorized, permissions
import milla
from milla.auth import permissions
import milla.auth
try:
import pkg_resources
except ImportError:
pkg_resources = None
__all__ = ['auth_required', 'require_perms']
@ -40,20 +43,32 @@ def _find_request(*args, **kwargs):
def _validate_request(func, requirement, *args, **kwargs):
request = _find_request(*args, **kwargs)
ep_name = request.config.get('request_validator', 'default')
# Override the RequestVariable name with a class from the specified
# entry point, if one is available. Otherwise, the default is used.
for ep in pkg_resources.iter_entry_points(VALIDATOR_EP_GROUP, ep_name):
rv = request.config.get('request_validator', 'default')
if hasattr(rv, 'validate'):
# Config specifies a request validator class explicitly instead
# of an entry point name, so use it directly
validator = rv()
elif pkg_resources:
for ep in pkg_resources.iter_entry_points(VALIDATOR_EP_GROUP, rv):
try:
RequestValidator = ep.load()
validator = ep.load()()
break
except:
# Ignore errors loading entry points or creating instances
continue
else:
# No entry point loaded or request validator instance
# created, use the default
validator = milla.auth.RequestValidator()
else:
# config does not specify a request validator class, and
# setuptools is not available, use the default
validator = milla.auth.RequestValidator()
try:
validator = RequestValidator()
validator.validate(request, requirement)
except NotAuthorized as e:
except milla.auth.NotAuthorized as e:
return e(request)
return func(*args, **kwargs)