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/>.
20 __author__
= "Florian Friesdorf <flo@chaoflow.net>"
21 __docformat__
= "plaintext"
24 from AccessControl
import ClassSecurityInfo
25 from Globals
import InitializeClass
27 from Products
.PageTemplates
.PageTemplateFile
import PageTemplateFile
28 from Products
.PlonePAS
.sheet
import MutablePropertySheet
30 from Products
.PluggableAuthService
.plugins
.BasePlugin
import BasePlugin
31 from Products
.PluggableAuthService
.interfaces
.plugins \
32 import IPropertiesPlugin
34 from zope
.app
.security
.interfaces
import IAuthentication
35 from zope
.app
.security
.interfaces
import PrincipalLookupError
36 from zope
.component
import getUtility
37 from zope
.interface
import alsoProvides
, implements
39 from paula
.pau_addons
.interfaces
import IPropertyInterface
42 manage_addPropertiesPluginForm
= PageTemplateFile(
43 '../www/PropertiesPluginForm',
44 globals(), __name__
='manage_addPropertiesPluginForm' )
47 def addPropertiesPlugin( dispatcher
, id, title
=None, REQUEST
=None ):
48 """Add a paula.plonepas PropertiesPlugin to a PluggableAuthService.
50 plugin
= PropertiesPlugin(id, title
)
51 dispatcher
._setObject
(plugin
.getId(), plugin
)
53 if REQUEST
is not None:
54 REQUEST
['RESPONSE'].redirect(
56 '?manage_tabs_message='
57 'paula.plonepas.PropertiesPlugin+added.'
58 % dispatcher
.absolute_url())
61 class PropertiesPlugin(BasePlugin
):
64 security
= ClassSecurityInfo()
66 implements(IPropertiesPlugin
)
68 meta_type
= "Paula PAS Properties Plugin"
70 def __init__(self
, id, title
=None):
71 self
._id
= self
.id = id
74 security
.declarePrivate('getPropertiesForUser')
75 def getPropertiesForUser(self
, user
, request
=None):
78 o User will implement IPropertiedUser.
80 o Plugin should return a dictionary or an object providing
83 o Plugin may scribble on the user, if needed (but must still
84 return a mapping, even if empty).
86 o May assign properties based on values in the REQUEST object, if
89 Create a sophisticated mock principal
91 >>> from zope.interface import Interface, Attribute
95 >>> class IA(Interface):
96 ... id = Attribute('id')
97 ... a1 = Attribute("a1")
98 ... a2 = Attribute("a2")
100 >>> class IB(Interface):
101 ... b1 = Attribute("b1")
103 >>> alsoProvides(IA, IPropertyInterface)
104 >>> alsoProvides(IB, IPropertyInterface)
105 >>> IPropertyInterface.providedBy(IA)
107 >>> IPropertyInterface.providedBy(IB)
110 and the mock principal
112 >>> class MockPrincipal(object):
113 ... implements(IA,IB)
118 ... c1 = 'will not show up'
120 >>> p = MockPrincipal()
122 Mockup IPluggableAuthentication
124 >>> from zope.component import provideUtility
125 >>> au = Mock(getPrincipal = lambda x : x == "login" and p)
126 >>> alsoProvides(au, IAuthentication)
127 >>> provideUtility(au, IAuthentication)
131 >>> pp = PropertiesPlugin('pp')
135 >>> ploneuser = Mock(getId = lambda : u"login")
136 >>> psheet = pp.getPropertiesForUser(ploneuser)
139 >>> psheet.propertyIds()
141 >>> psheet.propertyValues()
144 and for a non-existing user
146 >>> ploneuser = Mock(getId = lambda : u"foo")
147 >>> pp.getPropertiesForUser(ploneuser)
150 # get principal from pau
151 pau
= getUtility(IAuthentication
)
153 principal
= pau
.getPrincipal(user
.getId())
154 except PrincipalLookupError
:
160 # create property dictionary from all attributes, which belong to
163 for schema
in list(principal
.__provides
__):
164 if IPropertyInterface
.providedBy(schema
):
165 for name
in list(schema
):
167 properties
[name
] = getattr(principal
, name
)
168 except AttributeError:
169 # we should write a log message
172 if properties
.has_key('id'):
175 psheet
= MutablePropertySheet(self
.id, **properties
)
178 InitializeClass( PropertiesPlugin
)