[Repoze-checkins] r782 - in repoze.pam/trunk: . repoze/pam
Chris McDonough
chrism at agendaless.com
Sat Mar 8 02:59:25 UTC 2008
Author: Chris McDonough <chrism at agendaless.com>
Date: Fri Mar 7 21:59:25 2008
New Revision: 782
Log:
0.4 (03-07-2008)
- Allow plugins to specify a classifiers list per interface (instead
of a single classifiers list per plugin).
Modified:
repoze.pam/trunk/CHANGES.txt
repoze.pam/trunk/TODO.txt
repoze.pam/trunk/repoze/pam/middleware.py
repoze.pam/trunk/repoze/pam/tests.py
repoze.pam/trunk/setup.py
Modified: repoze.pam/trunk/CHANGES.txt
==============================================================================
--- repoze.pam/trunk/CHANGES.txt (original)
+++ repoze.pam/trunk/CHANGES.txt Fri Mar 7 21:59:25 2008
@@ -1,3 +1,8 @@
+0.4 (03-07-2008)
+
+ - Allow plugins to specify a classifiers list per interface (instead
+ of a single classifiers list per plugin).
+
0.3 (03-05-2008)
- Make SQLAuthenticatorPlugin's default_password_compare use
Modified: repoze.pam/trunk/TODO.txt
==============================================================================
--- repoze.pam/trunk/TODO.txt (original)
+++ repoze.pam/trunk/TODO.txt Fri Mar 7 21:59:25 2008
@@ -1,5 +1,2 @@
-- Fix so each plugin has a classifiers attr per-plugin-type (as
- opposed to a single classifiers attr as it has now).
-
- Config file parser.
Modified: repoze.pam/trunk/repoze/pam/middleware.py
==============================================================================
--- repoze.pam/trunk/repoze/pam/middleware.py (original)
+++ repoze.pam/trunk/repoze/pam/middleware.py Fri Mar 7 21:59:25 2008
@@ -58,8 +58,7 @@
if ids:
auth_ids = self.authenticate(environ, classification, ids)
# auth_ids will be a list of four-tuples; when sorted,
- # its first element will be the "best" identity. The fourth
- # element in the tuple is the user_id.
+ # its first element will be the "best" identity.
if auth_ids:
auth_ids.sort()
best = auth_ids[0]
@@ -111,7 +110,7 @@
candidates = self.registry.get(IIdentifier, ())
logger and self.logger.info('identifier plugins registered %s' %
candidates)
- plugins = self._match_classification(candidates, classification)
+ plugins = match_classification(IIdentifier, candidates, classification)
logger and self.logger.info(
'identifier plugins matched for '
'classification "%s": %s' % (classification, plugins))
@@ -135,7 +134,8 @@
candidates = self.registry.get(IAuthenticator, ())
logger and self.logger.info('authenticator plugins registered %s' %
candidates)
- plugins = self._match_classification(candidates, classification)
+ plugins = match_classification(IAuthenticator, candidates,
+ classification)
logger and self.logger.info(
'authenticator plugins matched for '
'classification "%s": %s' % (classification, plugins))
@@ -182,7 +182,8 @@
candidates = self.registry.get(IChallenger, ())
logger and logger.info('challengers registered: %s' % candidates)
- plugins = self._match_classification(candidates, classification)
+ plugins = match_classification(IChallenger,
+ candidates, classification)
logger and logger.info('challengers matched for '
'classification "%s": %s' % (classification,
plugins))
@@ -200,17 +201,19 @@
logger and logger.info('no challenge app returned')
return None
- def _match_classification(self, plugins, classification):
- result = []
- for plugin in plugins:
- plugin_classifications = getattr(plugin, 'classifications', None)
- if not plugin_classifications: # good for any
- result.append(plugin)
- continue
- if classification in plugin_classifications:
- result.append(plugin)
-
- return result
+def match_classification(iface, plugins, classification):
+ result = []
+ for plugin in plugins:
+
+ plugin_classifications = getattr(plugin, 'classifications', {})
+ iface_classifications = plugin_classifications.get(iface)
+ if not iface_classifications: # good for any
+ result.append(plugin)
+ continue
+ if classification in iface_classifications:
+ result.append(plugin)
+
+ return result
class StartResponseWrapper(object):
def __init__(self, start_response):
@@ -284,8 +287,6 @@
from repoze.pam.plugins.cookie import InsecureCookiePlugin
from repoze.pam.plugins.form import FormPlugin
basicauth = BasicAuthPlugin('repoze.pam')
- any = None # means good for any classification
- basicauth.classifications = any
from StringIO import StringIO
from repoze.pam.plugins.htpasswd import crypt_check
io = StringIO()
@@ -295,11 +296,10 @@
io.write('%s:%s\n' % (name, crypt.crypt(password, salt)))
io.seek(0)
htpasswd = HTPasswdPlugin(io, crypt_check)
- htpasswd.classifications = any
cookie = InsecureCookiePlugin('oatmeal')
- cookie.classifications = any
form = FormPlugin('__do_login', rememberer_name='cookie')
- form.classifications = set(('browser',)) # only for for browser requests
+ form.classifications = { IIdentifier:['browser'],
+ IChallenger:['browser'] } # only for browser
identifiers = [('form', form),('cookie',cookie),('basicauth',basicauth) ]
authenticators = [('htpasswd', htpasswd)]
challengers = [('form',form), ('basicauth',basicauth)]
Modified: repoze.pam/trunk/repoze/pam/tests.py
==============================================================================
--- repoze.pam/trunk/repoze/pam/tests.py (original)
+++ repoze.pam/trunk/repoze/pam/tests.py Fri Mar 7 21:59:25 2008
@@ -105,7 +105,8 @@
environ = self._makeEnviron()
mw = self._makeOne()
plugin1 = DummyIdentifier({'login':'fred','password':'fred'})
- plugin1.classifications = set(['nomatch'])
+ from repoze.pam.interfaces import IIdentifier
+ plugin1.classifications = {IIdentifier:['nomatch']}
plugin2 = DummyIdentifier({'login':'bob','password':'bob'})
plugins = [ ('identifier1', plugin1), ('identifier2', plugin2) ]
mw = self._makeOne(identifiers=plugins)
@@ -118,10 +119,11 @@
def test_identify_find_explicit_classifier(self):
environ = self._makeEnviron()
+ from repoze.pam.interfaces import IIdentifier
plugin1 = DummyIdentifier({'login':'fred','password':'fred'})
- plugin1.classifications = set(['nomatch'])
+ plugin1.classifications = {IIdentifier:['nomatch']}
plugin2 = DummyIdentifier({'login':'bob','password':'bob'})
- plugin2.classifications = set(['match'])
+ plugin2.classifications = {IIdentifier:['match']}
plugins= [ ('identifier1', plugin1), ('identifier2', plugin2) ]
mw = self._makeOne(identifiers=plugins)
results = mw.identify(environ, 'match')
@@ -203,7 +205,8 @@
environ = self._makeEnviron()
mw = self._makeOne()
plugin1 = DummyAuthenticator('chris_id1')
- plugin1.classifications = set(['nomatch'])
+ from repoze.pam.interfaces import IAuthenticator
+ plugin1.classifications = {IAuthenticator:['nomatch']}
plugin2 = DummyAuthenticator('chris_id2')
plugins = [ ('auth1', plugin1), ('auth2', plugin2) ]
mw = self._makeOne(authenticators = plugins)
@@ -221,10 +224,11 @@
def test_authenticate_find_explicit_classifier(self):
environ = self._makeEnviron()
mw = self._makeOne()
+ from repoze.pam.interfaces import IAuthenticator
plugin1 = DummyAuthenticator('chris_id1')
- plugin1.classifications = set(['nomatch'])
+ plugin1.classifications = {IAuthenticator:['nomatch']}
plugin2 = DummyAuthenticator('chris_id2')
- plugin2.classificationans = set(['match']) # game
+ plugin2.classifications = {IAuthenticator:['match']}
plugins = [ ('auth1', plugin1), ('auth2', plugin2) ]
mw = self._makeOne(authenticators = plugins)
identities = [ (None, {'login':'chris', 'password':'password'}) ]
@@ -241,12 +245,11 @@
def test_challenge_noidentifier_noapp(self):
environ = self._makeEnviron()
challenger = DummyChallenger()
- challenger.classifications = None
plugins = [ ('challenge', challenger) ]
mw = self._makeOne(challengers = plugins)
identity = {'login':'chris', 'password':'password'}
app = mw.challenge(environ, 'match', '401 Unauthorized',
- [], None, identity)
+ [], None, identity)
self.assertEqual(app, None)
self.assertEqual(environ['challenged'], app)
@@ -254,7 +257,6 @@
environ = self._makeEnviron()
app = DummyApp()
challenger = DummyChallenger(app)
- challenger.classifications = None
plugins = [ ('challenge', challenger) ]
mw = self._makeOne(challengers = plugins)
identity = {'login':'chris', 'password':'password'}
@@ -266,7 +268,6 @@
def test_challenge_identifier_noapp(self):
environ = self._makeEnviron()
challenger = DummyChallenger()
- challenger.classifications = None
identifier = DummyIdentifier()
plugins = [ ('challenge', challenger) ]
mw = self._makeOne(challengers = plugins)
@@ -281,7 +282,6 @@
environ = self._makeEnviron()
app = DummyApp()
challenger = DummyChallenger(app)
- challenger.classifications = None
identifier = DummyIdentifier()
plugins = [ ('challenge', challenger) ]
mw = self._makeOne(challengers = plugins)
@@ -297,9 +297,7 @@
app1 = DummyApp()
app2 = DummyApp()
challenger1 = DummyChallenger(app1)
- challenger1.classifications = None
challenger2 = DummyChallenger(app2)
- challenger2.classifications = None
identifier = DummyIdentifier()
plugins = [ ('challenge1', challenger1), ('challenge2', challenger2) ]
mw = self._makeOne(challengers = plugins)
@@ -314,10 +312,11 @@
environ = self._makeEnviron()
app1 = DummyApp()
app2 = DummyApp()
+ from repoze.pam.interfaces import IChallenger
challenger1 = DummyChallenger(app1)
- challenger1.classifications = ['nomatch']
+ challenger1.classifications = {IChallenger:['nomatch']}
challenger2 = DummyChallenger(app2)
- challenger2.classifications = None
+ challenger2.classifications = {IChallenger:None}
identifier = DummyIdentifier()
plugins = [ ('challenge1', challenger1), ('challenge2', challenger2) ]
mw = self._makeOne(challengers = plugins)
@@ -332,10 +331,11 @@
environ = self._makeEnviron()
app1 = DummyApp()
app2 = DummyApp()
+ from repoze.pam.interfaces import IChallenger
challenger1 = DummyChallenger(app1)
- challenger1.classifications = ['nomatch']
+ challenger1.classifications = {IChallenger:['nomatch']}
challenger2 = DummyChallenger(app2)
- challenger2.classifications = ['match']
+ challenger2.classifications = {IChallenger:['match']}
identifier = DummyIdentifier()
plugins = [ ('challenge1', challenger1), ('challenge2', challenger2) ]
mw = self._makeOne(challengers = plugins)
@@ -464,9 +464,37 @@
self.assertEqual(identifier.remembered, True)
self.assertEqual(environ['REMOTE_USER'], 'chris')
+
+
# XXX need more call tests:
# - auth_id sorting
+class TestMatchClassification(unittest.TestCase):
+ def _getFUT(self):
+ from repoze.pam.middleware import match_classification
+ return match_classification
+
+ def test_match_classification(self):
+ f = self._getFUT()
+ from repoze.pam.interfaces import IIdentifier
+ from repoze.pam.interfaces import IChallenger
+ from repoze.pam.interfaces import IAuthenticator
+ multi1 = DummyMultiPlugin()
+ multi2 = DummyMultiPlugin()
+ multi1.classifications = {IIdentifier:('foo', 'bar'),
+ IChallenger:('buz',),
+ IAuthenticator:None}
+ multi2.classifications = {IIdentifier:('foo', 'baz', 'biz')}
+ plugins = (multi1, multi2)
+ # specific
+ self.assertEqual(f(IIdentifier, plugins, 'foo'), [multi1, multi2])
+ self.assertEqual(f(IIdentifier, plugins, 'bar'), [multi1])
+ self.assertEqual(f(IIdentifier, plugins, 'biz'), [multi2])
+ # any for multi2
+ self.assertEqual(f(IChallenger, plugins, 'buz'), [multi1, multi2])
+ # any for either
+ self.assertEqual(f(IAuthenticator, plugins, 'buz'), [multi1, multi2])
+
class TestStartResponseWrapper(unittest.TestCase):
def _getTargetClass(self):
from repoze.pam.middleware import StartResponseWrapper
@@ -1159,6 +1187,9 @@
return credentials['login']
return self.userid
+class DummyMultiPlugin:
+ pass
+
class DummyFailAuthenticator:
def authenticate(self, environ, credentials):
return None
Modified: repoze.pam/trunk/setup.py
==============================================================================
--- repoze.pam/trunk/setup.py (original)
+++ repoze.pam/trunk/setup.py Fri Mar 7 21:59:25 2008
@@ -12,7 +12,7 @@
#
##############################################################################
-__version__ = '0.3'
+__version__ = '0.4'
import os
More information about the Repoze-checkins
mailing list