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"
23 from zope
.app
.authentication
.interfaces
import IPrincipalCreated
25 from zope
.component
import adapter
, queryUtility
26 from zope
.interface
import alsoProvides
28 from paula
.properties
.interfaces
import IPropertyInterface
29 from paula
.properties
.interfaces
import IPropertyProvider
30 from paula
.properties
.interfaces
import IPropertyProviders
32 def _copy_attributes_from_ppu( principal
, pps
):
38 A mockup property provider
40 >>> class IA(Interface):
41 ... a1 = Attribute(u"a1")
42 ... a2 = Attribute(u"a2")
43 >>> alsoProvides(IA, IPropertyInterface)
45 >>> class IB(Interface):
46 ... b = Attribute(u"b")
47 >>> alsoProvides(IB, IPropertyInterface)
49 >>> class IC(Interface):
50 ... c = Attribute(u"c")
57 ... alsoProvides=(IA,IB),
62 >>> class ID(Interface):
63 ... d = Attribute(u"d")
64 >>> alsoProvides(ID, IPropertyInterface)
66 >>> pp2 = Mock(d=4, alsoProvides=(ID,))
68 A list of property provider utilities
72 Call and check which attributes made it
74 >>> _copy_attributes_from_ppu(p, pps)
89 >>> getattr(p, 'c', 'foo')
95 schemas
= list(pp
.__provides
__)
96 for schema
in schemas
:
97 # only use interfaces that defined properties
98 if not IPropertyInterface
.providedBy(schema
):
100 # iterate over schema fields and copy values
101 # also see comment below, dynamic lookup would be great
102 for name
in list(schema
):
103 value
= getattr(schema(pp
), name
)
104 setattr(principal
, name
, value
)
105 alsoProvides(principal
, schema
)
108 #XXX: this is not working, as property object most probably
109 # do magic inside of __getattr__ and rely on classes to
110 # interpret them correctly.
111 # Another way would be to monkey-patch user's
113 # For now we leave it static, i.e. the values are taken
114 # only once and are not dynamically updated. Not sure,
115 # whether it is useful anyway, as I don't know how long
116 # Principals exist at all.
117 #prop = property( lambda self: getattr(principal, name))
118 #setattr(user, name, prop)
121 @adapter(IPrincipalCreated
)
122 def setPropertiesForPrincipal(event
):
123 """Put properties onto the principal
125 The properties are directly stored as attributes. Magic happens in
126 _copy_attributes_from_ppu, here we just get the utility and are tested
129 principal
= event
.principal
130 # we search for a property provider utility in the context of the auth
131 # plugin that authenticated the principal, if there is none, we do
137 # XXX: for some reason a ppu is False
138 if ppu
is not None and principal
.id in ppu
:
139 pps
= ppu
[principal
.id]
140 _copy_attributes_from_ppu( principal
, pps
)