paula.pasplugins: catched exception in property copy code
[paula.git] / paula.pasplugins / src / paula / pasplugins / plugins / properties.py
blobd29bdff8ea5a87d2df358570d2c456d9a5799f9b
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"
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.
49 """
50 plugin = PropertiesPlugin(id, title)
51 dispatcher._setObject(plugin.getId(), plugin)
53 if REQUEST is not None:
54 REQUEST['RESPONSE'].redirect(
55 '%s/manage_workspace'
56 '?manage_tabs_message='
57 'paula.plonepas.PropertiesPlugin+added.'
58 % dispatcher.absolute_url())
61 class PropertiesPlugin(BasePlugin):
62 """
63 """
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
72 self.title = title
74 security.declarePrivate('getPropertiesForUser')
75 def getPropertiesForUser(self, user, request=None):
76 """ user -> {}
78 o User will implement IPropertiedUser.
80 o Plugin should return a dictionary or an object providing
81 IPropertySheet.
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
87 present
89 Create a sophisticated mock principal
91 >>> from zope.interface import Interface, Attribute
93 property interfaces
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)
106 True
107 >>> IPropertyInterface.providedBy(IB)
108 True
110 and the mock principal
112 >>> class MockPrincipal(object):
113 ... implements(IA,IB)
114 ... id = 'login'
115 ... a1 = 1
116 ... a2 = 2
117 ... b1 = 1
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)
129 our property plugin
131 >>> pp = PropertiesPlugin('pp')
133 a mockup plone user
135 >>> ploneuser = Mock(getId = lambda : u"login")
136 >>> psheet = pp.getPropertiesForUser(ploneuser)
137 >>> psheet.getId()
138 'pp'
139 >>> psheet.propertyIds()
140 ['a1', 'a2', 'b1']
141 >>> psheet.propertyValues()
142 [1, 2, 1]
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)
152 try:
153 principal = pau.getPrincipal(user.getId())
154 except PrincipalLookupError:
155 return {}
157 if not principal:
158 return {}
160 # create property dictionary from all attributes, which belong to
161 # property schemas
162 properties = {}
163 for schema in list(principal.__provides__):
164 if IPropertyInterface.providedBy(schema):
165 for name in list(schema):
166 try:
167 properties[name] = getattr(principal, name)
168 except AttributeError:
169 # we should write a log message
170 pass
172 if properties.has_key('id'):
173 del properties['id']
175 psheet = MutablePropertySheet(self.id, **properties)
176 return psheet
178 InitializeClass( PropertiesPlugin)