blob: 80861828fb5e2e198480dcd335ed0aaf013ba528 [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"""Functions to help display attachments and compute quotas."""
6from __future__ import print_function
7from __future__ import division
8from __future__ import absolute_import
9
10import base64
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010011import hashlib
Copybara854996b2021-09-07 19:36:02 +000012import hmac
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010013import six
Copybara854996b2021-09-07 19:36:02 +000014
15from framework import urls
16from services import secrets_svc
17from tracker import tracker_helpers
18
19
20VIEWABLE_IMAGE_TYPES = [
21 'image/jpeg', 'image/gif', 'image/png', 'image/x-png', 'image/webp',
22 ]
23VIEWABLE_VIDEO_TYPES = [
24 'video/ogg', 'video/mp4', 'video/mpg', 'video/mpeg', 'video/webm',
25 'video/quicktime',
26 ]
27MAX_PREVIEW_FILESIZE = 15 * 1024 * 1024 # 15 MB
28
29
30def IsViewableImage(mimetype_charset, filesize):
31 """Return true if we can safely display such an image in the browser.
32
33 Args:
34 mimetype_charset: string with the mimetype string that we got back
35 from the 'file' command. It may have just the mimetype, or it
36 may have 'foo/bar; charset=baz'.
37 filesize: int length of the file in bytes.
38
39 Returns:
40 True iff we should allow the user to view a thumbnail or safe version
41 of the image in the browser. False if this might not be safe to view,
42 in which case we only offer a download link.
43 """
44 mimetype = mimetype_charset.split(';', 1)[0]
45 return (mimetype in VIEWABLE_IMAGE_TYPES and
46 filesize < MAX_PREVIEW_FILESIZE)
47
48
49def IsViewableVideo(mimetype_charset, filesize):
50 """Return true if we can safely display such a video in the browser.
51
52 Args:
53 mimetype_charset: string with the mimetype string that we got back
54 from the 'file' command. It may have just the mimetype, or it
55 may have 'foo/bar; charset=baz'.
56 filesize: int length of the file in bytes.
57
58 Returns:
59 True iff we should allow the user to watch the video in the page.
60 """
61 mimetype = mimetype_charset.split(';', 1)[0]
62 return (mimetype in VIEWABLE_VIDEO_TYPES and
63 filesize < MAX_PREVIEW_FILESIZE)
64
65
66def IsViewableText(mimetype, filesize):
67 """Return true if we can safely display such a file as escaped text."""
68 return (mimetype.startswith('text/') and
69 filesize < MAX_PREVIEW_FILESIZE)
70
71
72def SignAttachmentID(aid):
73 """One-way hash of attachment ID to make it harder for people to scan."""
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010074 digester = hmac.new(secrets_svc.GetXSRFKey(), digestmod=hashlib.md5)
75 digester.update(six.ensure_binary(str(aid)))
76 return six.ensure_str(base64.urlsafe_b64encode(digester.digest()))
Copybara854996b2021-09-07 19:36:02 +000077
78
79def GetDownloadURL(attachment_id):
80 """Return a relative URL to download an attachment to local disk."""
81 return 'attachment?aid=%s&signed_aid=%s' % (
82 attachment_id, SignAttachmentID(attachment_id))
83
84
85def GetViewURL(attach, download_url, project_name):
86 """Return a relative URL to view an attachment in the browser."""
87 if IsViewableImage(attach.mimetype, attach.filesize):
88 return download_url + '&inline=1'
89 elif IsViewableVideo(attach.mimetype, attach.filesize):
90 return download_url + '&inline=1'
91 elif IsViewableText(attach.mimetype, attach.filesize):
92 return tracker_helpers.FormatRelativeIssueURL(
93 project_name, urls.ISSUE_ATTACHMENT_TEXT,
94 aid=attach.attachment_id)
95 else:
96 return None
97
98
99def GetThumbnailURL(attach, download_url):
100 """Return a relative URL to view an attachment thumbnail."""
101 if IsViewableImage(attach.mimetype, attach.filesize):
102 return download_url + '&inline=1&thumb=1'
103 else:
104 return None
105
106
107def GetVideoURL(attach, download_url):
108 """Return a relative URL to view an attachment thumbnail."""
109 if IsViewableVideo(attach.mimetype, attach.filesize):
110 return download_url + '&inline=1'
111 else:
112 return None