From 94b98a062087c6b3a0508f2e5702227b9fdabadd Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Wed, 15 Apr 2015 19:47:24 -0500 Subject: [PATCH] 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. --- src/milla/auth/decorators.py | 41 ++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/milla/auth/decorators.py b/src/milla/auth/decorators.py index 104392f..d393800 100644 --- a/src/milla/auth/decorators.py +++ b/src/milla/auth/decorators.py @@ -18,9 +18,12 @@ ''' from functools import wraps -from milla.auth import RequestValidator, NotAuthorized, permissions -import milla -import pkg_resources +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): - try: - RequestValidator = ep.load() - except: - continue + 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: + 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)