[Repoze-checkins] r938 - in repoze.who/trunk: . repoze/who repoze/who/plugins
Tres Seaver
tseaver at palladion.com
Sat May 3 15:22:22 EDT 2008
Author: Tres Seaver <tseaver at palladion.com>
Date: Sat May 3 15:22:22 2008
New Revision: 938
Log:
- Fixed interface declarations of 'classifiers.default_request_classifier'
and 'classifiers.default_password_compare'.
- Added actual config-driven middleware factory,
'config.make_middleware_with_config'
- Removed fossilized 'who_conf' argument from plugin factory functions.
Modified:
repoze.who/trunk/CHANGES.txt
repoze.who/trunk/repoze/who/classifiers.py
repoze.who/trunk/repoze/who/config.py
repoze.who/trunk/repoze/who/interfaces.py
repoze.who/trunk/repoze/who/plugins/auth_tkt.py
repoze.who/trunk/repoze/who/plugins/basicauth.py
repoze.who/trunk/repoze/who/plugins/cookie.py
repoze.who/trunk/repoze/who/plugins/form.py
repoze.who/trunk/repoze/who/plugins/htpasswd.py
repoze.who/trunk/repoze/who/plugins/sql.py
repoze.who/trunk/repoze/who/tests.py
Modified: repoze.who/trunk/CHANGES.txt
==============================================================================
--- repoze.who/trunk/CHANGES.txt (original)
+++ repoze.who/trunk/CHANGES.txt Sat May 3 15:22:22 2008
@@ -3,6 +3,14 @@
After 0.9.1
+ - Fixed interface declarations of 'classifiers.default_request_classifier'
+ and 'classifiers.default_password_compare'.
+
+ - Added actual config-driven middleware factory,
+ 'config.make_middleware_with_config'
+
+ - Removed fossilized 'who_conf' argument from plugin factory functions.
+
- Added ConfigParser-based WhoConfig, implementing the spec outlined at
http://www.plope.com/static/misc/sphinxtest/intro.html#middleware-configuration-via-config-file, with the following changes:
Modified: repoze.who/trunk/repoze/who/classifiers.py
==============================================================================
--- repoze.who/trunk/repoze/who/classifiers.py (original)
+++ repoze.who/trunk/repoze/who/classifiers.py Sat May 3 15:22:22 2008
@@ -31,7 +31,6 @@
'Microsoft-WebDAV'
)
- at zope.interface.implementer(IRequestClassifier)
def default_request_classifier(environ):
""" Returns one of the classifiers 'dav', 'xmlpost', or 'browser',
depending on the imperative logic below"""
@@ -47,9 +46,10 @@
if CONTENT_TYPE(environ) == 'text/xml':
return 'xmlpost'
return 'browser'
+zope.interface.directlyProvides(default_request_classifier, IRequestClassifier)
- at zope.interface.implementer(IChallengeDecider)
def default_challenge_decider(environ, status, headers):
if status.startswith('401 '):
return True
return False
+zope.interface.directlyProvides(default_challenge_decider, IChallengeDecider)
Modified: repoze.who/trunk/repoze/who/config.py
==============================================================================
--- repoze.who/trunk/repoze/who/config.py (original)
+++ repoze.who/trunk/repoze/who/config.py Sat May 3 15:22:22 2008
@@ -4,8 +4,14 @@
from StringIO import StringIO
from pkg_resources import EntryPoint
+from repoze.who.interfaces import IAuthenticator
from repoze.who.interfaces import IChallengeDecider
+from repoze.who.interfaces import IChallenger
+from repoze.who.interfaces import IIdentifier
+from repoze.who.interfaces import IMetadataProvider
+from repoze.who.interfaces import IPlugin
from repoze.who.interfaces import IRequestClassifier
+from repoze.who.middleware import PluggableAuthenticationMiddleware
def _resolve(name):
if name:
@@ -24,25 +30,38 @@
self.challengers = []
self.mdproviders = []
- def _getPlugin(self, name):
+ def _makePlugin(self, name, iface, **kw):
+ obj = _resolve(name)
+ if not iface.providedBy(obj):
+ #if _isClassOrType(obj) and iface.implementedBy(obj):
+ obj = obj(**kw)
+ return obj
+
+ def _getPlugin(self, name, iface):
obj = self.plugins.get(name)
if obj is None:
- obj = _resolve(name)
- if _isClassOrType(obj):
- obj = obj()
+ obj = self._makePlugin(name, iface)
return obj
- def _parsePluginSequence(self, attr, proptext):
+ def _parsePluginSequence(self, attr, proptext, iface):
lines = proptext.split()
for line in lines:
+
if ';' in line:
plugin_name, classifier = line.split(';')
else:
plugin_name = line
classifier = None
- attr.append({'plugin': self._getPlugin(plugin_name),
- 'classifier': classifier
- })
+
+ plugin = self._getPlugin(plugin_name, iface)
+
+ if classifier is not None:
+ classifications = getattr(plugin, 'classifications', None)
+ if classifications is None:
+ classifications = plugin.classifications = {}
+ classifications[iface] = classifier
+
+ attr.append((plugin_name, plugin))
def parse(self, text):
if getattr(text, 'readline', None) is None:
@@ -54,37 +73,61 @@
plugin_id = s_id[len('plugin:'):]
options = dict(cp.items(s_id))
if 'use' in options:
- obj = _resolve(options['use'])
- if _isClassOrType(obj):
- del options['use']
- obj = obj(**options)
+ name = options.pop('use')
+ obj = self._makePlugin(name, IPlugin, **options)
self.plugins[plugin_id] = obj
if 'general' in cp.sections():
general = dict(cp.items('general'))
rc = general.get('request_classifier')
- self.request_classifier = self._getPlugin(rc)
+ if rc is not None:
+ rc = self._getPlugin(rc, IRequestClassifier)
+ self.request_classifier = rc
cd = general.get('challenge_decider')
- self.challenge_decider = self._getPlugin(cd)
+ if cd is not None:
+ cd = self._getPlugin(cd, IChallengeDecider)
+ self.challenge_decider = cd
if 'identifiers' in cp.sections():
identifiers = dict(cp.items('identifiers'))
self._parsePluginSequence(self.identifiers,
- identifiers['plugins'])
+ identifiers['plugins'],
+ IIdentifier,
+ )
if 'authenticators' in cp.sections():
authenticators = dict(cp.items('authenticators'))
self._parsePluginSequence(self.authenticators,
- authenticators['plugins'])
+ authenticators['plugins'],
+ IAuthenticator,
+ )
if 'challengers' in cp.sections():
challengers = dict(cp.items('challengers'))
self._parsePluginSequence(self.challengers,
- challengers['plugins'])
+ challengers['plugins'],
+ IChallenger,
+ )
if 'mdproviders' in cp.sections():
mdproviders = dict(cp.items('mdproviders'))
self._parsePluginSequence(self.mdproviders,
- mdproviders['plugins'])
+ mdproviders['plugins'],
+ IMetadataProvider,
+ )
+
+
+def make_middleware_with_config(app, config_file):
+ parser = WhoConfig()
+ parser.parse(open(config_file))
+ return PluggableAuthenticationMiddleware(
+ app,
+ parser.identifiers,
+ parser.authenticators,
+ parser.challengers,
+ parser.mdproviders,
+ parser.request_classifier,
+ parser.challenge_decider,
+ )
Modified: repoze.who/trunk/repoze/who/interfaces.py
==============================================================================
--- repoze.who/trunk/repoze/who/interfaces.py (original)
+++ repoze.who/trunk/repoze/who/interfaces.py Sat May 3 15:22:22 2008
@@ -1,6 +1,9 @@
from zope.interface import Interface
-class IRequestClassifier(Interface):
+class IPlugin(Interface):
+ pass
+
+class IRequestClassifier(IPlugin):
""" On ingress: classify a request.
"""
def __call__(environ):
@@ -12,7 +15,7 @@
o 'environ' is the WSGI environment.
"""
-class IChallengeDecider(Interface):
+class IChallengeDecider(IPlugin):
""" On egress: decide whether a challenge needs to be presented
to the user.
"""
@@ -31,7 +34,7 @@
a challenge needs to be presented to the user, False otherwise.
"""
-class IIdentifier(Interface):
+class IIdentifier(IPlugin):
"""
On ingress: Extract credentials from the WSGI environment and
@@ -109,7 +112,7 @@
included in the response provided by the challenge app.
"""
-class IAuthenticator(Interface):
+class IAuthenticator(IPlugin):
""" On ingress: validate the identity and return a user id or None.
"""
@@ -140,7 +143,7 @@
should return None).
"""
-class IChallenger(Interface):
+class IChallenger(IPlugin):
""" On egress: Conditionally initiate a challenge to the user to
provide credentials.
@@ -174,7 +177,7 @@
"""
-class IMetadataProvider(Interface):
+class IMetadataProvider(IPlugin):
"""On ingress: When an identity is authenticated, metadata
providers may scribble on the identity dictionary arbitrarily.
Return values from metadata providers are ignored.
Modified: repoze.who/trunk/repoze/who/plugins/auth_tkt.py
==============================================================================
--- repoze.who/trunk/repoze/who/plugins/auth_tkt.py (original)
+++ repoze.who/trunk/repoze/who/plugins/auth_tkt.py Sat May 3 15:22:22 2008
@@ -137,11 +137,17 @@
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, id(self))
-def make_plugin(who_conf, secret=None,
+def _bool(value):
+ if isinstance(value, basestring):
+ return value.lower() in ('yes', 'true', '1')
+ return value
+
+def make_plugin(secret=None,
cookie_name='auth_tkt',
secure=False, include_ip=False):
if secret is None:
raise ValueError('secret must not be None')
- plugin = AuthTktCookiePlugin(secret, cookie_name, secure, include_ip)
+ plugin = AuthTktCookiePlugin(secret, cookie_name,
+ _bool(secure), _bool(include_ip))
return plugin
Modified: repoze.who/trunk/repoze/who/plugins/basicauth.py
==============================================================================
--- repoze.who/trunk/repoze/who/plugins/basicauth.py (original)
+++ repoze.who/trunk/repoze/who/plugins/basicauth.py Sat May 3 15:22:22 2008
@@ -61,7 +61,7 @@
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, id(self))
-def make_plugin(who_conf, realm='basic'):
+def make_plugin(realm='basic'):
plugin = BasicAuthPlugin(realm)
return plugin
Modified: repoze.who/trunk/repoze/who/plugins/cookie.py
==============================================================================
--- repoze.who/trunk/repoze/who/plugins/cookie.py (original)
+++ repoze.who/trunk/repoze/who/plugins/cookie.py Sat May 3 15:22:22 2008
@@ -54,7 +54,7 @@
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, id(self))
-def make_plugin(who_conf, cookie_name='repoze.who.plugins.cookie'):
+def make_plugin(cookie_name='repoze.who.plugins.cookie'):
plugin = InsecureCookiePlugin(cookie_name)
return plugin
Modified: repoze.who/trunk/repoze/who/plugins/form.py
==============================================================================
--- repoze.who/trunk/repoze/who/plugins/form.py (original)
+++ repoze.who/trunk/repoze/who/plugins/form.py Sat May 3 15:22:22 2008
@@ -176,7 +176,7 @@
headers = headers + forget_headers
return HTTPFound(headers=headers)
-def make_plugin(who_conf, login_form_qs='__do_login', rememberer_name=None,
+def make_plugin(login_form_qs='__do_login', rememberer_name=None,
form=None):
if rememberer_name is None:
raise ValueError(
@@ -186,8 +186,7 @@
plugin = FormPlugin(login_form_qs, rememberer_name, form)
return plugin
-def make_redirecting_plugin(who_conf,
- login_form_url=None,
+def make_redirecting_plugin(login_form_url=None,
login_handler_path='/login_handler',
logout_handler_path='/logout_handler',
rememberer_name=None):
Modified: repoze.who/trunk/repoze/who/plugins/htpasswd.py
==============================================================================
--- repoze.who/trunk/repoze/who/plugins/htpasswd.py (original)
+++ repoze.who/trunk/repoze/who/plugins/htpasswd.py Sat May 3 15:22:22 2008
@@ -47,7 +47,7 @@
salt = hashed[:2]
return hashed == crypt(password, salt)
-def make_plugin(who_conf, filename=None, check_fn=None):
+def make_plugin(filename=None, check_fn=None):
if filename is None:
raise ValueError('filename must be specified')
if check_fn is None:
Modified: repoze.who/trunk/repoze/who/plugins/sql.py
==============================================================================
--- repoze.who/trunk/repoze/who/plugins/sql.py (original)
+++ repoze.who/trunk/repoze/who/plugins/sql.py Sat May 3 15:22:22 2008
@@ -20,7 +20,7 @@
return False
-def make_psycopg_conn_factory(who_conf, **kw):
+def make_psycopg_conn_factory(**kw):
# convenience (I always seem to use Postgres)
def conn_factory():
import psycopg2
@@ -78,7 +78,7 @@
del identity['__userid']
identity[self.name] = result
-def make_authenticator_plugin(who_conf, query=None, conn_factory=None,
+def make_authenticator_plugin(query=None, conn_factory=None,
compare_fn=None, **kw):
from repoze.who.utils import resolveDotted
if query is None:
@@ -86,14 +86,14 @@
if conn_factory is None:
raise ValueError('conn_factory must be specified')
try:
- conn_factory = resolveDotted(conn_factory)(who_conf, **kw)
+ conn_factory = resolveDotted(conn_factory)(**kw)
except Exception, why:
raise ValueError('conn_factory could not be resolved: %s' % why)
if compare_fn is not None:
compare_fn = resolveDotted(compare_fn)
return SQLAuthenticatorPlugin(query, conn_factory, compare_fn)
-def make_metadata_plugin(who_conf, name=None, query=None, conn_factory=None,
+def make_metadata_plugin(name=None, query=None, conn_factory=None,
filter=None, **kw):
from repoze.who.utils import resolveDotted
if name is None:
@@ -103,7 +103,7 @@
if conn_factory is None:
raise ValueError('conn_factory must be specified')
try:
- conn_factory = resolveDotted(conn_factory)(who_conf, **kw)
+ conn_factory = resolveDotted(conn_factory)(**kw)
except Exception, why:
raise ValueError('conn_factory could not be resolved: %s' % why)
if filter is not None:
Modified: repoze.who/trunk/repoze/who/tests.py
==============================================================================
--- repoze.who/trunk/repoze/who/tests.py (original)
+++ repoze.who/trunk/repoze/who/tests.py Sat May 3 15:22:22 2008
@@ -820,7 +820,7 @@
def test_factory(self):
from repoze.who.plugins.basicauth import make_plugin
- plugin = make_plugin({}, 'realm')
+ plugin = make_plugin('realm')
self.assertEqual(plugin.realm, 'realm')
class TestHTPasswdPlugin(Base):
@@ -915,7 +915,7 @@
def test_factory(self):
from repoze.who.plugins.htpasswd import make_plugin
from repoze.who.plugins.htpasswd import crypt_check
- plugin = make_plugin({}, 'foo',
+ plugin = make_plugin('foo',
'repoze.who.plugins.htpasswd:crypt_check')
self.assertEqual(plugin.filename, 'foo')
self.assertEqual(plugin.check, crypt_check)
@@ -976,7 +976,7 @@
def test_factory(self):
from repoze.who.plugins.cookie import make_plugin
- plugin = make_plugin(None, 'foo')
+ plugin = make_plugin('foo')
self.assertEqual(plugin.cookie_name, 'foo')
def test_forget(self):
@@ -1118,14 +1118,14 @@
fixtures = os.path.join(here, 'fixtures')
form = os.path.join(fixtures, 'form.html')
formbody = open(form).read()
- plugin = make_plugin(None, '__login', 'cookie', form)
+ plugin = make_plugin('__login', 'cookie', form)
self.assertEqual(plugin.login_form_qs, '__login')
self.assertEqual(plugin.rememberer_name, 'cookie')
self.assertEqual(plugin.formbody, formbody)
def test_factory_defaultform(self):
from repoze.who.plugins.form import make_plugin
- plugin = make_plugin(None, '__login', 'cookie')
+ plugin = make_plugin('__login', 'cookie')
self.assertEqual(plugin.login_form_qs, '__login')
self.assertEqual(plugin.rememberer_name, 'cookie')
self.assertEqual(plugin.formbody, None)
@@ -1517,7 +1517,7 @@
def test_factory(self):
from repoze.who.plugins.auth_tkt import make_plugin
- plugin = make_plugin(None, 'secret')
+ plugin = make_plugin('secret')
self.assertEqual(plugin.cookie_name, 'auth_tkt')
self.assertEqual(plugin.secret, 'secret')
self.assertEqual(plugin.include_ip, False)
@@ -1730,20 +1730,19 @@
def test_noquery(self):
f = self._getFUT()
- self.assertRaises(ValueError, f, None, None, 'conn', 'compare')
+ self.assertRaises(ValueError, f, None, 'conn', 'compare')
def test_no_connfactory(self):
f = self._getFUT()
- self.assertRaises(ValueError, f, None, 'statement', None, 'compare')
+ self.assertRaises(ValueError, f, 'statement', None, 'compare')
def test_bad_connfactory(self):
f = self._getFUT()
- self.assertRaises(ValueError, f, None, 'statement', 'does.not:exist',
- None)
+ self.assertRaises(ValueError, f, 'statement', 'does.not:exist', None)
def test_connfactory_specd(self):
f = self._getFUT()
- plugin = f(None, 'statement',
+ plugin = f('statement',
'repoze.who.tests:make_dummy_connfactory',
None)
self.assertEqual(plugin.query, 'statement')
@@ -1753,7 +1752,7 @@
def test_comparefunc_specd(self):
f = self._getFUT()
- plugin = f(None, 'statement',
+ plugin = f('statement',
'repoze.who.tests:make_dummy_connfactory',
'repoze.who.tests:make_dummy_connfactory')
self.assertEqual(plugin.query, 'statement')
@@ -1767,20 +1766,20 @@
def test_no_name(self):
f = self._getFUT()
- self.assertRaises(ValueError, f, None)
+ self.assertRaises(ValueError, f)
def test_no_query(self):
f = self._getFUT()
- self.assertRaises(ValueError, f, None, 'name', None, None)
+ self.assertRaises(ValueError, f, 'name', None, None)
def test_bad_connfactory(self):
f = self._getFUT()
- self.assertRaises(ValueError, f, None, 'name', 'statement',
+ self.assertRaises(ValueError, f, 'name', 'statement',
'does.not:exist', None)
def test_connfactory_specd(self):
f = self._getFUT()
- plugin = f(None, 'name', 'statement',
+ plugin = f('name', 'statement',
'repoze.who.tests:make_dummy_connfactory', None)
self.assertEqual(plugin.name, 'name')
self.assertEqual(plugin.query, 'statement')
@@ -1789,7 +1788,7 @@
def test_comparefn_specd(self):
f = self._getFUT()
- plugin = f(None, 'name', 'statement',
+ plugin = f('name', 'statement',
'repoze.who.tests:make_dummy_connfactory',
'repoze.who.tests:make_dummy_connfactory')
self.assertEqual(plugin.name, 'name')
@@ -1825,6 +1824,12 @@
def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
+ def _getDummyPluginClass(self, iface):
+ from zope.interface import classImplements
+ if not iface.implementedBy(DummyPlugin):
+ classImplements(DummyPlugin, iface)
+ return DummyPlugin
+
def test_defaults_before_parse(self):
config = self._makeOne()
self.assertEqual(config.request_classifier, None)
@@ -1863,9 +1868,9 @@
config.parse(PLUGINS_ONLY)
self.assertEqual(len(config.plugins), 2)
self.failUnless(isinstance(config.plugins['foo'],
- DummyRequestClassifier))
+ DummyPlugin))
bar = config.plugins['bar']
- self.failUnless(isinstance(bar, DummyIdentifier))
+ self.failUnless(isinstance(bar, DummyPlugin))
self.assertEqual(bar.credentials, 'qux')
def test_parse_general_empty(self):
@@ -1876,118 +1881,165 @@
self.assertEqual(len(config.plugins), 0)
def test_parse_general_only(self):
+ from repoze.who.interfaces import IRequestClassifier
+ from repoze.who.interfaces import IChallengeDecider
+ class IDummy(IRequestClassifier, IChallengeDecider):
+ pass
+ PLUGIN_CLASS = self._getDummyPluginClass(IDummy)
config = self._makeOne()
config.parse(GENERAL_ONLY)
- self.failUnless(isinstance(config.request_classifier,
- DummyRequestClassifier))
- self.failUnless(isinstance(config.challenge_decider,
- DummyChallengeDecider))
+ self.failUnless(isinstance(config.request_classifier, PLUGIN_CLASS))
+ self.failUnless(isinstance(config.challenge_decider, PLUGIN_CLASS))
self.assertEqual(len(config.plugins), 0)
def test_parse_general_with_plugins(self):
+ from repoze.who.interfaces import IRequestClassifier
+ from repoze.who.interfaces import IChallengeDecider
+ class IDummy(IRequestClassifier, IChallengeDecider):
+ pass
+ PLUGIN_CLASS = self._getDummyPluginClass(IDummy)
config = self._makeOne()
config.parse(GENERAL_WITH_PLUGINS)
- self.failUnless(isinstance(config.request_classifier,
- DummyRequestClassifier))
- self.failUnless(isinstance(config.challenge_decider,
- DummyChallengeDecider))
+ self.failUnless(isinstance(config.request_classifier, PLUGIN_CLASS))
+ self.failUnless(isinstance(config.challenge_decider, PLUGIN_CLASS))
def test_parse_identifiers_only(self):
+ from repoze.who.interfaces import IIdentifier
+ PLUGIN_CLASS = self._getDummyPluginClass(IIdentifier)
config = self._makeOne()
config.parse(IDENTIFIERS_ONLY)
identifiers = config.identifiers
self.assertEqual(len(identifiers), 2)
- self.failUnless(identifiers[0]['plugin'] is cp_first)
- self.assertEqual(identifiers[0]['classifier'], 'klass1')
- self.failUnless(identifiers[1]['plugin'] is cp_second)
- self.assertEqual(identifiers[1]['classifier'], None)
+ first, second = identifiers
+ self.assertEqual(first[0], 'repoze.who.tests:DummyPlugin')
+ self.failUnless(isinstance(first[1], PLUGIN_CLASS))
+ self.assertEqual(len(first[1].classifications), 1)
+ self.assertEqual(first[1].classifications[IIdentifier], 'klass1')
+ self.assertEqual(second[0], 'repoze.who.tests:DummyPlugin')
+ self.failUnless(isinstance(second[1], PLUGIN_CLASS))
def test_parse_identifiers_with_plugins(self):
+ from repoze.who.interfaces import IIdentifier
+ PLUGIN_CLASS = self._getDummyPluginClass(IIdentifier)
config = self._makeOne()
config.parse(IDENTIFIERS_WITH_PLUGINS)
identifiers = config.identifiers
self.assertEqual(len(identifiers), 2)
- self.failUnless(identifiers[0]['plugin'] is cp_first)
- self.assertEqual(identifiers[0]['classifier'], 'klass1')
- self.failUnless(identifiers[1]['plugin'] is cp_second)
- self.assertEqual(identifiers[1]['classifier'], None)
+ first, second = identifiers
+ self.assertEqual(first[0], 'foo')
+ self.failUnless(isinstance(first[1], PLUGIN_CLASS))
+ self.assertEqual(len(first[1].classifications), 1)
+ self.assertEqual(first[1].classifications[IIdentifier], 'klass1')
+ self.assertEqual(second[0], 'bar')
+ self.failUnless(isinstance(second[1], PLUGIN_CLASS))
def test_parse_authenticators_only(self):
+ from repoze.who.interfaces import IAuthenticator
+ PLUGIN_CLASS = self._getDummyPluginClass(IAuthenticator)
config = self._makeOne()
config.parse(AUTHENTICATORS_ONLY)
authenticators = config.authenticators
self.assertEqual(len(authenticators), 2)
- self.failUnless(authenticators[0]['plugin'] is cp_first)
- self.assertEqual(authenticators[0]['classifier'], 'klass1')
- self.failUnless(authenticators[1]['plugin'] is cp_second)
- self.assertEqual(authenticators[1]['classifier'], None)
+ first, second = authenticators
+ self.assertEqual(first[0], 'repoze.who.tests:DummyPlugin')
+ self.failUnless(isinstance(first[1], PLUGIN_CLASS))
+ self.assertEqual(len(first[1].classifications), 1)
+ self.assertEqual(first[1].classifications[IAuthenticator], 'klass1')
+ self.assertEqual(second[0], 'repoze.who.tests:DummyPlugin')
+ self.failUnless(isinstance(second[1], PLUGIN_CLASS))
def test_parse_authenticators_with_plugins(self):
+ from repoze.who.interfaces import IAuthenticator
+ PLUGIN_CLASS = self._getDummyPluginClass(IAuthenticator)
config = self._makeOne()
config.parse(AUTHENTICATORS_WITH_PLUGINS)
authenticators = config.authenticators
self.assertEqual(len(authenticators), 2)
- self.failUnless(authenticators[0]['plugin'] is cp_first)
- self.assertEqual(authenticators[0]['classifier'], 'klass1')
- self.failUnless(authenticators[1]['plugin'] is cp_second)
- self.assertEqual(authenticators[1]['classifier'], None)
+ first, second = authenticators
+ self.assertEqual(first[0], 'foo')
+ self.failUnless(isinstance(first[1], PLUGIN_CLASS))
+ self.assertEqual(len(first[1].classifications), 1)
+ self.assertEqual(first[1].classifications[IAuthenticator], 'klass1')
+ self.assertEqual(second[0], 'bar')
+ self.failUnless(isinstance(second[1], PLUGIN_CLASS))
def test_parse_challengers_only(self):
+ from repoze.who.interfaces import IChallenger
+ PLUGIN_CLASS = self._getDummyPluginClass(IChallenger)
config = self._makeOne()
config.parse(CHALLENGERS_ONLY)
challengers = config.challengers
self.assertEqual(len(challengers), 2)
- self.failUnless(challengers[0]['plugin'] is cp_first)
- self.assertEqual(challengers[0]['classifier'], 'klass1')
- self.failUnless(challengers[1]['plugin'] is cp_second)
- self.assertEqual(challengers[1]['classifier'], None)
+ first, second = challengers
+ self.assertEqual(first[0], 'repoze.who.tests:DummyPlugin')
+ self.failUnless(isinstance(first[1], PLUGIN_CLASS))
+ self.assertEqual(len(first[1].classifications), 1)
+ self.assertEqual(first[1].classifications[IChallenger], 'klass1')
+ self.assertEqual(second[0], 'repoze.who.tests:DummyPlugin')
+ self.failUnless(isinstance(second[1], PLUGIN_CLASS))
def test_parse_challengers_with_plugins(self):
+ from repoze.who.interfaces import IChallenger
+ PLUGIN_CLASS = self._getDummyPluginClass(IChallenger)
config = self._makeOne()
config.parse(CHALLENGERS_WITH_PLUGINS)
challengers = config.challengers
self.assertEqual(len(challengers), 2)
- self.failUnless(challengers[0]['plugin'] is cp_first)
- self.assertEqual(challengers[0]['classifier'], 'klass1')
- self.failUnless(challengers[1]['plugin'] is cp_second)
- self.assertEqual(challengers[1]['classifier'], None)
+ first, second = challengers
+ self.assertEqual(first[0], 'foo')
+ self.failUnless(isinstance(first[1], PLUGIN_CLASS))
+ self.assertEqual(len(first[1].classifications), 1)
+ self.assertEqual(first[1].classifications[IChallenger], 'klass1')
+ self.assertEqual(second[0], 'bar')
+ self.failUnless(isinstance(second[1], PLUGIN_CLASS))
def test_parse_mdproviders_only(self):
+ from repoze.who.interfaces import IMetadataProvider
+ PLUGIN_CLASS = self._getDummyPluginClass(IMetadataProvider)
config = self._makeOne()
config.parse(MDPROVIDERS_ONLY)
mdproviders = config.mdproviders
self.assertEqual(len(mdproviders), 2)
- self.failUnless(mdproviders[0]['plugin'] is cp_first)
- self.assertEqual(mdproviders[0]['classifier'], 'klass1')
- self.failUnless(mdproviders[1]['plugin'] is cp_second)
- self.assertEqual(mdproviders[1]['classifier'], None)
+ first, second = mdproviders
+ self.assertEqual(first[0], 'repoze.who.tests:DummyPlugin')
+ self.failUnless(isinstance(first[1], PLUGIN_CLASS))
+ self.assertEqual(len(first[1].classifications), 1)
+ self.assertEqual(first[1].classifications[IMetadataProvider], 'klass1')
+ self.assertEqual(second[0], 'repoze.who.tests:DummyPlugin')
+ self.failUnless(isinstance(second[1], PLUGIN_CLASS))
def test_parse_mdproviders_with_plugins(self):
+ from repoze.who.interfaces import IMetadataProvider
+ PLUGIN_CLASS = self._getDummyPluginClass(IMetadataProvider)
config = self._makeOne()
config.parse(MDPROVIDERS_WITH_PLUGINS)
mdproviders = config.mdproviders
self.assertEqual(len(mdproviders), 2)
- self.failUnless(mdproviders[0]['plugin'] is cp_first)
- self.assertEqual(mdproviders[0]['classifier'], 'klass1')
- self.failUnless(mdproviders[1]['plugin'] is cp_second)
- self.assertEqual(mdproviders[1]['classifier'], None)
-
-cp_first = object()
-cp_second = object()
+ first, second = mdproviders
+ self.assertEqual(first[0], 'foo')
+ self.failUnless(isinstance(first[1], PLUGIN_CLASS))
+ self.assertEqual(len(first[1].classifications), 1)
+ self.assertEqual(first[1].classifications[IMetadataProvider], 'klass1')
+ self.assertEqual(second[0], 'bar')
+ self.failUnless(isinstance(second[1], PLUGIN_CLASS))
+
+class DummyPlugin:
+ def __init__(self, **kw):
+ self.__dict__.update(kw)
PLUGINS_ONLY = """\
[plugin:foo]
-use = repoze.who.tests:DummyRequestClassifier
+use = repoze.who.tests:DummyPlugin
[plugin:bar]
-use = repoze.who.tests:DummyIdentifier
+use = repoze.who.tests:DummyPlugin
credentials = qux
"""
GENERAL_ONLY = """\
[general]
-request_classifier = repoze.who.tests:DummyRequestClassifier
-challenge_decider = repoze.who.tests:DummyChallengeDecider
+request_classifier = repoze.who.tests:DummyPlugin
+challenge_decider = repoze.who.tests:DummyPlugin
"""
GENERAL_WITH_PLUGINS = """\
@@ -1996,17 +2048,17 @@
challenge_decider = decider
[plugin:classifier]
-use = repoze.who.tests:DummyRequestClassifier
+use = repoze.who.tests:DummyPlugin
[plugin:decider]
-use = repoze.who.tests:DummyChallengeDecider
+use = repoze.who.tests:DummyPlugin
"""
IDENTIFIERS_ONLY = """\
[identifiers]
plugins =
- repoze.who.tests:cp_first;klass1
- repoze.who.tests:cp_second
+ repoze.who.tests:DummyPlugin;klass1
+ repoze.who.tests:DummyPlugin
"""
IDENTIFIERS_WITH_PLUGINS = """\
@@ -2016,17 +2068,17 @@
bar
[plugin:foo]
-use = repoze.who.tests:cp_first
+use = repoze.who.tests:DummyPlugin
[plugin:bar]
-use = repoze.who.tests:cp_second
+use = repoze.who.tests:DummyPlugin
"""
AUTHENTICATORS_ONLY = """\
[authenticators]
plugins =
- repoze.who.tests:cp_first;klass1
- repoze.who.tests:cp_second
+ repoze.who.tests:DummyPlugin;klass1
+ repoze.who.tests:DummyPlugin
"""
AUTHENTICATORS_WITH_PLUGINS = """\
@@ -2036,17 +2088,17 @@
bar
[plugin:foo]
-use = repoze.who.tests:cp_first
+use = repoze.who.tests:DummyPlugin
[plugin:bar]
-use = repoze.who.tests:cp_second
+use = repoze.who.tests:DummyPlugin
"""
CHALLENGERS_ONLY = """\
[challengers]
plugins =
- repoze.who.tests:cp_first;klass1
- repoze.who.tests:cp_second
+ repoze.who.tests:DummyPlugin;klass1
+ repoze.who.tests:DummyPlugin
"""
CHALLENGERS_WITH_PLUGINS = """\
@@ -2056,17 +2108,17 @@
bar
[plugin:foo]
-use = repoze.who.tests:cp_first
+use = repoze.who.tests:DummyPlugin
[plugin:bar]
-use = repoze.who.tests:cp_second
+use = repoze.who.tests:DummyPlugin
"""
MDPROVIDERS_ONLY = """\
[mdproviders]
plugins =
- repoze.who.tests:cp_first;klass1
- repoze.who.tests:cp_second
+ repoze.who.tests:DummyPlugin;klass1
+ repoze.who.tests:DummyPlugin
"""
MDPROVIDERS_WITH_PLUGINS = """\
@@ -2076,10 +2128,79 @@
bar
[plugin:foo]
-use = repoze.who.tests:cp_first
+use = repoze.who.tests:DummyPlugin
[plugin:bar]
-use = repoze.who.tests:cp_second
+use = repoze.who.tests:DummyPlugin
+"""
+
+class TestConfigMiddleware(unittest.TestCase):
+ tempfile = None
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ if self.tempfile is not None:
+ self.tempfile.close()
+
+ def _getFactory(self):
+ from repoze.who.config import make_middleware_with_config
+ return make_middleware_with_config
+
+ def _getTempfile(self, text):
+ import tempfile
+ tf = self.tempfile = tempfile.NamedTemporaryFile()
+ text = text % {'here': os.getcwd()}
+ tf.write(text)
+ tf.flush()
+ return tf
+
+ def test_sample_config(self):
+ app = DummyApp()
+ factory = self._getFactory()
+ tempfile = self._getTempfile(SAMPLE_CONFIG)
+ middleware = factory(app, config_file=tempfile.name)
+
+SAMPLE_CONFIG = """\
+[plugin:form]
+use = repoze.who.plugins.form:make_plugin
+login_form_qs = __do_login
+rememberer_name = auth_tkt
+
+[plugin:auth_tkt]
+use = repoze.who.plugins.auth_tkt:make_plugin
+secret = s33kr1t
+cookie_name = oatmeal
+secure = False
+include_ip = True
+
+[plugin:basicauth]
+use = repoze.who.plugins.basicauth:make_plugin
+realm = 'sample'
+
+[plugin:htpasswd]
+use = repoze.who.plugins.htpasswd:make_plugin
+filename = %(here)s/etc/passwd
+check_fn = repoze.who.plugins.htpasswd:crypt_check
+
+[general]
+request_classifier = repoze.who.classifiers:default_request_classifier
+challenge_decider = repoze.who.classifiers:default_challenge_decider
+
+[identifiers]
+plugins =
+ form;browser
+ auth_tkt
+ basicauth
+
+[authenticators]
+plugins = htpasswd
+
+[challengers]
+plugins =
+ form;browser
+ basicauth
"""
def compare_success(*arg):
@@ -2264,7 +2385,7 @@
DummyConnFactory = _DummyConnFactory()
-def make_dummy_connfactory(who_conf, **kw):
+def make_dummy_connfactory(**kw):
return DummyConnFactory
def encode_multipart_formdata(fields):
More information about the Repoze-checkins
mailing list