paula.pasplugins: IUserAdder stub
[paula.git] / paula.pasplugins / src / paula / pasplugins / plugins / auth.py
blob9f56bd73893997757494627c1633b1f202414a67
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 AccessControl import ClassSecurityInfo
26 from Globals import InitializeClass
27 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
29 #from Products.PlonePAS.interfaces.plugins import IUserIntrospection
30 from Products.PluggableAuthService.interfaces.plugins \
31 import IAuthenticationPlugin
32 from Products.PluggableAuthService.interfaces.plugins import IUserAdderPlugin
33 from Products.PluggableAuthService.interfaces.plugins \
34 import IUserEnumerationPlugin
35 from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
37 from zope.app.security.interfaces import IAuthentication
38 from zope.app.security.interfaces import PrincipalLookupError
40 from zope.interface import implements, alsoProvides
41 from zope.component import getUtility
42 from zope.publisher.interfaces import IRequest
44 from paula.pasplugins.tests.fake_pau_ap import FAKE_LOGIN
46 manage_addAuthenticationPluginForm = PageTemplateFile(
47 '../www/AuthenticationPluginForm',
48 globals(), __name__='manage_addAuthenticationPluginForm' )
51 def addAuthenticationPlugin( dispatcher, id, title=None, REQUEST=None ):
52 """Add a paula.plonepas AuthenticationPlugin to a PluggableAuthService.
53 """
54 plugin = AuthenticationPlugin(id, title)
55 dispatcher._setObject(plugin.getId(), plugin)
57 if REQUEST is not None:
58 REQUEST['RESPONSE'].redirect(
59 '%s/manage_workspace'
60 '?manage_tabs_message='
61 'paula.pasplugins.AuthenticationPlugin+added.'
62 % dispatcher.absolute_url())
65 class AuthenticationPlugin(BasePlugin):
66 """
67 """
68 security = ClassSecurityInfo()
70 implements(
71 IAuthenticationPlugin,
72 IUserEnumerationPlugin,
73 IUserAdderPlugin,
74 # IUserIntrospection,
77 meta_type = "Paula PAS Authentication Plugin"
79 def __init__(self, id, title=None):
80 self._id = self.id = id
81 self.title = title
83 # IAuthenticationPlugin
85 security.declarePrivate('authenticateCredentials')
86 def authenticateCredentials(self, credentials):
87 """ credentials -> (userid, login)
89 o 'credentials' will be a mapping, as returned by IExtractionPlugin.
91 o Return a tuple consisting of user ID (which may be different
92 from the login name) and login
94 o If the credentials cannot be authenticated, return None.
96 Mock principal
98 >>> p = Mock(id = 'login')
100 Mockup IPluggableAuthentication
102 >>> au = Mock(authenticate = \\
103 ... lambda x : IRequest.providedBy(x) \\
104 ... and x.has_key('login') \\
105 ... and x.has_key('password') \\
106 ... and p,
107 ... alsoProvides=(IAuthentication,))
108 >>> provideUtility(au, IAuthentication)
110 our authentication plugin
112 >>> ap = AuthenticationPlugin('ap')
114 wrong credentials
116 >>> creds = {}
117 >>> creds['login'] = 'foo'
118 >>> ap.authenticateCredentials(creds) is None
119 True
121 correct credentials
123 >>> creds['password'] = 'foo'
124 >>> ap.authenticateCredentials(creds)
125 ('login', 'login')
127 and otherway wrong creds
129 >>> del creds['login']
130 >>> ap.authenticateCredentials(creds) is None
131 True
133 pau = getUtility(IAuthentication)
135 # pau expects something providing request
136 # our fake credentials plugin is fine with a mapping
137 request = UserDict.UserDict(credentials)
138 alsoProvides(request, IRequest)
140 principal = pau.authenticate(request)
141 if principal:
142 return (principal.id, principal.id)
144 #if credentials['login'] is 'adam':
145 # return ('adam', 'adam')
147 return None
149 # IUserAdderPlugin
151 security.declarePrivate( 'enumerateUsers' )
152 def doAddUser(self, login, password):
153 # if successful add return True
156 return False
158 # IUserEnumerationPlugin
160 security.declarePrivate( 'enumerateUsers' )
161 def enumerateUsers( self
162 , id=None
163 , login=None
164 , exact_match=False
165 , sort_by=None
166 , max_results=None
167 , **kw
169 pau = getUtility(IAuthentication)
171 #XXX: currently we only know exact match
172 #if exact_match:
173 if exact_match or not exact_match:
174 #XXX: id and login are treated equal - fixme!
175 try:
176 principal = pau.getPrincipal( id or login)
177 except PrincipalLookupError:
178 return ({},)
180 #XXX: do something with the data from the returned principal?!
181 return ({
182 'id': login or id,
183 'login': login or id,
184 'pluginid': self.getId(),
187 # IUserIntrospection
189 #security.declarePrivate('getUserIds')
190 #def getUserIds(self):
191 # return ('fakelogin',)
193 # IUserIntrospection
195 #security.declarePrivate('getUserNames')
196 #def getUserNames(self):
197 # return ('fakelogin',)
199 # IUserIntrospection
201 #security.declarePrivate('getUsers')
202 #def getUsers(self):
203 # """
204 # Return a list of users
206 # XXX DON'T USE THIS, it will kill performance
207 # """
208 # uf = getToolByName(self, 'acl_users')
209 # return tuple([uf.getUserById(x) for x in self.getUserIds()])
212 InitializeClass( AuthenticationPlugin)