paula.testing: test for finding txt files + minor bugfix
[paula/paual.testing.git] / paula.pasplugins / src / paula / pasplugins / plugins / auth.py
blob20f15b3b23085ab18bf2942e79a87414988b95b0
1 # Copyright (c) 2008 by Florian Friesdorf
3 # GNU Affero General Public License (AGPL)
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as
7 # published by the Free Software Foundation; either version 3 of the
8 # License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Affero General Public License for more details.
15 # You should have received a copy of the GNU Affero General Public
16 # License along with this program. If not, see
17 # <http://www.gnu.org/licenses/>.
18 """
19 """
20 __author__ = "Florian Friesdorf <flo@chaoflow.net>"
21 __docformat__ = "plaintext"
23 import UserDict
25 from Globals import InitializeClass
26 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
28 from Products.PlonePAS.interfaces.capabilities import IDeleteCapability
29 from Products.PlonePAS.interfaces.capabilities import IPasswordSetCapability
30 from Products.PlonePAS.interfaces.plugins import IUserIntrospection
31 from Products.PlonePAS.interfaces.plugins import IUserManagement
33 from Products.PluggableAuthService.interfaces.plugins \
34 import IAuthenticationPlugin
35 from Products.PluggableAuthService.interfaces.plugins import IUserAdderPlugin
36 from Products.PluggableAuthService.interfaces.plugins \
37 import IUserEnumerationPlugin
39 from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
41 from zope.app.security.interfaces import IAuthentication
42 from zope.app.security.interfaces import PrincipalLookupError
44 from zope.interface import implements, alsoProvides
45 from zope.component import getUtility
46 from zope.publisher.interfaces import IRequest
48 from paula.pasplugins.tests.fake_pau_ap import FAKE_LOGIN
50 manage_addAuthenticationPluginForm = PageTemplateFile(
51 '../www/AuthenticationPluginForm',
52 globals(), __name__='manage_addAuthenticationPluginForm' )
55 def addAuthenticationPlugin( dispatcher, id, title=None, REQUEST=None ):
56 """Add a paula.plonepas AuthenticationPlugin to a PluggableAuthService.
57 """
58 plugin = AuthenticationPlugin(id, title)
59 dispatcher._setObject(plugin.getId(), plugin)
61 if REQUEST is not None:
62 REQUEST['RESPONSE'].redirect(
63 '%s/manage_workspace'
64 '?manage_tabs_message='
65 'paula.pasplugins.AuthenticationPlugin+added.'
66 % dispatcher.absolute_url())
69 paula_auth_ifs = (
70 IAuthenticationPlugin,
71 IUserAdderPlugin,
72 IUserEnumerationPlugin,
73 IUserManagement,
74 # IUserIntrospection,
77 class AuthenticationPlugin(BasePlugin):
78 """
79 """
80 implements(
81 IDeleteCapability,
82 IPasswordSetCapability,
83 *paula_auth_ifs
86 meta_type = "Paula PAS Authentication Plugin"
88 def __init__(self, id, title=None):
89 self._id = self.id = id
90 self.title = title
92 # IAuthenticationPlugin
94 def authenticateCredentials(self, credentials):
95 """ credentials -> (userid, login)
97 o 'credentials' will be a mapping, as returned by IExtractionPlugin.
99 o Return a tuple consisting of user ID (which may be different
100 from the login name) and login
102 o If the credentials cannot be authenticated, return None.
104 Mock principal
106 >>> p = Mock(id = 'login')
108 Mockup IPluggableAuthentication
110 >>> au = Mock(authenticate = \\
111 ... lambda x : IRequest.providedBy(x) \\
112 ... and x.has_key('login') \\
113 ... and x.has_key('password') \\
114 ... and p,
115 ... alsoProvides=(IAuthentication,))
116 >>> provideUtility(au, IAuthentication)
118 our authentication plugin
120 >>> ap = AuthenticationPlugin('ap')
122 wrong credentials
124 >>> creds = {}
125 >>> creds['login'] = 'foo'
126 >>> ap.authenticateCredentials(creds) is None
127 True
129 correct credentials
131 >>> creds['password'] = 'foo'
132 >>> ap.authenticateCredentials(creds)
133 ('login', 'login')
135 and otherway wrong creds
137 >>> del creds['login']
138 >>> ap.authenticateCredentials(creds) is None
139 True
141 pau = getUtility(IAuthentication)
143 # pau expects something providing request
144 # our fake credentials plugin is fine with a mapping
145 request = UserDict.UserDict(credentials)
146 alsoProvides(request, IRequest)
148 principal = pau.authenticate(request)
149 if principal:
150 return (principal.id, principal.id)
152 #if credentials['login'] is 'adam':
153 # return ('adam', 'adam')
155 return None
157 # IUserAdderPlugin
159 def doAddUser(self, login, password):
160 """ Add a user record to a User Manager, with the given login
161 and password
163 o Return a Boolean indicating whether a user was added or not
165 pau = getUtility(IAuthentication)
166 if pau.addUser(login, password):
167 return True
169 return False
172 # IDeleteCapability
174 def allowDeletePrincipal(self, id):
175 """True iff this plugin can delete a certain user/group.
177 #XXX: We need to check with PAU whether we can delete the principal
178 pau = getUtility(IAuthentication)
179 return pau.allowDeletePrincipal(id)
181 # IPasswordSetCapability
183 def allowPasswordSet(self, id):
184 """True iff this plugin can set the password of a certain user.
186 pau = getUtility(IAuthentication)
187 return pau.allowPasswordSet(id)
189 # IUserManagamenet
191 def doChangeUser(self, login, password, **kws):
193 Change a user's password (differs from role) roles are set in
194 the pas engine api for the same but are set via a role
195 manager)
197 pau = getUtility(IAuthentication)
198 if not pau.doChangeUser(login, password, **kws):
199 # maybe should be moved to the PAU auth plugins
200 raise RuntimeError
202 def doDeleteUser(self, login):
204 Remove a user record from a User Manager, with the given login
205 and password
207 o Return a Boolean indicating whether a user was removed or
210 pau = getUtility(IAuthentication)
211 return pau.delPrincipal(login)
213 # IUserEnumerationPlugin
215 def enumerateUsers( self
216 , id=None
217 , login=None
218 , exact_match=False
219 , sort_by=None
220 , max_results=None
221 , **kw
223 pau = getUtility(IAuthentication)
225 if exact_match:
226 #XXX: id and login are treated equal - fixme!
227 try:
228 principal = pau.getPrincipal( id or login)
229 except PrincipalLookupError:
230 return ()
232 #XXX: do something with the data from the returned principal?!
233 return ({
234 'id': login or id,
235 'login': login or id,
236 'pluginid': self.getId(),
239 # XXX: no exact_match, we need to search for the user in PAU
241 # # IUserIntrospection
243 # def getUserIds(self):
244 # # called eg when going into the memberdata tool contents
245 # return ('fakelogin',)
247 # # IUserIntrospection
249 # def getUserNames(self):
250 # return ('fakelogin',)
252 # # IUserIntrospection
254 # def getUsers(self):
255 # """
256 # Return a list of users
258 # XXX DON'T USE THIS, it will kill performance
259 # """
260 # uf = getToolByName(self, 'acl_users')
261 # return tuple([uf.getUserById(x) for x in self.getUserIds()])
264 InitializeClass( AuthenticationPlugin)