blob: 0330e19dd722bdefb45f3002ea00666ba937eb6e [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001# Copyright 2016 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Copybara854996b2021-09-07 19:36:02 +00004
5"""Tests for monorail.tracker.issueattachment."""
6from __future__ import print_function
7from __future__ import division
8from __future__ import absolute_import
9
10import unittest
11
Copybara854996b2021-09-07 19:36:02 +000012from google.appengine.ext import testbed
13
Adrià Vilanova Martínez9f9ade52022-10-10 23:20:11 +020014try:
15 from mox3 import mox
16except ImportError:
17 import mox
Copybara854996b2021-09-07 19:36:02 +000018
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010019from framework import exceptions, gcs_helpers
Copybara854996b2021-09-07 19:36:02 +000020from framework import permissions
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010021from mrproto import tracker_pb2
Copybara854996b2021-09-07 19:36:02 +000022from services import service_manager
23from testing import fake
24from testing import testing_helpers
25from tracker import attachment_helpers
26from tracker import issueattachment
Copybara854996b2021-09-07 19:36:02 +000027
28
29class IssueattachmentTest(unittest.TestCase):
30
31 def setUp(self):
32 self.mox = mox.Mox()
33 self.testbed = testbed.Testbed()
34 self.testbed.activate()
35 self.testbed.init_memcache_stub()
36 self.testbed.init_app_identity_stub()
37 self.testbed.init_urlfetch_stub()
38 self.attachment_data = ""
39
Copybara854996b2021-09-07 19:36:02 +000040 services = service_manager.Services(
41 project=fake.ProjectService(),
42 config=fake.ConfigService(),
43 issue=fake.IssueService(),
44 user=fake.UserService())
45 self.project = services.project.TestAddProject('proj')
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010046 self.servlet = issueattachment.AttachmentPage(services=services)
Copybara854996b2021-09-07 19:36:02 +000047 services.user.TestAddUser('commenter@example.com', 111)
48 self.issue = fake.MakeTestIssue(
49 self.project.project_id, 1, 'summary', 'New', 111)
50 services.issue.TestAddIssue(self.issue)
51 self.comment = tracker_pb2.IssueComment(
52 id=123, issue_id=self.issue.issue_id,
53 project_id=self.project.project_id, user_id=111,
54 content='this is a comment')
55 services.issue.TestAddComment(self.comment, self.issue.local_id)
56 self.attachment = tracker_pb2.Attachment(
57 attachment_id=54321, filename='hello.txt', filesize=23432,
58 mimetype='text/plain', gcs_object_id='/pid/attachments/object_id')
59 services.issue.TestAddAttachment(
60 self.attachment, self.comment.id, self.issue.issue_id)
61 self.orig_sign_attachment_id = attachment_helpers.SignAttachmentID
62 attachment_helpers.SignAttachmentID = (
63 lambda aid: 'signed_%d' % aid)
64
65 def tearDown(self):
66 self.mox.UnsetStubs()
67 self.mox.ResetAll()
68 self.testbed.deactivate()
Copybara854996b2021-09-07 19:36:02 +000069 attachment_helpers.SignAttachmentID = self.orig_sign_attachment_id
70
71 def testGatherPageData_NotFound(self):
72 aid = 12345
73 path = '/p/proj/issues/attachment?aid=%s&signed_aid=signed_%d' % (
74 aid, aid)
75 # But, no such attachment is in the database.
76 _request, mr = testing_helpers.GetRequestObjects(
77 project=self.project, path=path,
78 perms=permissions.EMPTY_PERMISSIONSET)
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010079 with self.assertRaises(Exception) as cm:
Copybara854996b2021-09-07 19:36:02 +000080 self.servlet.GatherPageData(mr)
81 self.assertEqual(404, cm.exception.code)
82
83 # TODO(jrobbins): test cases for missing comment and missing issue.
84
85 def testGatherPageData_PermissionDenied(self):
86 aid = self.attachment.attachment_id
87 path = '/p/proj/issues/attachment?aid=%s&signed_aid=signed_%d' % (
88 aid, aid)
89 _request, mr = testing_helpers.GetRequestObjects(
90 project=self.project, path=path,
91 perms=permissions.EMPTY_PERMISSIONSET) # not even VIEW
92 self.assertRaises(
93 permissions.PermissionException,
94 self.servlet.GatherPageData, mr)
95
96 _request, mr = testing_helpers.GetRequestObjects(
97 project=self.project, path=path,
98 perms=permissions.READ_ONLY_PERMISSIONSET) # includes VIEW
99
100 # issue is now deleted
101 self.issue.deleted = True
102 self.assertRaises(
103 permissions.PermissionException,
104 self.servlet.GatherPageData, mr)
105 self.issue.deleted = False
106
107 # issue is now restricted
108 self.issue.labels.extend(['Restrict-View-PermYouLack'])
109 self.assertRaises(
110 permissions.PermissionException,
111 self.servlet.GatherPageData, mr)
112
113 def testGatherPageData_Download_WithDisposition(self):
114 aid = self.attachment.attachment_id
115 self.mox.StubOutWithMock(gcs_helpers, 'MaybeCreateDownload')
116 gcs_helpers.MaybeCreateDownload(
117 'app_default_bucket',
118 '/pid/attachments/object_id',
119 self.attachment.filename).AndReturn(True)
120 self.mox.StubOutWithMock(gcs_helpers, 'SignUrl')
121 gcs_helpers.SignUrl(
122 'app_default_bucket',
123 '/pid/attachments/object_id-download'
124 ).AndReturn('googleusercontent.com/...-download...')
Copybara854996b2021-09-07 19:36:02 +0000125 path = '/p/proj/issues/attachment?aid=%s&signed_aid=signed_%d' % (
126 aid, aid)
127 _request, mr = testing_helpers.GetRequestObjects(
128 project=self.project, path=path,
129 perms=permissions.READ_ONLY_PERMISSIONSET) # includes VIEW
Copybara854996b2021-09-07 19:36:02 +0000130 self.mox.ReplayAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100131 with self.assertRaises(exceptions.RedirectException) as e:
132 self.servlet.GatherPageData(mr)
Copybara854996b2021-09-07 19:36:02 +0000133 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100134 self.assertIn('googleusercontent.com', str(e.exception))
135 self.assertIn('-download', str(e.exception))
Copybara854996b2021-09-07 19:36:02 +0000136
137 def testGatherPageData_Download_WithoutDisposition(self):
138 aid = self.attachment.attachment_id
139 path = '/p/proj/issues/attachment?aid=%s&signed_aid=signed_%d' % (
140 aid, aid)
141 self.mox.StubOutWithMock(gcs_helpers, 'MaybeCreateDownload')
142 gcs_helpers.MaybeCreateDownload(
143 'app_default_bucket',
144 '/pid/attachments/object_id',
145 self.attachment.filename).AndReturn(False)
146 self.mox.StubOutWithMock(gcs_helpers, 'SignUrl')
147 gcs_helpers.SignUrl(
148 'app_default_bucket',
149 '/pid/attachments/object_id'
150 ).AndReturn('googleusercontent.com/...')
Copybara854996b2021-09-07 19:36:02 +0000151 _request, mr = testing_helpers.GetRequestObjects(
152 project=self.project, path=path,
153 perms=permissions.READ_ONLY_PERMISSIONSET) # includes VIEW
Copybara854996b2021-09-07 19:36:02 +0000154 self.mox.ReplayAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100155 with self.assertRaises(exceptions.RedirectException) as e:
156 self.servlet.GatherPageData(mr)
Copybara854996b2021-09-07 19:36:02 +0000157 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100158 self.assertIn('googleusercontent.com', str(e.exception))
159 self.assertNotIn('-download', str(e.exception))
Copybara854996b2021-09-07 19:36:02 +0000160
161 def testGatherPageData_DownloadBadFilename(self):
162 aid = self.attachment.attachment_id
163 path = '/p/proj/issues/attachment?aid=%s&signed_aid=signed_%d' % (
164 aid, aid)
165 self.attachment.filename = '<script>alert("xsrf")</script>.txt';
166 safe_filename = 'attachment-%d.dat' % aid
167 self.mox.StubOutWithMock(gcs_helpers, 'MaybeCreateDownload')
168 gcs_helpers.MaybeCreateDownload(
169 'app_default_bucket',
170 '/pid/attachments/object_id',
171 safe_filename).AndReturn(True)
172 self.mox.StubOutWithMock(gcs_helpers, 'SignUrl')
173 gcs_helpers.SignUrl(
174 'app_default_bucket',
175 '/pid/attachments/object_id-download'
176 ).AndReturn('googleusercontent.com/...-download...')
Copybara854996b2021-09-07 19:36:02 +0000177 _request, mr = testing_helpers.GetRequestObjects(
178 project=self.project,
179 path=path,
180 perms=permissions.READ_ONLY_PERMISSIONSET) # includes VIEW
Copybara854996b2021-09-07 19:36:02 +0000181 self.mox.ReplayAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100182 with self.assertRaises(exceptions.RedirectException) as e:
183 self.servlet.GatherPageData(mr)
Copybara854996b2021-09-07 19:36:02 +0000184 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100185 self.assertIn('googleusercontent.com', str(e.exception))