]> littlesong.place Git - littlesongplace.git/commitdiff
Allow HTML in user bio
authorChris Fulljames <christianfulljames@gmail.com>
Fri, 10 Jan 2025 13:09:14 +0000 (08:09 -0500)
committerChris Fulljames <christianfulljames@gmail.com>
Fri, 10 Jan 2025 13:09:14 +0000 (08:09 -0500)
main.py
requirements.txt
templates/profile.html

diff --git a/main.py b/main.py
index e56bebd7c261b10f357c95a959cceaeb4e234357..ef8560aeb579c8e9ec26051025e2e44ced5c710f 100644 (file)
--- a/main.py
+++ b/main.py
@@ -9,7 +9,9 @@ import uuid
 from pathlib import Path, PosixPath
 
 import bcrypt
+import bleach
 import click
+from bleach.css_sanitizer import CSSSanitizer
 from flask import Flask, render_template, request, redirect, g, session, abort, \
         send_from_directory, flash
 from werkzeug.utils import secure_filename
@@ -113,9 +115,30 @@ def users_profile(profile_username):
 
     # Get songs for current profile
     profile_userid = profile_data["userid"]
-    profile_bio = profile_data["bio"]
     songs = Song.get_all_for_user(profile_userid)
 
+    # Sanitize bio
+    allowed_tags = bleach.sanitizer.ALLOWED_TAGS.union({
+        'area', 'br', 'div', 'img', 'map', 'hr', 'header', 'hgroup', 'table', 'tr', 'td',
+        'th', 'thead', 'tbody', 'span', 'small', 'p', 'q', 'u', 'pre',
+    })
+    allowed_attributes = {
+        "*": ["style"], "a": ["href", "title"], "abbr": ["title"], "acronym": ["title"],
+        "img": ["src", "alt", "usemap", "width", "height"], "map": ["name"],
+        "area": ["shape", "coords", "alt", "href"]
+    }
+    allowed_css_properties = {
+        "font-size", "font-style", "font-variant", "font-family", "font-weight", "color",
+        "background-color", "background-image", "border", "border-color",
+        "border-image", "width", "height"
+    }
+    css_sanitizer = CSSSanitizer(allowed_css_properties=allowed_css_properties)
+    profile_bio = bleach.clean(
+            profile_data["bio"],
+            tags=allowed_tags,
+            attributes=allowed_attributes,
+            css_sanitizer=css_sanitizer)
+
     return render_template(
             "profile.html",
             name=profile_username,
index bb2793b937a0add60f370c6e0e0e7f1668d74acb..d9c96abb20d3e95ec0609fe5e5a71881b53db6fd 100644 (file)
@@ -1,2 +1,4 @@
-flask
 bcrypt
+bleach[css]
+flask
+
index 4cd2ff7fb9c4677fa5e0fb3184a39d7d17080aad..22c1619ac1fb05702ee16edf1032923982e31c1c 100644 (file)
@@ -7,7 +7,7 @@
 <h1 class="profile-name">{{ name }}</h1>
 
 <!-- Bio -->
-<div class="profile-bio" id="profile-bio">{{ bio }}</div>
+<div class="profile-bio" id="profile-bio">{{ bio|safe }}</div>
 
 <!-- Bio edit form -->
 {% if session["userid"] == userid %}
@@ -15,6 +15,8 @@
 <a href="javascript:showEditForm();" id="profile-bio-edit-btn">Edit Bio</a>
 
 <form id="profile-edit-form" action="/update-bio" method="post" hidden>
+    <h2> Edit Bio </h2>
+    <p>Common HTML tags (&lt;a&gt;, &lt;b&gt;, &lt;i&gt;, &lt;img&gt;, etc.) are allowed.</p>
     <div class="profile-edit">
         <textarea name="bio">{{ bio }}</textarea>
     </div>