diff options
Diffstat (limited to 'cli/onionshare_cli')
-rw-r--r-- | cli/onionshare_cli/resources/templates/receive.html | 2 | ||||
-rw-r--r-- | cli/onionshare_cli/resources/version.txt | 2 | ||||
-rw-r--r-- | cli/onionshare_cli/settings.py | 2 | ||||
-rw-r--r-- | cli/onionshare_cli/web/chat_mode.py | 93 | ||||
-rw-r--r-- | cli/onionshare_cli/web/receive_mode.py | 7 |
5 files changed, 78 insertions, 28 deletions
diff --git a/cli/onionshare_cli/resources/templates/receive.html b/cli/onionshare_cli/resources/templates/receive.html index 159bfac5..90f10798 100644 --- a/cli/onionshare_cli/resources/templates/receive.html +++ b/cli/onionshare_cli/resources/templates/receive.html @@ -53,7 +53,7 @@ <p><input type="file" id="file-select" name="file[]" multiple /></p> {% endif %} {% if not disable_text %} - <p><textarea id="text" name="text" placeholder="Write a message"></textarea></p> + <p><textarea id="text" name="text" placeholder="Write a message (max length 524288 characters)" maxlength="524288"></textarea></p> {% endif %} <p><button type="submit" id="send-button" class="button">Submit</button></p> </form> diff --git a/cli/onionshare_cli/resources/version.txt b/cli/onionshare_cli/resources/version.txt index 6a6a3d8e..097a15a2 100644 --- a/cli/onionshare_cli/resources/version.txt +++ b/cli/onionshare_cli/resources/version.txt @@ -1 +1 @@ -2.6.1 +2.6.2 diff --git a/cli/onionshare_cli/settings.py b/cli/onionshare_cli/settings.py index 74cc1c74..9ee65a87 100644 --- a/cli/onionshare_cli/settings.py +++ b/cli/onionshare_cli/settings.py @@ -66,7 +66,7 @@ class Settings(object): "zh_Hans": "中文 (简体)", # Simplified Chinese "hr": "Hrvatski", # Croatian "cs": "čeština", # Czech - # "da": "Dansk", # Danish + "da": "Dansk", # Danish # "nl": "Nederlands", # Dutch "en": "English", # English "fi": "Suomi", # Finnish diff --git a/cli/onionshare_cli/web/chat_mode.py b/cli/onionshare_cli/web/chat_mode.py index 5a11eedd..7f608c60 100644 --- a/cli/onionshare_cli/web/chat_mode.py +++ b/cli/onionshare_cli/web/chat_mode.py @@ -17,6 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ +import unicodedata from flask import request, render_template, make_response, jsonify, session from flask_socketio import emit, ConnectionRefusedError @@ -47,15 +48,45 @@ class ChatModeWeb: self.define_routes() - def validate_username(self, username): - username = username.strip() - return ( - username - and username.isascii() - and username not in self.connected_users - and len(username) < 128 + def remove_unallowed_characters(self, text): + """ + Sanitize username to remove unwanted characters. + Allowed characters right now are: + - all ASCII numbers + - all ASCII letters + - dash, underscore and single space + """ + + def allowed_character(ch): + allowed_unicode_categories = [ + 'L', # All letters + 'N', # All numbers + ] + allowed_special_characters = [ + '-', # dash + '_', # underscore + ' ', # single space + ] + return ( + unicodedata.category(ch)[0] in allowed_unicode_categories and ord(ch) < 128 + ) or ch in allowed_special_characters + + return "".join( + ch for ch in text if allowed_character(ch) ) + def validate_username(self, username): + try: + username = self.remove_unallowed_characters(username.strip()) + return ( + username + and username not in self.connected_users + and len(username) < 128 + ) + except Exception as e: + self.common.log("ChatModeWeb", "validate_username", e) + return False + def define_routes(self): """ The web app routes for chatting @@ -77,13 +108,17 @@ class ChatModeWeb: self.web.add_request(self.web.REQUEST_LOAD, request.path) return render_template( - "chat.html", - static_url_path=self.web.static_url_path, - username=session.get("name"), - title=self.web.settings.get("general", "title"), + "chat.html", + static_url_path=self.web.static_url_path, + username=session.get("name"), + title=self.web.settings.get("general", "title"), ) - @self.web.app.route("/update-session-username", methods=["POST"], provide_automatic_options=False) + @self.web.app.route( + "/update-session-username", + methods=["POST"], + provide_automatic_options=False, + ) def update_session_username(): history_id = self.cur_history_id data = request.get_json() @@ -122,6 +157,8 @@ class ChatModeWeb: A status message is broadcast to all people in the room.""" if self.validate_username(session.get("name")): self.connected_users.append(session.get("name")) + # Store the session id for the user + session["socketio_session_id"] = request.sid emit( "status", { @@ -133,7 +170,7 @@ class ChatModeWeb: broadcast=True, ) else: - raise ConnectionRefusedError('You are active from another session!') + raise ConnectionRefusedError('Invalid session') @self.web.socketio.on("text", namespace="/chat") def text(message): @@ -153,9 +190,9 @@ class ChatModeWeb: new_name = message.get("username", "").strip() if self.validate_username(new_name): session["name"] = new_name - self.connected_users[ - self.connected_users.index(current_name) - ] = session.get("name") + self.connected_users[self.connected_users.index(current_name)] = ( + session.get("name") + ) emit( "status", { @@ -178,13 +215,23 @@ class ChatModeWeb: def disconnect(): """Sent by clients when they disconnect. A status message is broadcast to all people in the server.""" + user_already_disconnected = False if session.get("name") in self.connected_users: self.connected_users.remove(session.get("name")) - emit( - "status", - { - "msg": "{} has left the room.".format(session.get("name")), - "connected_users": self.connected_users, - }, - broadcast=True, + else: + user_already_disconnected = True + + # Forcefully disconnect the user + self.web.socketio.server.disconnect( + sid=session.get("socketio_session_id"), namespace="/chat" ) + + if not user_already_disconnected: + emit( + "status", + { + "msg": "{} has left the room.".format(session.get("name")), + "connected_users": self.connected_users, + }, + broadcast=True, + ) diff --git a/cli/onionshare_cli/web/receive_mode.py b/cli/onionshare_cli/web/receive_mode.py index 9ddf22ff..a25f82a1 100644 --- a/cli/onionshare_cli/web/receive_mode.py +++ b/cli/onionshare_cli/web/receive_mode.py @@ -194,7 +194,10 @@ class ReceiveModeWeb: if files_received > 0: msg = f"Uploaded {files_msg}" else: - msg = "Nothing submitted" + if not self.web.settings.get("receive", "disable_text"): + msg = "Nothing submitted or message was too long (> 524288 characters)" + else: + msg = "Nothing submitted" if ajax: info_flashes.append(msg) @@ -462,7 +465,7 @@ class ReceiveModeRequest(Request): self.includes_message = False if not self.web.settings.get("receive", "disable_text"): text_message = self.form.get("text") - if text_message: + if text_message and len(text_message) <= 524288: if text_message.strip() != "": self.includes_message = True |