1
# -*- coding: iso-8859-1 -*-
3
MoinMoin - MoinMoin.security Tests
5
TODO: when refactoring this, do not use "iter" (is a builtin)
7
@copyright: 2003-2004 by Juergen Hermann <jh@web.de>,
8
2007 by MoinMoin:ReimarBauer,
9
2007 by MoinMoin:ThomasWaldmann
10
@license: GNU GPL, see COPYING for details.
15
from MoinMoin import security
16
acliter = security.ACLStringIterator
17
AccessControlList = security.AccessControlList
19
from MoinMoin.PageEditor import PageEditor
20
from MoinMoin.user import User
22
from MoinMoin._tests import become_trusted, create_page, nuke_page
24
class TestACLStringIterator(object):
26
def setup_method(self, method):
27
self.config = self.TestConfig(defaults=['acl_rights_valid', 'acl_rights_before'])
28
def teardown_method(self, method):
32
""" security: empty acl string raise StopIteration """
33
iter = acliter(self.request.cfg.acl_rights_valid, '')
34
py.test.raises(StopIteration, iter.next)
36
def testWhiteSpace(self):
37
""" security: white space acl string raise StopIteration """
38
iter = acliter(self.request.cfg.acl_rights_valid, ' ')
39
py.test.raises(StopIteration, iter.next)
41
def testDefault(self):
42
""" security: default meta acl """
43
iter = acliter(self.request.cfg.acl_rights_valid, 'Default Default')
44
for mod, entries, rights in iter:
45
assert entries == ['Default']
48
def testEmptyRights(self):
49
""" security: empty rights """
50
iter = acliter(self.request.cfg.acl_rights_valid, 'WikiName:')
51
mod, entries, rights = iter.next()
52
assert entries == ['WikiName']
55
def testSingleWikiNameSingleWrite(self):
56
""" security: single wiki name, single right """
57
iter = acliter(self.request.cfg.acl_rights_valid, 'WikiName:read')
58
mod, entries, rights = iter.next()
59
assert entries == ['WikiName']
60
assert rights == ['read']
62
def testMultipleWikiNameAndRights(self):
63
""" security: multiple wiki names and rights """
64
iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne,UserTwo:read,write')
65
mod, entries, rights = iter.next()
66
assert entries == ['UserOne', 'UserTwo']
67
assert rights == ['read', 'write']
69
def testMultipleWikiNameAndRightsSpaces(self):
70
""" security: multiple names with spaces """
71
iter = acliter(self.request.cfg.acl_rights_valid, 'user one,user two:read')
72
mod, entries, rights = iter.next()
73
assert entries == ['user one', 'user two']
74
assert rights == ['read']
76
def testMultipleEntries(self):
77
""" security: multiple entries """
78
iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read,write UserTwo:read All:')
79
mod, entries, rights = iter.next()
80
assert entries == ['UserOne']
81
assert rights == ['read', 'write']
82
mod, entries, rights = iter.next()
83
assert entries == ['UserTwo']
84
assert rights == ['read']
85
mod, entries, rights = iter.next()
86
assert entries == ['All']
89
def testNameWithSpaces(self):
90
""" security: single name with spaces """
91
iter = acliter(self.request.cfg.acl_rights_valid, 'user one:read')
92
mod, entries, rights = iter.next()
93
assert entries == ['user one']
94
assert rights == ['read']
96
def testMultipleEntriesWithSpaces(self):
97
""" security: multiple entries with spaces """
98
iter = acliter(self.request.cfg.acl_rights_valid, 'user one:read,write user two:read')
99
mod, entries, rights = iter.next()
100
assert entries == ['user one']
101
assert rights == ['read', 'write']
102
mod, entries, rights = iter.next()
103
assert entries == ['user two']
104
assert rights == ['read']
106
def testMixedNames(self):
107
""" security: mixed wiki names and names with spaces """
108
iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne,user two:read,write user three,UserFour:read')
109
mod, entries, rights = iter.next()
110
assert entries == ['UserOne', 'user two']
111
assert rights == ['read', 'write']
112
mod, entries, rights = iter.next()
113
assert entries == ['user three', 'UserFour']
114
assert rights == ['read']
116
def testModifier(self):
117
""" security: acl modifiers """
118
iter = acliter(self.request.cfg.acl_rights_valid, '+UserOne:read -UserTwo:')
119
mod, entries, rights = iter.next()
121
assert entries == ['UserOne']
122
assert rights == ['read']
123
mod, entries, rights = iter.next()
125
assert entries == ['UserTwo']
128
def testIgnoreInvalidACL(self):
129
""" security: ignore invalid acl
131
The last part of this acl can not be parsed. If it ends with :
132
then it will be parsed as one name with spaces.
134
iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read user two is ignored')
135
mod, entries, rights = iter.next()
136
assert entries == ['UserOne']
137
assert rights == ['read']
138
py.test.raises(StopIteration, iter.next)
140
def testEmptyNamesWithRight(self):
141
""" security: empty names with rights
143
The documents does not talk about this case, may() should ignore
144
the rights because there is no entry.
146
iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read :read All:')
147
mod, entries, rights = iter.next()
148
assert entries == ['UserOne']
149
assert rights == ['read']
150
mod, entries, rights = iter.next()
152
assert rights == ['read']
153
mod, entries, rights = iter.next()
154
assert entries == ['All']
157
def testIgnodeInvalidRights(self):
158
""" security: ignore rights not in acl_rights_valid """
159
iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read,sing,write,drink,sleep')
160
mod, entries, rights = iter.next()
161
assert rights == ['read', 'write']
163
def testBadGuy(self):
164
""" security: bad guy may not allowed anything
166
This test was failing on the apply acl rights test.
168
iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read,write BadGuy: All:read')
169
mod, entries, rights = iter.next()
170
mod, entries, rights = iter.next()
171
assert entries == ['BadGuy']
174
def testAllowExtraWhitespace(self):
175
""" security: allow extra white space between entries """
176
iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne,user two:read,write user three,UserFour:read All:')
177
mod, entries, rights = iter.next()
178
assert entries == ['UserOne', 'user two']
179
assert rights == ['read', 'write']
180
mod, entries, rights = iter.next()
181
assert entries == ['user three', 'UserFour']
182
assert rights == ['read']
183
mod, entries, rights = iter.next()
184
assert entries == ['All']
188
class TestAcl(object):
189
""" security: testing access control list
191
TO DO: test unknown user?
193
def setup_method(self, method):
195
self.config = self.TestConfig(defaults=['acl_rights_valid', 'acl_rights_before'])
196
self.savedUser = self.request.user.name
198
def teardown_method(self, method):
200
self.request.user.name = self.savedUser
203
def testApplyACLByUser(self):
204
""" security: applying acl by user name"""
207
"Admin1,Admin2:read,write,delete,revert,admin "
208
"Admin3:read,write,admin "
210
"name with spaces,another one:read,write "
211
"CamelCase,extended name:read,write "
215
acl = security.AccessControlList(self.request.cfg, acl_rights)
217
# Should apply these rights:
221
('Admin1', ('read', 'write', 'admin', 'revert', 'delete')),
222
('Admin2', ('read', 'write', 'admin', 'revert', 'delete')),
223
('Admin3', ('read', 'write', 'admin')),
224
('JoeDoe', ('read', 'write')),
225
('SomeGuy', ('read', )),
226
# Extended names or mix of extended and CamelCase
227
('name with spaces', ('read', 'write', )),
228
('another one', ('read', 'write', )),
229
('CamelCase', ('read', 'write', )),
230
('extended name', ('read', 'write', )),
233
# All other users - every one not mentioned in the acl lines
235
('Anonymous', ('read', )),
239
for user, may in users:
240
mayNot = [right for right in self.request.cfg.acl_rights_valid
242
# User should have these rights...
244
assert acl.may(self.request, user, right)
247
assert not acl.may(self.request, user, right)
250
class TestPageAcls(object):
251
""" security: real-life access control list on pages testing
253
acls_before = u"WikiAdmin:admin,read,write,delete,revert"
254
acls_default = u"All:read,write"
255
acls_after = u"All:read"
256
mainpage_name = u'AclTestMainPage'
257
subpage_name = u'AclTestMainPage/SubPage'
260
(mainpage_name, u"#acl JoeDoe: JaneDoe:read,write\nFoo!"),
261
(subpage_name, u"FooFoo!"),
264
def setup_class(self):
265
self.config = self.TestConfig(
266
acl_rights_before=self.acls_before,
267
acl_rights_default=self.acls_default,
268
acl_rights_after=self.acls_after,
269
acl_hierarchic=False,
270
defaults=['acl_rights_valid'])
271
# TestConfig is crap, it does some wild hack and does not inherit from DefaultConfig
272
# nor call DefaultConfig's __init__() to do post processing, thus we do it here for now:
273
cfg = self.request.cfg
274
cfg.cache.acl_rights_before = AccessControlList(cfg, [cfg.acl_rights_before])
275
cfg.cache.acl_rights_default = AccessControlList(cfg, [cfg.acl_rights_default])
276
cfg.cache.acl_rights_after = AccessControlList(cfg, [cfg.acl_rights_after])
279
self.savedUser = self.request.user.name
280
self.request.user = User(self.request, auth_username=u'WikiAdmin')
281
self.request.user.valid = True
283
for page_name, page_content in self.pages:
284
create_page(self.request, page_name, page_content)
286
def teardown_class(self):
288
cfg = self.request.cfg
289
cfg.cache.acl_rights_before = AccessControlList(cfg, [cfg.acl_rights_before])
290
cfg.cache.acl_rights_default = AccessControlList(cfg, [cfg.acl_rights_default])
291
cfg.cache.acl_rights_after = AccessControlList(cfg, [cfg.acl_rights_after])
294
self.request.user.name = self.savedUser
296
for page_name, dummy in self.pages:
297
nuke_page(self.request, page_name)
299
def testPageACLs(self):
300
""" security: test page acls """
302
# hierarchic, pagename, username, expected_rights
303
(False, self.mainpage_name, u'WikiAdmin', ['read', 'write', 'admin', 'revert', 'delete']),
304
(True, self.mainpage_name, u'WikiAdmin', ['read', 'write', 'admin', 'revert', 'delete']),
305
(False, self.mainpage_name, u'AnyUser', ['read']), # by after acl
306
(True, self.mainpage_name, u'AnyUser', ['read']), # by after acl
307
(False, self.mainpage_name, u'JaneDoe', ['read', 'write']), # by page acl
308
(True, self.mainpage_name, u'JaneDoe', ['read', 'write']), # by page acl
309
(False, self.mainpage_name, u'JoeDoe', []), # by page acl
310
(True, self.mainpage_name, u'JoeDoe', []), # by page acl
311
(False, self.subpage_name, u'WikiAdmin', ['read', 'write', 'admin', 'revert', 'delete']),
312
(True, self.subpage_name, u'WikiAdmin', ['read', 'write', 'admin', 'revert', 'delete']),
313
(False, self.subpage_name, u'AnyUser', ['read', 'write']), # by default acl
314
(True, self.subpage_name, u'AnyUser', ['read']), # by after acl
315
(False, self.subpage_name, u'JoeDoe', ['read', 'write']), # by default acl
316
(True, self.subpage_name, u'JoeDoe', []), # by inherited acl from main page
317
(False, self.subpage_name, u'JaneDoe', ['read', 'write']), # by default acl
318
(True, self.subpage_name, u'JaneDoe', ['read', 'write']), # by inherited acl from main page
321
for hierarchic, pagename, username, may in tests:
322
self.request.cfg.acl_hierarchic = hierarchic
323
u = User(self.request, auth_username=username)
326
# User should have these rights...
328
can_access = u.may.__getattr__(right)(pagename)
330
print "page %s: %s test if %s may %s (success)" % (
331
pagename, ['normal', 'hierarchic'][hierarchic], username, right)
333
print "page %s: %s test if %s may %s (failure)" % (
334
pagename, ['normal', 'hierarchic'][hierarchic], username, right)
337
# User should NOT have these rights:
338
mayNot = [right for right in self.request.cfg.acl_rights_valid
341
can_access = u.may.__getattr__(right)(pagename)
343
print "page %s: %s test if %s may not %s (failure)" % (
344
pagename, ['normal', 'hierarchic'][hierarchic], username, right)
346
print "page %s: %s test if %s may not %s (success)" % (
347
pagename, ['normal', 'hierarchic'][hierarchic], username, right)
348
assert not can_access
350
coverage_modules = ['MoinMoin.security']