1 | # -*- coding: utf-8 -*- |
---|
2 | # |
---|
3 | # Copyright (C) 2015 Ryan J Ollos <ryan.j.ollos@gmail.com> |
---|
4 | # |
---|
5 | # This software is licensed as described in the file COPYING, which |
---|
6 | # you should have received as part of this distribution. |
---|
7 | # |
---|
8 | |
---|
9 | import unittest |
---|
10 | |
---|
11 | from trac.perm import PermissionCache, PermissionSystem |
---|
12 | from trac.test import EnvironmentStub, Mock, MockPerm, locale_en |
---|
13 | from trac.util.datefmt import utc |
---|
14 | from trac.web.api import RequestDone |
---|
15 | from trac.web.main import RequestDispatcher |
---|
16 | from trac.wiki.macros import WikiMacroBase |
---|
17 | from trac.wiki.model import WikiPage |
---|
18 | |
---|
19 | from trachacks.web_ui import ReadonlyHelpPolicy |
---|
20 | |
---|
21 | |
---|
22 | class MockBoxMacro(WikiMacroBase): |
---|
23 | |
---|
24 | def expand_macro(self, formatter, name, content, args=None): |
---|
25 | return content |
---|
26 | |
---|
27 | def get_macros(self): |
---|
28 | yield 'box' |
---|
29 | |
---|
30 | |
---|
31 | class ReadonlyHelpPolicyTestCase(unittest.TestCase): |
---|
32 | |
---|
33 | def setUp(self): |
---|
34 | self.env = EnvironmentStub(enable=('trac.*', 'trachacks.*', |
---|
35 | MockBoxMacro)) |
---|
36 | self.env.config.set('trac', 'permission_policies', |
---|
37 | 'ReadonlyHelpPolicy, DefaultPermissionPolicy, ' |
---|
38 | 'LegacyAttachmentPolicy') |
---|
39 | perm_sys = PermissionSystem(self.env) |
---|
40 | perm_sys.grant_permission('user_with_view', 'WIKI_VIEW') |
---|
41 | perm_sys.grant_permission('user_with_modify', 'WIKI_MODIFY') |
---|
42 | perm_sys.grant_permission('user_with_delete', 'WIKI_DELETE') |
---|
43 | perm_sys.grant_permission('user_with_admin', 'WIKI_ADMIN') |
---|
44 | for name in ('WikiStart', 'RandomPage', 'TracGuide'): |
---|
45 | page = WikiPage(self.env, name) |
---|
46 | page.text = "The Text" |
---|
47 | page.save('the creator', 'the comment') |
---|
48 | self.content = None |
---|
49 | |
---|
50 | def tearDown(self): |
---|
51 | self.env.reset_db() |
---|
52 | |
---|
53 | def create_request(self, authname='anonymous', **kwargs): |
---|
54 | kw = {'perm': PermissionCache(self.env, authname), |
---|
55 | 'args': {}, 'callbacks': {}, 'path_info': '', |
---|
56 | 'form_token': None, 'href': self.env.href, |
---|
57 | 'abs_href': self.env.abs_href, 'tz': utc, 'locale': None, |
---|
58 | 'lc_time': locale_en, 'session': {}, 'authname': authname, |
---|
59 | 'chrome': {'notices': [], 'warnings': []}, |
---|
60 | 'method': None, 'get_header': lambda v: None, 'is_xhr': False} |
---|
61 | kw.update(kwargs) |
---|
62 | def send(content, content_type='text/html', status=200): |
---|
63 | self.content = content |
---|
64 | raise RequestDone |
---|
65 | return Mock(send=send, **kw) |
---|
66 | |
---|
67 | def test_wiki_view_permission(self): |
---|
68 | """User with WIKI_VIEW can view any page.""" |
---|
69 | perm_cache = PermissionCache(self.env, 'user_with_view') |
---|
70 | self.assertTrue('WIKI_VIEW' in perm_cache('wiki', 'WikiStart')) |
---|
71 | self.assertTrue('WIKI_VIEW' in perm_cache('wiki', 'RandomPage')) |
---|
72 | self.assertTrue('WIKI_VIEW' in perm_cache('wiki', 'TracGuide')) |
---|
73 | |
---|
74 | def test_no_wiki_modify_permission(self): |
---|
75 | """User with WIKI_MODIFY can't modify help pages.""" |
---|
76 | perm_cache = PermissionCache(self.env, 'user_with_modify') |
---|
77 | self.assertTrue('WIKI_MODIFY' in perm_cache('wiki', 'WikiStart')) |
---|
78 | self.assertTrue('WIKI_MODIFY' in perm_cache('wiki', 'RandomPage')) |
---|
79 | self.assertFalse('WIKI_MODIFY' in perm_cache('wiki', 'TracGuide')) |
---|
80 | |
---|
81 | def test_no_wiki_delete_permission(self): |
---|
82 | """User with WIKI_DELETE can't delete help pages.""" |
---|
83 | perm_cache = PermissionCache(self.env, 'user_with_delete') |
---|
84 | self.assertTrue('WIKI_DELETE' in perm_cache('wiki', 'WikiStart')) |
---|
85 | self.assertTrue('WIKI_DELETE' in perm_cache('wiki', 'RandomPage')) |
---|
86 | self.assertFalse('WIKI_DELETE' in perm_cache('wiki', 'TracGuide')) |
---|
87 | |
---|
88 | def test_no_wiki_admin_permission(self): |
---|
89 | """User with WIKI_ADMIN can't modify or delete help pages.""" |
---|
90 | perm_cache = PermissionCache(self.env, 'user_with_admin') |
---|
91 | self.assertTrue('WIKI_ADMIN' in perm_cache('wiki', 'WikiStart')) |
---|
92 | self.assertTrue('WIKI_ADMIN' in perm_cache('wiki', 'RandomPage')) |
---|
93 | self.assertFalse('WIKI_ADMIN' in perm_cache('wiki', 'TracGuide')) |
---|
94 | |
---|
95 | def test_help_page_has_notice(self): |
---|
96 | """Help page has notice inserted into top of page content.""" |
---|
97 | req = self.create_request('user_with_view', |
---|
98 | path_info='/wiki/TracGuide') |
---|
99 | dispatcher = RequestDispatcher(self.env) |
---|
100 | self.assertRaises(RequestDone, dispatcher.dispatch, req) |
---|
101 | self.assertIn("The TracGuide is not editable on this site.", |
---|
102 | self.content) |
---|
103 | |
---|
104 | def test_non_help_page_has_no_notice(self): |
---|
105 | """Non-help page doesn't have notice inserted into top of page |
---|
106 | content.""" |
---|
107 | req = self.create_request('user_with_view', |
---|
108 | path_info='/wiki/WikiStart') |
---|
109 | dispatcher = RequestDispatcher(self.env) |
---|
110 | self.assertRaises(RequestDone, dispatcher.dispatch, req) |
---|
111 | self.assertNotIn("The TracGuide is not editable on this site.", |
---|
112 | self.content) |
---|
113 | |
---|
114 | def test_only_view_page_has_notice(self): |
---|
115 | """Help page history doesn't have a notice inserted into top |
---|
116 | of page content. Regression test for #12613.""" |
---|
117 | req = self.create_request('user_with_view', |
---|
118 | args={'action': 'history'}, |
---|
119 | path_info='/wiki/TracGuide') |
---|
120 | dispatcher = RequestDispatcher(self.env) |
---|
121 | self.assertRaises(RequestDone, dispatcher.dispatch, req) |
---|
122 | self.assertNotIn("The TracGuide is not editable on this site.", |
---|
123 | self.content) |
---|
124 | |
---|
125 | |
---|
126 | def test_suite(): |
---|
127 | suite = unittest.TestSuite() |
---|
128 | suite.addTest(unittest.makeSuite(ReadonlyHelpPolicyTestCase)) |
---|
129 | return suite |
---|
130 | |
---|
131 | |
---|
132 | if __name__ == '__main__': |
---|
133 | unittest.main(defaultTest='test_suite') |
---|