[Zope-CVS] CVS: Products/PluggableAuthService - CHANGES.txt:1.1.2.1
PluggableAuthService.py:1.6.2.4 PropertiedUser.py:1.3.4.1
Lennart Regebro
regebro at nuxeo.com
Tue Aug 31 10:42:13 EDT 2004
Update of /cvs-repository/Products/PluggableAuthService
In directory cvs.zope.org:/tmp/cvs-serv26731
Modified Files:
Tag: regebro-implement_challenge-branch
PluggableAuthService.py PropertiedUser.py
Added Files:
Tag: regebro-implement_challenge-branch
CHANGES.txt
Log Message:
Merge from HEAD + new challenge implementation.
=== Added File Products/PluggableAuthService/CHANGES.txt ===
22 August 2004
PluggableAuthService.py:
- arrows images finally work in the ZMI
- searchPrincipals will work for exact matches when a plugin
supports both enumerateUsers and enumerateGroups
- 'Authenticated' Role is added dynamically by the
PluggableAuthService, not by any role manager
plugins/ZODBGroupManager.py:
- if a previously assigned principal goes away, the
ZODBGroupManager won't freak out.
plugins/ZODBRoleManager.py:
- ZODBRoleManager will only claim authority for the
__ac_roles__ of its grandparent that aren't 'Authenticated'
or 'Anonymous'
- if a previously assigned principal goes away, the
ZODBRoleManager won't freak out.
plugins/ZODBUserManager.py:
- ZODBUserManager now uses AuthEncoding for its password
encryption so that we can more easily support migrating
existing UserFolders. Since PAS has been out for a while,
though, we still will authenticate against old credentials
=== Products/PluggableAuthService/PluggableAuthService.py 1.6.2.3 => 1.6.2.4 ===
--- Products/PluggableAuthService/PluggableAuthService.py:1.6.2.3 Mon Aug 30 13:12:07 2004
+++ Products/PluggableAuthService/PluggableAuthService.py Tue Aug 31 10:41:42 2004
@@ -17,6 +17,8 @@
$Id$
"""
+import sys
+
from Acquisition import Implicit, aq_parent, aq_base, aq_inner
from AccessControl import ClassSecurityInfo, ModuleSecurityInfo
@@ -27,7 +29,8 @@
from AccessControl.User import nobody
from AccessControl.SpecialUsers import emergency_user
-import sys
+from App.ImageFile import ImageFile
+
from zLOG import LOG, WARNING
from zExceptions import Unauthorized
from Persistence import PersistentMapping
@@ -117,7 +120,7 @@
return creds
InitializeClass( DumbHTTPExtractor )
-
+
class EmergencyUserAuthenticator( Implicit ):
@@ -146,7 +149,7 @@
InitializeClass( EmergencyUserAuthenticator )
-
+
class PluggableAuthService( Folder ):
""" All-singing, all-dancing user folder.
@@ -163,7 +166,15 @@
_nobody = nobody
maxlistusers = -1 # Don't allow local role form to try to list us!
-
+
+ #
+ # ZMI
+ #
+ arrow_right_gif = ImageFile( 'www/arrow-right.gif', globals() )
+ arrow_left_gif = ImageFile( 'www/arrow-left.gif', globals() )
+ arrow_up_gif = ImageFile( 'www/arrow-up.gif', globals() )
+ arrow_down_gif = ImageFile( 'www/arrow-down.gif', globals() )
+
def getId( self ):
return self._id
@@ -254,7 +265,7 @@
else:
return None
- if self._authorizeUser( user
+ if self._authorizeUser( user
, accessed
, container
, name
@@ -264,23 +275,25 @@
return user
if not is_top:
- # Try to validate with user folders higher up.
- innerob=self.aq_parent
- while hasattr(innerob,"aq_parent"):
- inner = getattr(innerob, 'aq_inner', innerob)
- parent = getattr(inner, 'aq_parent', None)
- if parent is not None:
- innerob = parent
- else:
- if hasattr(innerob, 'im_self'):
- innerob = innerob.im_self
- innerob = getattr(innerob, 'aq_inner', innerob)
- if hasattr(innerob,"__allow_groups__"):
- userfolder=innerob.__allow_groups__
- if hasattr(userfolder,"validate"):
- user=userfolder.validate(request,auth,roles)
- if user is not None:
- return user
+ self.setupChallenge(plugins, request.RESPONSE)
+ return None
+# # Try to validate with user folders higher up.
+# innerob=self.aq_parent
+# while hasattr(innerob,"aq_parent"):
+# inner = getattr(innerob, 'aq_inner', innerob)
+# parent = getattr(inner, 'aq_parent', None)
+# if parent is not None:
+# innerob = parent
+# else:
+# if hasattr(innerob, 'im_self'):
+# innerob = innerob.im_self
+# innerob = getattr(innerob, 'aq_inner', innerob)
+# if hasattr(innerob,"__allow_groups__"):
+# userfolder=innerob.__allow_groups__
+# if hasattr(userfolder,"validate"):
+# user=userfolder.validate(request,auth,roles)
+# if user is not None:
+# return user
#
# No other user folder above us can satisfy, and we have no user;
@@ -297,26 +310,57 @@
return anonymous
# No validation in upper user folders: Make a challenge
+
+# for challenger_id, challenger in challengers:
+# try:
+# # A successful challenge involves raising a
+# # "Redirect", url exception.
+# if challenger.challenge(request, request.RESPONSE):
+# break
+#
+# except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
+# LOG('PluggableAuthService', WARNING,
+# 'ChallengePlugin %s error' % challenger_id,
+# error=sys.exc_info())
+
+ return None
+
+
+ def setupChallenge(self, plugins, response):
+ #import pdb;pdb.set_trace()
+ challengers = plugins.listPlugins(IChallengePlugin)
+ if len(challengers) > 0 and \
+ not getattr(response, '_old_unauthorized', None):
+ response._old_unauthorized = response.unauthorized
+ response.unauthorized = self.challenge
+ response._challenger = self
+
+ def challenge(self):
+ #import pdb;pdb.set_trace()
+ request = self.REQUEST
+ response = request.RESPONSE
+ plugins = self._getOb( 'plugins' )
+
challengers = plugins.listPlugins(IChallengePlugin)
for challenger_id, challenger in challengers:
try:
- # A successful challenge involves raising a
- # "Redirect", url exception.
- challenger.challenge(request, request.RESPONSE)
+ if challenger.challenge(request, response):
+ return
+
except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
LOG('PluggableAuthService', WARNING,
'ChallengePlugin %s error' % challenger_id,
error=sys.exc_info())
-
- return None
-
+
+ response._old_unauthorized()
+
security.declareProtected( SearchPrincipals, 'searchUsers')
def searchUsers(self, **kw):
""" Search for users """
exact_match = kw.get( 'exact_match', False )
search_id = kw.get( 'id', None )
search_name = kw.get( 'name', None )
-
+
if exact_match and search_id:
plugin_id, principal_id = self._unmangleId( search_id )
plugin = getattr( self, plugin_id, None )
@@ -341,7 +385,7 @@
'UserEnumerationPlugin %s error' % plugin_id,
error=sys.exc_info())
return ()
-
+
result = []
max_results = kw.get('max_results', '')
sort_by = kw.get('sort_by', '')
@@ -359,7 +403,7 @@
plugins = self._getOb( 'plugins' )
enumerators = plugins.listPlugins( IUserEnumerationPlugin )
-
+
for enumerator_id, enum in enumerators:
try:
user_list = enum.enumerateUsers(**kw)
@@ -371,7 +415,7 @@
info[ 'principal_type' ] = 'user'
info[ 'title' ] = info[ 'login' ]
result.append(info)
-
+
except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
LOG('PluggableAuthService', WARNING,
'UserEnumerationPlugin %s error' % enumerator_id,
@@ -397,7 +441,7 @@
exact_match = kw.get( 'exact_match', False )
search_id = kw.get( 'id', None )
search_name = kw.get( 'name', None )
-
+
if exact_match and search_id:
plugin_id, principal_id = self._unmangleId( search_id )
plugin = getattr( self, plugin_id, None )
@@ -422,7 +466,7 @@
'GroupEnumerationPlugin %s error' % plugin_id,
error=sys.exc_info())
return ()
-
+
result = []
max_results = kw.get('max_results', '')
sort_by = kw.get('sort_by', '')
@@ -484,24 +528,29 @@
kw['login'] = search_name
if exact_match and search_id:
+ user_info = group_info = ()
+
plugin_id, principal_id = self._unmangleId( search_id )
plugin = getattr( self, plugin_id, None )
if plugin is not None:
if getattr( aq_base( plugin ), 'enumerateUsers', None ):
- enumeratePrincipals = plugin.enumerateUsers
- local_key = 'userid'
- principal_type = 'user'
- title_key = 'login'
- title_pattern = "%s"
- else:
- enumeratePrincipals = plugin.enumerateGroups
- local_key = 'groupid'
- principal_type = 'group'
- title_key = 'groupid'
- title_pattern = "(Group) %s"
+ user_info = plugin.enumerateUsers( id=principal_id
+ , exact_match=True )
+ if user_info:
+ local_key = 'userid'
+ principal_type = 'user'
+ title_key = 'login'
+ title_pattern = "%s"
+ if getattr( aq_base( plugin ), 'enumerateGroups', None ):
+ group_info = plugin.enumerateGroups( id=principal_id
+ , exact_match=True )
+ if group_info:
+ local_key = 'groupid'
+ principal_type = 'group'
+ title_key = 'groupid'
+ title_pattern = "(Group) %s"
try:
- principal_info = enumeratePrincipals( id=principal_id
- , exact_match=True )
+ principal_info = filter(None, (user_info + group_info))
assert( len( principal_info ) in [ 0, 1 ] )
if principal_info:
principal_info = principal_info[ 0 ]
@@ -571,7 +620,7 @@
manage_options = ( Folder.manage_options[:1]
+ ( { 'label' : 'Search'
, 'action': 'manage_search' }
- ,
+ ,
)
+ Folder.manage_options[2:]
)
@@ -719,8 +768,7 @@
continue
if user_id is not None:
- mangled_id = self._mangleId( authenticator_id
- , user_id )
+ mangled_id = self._verifyUser(plugins, user_id)
user_ids.append( (mangled_id, name) )
@@ -739,28 +787,26 @@
security.declarePrivate( '_unmangleId' )
def _unmangleId( self, mangled_id ):
-
+
return mangled_id.split( MANGLE_DELIMITER, 1 )
security.declarePrivate( '_mangleId' )
def _mangleId( self, namespace, id ):
- if id.find(MANGLE_DELIMITER) != -1:
- return id
return MANGLE_DELIMITER.join( ( namespace, id ) )
security.declarePrivate( '_computeMangledId' )
def _computeMangledId( self, info_dict ):
""" Synthesize an from info_dict.
-
+
o Mangle plugin and original id together.
"""
return self._mangleId( info_dict[ 'pluginid' ], info_dict[ 'id' ] )
security.declarePrivate( '_tryEmergencyUserAuthentication' )
def _tryEmergencyUserAuthentication( self, credentials ):
-
+
""" credentials -> emergency_user or None
"""
try:
@@ -870,7 +916,7 @@
groups = self._getGroupsForPrincipal( user, request
, plugins=plugins )
user._addGroups( groups )
-
+
rolemakers = plugins.listPlugins( IRolesPlugin )
for rolemaker_id, rolemaker in rolemakers:
@@ -882,6 +928,7 @@
if roles:
user._addRoles( roles )
+ user._addRoles( ['Authenticated'] )
cache[ user_id ] = user
return user.__of__( self )
@@ -1038,7 +1085,7 @@
plugins = self._getOb( 'plugins' )
useradders = plugins.listPlugins( IUserAdderPlugin )
roleassigners = plugins.listPlugins( IRoleAssignerPlugin )
-
+
user = None
if not (useradders and roleassigners):
=== Products/PluggableAuthService/PropertiedUser.py 1.3 => 1.3.4.1 ===
--- Products/PluggableAuthService/PropertiedUser.py:1.3 Thu Aug 12 11:15:53 2004
+++ Products/PluggableAuthService/PropertiedUser.py Tue Aug 31 10:41:42 2004
@@ -55,7 +55,7 @@
""" -> login name
"""
return self._login
-
+
def getRoles( self ):
""" -> [ role ]
@@ -125,7 +125,7 @@
continue
new = getattr( object, 'im_self', None )
-
+
if new is not None:
object = aq_inner( new )
@@ -138,7 +138,7 @@
def allowed( self, object, object_roles=None ):
""" Check whether the user has access to object.
-
+
o The user must have one of the roles in object_roles to allow access.
o Include *both* local roles assigned directly to us *and* those
More information about the Zope-CVS
mailing list