paula: removed old per-repo trunk subdirs
[paula.git] / paula.properties / src / paula / properties / subscribers.py
blobee4c627f25c299c08488df0ce5c93cd8cadda843
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 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):
33 """
34 A mockup principal
36 >>> p = Mock(id='1')
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")
52 >>> pp1 = Mock(
53 ... a1=1,
54 ... a2=2,
55 ... b=3,
56 ... c='not copied',
57 ... alsoProvides=(IA,IB),
58 ... )
60 And another one
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
70 >>> pps = [pp1, pp2]
72 Call and check which attributes made it
74 >>> _copy_attributes_from_ppu(p, pps)
75 >>> IA.providedBy(p)
76 True
77 >>> IB.providedBy(p)
78 True
79 >>> IC.providedBy(p)
80 False
81 >>> ID.providedBy(p)
82 True
83 >>> p.a1
85 >>> p.a2
87 >>> p.b
89 >>> getattr(p, 'c', 'foo')
90 'foo'
91 >>> p.d
93 """
94 for pp in pps:
95 schemas = list(pp.__provides__)
96 for schema in schemas:
97 # only use interfaces that defined properties
98 if not IPropertyInterface.providedBy(schema):
99 continue
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
112 # __getattr__...
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
127 in README.txt
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
132 # nothing
133 ppu = queryUtility(
134 IPropertyProviders,
135 # context=getSite(),
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)