blob: ef52f1ec984279d6970f50b53ac9f2e430e3bf92 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2016 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file or at
4# https://developers.google.com/open-source/licenses/bsd
5
6"""Unit tests for the monorailrequest module."""
7from __future__ import print_function
8from __future__ import division
9from __future__ import absolute_import
10
11import endpoints
12import mock
13import re
14import unittest
15
Adrià Vilanova Martínez9f9ade52022-10-10 23:20:11 +020016try:
17 from mox3 import mox
18except ImportError:
19 import mox
Copybara854996b2021-09-07 19:36:02 +000020import six
21
22from google.appengine.api import oauth
23from google.appengine.api import users
24
25import webapp2
26
27from framework import exceptions
28from framework import monorailrequest
29from framework import permissions
30from proto import project_pb2
31from proto import tracker_pb2
32from services import service_manager
33from testing import fake
34from testing import testing_helpers
35from tracker import tracker_constants
36
37
38class HostportReTest(unittest.TestCase):
39
40 def testGood(self):
41 test_data = [
42 'localhost:8080',
43 'app.appspot.com',
44 'bugs-staging.chromium.org',
45 'vers10n-h3x-dot-app-id.appspot.com',
46 ]
47 for hostport in test_data:
48 self.assertTrue(monorailrequest._HOSTPORT_RE.match(hostport),
49 msg='Incorrectly rejected %r' % hostport)
50
51 def testBad(self):
52 test_data = [
53 '',
54 ' ',
55 '\t',
56 '\n',
57 '\'',
58 '"',
59 'version"cruft-dot-app-id.appspot.com',
60 '\nother header',
61 'version&cruft-dot-app-id.appspot.com',
62 ]
63 for hostport in test_data:
64 self.assertFalse(monorailrequest._HOSTPORT_RE.match(hostport),
65 msg='Incorrectly accepted %r' % hostport)
66
67
68class MonorailApiRequestUnitTest(unittest.TestCase):
69
70 def setUp(self):
71 self.cnxn = 'fake cnxn'
72 self.services = service_manager.Services(
73 config=fake.ConfigService(),
74 issue=fake.IssueService(),
75 project=fake.ProjectService(),
76 user=fake.UserService(),
77 usergroup=fake.UserGroupService())
78 self.project = self.services.project.TestAddProject(
79 'proj', project_id=789)
80 self.services.user.TestAddUser('requester@example.com', 111)
81 self.issue = fake.MakeTestIssue(
82 789, 1, 'sum', 'New', 111)
83 self.services.issue.TestAddIssue(self.issue)
84
85 self.patcher_1 = mock.patch('endpoints.get_current_user')
86 self.mock_endpoints_gcu = self.patcher_1.start()
87 self.mock_endpoints_gcu.return_value = None
88 self.patcher_2 = mock.patch('google.appengine.api.oauth.get_current_user')
89 self.mock_oauth_gcu = self.patcher_2.start()
90 self.mock_oauth_gcu.return_value = testing_helpers.Blank(
91 email=lambda: 'requester@example.com')
92
93 def tearDown(self):
94 mock.patch.stopall()
95
96 def testInit_NoProjectIssueOrViewedUser(self):
97 request = testing_helpers.Blank()
98 mar = monorailrequest.MonorailApiRequest(
99 request, self.services, cnxn=self.cnxn)
100 self.assertIsNone(mar.project)
101 self.assertIsNone(mar.issue)
102
103 def testInit_WithProject(self):
104 request = testing_helpers.Blank(projectId='proj')
105 mar = monorailrequest.MonorailApiRequest(
106 request, self.services, cnxn=self.cnxn)
107 self.assertEqual(self.project, mar.project)
108 self.assertIsNone(mar.issue)
109
110 def testInit_WithProjectAndIssue(self):
111 request = testing_helpers.Blank(
112 projectId='proj', issueId=1)
113 mar = monorailrequest.MonorailApiRequest(
114 request, self.services, cnxn=self.cnxn)
115 self.assertEqual(self.project, mar.project)
116 self.assertEqual(self.issue, mar.issue)
117
118 def testGetParam_Normal(self):
119 request = testing_helpers.Blank(q='owner:me')
120 mar = monorailrequest.MonorailApiRequest(
121 request, self.services, cnxn=self.cnxn)
122 self.assertEqual(None, mar.GetParam('unknown'))
123 self.assertEqual(100, mar.GetParam('num'))
124 self.assertEqual('owner:me', mar.GetParam('q'))
125
126 request = testing_helpers.Blank(q='owner:me', maxResults=200)
127 mar = monorailrequest.MonorailApiRequest(
128 request, self.services, cnxn=self.cnxn)
129 self.assertEqual(200, mar.GetParam('num'))
130
131
132class MonorailRequestUnitTest(unittest.TestCase):
133
134 def setUp(self):
135 self.services = service_manager.Services(
136 project=fake.ProjectService(),
137 user=fake.UserService(),
138 usergroup=fake.UserGroupService(),
139 features=fake.FeaturesService())
140 self.project = self.services.project.TestAddProject('proj')
141 self.hotlist = self.services.features.TestAddHotlist(
142 'TestHotlist', owner_ids=[111])
143 self.services.user.TestAddUser('jrobbins@example.com', 111)
144
145 self.mox = mox.Mox()
146 self.mox.StubOutWithMock(users, 'get_current_user')
147 users.get_current_user().AndReturn(None)
148 self.mox.ReplayAll()
149
150 def tearDown(self):
151 self.mox.UnsetStubs()
152
153 def testGetIntParam_ConvertsQueryParamToInt(self):
154 notice_id = 12345
155 mr = testing_helpers.MakeMonorailRequest(
156 path='/foo?notice=%s' % notice_id)
157
158 value = mr.GetIntParam('notice')
159 self.assertTrue(isinstance(value, int))
160 self.assertEqual(notice_id, value)
161
162 def testGetIntParam_ConvertsQueryParamToLong(self):
163 notice_id = 12345678901234567890
164 mr = testing_helpers.MakeMonorailRequest(
165 path='/foo?notice=%s' % notice_id)
166
167 value = mr.GetIntParam('notice')
168 self.assertTrue(isinstance(value, six.integer_types))
169 self.assertEqual(notice_id, value)
170
171 def testGetIntListParam_NoParam(self):
172 mr = monorailrequest.MonorailRequest(self.services)
173 mr.ParseRequest(webapp2.Request.blank('servlet'), self.services)
174 self.assertEqual(mr.GetIntListParam('ids'), None)
175 self.assertEqual(mr.GetIntListParam('ids', default_value=['test']),
176 ['test'])
177
178 def testGetIntListParam_OneValue(self):
179 mr = monorailrequest.MonorailRequest(self.services)
180 mr.ParseRequest(webapp2.Request.blank('servlet?ids=11'), self.services)
181 self.assertEqual(mr.GetIntListParam('ids'), [11])
182 self.assertEqual(mr.GetIntListParam('ids', default_value=['test']),
183 [11])
184
185 def testGetIntListParam_MultiValue(self):
186 mr = monorailrequest.MonorailRequest(self.services)
187 mr.ParseRequest(
188 webapp2.Request.blank('servlet?ids=21,22,23'), self.services)
189 self.assertEqual(mr.GetIntListParam('ids'), [21, 22, 23])
190 self.assertEqual(mr.GetIntListParam('ids', default_value=['test']),
191 [21, 22, 23])
192
193 def testGetIntListParam_BogusValue(self):
194 mr = monorailrequest.MonorailRequest(self.services)
195 with self.assertRaises(exceptions.InputException):
196 mr.ParseRequest(
197 webapp2.Request.blank('servlet?ids=not_an_int'), self.services)
198
199 def testGetIntListParam_Malformed(self):
200 mr = monorailrequest.MonorailRequest(self.services)
201 with self.assertRaises(exceptions.InputException):
202 mr.ParseRequest(
203 webapp2.Request.blank('servlet?ids=31,32,,'), self.services)
204
205 def testDefaultValuesNoUrl(self):
206 """If request has no param, default param values should be used."""
207 mr = monorailrequest.MonorailRequest(self.services)
208 mr.ParseRequest(webapp2.Request.blank('servlet'), self.services)
209 self.assertEqual(mr.GetParam('r', 3), 3)
210 self.assertEqual(mr.GetIntParam('r', 3), 3)
211 self.assertEqual(mr.GetPositiveIntParam('r', 3), 3)
212 self.assertEqual(mr.GetIntListParam('r', [3, 4]), [3, 4])
213
214 def _MRWithMockRequest(
215 self, path, headers=None, *mr_args, **mr_kwargs):
216 request = webapp2.Request.blank(path, headers=headers)
217 mr = monorailrequest.MonorailRequest(self.services, *mr_args, **mr_kwargs)
218 mr.ParseRequest(request, self.services)
219 return mr
220
221 def testParseQueryParameters(self):
222 mr = self._MRWithMockRequest(
223 '/p/proj/issues/list?q=foo+OR+bar&num=50')
224 self.assertEqual('foo OR bar', mr.query)
225 self.assertEqual(50, mr.num)
226
227 def testParseQueryParameters_ModeMissing(self):
228 mr = self._MRWithMockRequest(
229 '/p/proj/issues/list?q=foo+OR+bar&num=50')
230 self.assertEqual('list', mr.mode)
231
232 def testParseQueryParameters_ModeList(self):
233 mr = self._MRWithMockRequest(
234 '/p/proj/issues/list?q=foo+OR+bar&num=50&mode=')
235 self.assertEqual('list', mr.mode)
236
237 def testParseQueryParameters_ModeGrid(self):
238 mr = self._MRWithMockRequest(
239 '/p/proj/issues/list?q=foo+OR+bar&num=50&mode=grid')
240 self.assertEqual('grid', mr.mode)
241
242 def testParseQueryParameters_ModeChart(self):
243 mr = self._MRWithMockRequest(
244 '/p/proj/issues/list?q=foo+OR+bar&num=50&mode=chart')
245 self.assertEqual('chart', mr.mode)
246
247 def testParseRequest_Scheme(self):
248 mr = self._MRWithMockRequest('/p/proj/')
249 self.assertEqual('http', mr.request.scheme)
250
251 def testParseRequest_HostportAndCurrentPageURL(self):
252 mr = self._MRWithMockRequest('/p/proj/', headers={
253 'Host': 'example.com',
254 'Cookie': 'asdf',
255 })
256 self.assertEqual('http', mr.request.scheme)
257 self.assertEqual('example.com', mr.request.host)
258 self.assertEqual('http://example.com/p/proj/', mr.current_page_url)
259
260 def testParseRequest_ProjectFound(self):
261 mr = self._MRWithMockRequest('/p/proj/')
262 self.assertEqual(mr.project, self.project)
263
264 def testParseRequest_ProjectNotFound(self):
265 with self.assertRaises(exceptions.NoSuchProjectException):
266 self._MRWithMockRequest('/p/no-such-proj/')
267
268 def testViewedUser_WithEmail(self):
269 mr = self._MRWithMockRequest('/u/jrobbins@example.com/')
270 self.assertEqual('jrobbins@example.com', mr.viewed_username)
271 self.assertEqual(111, mr.viewed_user_auth.user_id)
272 self.assertEqual(
273 self.services.user.GetUser('fake cnxn', 111),
274 mr.viewed_user_auth.user_pb)
275
276 def testViewedUser_WithUserID(self):
277 mr = self._MRWithMockRequest('/u/111/')
278 self.assertEqual('jrobbins@example.com', mr.viewed_username)
279 self.assertEqual(111, mr.viewed_user_auth.user_id)
280 self.assertEqual(
281 self.services.user.GetUser('fake cnxn', 111),
282 mr.viewed_user_auth.user_pb)
283
284 def testViewedUser_NoSuchEmail(self):
285 with self.assertRaises(webapp2.HTTPException) as cm:
286 self._MRWithMockRequest('/u/unknownuser@example.com/')
287 self.assertEqual(404, cm.exception.code)
288
289 def testViewedUser_NoSuchUserID(self):
290 with self.assertRaises(exceptions.NoSuchUserException):
291 self._MRWithMockRequest('/u/234521111/')
292
293 def testGetParam(self):
294 mr = testing_helpers.MakeMonorailRequest(
295 path='/foo?syn=error!&a=a&empty=',
296 params=dict(over1='over_value1', over2='over_value2'))
297
298 # test tampering
299 self.assertRaises(exceptions.InputException, mr.GetParam, 'a',
300 antitamper_re=re.compile(r'^$'))
301 self.assertRaises(exceptions.InputException, mr.GetParam,
302 'undefined', default_value='default',
303 antitamper_re=re.compile(r'^$'))
304
305 # test empty value
306 self.assertEqual('', mr.GetParam(
307 'empty', default_value='default', antitamper_re=re.compile(r'^$')))
308
309 # test default
310 self.assertEqual('default', mr.GetParam(
311 'undefined', default_value='default'))
312
313 def testComputeColSpec(self):
314 # No config passed, and nothing in URL
315 mr = testing_helpers.MakeMonorailRequest(
316 path='/p/proj/issues/detail?id=123')
317 mr.ComputeColSpec(None)
318 self.assertEqual(tracker_constants.DEFAULT_COL_SPEC, mr.col_spec)
319
320 # No config passed, but set in URL
321 mr = testing_helpers.MakeMonorailRequest(
322 path='/p/proj/issues/detail?id=123&colspec=a b C')
323 mr.ComputeColSpec(None)
324 self.assertEqual('a b C', mr.col_spec)
325
326 config = tracker_pb2.ProjectIssueConfig()
327
328 # No default in the config, and nothing in URL
329 mr = testing_helpers.MakeMonorailRequest(
330 path='/p/proj/issues/detail?id=123')
331 mr.ComputeColSpec(config)
332 self.assertEqual(tracker_constants.DEFAULT_COL_SPEC, mr.col_spec)
333
334 # No default in the config, but set in URL
335 mr = testing_helpers.MakeMonorailRequest(
336 path='/p/proj/issues/detail?id=123&colspec=a b C')
337 mr.ComputeColSpec(config)
338 self.assertEqual('a b C', mr.col_spec)
339
340 config.default_col_spec = 'd e f'
341
342 # Default in the config, and nothing in URL
343 mr = testing_helpers.MakeMonorailRequest(
344 path='/p/proj/issues/detail?id=123')
345 mr.ComputeColSpec(config)
346 self.assertEqual('d e f', mr.col_spec)
347
348 # Default in the config, but overrided via URL
349 mr = testing_helpers.MakeMonorailRequest(
350 path='/p/proj/issues/detail?id=123&colspec=a b C')
351 mr.ComputeColSpec(config)
352 self.assertEqual('a b C', mr.col_spec)
353
354 # project colspec contains hotlist columns
355 mr = testing_helpers.MakeMonorailRequest(
356 path='p/proj/issues/detail?id=123&colspec=Rank Adder Adder Owner')
357 mr.ComputeColSpec(None)
358 self.assertEqual(tracker_constants.DEFAULT_COL_SPEC, mr.col_spec)
359
360 # hotlist columns are not deleted when page is a hotlist page
361 mr = testing_helpers.MakeMonorailRequest(
362 path='u/jrobbins@example.com/hotlists/TestHotlist?colspec=Rank Adder',
363 hotlist=self.hotlist)
364 mr.ComputeColSpec(None)
365 self.assertEqual('Rank Adder', mr.col_spec)
366
367 def testComputeColSpec_XSS(self):
368 config_1 = tracker_pb2.ProjectIssueConfig()
369 config_2 = tracker_pb2.ProjectIssueConfig()
370 config_2.default_col_spec = "id '+alert(1)+'"
371 mr_1 = testing_helpers.MakeMonorailRequest(
372 path='/p/proj/issues/detail?id=123')
373 mr_2 = testing_helpers.MakeMonorailRequest(
374 path="/p/proj/issues/detail?id=123&colspec=id '+alert(1)+'")
375
376 # Normal colspec in config but malicious request
377 self.assertRaises(
378 exceptions.InputException,
379 mr_2.ComputeColSpec, config_1)
380
381 # Malicious colspec in config but normal request
382 self.assertRaises(
383 exceptions.InputException,
384 mr_1.ComputeColSpec, config_2)
385
386 # Malicious colspec in config and malicious request
387 self.assertRaises(
388 exceptions.InputException,
389 mr_2.ComputeColSpec, config_2)
390
391
392class CalcDefaultQueryTest(unittest.TestCase):
393
394 def setUp(self):
395 self.project = project_pb2.Project()
396 self.project.project_name = 'proj'
397 self.project.owner_ids = [111]
398 self.config = tracker_pb2.ProjectIssueConfig()
399
400 def testIssueListURL_NotDefaultCan(self):
401 mr = monorailrequest.MonorailRequest(None)
402 mr.query = None
403 mr.can = 1
404 self.assertEqual('', mr._CalcDefaultQuery())
405
406 def testIssueListURL_NoProject(self):
407 mr = monorailrequest.MonorailRequest(None)
408 mr.query = None
409 mr.can = 2
410 self.assertEqual('', mr._CalcDefaultQuery())
411
412 def testIssueListURL_NoConfig(self):
413 mr = monorailrequest.MonorailRequest(None)
414 mr.query = None
415 mr.can = 2
416 mr.project = self.project
417 self.assertEqual('', mr._CalcDefaultQuery())
418
419 def testIssueListURL_NotCustomized(self):
420 mr = monorailrequest.MonorailRequest(None)
421 mr.query = None
422 mr.can = 2
423 mr.project = self.project
424 mr.config = self.config
425 self.assertEqual('', mr._CalcDefaultQuery())
426
427 def testIssueListURL_Customized_Nonmember(self):
428 mr = monorailrequest.MonorailRequest(None)
429 mr.query = None
430 mr.can = 2
431 mr.project = self.project
432 mr.config = self.config
433 mr.config.member_default_query = 'owner:me'
434 self.assertEqual('', mr._CalcDefaultQuery())
435
436 mr.auth = testing_helpers.Blank(effective_ids=set())
437 self.assertEqual('', mr._CalcDefaultQuery())
438
439 mr.auth = testing_helpers.Blank(effective_ids={999})
440 self.assertEqual('', mr._CalcDefaultQuery())
441
442 def testIssueListURL_Customized_Member(self):
443 mr = monorailrequest.MonorailRequest(None)
444 mr.query = None
445 mr.can = 2
446 mr.project = self.project
447 mr.config = self.config
448 mr.config.member_default_query = 'owner:me'
449 mr.auth = testing_helpers.Blank(effective_ids={111})
450 self.assertEqual('owner:me', mr._CalcDefaultQuery())
451
452
453class TestMonorailRequestFunctions(unittest.TestCase):
454
455 def testExtractPathIdentifiers_ProjectOnly(self):
456 (username, project_name, hotlist_id,
457 hotlist_name) = monorailrequest._ParsePathIdentifiers(
458 '/p/proj/issues/list?q=foo+OR+bar&ts=1234')
459 self.assertIsNone(username)
460 self.assertIsNone(hotlist_id)
461 self.assertIsNone(hotlist_name)
462 self.assertEqual('proj', project_name)
463
464 def testExtractPathIdentifiers_ViewedUserOnly(self):
465 (username, project_name, hotlist_id,
466 hotlist_name) = monorailrequest._ParsePathIdentifiers(
467 '/u/jrobbins@example.com/')
468 self.assertEqual('jrobbins@example.com', username)
469 self.assertIsNone(project_name)
470 self.assertIsNone(hotlist_id)
471 self.assertIsNone(hotlist_name)
472
473 def testExtractPathIdentifiers_ViewedUserURLSpace(self):
474 (username, project_name, hotlist_id,
475 hotlist_name) = monorailrequest._ParsePathIdentifiers(
476 '/u/jrobbins@example.com/updates')
477 self.assertEqual('jrobbins@example.com', username)
478 self.assertIsNone(project_name)
479 self.assertIsNone(hotlist_id)
480 self.assertIsNone(hotlist_name)
481
482 def testExtractPathIdentifiers_ViewedGroupURLSpace(self):
483 (username, project_name, hotlist_id,
484 hotlist_name) = monorailrequest._ParsePathIdentifiers(
485 '/g/user-group@example.com/updates')
486 self.assertEqual('user-group@example.com', username)
487 self.assertIsNone(project_name)
488 self.assertIsNone(hotlist_id)
489 self.assertIsNone(hotlist_name)
490
491 def testExtractPathIdentifiers_HotlistIssuesURLSpaceById(self):
492 (username, project_name, hotlist_id,
493 hotlist_name) = monorailrequest._ParsePathIdentifiers(
494 '/u/jrobbins@example.com/hotlists/13124?q=stuff&ts=more')
495 self.assertIsNone(hotlist_name)
496 self.assertIsNone(project_name)
497 self.assertEqual('jrobbins@example.com', username)
498 self.assertEqual(13124, hotlist_id)
499
500 def testExtractPathIdentifiers_HotlistIssuesURLSpaceByName(self):
501 (username, project_name, hotlist_id,
502 hotlist_name) = monorailrequest._ParsePathIdentifiers(
503 '/u/jrobbins@example.com/hotlists/testname?q=stuff&ts=more')
504 self.assertIsNone(project_name)
505 self.assertIsNone(hotlist_id)
506 self.assertEqual('jrobbins@example.com', username)
507 self.assertEqual('testname', hotlist_name)
508
509 def testParseColSpec(self):
510 parse = monorailrequest.ParseColSpec
511 self.assertEqual(['PageName', 'Summary', 'Changed', 'ChangedBy'],
512 parse(u'PageName Summary Changed ChangedBy'))
513 self.assertEqual(['Foo-Bar', 'Foo-Bar-Baz', 'Release-1.2', 'Hey', 'There'],
514 parse('Foo-Bar Foo-Bar-Baz Release-1.2 Hey!There'))
515 self.assertEqual(
516 ['\xe7\xaa\xbf\xe8\x8b\xa5\xe7\xb9\xb9'.decode('utf-8'),
517 '\xe5\x9f\xba\xe5\x9c\xb0\xe3\x81\xaf'.decode('utf-8')],
518 parse('\xe7\xaa\xbf\xe8\x8b\xa5\xe7\xb9\xb9 '
519 '\xe5\x9f\xba\xe5\x9c\xb0\xe3\x81\xaf'.decode('utf-8')))
520
521 def testParseColSpec_Dedup(self):
522 """An attacker cannot inflate response size by repeating a column."""
523 parse = monorailrequest.ParseColSpec
524 self.assertEqual([], parse(''))
525 self.assertEqual(
526 ['Aa', 'b', 'c/d'],
527 parse(u'Aa Aa AA AA AA b Aa aa c/d d c aA b aa B C/D D/aa/c'))
528 self.assertEqual(
529 ['A', 'b', 'c/d', 'e', 'f'],
530 parse(u'A b c/d e f g h i j a/k l m/c/a n/o'))
531
532 def testParseColSpec_Huge(self):
533 """An attacker cannot inflate response size with a huge column name."""
534 parse = monorailrequest.ParseColSpec
535 self.assertEqual(
536 ['Aa', 'b', 'c/d'],
537 parse(u'Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c/d'))
538
539 def testParseColSpec_Ignore(self):
540 """We ignore groupby and grid axes that would be useless."""
541 parse = monorailrequest.ParseColSpec
542 self.assertEqual(
543 ['Aa', 'b', 'c/d'],
544 parse(u'Aa AllLabels alllabels Id b opened/summary c/d',
545 ignore=tracker_constants.NOT_USED_IN_GRID_AXES))
546
547
548class TestPermissionLookup(unittest.TestCase):
549 OWNER_ID = 1
550 OTHER_USER_ID = 2
551
552 def setUp(self):
553 self.services = service_manager.Services(
554 project=fake.ProjectService(),
555 user=fake.UserService(),
556 usergroup=fake.UserGroupService())
557 self.services.user.TestAddUser('owner@gmail.com', self.OWNER_ID)
558 self.services.user.TestAddUser('user@gmail.com', self.OTHER_USER_ID)
559 self.live_project = self.services.project.TestAddProject(
560 'live', owner_ids=[self.OWNER_ID])
561 self.archived_project = self.services.project.TestAddProject(
562 'archived', owner_ids=[self.OWNER_ID],
563 state=project_pb2.ProjectState.ARCHIVED)
564 self.members_only_project = self.services.project.TestAddProject(
565 'members-only', owner_ids=[self.OWNER_ID],
566 access=project_pb2.ProjectAccess.MEMBERS_ONLY)
567
568 self.mox = mox.Mox()
569
570 def tearDown(self):
571 self.mox.UnsetStubs()
572
573 def CheckPermissions(self, perms, expect_view, expect_commit, expect_edit):
574 may_view = perms.HasPerm(permissions.VIEW, None, None)
575 self.assertEqual(expect_view, may_view)
576 may_commit = perms.HasPerm(permissions.COMMIT, None, None)
577 self.assertEqual(expect_commit, may_commit)
578 may_edit = perms.HasPerm(permissions.EDIT_PROJECT, None, None)
579 self.assertEqual(expect_edit, may_edit)
580
581 def MakeRequestAsUser(self, project_name, email):
582 self.mox.StubOutWithMock(users, 'get_current_user')
583 users.get_current_user().AndReturn(testing_helpers.Blank(
584 email=lambda: email))
585 self.mox.ReplayAll()
586
587 request = webapp2.Request.blank('/p/' + project_name)
588 mr = monorailrequest.MonorailRequest(self.services)
589 with mr.profiler.Phase('parse user info'):
590 mr.ParseRequest(request, self.services)
591 print('mr.auth is %r' % mr.auth)
592 return mr
593
594 def testOwnerPermissions_Live(self):
595 mr = self.MakeRequestAsUser('live', 'owner@gmail.com')
596 self.CheckPermissions(mr.perms, True, True, True)
597
598 def testOwnerPermissions_Archived(self):
599 mr = self.MakeRequestAsUser('archived', 'owner@gmail.com')
600 self.CheckPermissions(mr.perms, True, False, True)
601
602 def testOwnerPermissions_MembersOnly(self):
603 mr = self.MakeRequestAsUser('members-only', 'owner@gmail.com')
604 self.CheckPermissions(mr.perms, True, True, True)
605
606 def testExternalUserPermissions_Live(self):
607 mr = self.MakeRequestAsUser('live', 'user@gmail.com')
608 self.CheckPermissions(mr.perms, True, False, False)
609
610 def testExternalUserPermissions_Archived(self):
611 mr = self.MakeRequestAsUser('archived', 'user@gmail.com')
612 self.CheckPermissions(mr.perms, False, False, False)
613
614 def testExternalUserPermissions_MembersOnly(self):
615 mr = self.MakeRequestAsUser('members-only', 'user@gmail.com')
616 self.CheckPermissions(mr.perms, False, False, False)