Permalink
Browse files

New auth configuration layer that doesn't require repoze.what anymore…

… while still being compatible
  • Loading branch information...
1 parent 9d04797 commit 9d08b1aec160b7feed2a2f26595368f0d4a7161f @amol- amol- committed May 3, 2012
View
@@ -4,7 +4,7 @@ release = egg_info -RDb "" sdist bdist_egg register upload
# A handy alias to install for development
tgdevelop = develop -i http://tg.gy/beta
# Another alias for installing all possible requirements for testing
-tgtesting = easy_install -i http://tg.gy/beta AddOns BytecodeAssembler Chameleon coverage DecoratorTools Extremes Genshi Jinja2 Kajiki kid nose PEAK_Rules repoze.tm2 repoze.what repoze.what.plugins.sql repoze.what_pylons repoze.what_quickstart repoze.who repoze.who_friendlyform repoze.who.plugins.sa repoze.who_testutil simplegeneric sprox SQLAlchemy SymbolType tgext.admin tgext.crud ToscaWidgets transaction TurboJson TurboKid tw.forms zope.interface zope.sqlalchemy tw2.forms tw2.core speaklater
+tgtesting = easy_install -i http://tg.gy/beta AddOns BytecodeAssembler Chameleon coverage DecoratorTools Extremes Genshi Jinja2 Kajiki kid nose PEAK_Rules repoze.tm2 repoze.who repoze.who_friendlyform repoze.who.plugins.sa repoze.who_testutil simplegeneric sprox SQLAlchemy SymbolType tgext.admin tgext.crud ToscaWidgets transaction TurboJson TurboKid tw.forms zope.interface zope.sqlalchemy tw2.forms tw2.core speaklater
tgrelease = easy_install yolk basketweaver sphinx
tgnose = nosetests --with-coverage --cover-erase --cover-package=turbogears --with-xunit --verbosity=2
View
@@ -13,12 +13,9 @@
'jinja2',
'Chameleon < 2.0a',
'simplegeneric',
- 'repoze.what >= 1.0.3',
'repoze.who >= 1.0.18, <= 1.99',
'repoze.who.plugins.sa >= 1.0.1',
- 'repoze.what.plugins.sql >= 1.0rc2',
'repoze.who-testutil >= 1.0.1',
- 'repoze.what-pylons >= 1.0',
"repoze.who-friendlyform >=1.0.4",
'repoze.tm2 >= 1.0a4',
'wsgiref',
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
-repoze.what & repoze.what-pylons **integration** tests.
+repoze.who **integration** tests.
Note that it is not necessary to have integration tests for the other auth*
software in this package. They must be in tg.devtools, specifically in the test
@@ -29,8 +29,8 @@
from pylons.testutil import ControllerWrap, SetupCacheGlobal
from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
-from repoze.what.middleware import setup_auth
-from repoze.what.predicates import Not, is_user, not_anonymous
+from tg.configuration.auth import setup_auth, TGAuthMetadata
+from tg.predicates import is_user, not_anonymous
from pylons.middleware import StatusCodeRedirect
from tg.error import ErrorHandler
@@ -56,17 +56,13 @@ def make_app(controller_klass, environ={}, with_errors=False):
app = SessionMiddleware(app, {}, data_dir=session_dir)
app = CacheMiddleware(app, {}, data_dir=os.path.join(data_dir, 'cache'))
- # We're not going to use groups or permissions-related predicates here:
- groups_adapters = None
- permissions_adapters = None
-
# Setting repoze.who up:
cookie = AuthTktCookiePlugin('secret', 'authtkt')
identifiers = [('cookie', cookie)]
- app = setup_auth(app, groups_adapters, permissions_adapters,
- identifiers=identifiers, authenticators=[],
- challengers=[], skip_authentication=True)
+ app = setup_auth(app, TGAuthMetadata(),
+ identifiers=identifiers, skip_authentication=True,
+ authenticators=[], challengers=[])
app = httpexceptions.make_middleware(app)
return TestApp(app)
@@ -734,12 +734,27 @@ def add_auth_middleware(self, app, skip_authentication):
"sa_auth.cookie_secret in development.ini"
raise TGConfigError(msg)
- if self.auth_backend == "sqlalchemy":
- from tg.configuration.sqla.auth import setup_sql_auth
- app = setup_sql_auth(app, skip_authentication=skip_authentication, **auth_args)
- elif self.auth_backend == "ming":
- from tgming import setup_ming_auth
- app = setup_ming_auth(app, skip_authentication=skip_authentication, **auth_args)
+ if 'authmetadata' not in auth_args:
+ #authmetadata not provided, fallback to old authentication setup
+ if self.auth_backend == "sqlalchemy":
+ from repoze.what.plugins.quickstart import setup_sql_auth
+ app = setup_sql_auth(app, skip_authentication=skip_authentication, **auth_args)
+ elif self.auth_backend == "ming":
+ from tgming import setup_ming_auth
+ app = setup_ming_auth(app, skip_authentication=skip_authentication, **auth_args)
+ else:
+ from tg.configuration.auth import setup_auth
+ if 'authenticators' not in auth_args:
+ if self.auth_backend == "sqlalchemy":
+ from tg.configuration.sqla.auth import create_default_authenticator
+ auth_args, sqlauth = create_default_authenticator(**auth_args)
+ auth_args['authenticators'] = [('sqlauth', sqlauth)]
+ elif self.auth_backend == "ming":
+ from tgming.auth import MingAuthenticatorPlugin
+ mingauth = MingAuthenticatorPlugin(auth_args.pop('user_class', None))
+ auth_args['authenticators'] = [('mingauth', mingauth)]
+ app = setup_auth(app, skip_authentication=skip_authentication, **auth_args)
+
return app
def add_core_middleware(self, app):
View
@@ -0,0 +1,144 @@
+"""
+New TurboGears2 identification, authentication and authorization setup.
+
+This aims to provide an easier way to setup auth layer in TurboGears2
+and removes the dependency from repoze.what.
+"""
+import sys, logging
+from zope.interface import implements
+from repoze.who.plugins.testutil import make_middleware
+from repoze.who.interfaces import IMetadataProvider
+from repoze.who.classifiers import default_challenge_decider, default_request_classifier
+from repoze.who.config import _LEVELS
+
+class TGAuthMetadata(object):
+ """
+ Provides a way to lookup for user, groups and permissions
+ given the current identity. This has to be specialized
+ for each storage backend.
+
+ By default it returns empty lists for groups and permissions
+ and None for the user.
+ """
+ def get_user(self, identity, userid):
+ return None
+
+ def get_groups(self, identity, userid):
+ return []
+
+ def get_permissions(self, identity, userid):
+ return []
+
+class AuthMetadataProvider(object):
+ """
+ repoze.who metadata provider to load groups and permissions data for
+ the current user. This uses a :class:`TGAuthMetadata` to fetch
+ the groups and permissions.
+ """
+ implements(IMetadataProvider)
+
+ def __init__(self, tgmdprovider):
+ self.tgmdprovider = tgmdprovider
+
+ # IMetadataProvider
+ def add_metadata(self, environ, identity):
+ # Get the userid retrieved by repoze.who Authenticator
+ userid = identity['repoze.who.userid']
+
+ # Finding the user, groups and permissions:
+ identity['user'] = self.tgmdprovider.get_user(identity, userid)
+ if identity['user']:
+ identity['groups'] = self.tgmdprovider.get_groups(identity, userid)
+ identity['permissions'] = self.tgmdprovider.get_permissions(identity, userid)
+ else:
+ identity['groups'] = identity['permissions'] = []
+
+ # Adding the groups and permissions to the repoze.what
+ # credentials for repoze.what compatibility:
+ if 'repoze.what.credentials' not in environ:
+ environ['repoze.what.credentials'] = {}
+ environ['repoze.what.credentials'].update(identity)
+ environ['repoze.what.credentials']['repoze.what.userid'] = userid
+
+def setup_auth(app, authmetadata,
+ form_plugin=None, form_identifies=True,
+ cookie_secret='secret', cookie_name='authtkt',
+ login_url='/login', login_handler='/login_handler',
+ post_login_url=None, logout_handler='/logout_handler',
+ post_logout_url=None, login_counter_name=None,
+ cookie_timeout=None, cookie_reissue_time=None,
+ charset="iso-8859-1",
+ **who_args):
+ """
+ Sets :mod:`repoze.who` up with the provided authenticators and
+ options to create FriendlyFormPlugin.
+
+ It returns a middleware that provides identification,
+ authentication and authorization in a way that is compatible
+ with repoze.who and repoze.what.
+ """
+
+ # If no identifiers are provided in repoze setup arguments
+ # then create a default one using AuthTktCookiePlugin.
+ if 'identifiers' not in who_args:
+ from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
+ cookie = AuthTktCookiePlugin(cookie_secret, cookie_name,
+ timeout=cookie_timeout,
+ reissue_time=cookie_reissue_time)
+ who_args['identifiers'] = [('cookie', cookie)]
+
+ # If no form plugin is provided then create a default
+ # one using the provided options.
+ if form_plugin is None:
+ from repoze.who.plugins.friendlyform import FriendlyFormPlugin
+ form = FriendlyFormPlugin(login_url, login_handler, post_login_url,
+ logout_handler, post_logout_url,
+ login_counter_name=login_counter_name,
+ rememberer_name='cookie',
+ charset=charset)
+ else:
+ form = form_plugin
+
+ if form_identifies:
+ who_args['identifiers'].insert(0, ('main_identifier', form))
+
+ # Setting the repoze.who challengers:
+ if 'challengers' not in who_args:
+ who_args['challengers'] = []
+ who_args['challengers'].append(('form', form))
+
+ # Including logging
+ log_file = who_args.pop('log_file', None)
+ if log_file is not None:
+ if log_file.lower() == 'stdout':
+ log_stream = sys.stdout
+ elif log_file.lower() == 'stderr':
+ log_stream = sys.stderr
+ else:
+ log_stream = open(log_file, 'wb')
+ who_args['log_stream'] = log_stream
+
+ log_level = who_args.get('log_level', None)
+ if log_level is None:
+ log_level = logging.INFO
+ else:
+ log_level = _LEVELS[log_level.lower()]
+ who_args['log_level'] = log_level
+
+ # Setting up the metadata provider for the user informations
+ authmd = AuthMetadataProvider(authmetadata)
+ if 'mdproviders' not in who_args:
+ who_args['mdproviders'] = []
+ who_args['mdproviders'].append(('authmd', authmd))
+
+ # Set up default classifier
+ if 'classifier' not in who_args:
+ who_args['classifier'] = default_request_classifier
+
+ # Set up default challenger decider
+ if 'challenge_decider' not in who_args:
+ who_args['challenge_decider'] = default_challenge_decider
+
+ skip_authn = who_args.pop('skip_authentication', False)
+ middleware = make_middleware(skip_authn, app, **who_args)
+ return middleware
Oops, something went wrong.

0 comments on commit 9d08b1a

Please sign in to comment.