annotate libervia/web/pages/_browser/file_uploader.py @ 1598:86c7a3a625d5

server: always start a new session on connection: The session was kept when a user was connecting from service profile (but not from other profiles), this was leading to session fixation vulnerability (an attacker on the same machine could get service profile session cookie, and use it when a victim would log-in). This patch fixes it by always starting a new session on connection. fix 443
author Goffi <goffi@goffi.org>
date Fri, 23 Feb 2024 13:35:24 +0100 (13 months ago)
parents 106945841fbc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1532
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 import json
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 from bridge import Bridge
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 from browser import console as log, window
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 import dialog
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 from template import Template
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 bridge = Bridge()
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
7
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 log.warning = log.warn
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
9
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 class FileUploader:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 """Class handling HTTP upload and progress display"""
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
13
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 def __init__(self, files_service, template_file, files_path=None, on_delete_cb=None):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 self.files_service = files_service
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 self.files_path = files_path
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 self.item_tpl = Template(template_file)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 self.on_delete_cb = on_delete_cb
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 self.uploaded = {}
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 def on_progress(self, ev, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 if ev.lengthComputable:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 percent = int(ev.loaded/ev.total*100)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 self.update_progress(item_elt, percent)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
25
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 def on_load(self, file_, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 self.update_progress(item_elt, 100)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 item_elt.classList.add("progress_finished")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 item_elt.classList.remove("progress_started")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 if self.on_delete_cb is not None:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 delete_btn = item_elt.select_one('.action_delete')
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 if delete_btn is not None:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 delete_btn.bind("click", self.on_delete_cb)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 log.info(f"file {file_.name} uploaded correctly")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
35
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 def on_error(self, failure, file_, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 dialog.notification.show(
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 f"can't upload {file_.name}: {failure}",
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 level="error"
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 )
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
41
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 def update_progress(self, item_elt, new_value):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 progress_elt = item_elt.select_one("progress")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 if progress_elt is not None:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 progress_elt.value = new_value
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 progress_elt.text = f"{new_value}%"
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
47
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 def on_slot_cb(self, file_, upload_slot, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 put_url, get_url, headers = upload_slot
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 xhr = window.XMLHttpRequest.new()
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 xhr.open("PUT", put_url, True)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 xhr.upload.bind('progress', lambda ev: self.on_progress(ev, item_elt))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 xhr.upload.bind('load', lambda ev: self.on_load(file_, item_elt))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 xhr.upload.bind('error', lambda ev: self.on_error(xhr.response, file_, item_elt))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 if self.files_path is not None:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 xhr.setRequestHeader(
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 'Xmpp-File-Path',
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 window.encodeURIComponent(self.files_path)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 )
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 xhr.setRequestHeader('Xmpp-File-No-Http', "true")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 xhr.send(file_)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
62
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 # we update file data with the get URL
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 file_data = json.loads(item_elt.getAttribute("data-file"))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 file_data["url"] = get_url
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 item_elt.setAttribute("data-file", json.dumps(file_data))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
67
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 def on_slot_eb(self, file_, failure, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 dialog.notification.show(
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 f"Can't get upload slot: {failure['message']}",
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 level="error"
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 )
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 item_elt.remove()
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
74
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 def upload_files(self, files, container_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 """Start file upload, and add item_tpl to container_elt"""
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 log.info(f"uploading {len(files)} files")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 for file_ in files:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 url = window.URL.createObjectURL(file_)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
80
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 file_data = {
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 "name": file_.name,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 "mime_type": file_.type,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 }
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 template_file_data = file_data.copy()
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 # we don't want to open the file on click, it's not yet the
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 # uploaded URL
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 template_file_data["url"] = url
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 # we have no thumb yet, so we use the whole image
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 # TODO: reduce image for preview
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 template_file_data["thumb_url"] = url
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
92
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 item_elt = self.item_tpl.get_elt({
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 "file": template_file_data,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 "uploading": True,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 })
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 item_elt.setAttribute("data-file", json.dumps(file_data))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 item_elt.classList.add("progress_started")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 container_elt <= item_elt
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
100
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 bridge.file_http_upload_get_slot(
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 file_.name,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 file_.size,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 file_.type or '',
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 self.files_service,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 callback=lambda upload_slot, file_=file_, item_elt=item_elt:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 self.on_slot_cb(file_, upload_slot, item_elt),
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 errback=lambda failure, file_=file_, item_elt=item_elt:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 self.on_slot_eb(file_, failure, item_elt),
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 )