1
2 --- a/MoinMoin/groups/__init__.py Sat May 30 08:22:09 2009 +0200
3 +++ b/MoinMoin/groups/__init__.py Sat May 30 14:30:10 2009 +0200
4 -1,9 +1,6 @@
5 # -*- coding: iso-8859-1 -*-
6 -
7 """
8 -MoinMoin - group definition access via various backends.
9 -
10 -TODO Group name mapping for the BackendManager.
11 +MoinMoin - group access via various backends.
12
13 @copyright: 2009 DmitrijsMilajevs
14 @license: GPL, see COPYING for details
15 -12,31 +9,23 @@
16
17 class BackendManager(object):
18 """
19 - BackendManager maps string to the Group object. String represents
20 - group name. It provides access to groups of specific backend.
21 + A BackendManager maps a group name to a Group object.
22 + It provides access to groups of one specific backend.
23 """
24
25 def __init__(self, request, backend, mapper_to_backend=lambda x: x, mapper_from_backend=lambda x: x):
26 """
27 - Creates backend manager object.
28 + Create backend manager object.
29
30 XXX Decorators can be used for group name mapping.
31
32 @param request: request object.
33 -
34 - @type backend: group backend object.
35 - @param backend: the backend which provides access to the group
36 - definitions.
37 -
38 - @type mapper_to_backend: function which takes one string as an
39 - argument and returns a string
40 - @param mapper_to_backend: function which maps moin group
41 - name to the backend group name
42 -
43 - @type mapper_from_backend: function which takes one string as an
44 - argument and returns a string
45 - @param mapper_from_backend: function which maps backend group
46 - name to the moin group name
47 + @param backend: the group backend which provides access to the
48 + group definitions.
49 + @param mapper_to_backend: a function mapping the moin group
50 + name to the backend group name
51 + @param mapper_from_backend: a function mapping the backend group
52 + name to the moin group name
53 """
54 self._backend = backend
55 self.mapper_to_backend = mapper_to_backend
56 -44,33 +33,32 @@
57
58 def __getitem__(self, group_name):
59 """
60 - Selection of a group by its name.
61 + Get a group by its name.
62
63 - @type group_name: unicode string.
64 - @param group_name: name of the group which object to select.
65 + @param group_name: name of the group [unicode]
66 """
67 return self._backend[self.mapper_to_backend(group_name)]
68
69 def __iter__(self):
70 """
71 - Iteration over group names.
72 + Iterate over group names of the groups defined in this backend.
73 """
74 return (self.mapper_from_backend(group_name) for group_name in self._backend)
75
76 def __contains__(self, group_name):
77 """
78 - Check if a group called group name is avaliable via this backend.
79 + Checks if a group called group_name is available in this backend.
80
81 - @type group_name: unicode string.
82 - @param group_name: name of the group which is checked for an containment.
83 + @param group_name: name of the group [unicode]
84 """
85 return self.mapper_to_backend(group_name) in self._backend
86
87 def membergroups(self, member):
88 """
89 - List all groups where member is a member of.
90 - @rtype: list of unicode strings
91 - @return: list of group names in which member takes part in
92 + List all group names of the groups where <member> is a member of.
93 +
94 + @param member: member name [unicode]
95 + @return: list of group names [unicode]
96 """
97 return [group_name for group_name in self
98 if member in self[group_name]]
99 -85,15 +73,16 @@
100 """
101 Create a group manager object.
102
103 - @type backends: list of objects.
104 - @param backend: group backends which are used to get access to the
105 - group definitions.
106 + @param backends: list of group backends which are used to get access
107 + to the group definitions.
108 """
109 self._backends = backends
110
111 def __getitem__(self, group_name):
112 """
113 - Selection of a group by its name.
114 + Get a group by its name. First match counts.
115 +
116 + @param group_name: name of the group [unicode]
117 """
118 for backend in self._backends:
119 if group_name in backend:
120 -102,7 +91,7 @@
121
122 def __iter__(self):
123 """
124 - Iteration over groups names.
125 + Iterate over group names in all backends (filtering duplicates).
126 """
127 yielded_groups = set()
128
129 -114,17 +103,22 @@
130
131 def __contains__(self, group_name):
132 """
133 - Check if a group called group_name is defined.
134 + Check if a group called group_name is available in any of the backends.
135 +
136 + @param group_name: name of the group [unicode]
137 """
138 for backend in self._backends:
139 if group_name in backend:
140 return True
141 + return False
142
143 def membergroups(self, member):
144 """
145 - List all groups where member is a member of.
146 - @rtype: list of unicode strings
147 - @return: list of group names in which member takes part in
148 + List all group names of the groups where <member> is a member of.
149 +
150 + @param member: member name [unicode]
151 + @return: list of group names [unicode]
152 """
153 return [group_name for group_name in self
154 - if member in self[group_name]]
155 + if member in self[group_name]]
156 +
157
158 --- a/MoinMoin/groups/_tests/test_backend_manager.py Sat May 30 08:22:09 2009 +0200
159 +++ b/MoinMoin/groups/_tests/test_backend_manager.py Sat May 30 14:30:10 2009 +0200
160 -1,5 +1,4 @@
161 # -*- coding: iso-8859-1 -*-
162 -
163 """
164 MoinMoin.groups.BackendManager test
165
166 -12,10 +11,7 @@
167 from MoinMoin.groups import BackendManager
168
169
170 -class TestBackendManagerAPI(object):
171 - """
172 - This tastcase test Backend manager API
173 - """
174 +class TestBackendManager(object):
175
176 def setup_method(self, method):
177 self.admin_group = frozenset([u'Admin', u'JohnDoe'])
178 -26,34 +22,21 @@
179 u'EditorGroup': self.editor_group,
180 u'FruitGroup': self.fruit_group}
181
182 - self.group_backend = BackendManager(request=self.request,
183 - backend=groups)
184 + self.group_backend = BackendManager(request=self.request, backend=groups)
185
186 def test_getitem(self):
187 - """
188 - Test of the __getitem__ API method. It should return a group
189 - object by the group name.
190 - """
191 assert self.admin_group == self.group_backend[u'AdminGroup']
192 assert self.fruit_group == self.group_backend[u'FruitGroup']
193
194 raises(KeyError, lambda: self.group_backend[u'not existing group'])
195
196 def test_contains(self):
197 - """
198 - Test of the __contains__ API method. It checks if a group is
199 - avaliable via this backend. Check is done by group's name.
200 - """
201 assert u'AdminGroup' in self.group_backend
202 assert u'FruitGroup' in self.group_backend
203
204 assert u'not existing group' not in self.group_backend
205
206 - def test_membergroups(self):
207 - """
208 - Test of membergroups API method. It lists all groups where
209 - member is a member of. It should return a list of group names.
210 - """
211 + def test_membergroups(self):
212 apple_groups = self.group_backend.membergroups(u'Apple')
213 assert 1 == len(apple_groups)
214 assert u'FruitGroup' in apple_groups
215 -68,28 +51,28 @@
216
217 class TestManagerMapping(object):
218 """
219 - This class tests mapping of the group names from a backend to the
220 - moin and from the moin to a backend.
221 + Test group name mapping:
222 + moin -> backend (e.g. "AdminGroup" -> "Admin")
223 + backend -> moin (e.g. "Admin" -> "AdminGroup")
224
225 - Here the simplest situation is considered. Moin expect groups to
226 - be named as *Group, but backend stores group names without this prefix.
227 -
228 - When group names are passed or retrieved from the backend they
229 - should be mapped.
230 + Moin expects group names to match the page_group_regex (e.g. "AdminGroup"),
231 + but a backend might want to use different group names (e.g. just "Admin").
232 """
233
234 def setup_class(self):
235 self.admin_group = frozenset([u'Admin', u'JohnDoe'])
236 self.editor_group = frozenset([u'MainEditor', u'JohnDoe'])
237
238 - # Group names here do not follow moin convention: they do not
239 - # have group prefix.
240 + # These backend group names do not follow moin convention:
241 groups = {u'Admin': self.admin_group,
242 u'Editor': self.editor_group}
243
244 - # Simply drop last five letters, what is length of word "Group"
245 + # Simply drop the "Group" postfix for group names given to a backend.
246 + # Note: in the real world, this would not work good enough:
247 mapper_to_backend = lambda group_name: group_name[:-5]
248 - # Add "Group" postfix for every group name received from a backend
249 +
250 + # Add "Group" postfix for group names received from a backend.
251 + # Note: in the real world, this would not work good enough:
252 mapper_from_backend = lambda group_name: "%sGroup" % group_name
253
254 self.group_backend = BackendManager(request=self.request,
255 -108,3 +91,4 @@
256 assert u'AdminGroup' in self.group_backend.membergroups(u'JohnDoe')
257
258 coverage_modules = ['MoinMoin.groups']
259 +
260
261 --- a/MoinMoin/groups/_tests/test_group_manager.py Sat May 30 08:22:09 2009 +0200
262 +++ b/MoinMoin/groups/_tests/test_group_manager.py Sat May 30 14:30:10 2009 +0200
263 -1,5 +1,4 @@
264 # -*- coding: iso-8859-1 -*-
265 -
266 """
267 MoinMoin.groups.GroupManager test
268
269 -12,10 +11,7 @@
270
271 from MoinMoin.groups import BackendManager, GroupManager
272
273 -class TestGroupManagerAPI(object):
274 - """
275 - Performs test of the API of GroupManager.
276 - """
277 +class TestGroupManager(object):
278
279 from MoinMoin._tests import wikiconfig
280 class Config(wikiconfig.Config):
281 -32,8 +28,8 @@
282
283 self.user_group = frozenset([u'JohnDoe', u'Bob', u'Joe'])
284 self.city_group = frozenset([u'Bolzano', u'Riga', u'London'])
285 - # Suppose, someone hacked second backend
286 - # and added himself to AdminGroup
287 +
288 + # Suppose someone hacked the second backend and added himself to AdminGroup
289 self.second_admin_group = frozenset([u'TheHacker'])
290
291 second_backend_groups = {u'UserGroup': self.user_group,
292 -43,40 +39,32 @@
293 # first_backend and second_backend.
294 u'AdminGroup': self.second_admin_group}
295
296 - self.Config.group_manager = lambda self, request: GroupManager(backends=[BackendManager(request, first_backend_groups),
297 - BackendManager(request, second_backend_groups)])
298 + self.Config.group_manager = lambda self, request: GroupManager(
299 + backends=[BackendManager(request, first_backend_groups),
300 + BackendManager(request, second_backend_groups)])
301
302 def setup_method(self, method):
303 self.group_manager = self.request.cfg.group_manager(self.request)
304
305 def test_getitem(self):
306 - """
307 - Tests __getitem__ API method. It should return a group by its name.
308 - """
309 assert self.fruit_group == self.group_manager[u'FruitGroup']
310 raises(KeyError, lambda: self.group_manager[u'not existing group'])
311
312 def test_clashed_getitem(self):
313 """
314 - This test check situation when groups with a same name are
315 - defined in several backends. In this case, the only one
316 - backend must be taken in consideration, that backend which is
317 - defined first in the backends list.
318 + Check the case when groups of the same name are defined in multiple
319 + backends. __getitem__ should return the first match (backends are
320 + considered in the order they are given in the backends list).
321 """
322 admin_group = self.group_manager[u'AdminGroup']
323 -
324 assert self.admin_group == admin_group
325
326 - # Nevertheless, TheHacker added himself to the second backend,
327 - # it must not be taken into consideration, because AdminGroup is defined
328 - # in first backend
329 + # TheHacker added himself to the second backend, but that must not be
330 + # taken into consideration, because AdminGroup is defined in first
331 + # backend and we only use the first match.
332 assert u'TheHacker' not in admin_group
333
334 def test_iter(self):
335 - """
336 - Tests __iter__ API method. It should iterate over all groups
337 - available via backends. It should avoid group name clashes.
338 - """
339 all_group_names = [group_name for group_name in self.group_manager]
340
341 assert 5 == len(all_group_names)
342 -84,19 +72,10 @@
343 assert len(set(all_group_names)) == len(all_group_names)
344
345 def test_contains(self):
346 - """
347 - Tests __contains__ API method. It should check if a group
348 - called group_name is available via some backend.
349 - """
350 assert u'UserGroup' in self.group_manager
351 assert u'not existing group' not in self.group_manager
352
353 def test_membergroups(self):
354 - """
355 - Tests membergroups API method. It should lists all groups
356 - where member is a member of. It should return a list of group
357 - names.
358 - """
359 apple_groups = self.group_manager.membergroups(u'Apple')
360 assert 1 == len(apple_groups)
361 assert u'FruitGroup' in apple_groups
362 -110,3 +89,4 @@
363 assert u'FruitGroup' not in john_doe_groups
364
365 coverage_modules = ['MoinMoin.groups']
366 +
367
368 --- a/MoinMoin/groups/_tests/test_group_manager_acl.py Sat May 30 08:22:09 2009 +0200
369 +++ b/MoinMoin/groups/_tests/test_group_manager_acl.py Sat May 30 14:30:10 2009 +0200
370 -47,8 +47,7 @@
371
372 def testConfigBackend(self):
373 """
374 - tests getting a group from the group manager, does group
375 - membership tests.
376 + tests getting a group from the group manager, does group membership tests.
377 """
378 # define config groups
379 groups = {'A': set(['a1', 'a2']),
380 -75,3 +74,4 @@
381 assert 'b1' not in group_A
382
383 coverage_modules = ['MoinMoin.groups']
384 +
385