Skip to content

Commit

Permalink
fix: Simplify permission checks for TOTP and profile actions; enhance…
Browse files Browse the repository at this point in the history
… error handling for hooks
  • Loading branch information
TheophileDiot committed Feb 27, 2025
1 parent 3d7ed63 commit 1eebadf
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 41 deletions.
20 changes: 5 additions & 15 deletions src/ui/app/routes/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,7 @@ def generate_stream():
@profile.route("/profile/totp-refresh", methods=["POST"])
@login_required
def totp_refresh():
if "write" not in current_user.list_permissions:
return Response("You don't have the required permissions to refresh the recovery codes.", 403)
elif DB.readonly:
if DB.readonly:
return handle_error("Database is in read-only mode", "profile")

if not bool(current_user.totp_secret):
Expand All @@ -129,9 +127,7 @@ def totp_refresh():
@profile.route("/profile/totp-disable", methods=["POST"])
@login_required
def totp_disable():
if "write" not in current_user.list_permissions:
return Response("You don't have the required permissions to disable two-factor authentication.", 403)
elif DB.readonly:
if DB.readonly:
return handle_error("Database is in read-only mode", "profile")

if not bool(current_user.totp_secret):
Expand Down Expand Up @@ -162,9 +158,7 @@ def totp_disable():
@profile.route("/profile/totp-enable", methods=["POST"])
@login_required
def totp_enable():
if "write" not in current_user.list_permissions:
return Response("You don't have the required permissions to enable two-factor authentication.", 403)
elif DB.readonly:
if DB.readonly:
return handle_error("Database is in read-only mode", "profile")

if bool(current_user.totp_secret):
Expand Down Expand Up @@ -206,9 +200,7 @@ def totp_enable():
@profile.route("/profile/edit", methods=["POST"])
@login_required
def edit_profile():
if "write" not in current_user.list_permissions:
return Response("You don't have the required permissions to edit your profile.", 403)
elif DB.readonly:
if DB.readonly:
return handle_error("Database is in read-only mode", "profile")

user_data = {
Expand Down Expand Up @@ -286,9 +278,7 @@ def edit_profile():
@profile.route("/profile/wipe-other-sessions", methods=["POST"])
@login_required
def wipe_old_sessions():
if "write" not in current_user.list_permissions:
return Response("You don't have the required permissions to wipe your other sessions.", 403)
elif DB.readonly:
if DB.readonly:
return handle_error("Database is in read-only mode", "profile")

verify_data_in_form(data={"password": None}, err_message="Missing current password parameter on /profile/wipe-other-sessions.", redirect_url="profile")
Expand Down
2 changes: 1 addition & 1 deletion src/ui/app/templates/flash.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{% if messages.append(('error', 'You have more services than allowed by your pro license. Upgrade your license or move some services to draft mode to unlock your pro license.')) %}
{% endif %}
{% endif %}
{% if user_readonly %}
{% if user_readonly and current_endpoint != "profile" %}
{% if messages.append(('warning', 'You are in read-only mode. You can\'t make changes that will be saved in the database.')) %}
{% endif %}
{% endif %}
Expand Down
21 changes: 7 additions & 14 deletions src/ui/app/templates/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,7 @@ <h5 class="card-header">Edit Profile</h5>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title={% if user_readonly %}"Readonly mode enabled"{% else %}"The database is in readonly, therefore the configuration is locked"{% endif %}
{% endif %}>
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The database is in readonly, therefore the configuration is locked" {% endif %}>
<button type="submit"
class="btn btn-primary me-2{% if is_readonly %} disabled{% endif %}">
Save Changes
Expand Down Expand Up @@ -193,8 +192,7 @@ <h5 class="card-header">Change Theme</h5>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title={% if user_readonly %}"Readonly mode enabled"{% else %}"The database is in readonly, therefore the configuration is locked"{% endif %}
{% endif %}>
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The database is in readonly, therefore the configuration is locked" {% endif %}>
<button type="submit"
class="btn btn-primary me-2{% if is_readonly %} disabled{% endif %}">
Save Changes
Expand Down Expand Up @@ -283,8 +281,7 @@ <h5 class="card-header">Change Password</h5>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title={% if user_readonly %}"Readonly mode enabled"{% else %}"The database is in readonly, therefore the configuration is locked"{% endif %}
{% endif %}>
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The database is in readonly, therefore the configuration is locked" {% endif %}>
<button type="submit"
class="btn btn-primary me-2{% if is_readonly %} disabled{% endif %}">
Save Changes
Expand Down Expand Up @@ -365,8 +362,7 @@ <h5 class="mb-0">Enable 2FA</h5>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title={% if user_readonly %}"Readonly mode enabled"{% else %}"The database is in readonly, therefore the configuration is locked"{% endif %}
{% endif %}>
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The database is in readonly, therefore the configuration is locked" {% endif %}>
<button type="submit"
class="btn btn-primary{% if is_readonly %} disabled{% endif %}">
Enable TOTP
Expand Down Expand Up @@ -412,8 +408,7 @@ <h5 class="mb-0">Disable 2FA</h5>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title={% if user_readonly %}"Readonly mode enabled"{% else %}"The database is in readonly, therefore the configuration is locked"{% endif %}
{% endif %}>
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The database is in readonly, therefore the configuration is locked" {% endif %}>
<button type="submit"
class="btn btn-primary{% if is_readonly %} disabled{% endif %}">
Disable TOTP
Expand Down Expand Up @@ -457,8 +452,7 @@ <h5 class="card-header">Refresh Recovery Codes</h5>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title={% if user_readonly %}"Readonly mode enabled"{% else %}"The database is in readonly, therefore the configuration is locked"{% endif %}
{% endif %}>
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The database is in readonly, therefore the configuration is locked" {% endif %}>
<button type="submit"
class="btn btn-primary{% if is_readonly %} disabled{% endif %}">
Refresh Recovery Codes
Expand Down Expand Up @@ -499,8 +493,7 @@ <h5 class="card-header">Sessions</h5>
</div>
</div>
<div class="mt-4 d-flex justify-content-center">
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title={% if user_readonly %}"Readonly mode enabled"{% else %}"The database is in readonly, therefore the configuration is locked"{% endif %}
{% endif %}>
<div {% if is_readonly %}data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The database is in readonly, therefore the configuration is locked" {% endif %}>
<button type="submit"
class="btn btn-danger{% if is_readonly %} disabled{% endif %}">
Wipe other sessions
Expand Down
34 changes: 23 additions & 11 deletions src/ui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,12 @@ def custom_url_for(endpoint, **values):
@app.context_processor
def inject_variables():
for hook in app.config["CONTEXT_PROCESSOR_HOOKS"]:
resp = hook()
if resp:
app.config["ENV"] = {**app.config["ENV"], **resp}
try:
resp = hook()
if resp:
app.config["ENV"] = {**app.config["ENV"], **resp}
except Exception:
LOGGER.exception("Error in context_processor hook")

return app.config["ENV"]

Expand Down Expand Up @@ -739,7 +742,7 @@ def before_request():
pro_overlapped=metadata["pro_overlapped"],
plugins=BW_CONFIG.get_plugins(),
flash_messages=session.get("flash_messages", []),
is_readonly=DATA.get("READONLY_MODE", False) or "write" not in current_user.list_permissions,
is_readonly=DATA.get("READONLY_MODE", False) or ("write" not in current_user.list_permissions and not request.path.startswith("/profile")),
user_readonly="write" not in current_user.list_permissions,
theme=current_user.theme if current_user.is_authenticated else "dark",
columns_preferences_defaults=COLUMNS_PREFERENCES_DEFAULTS,
Expand All @@ -752,9 +755,12 @@ def before_request():
app.config["ENV"] = data

for hook in app.config["BEFORE_REQUEST_HOOKS"]:
resp = hook()
if resp:
return resp
try:
resp = hook()
if resp:
return resp
except Exception:
LOGGER.exception("Error in before_request hook")


def mark_user_access(user, session_id):
Expand Down Expand Up @@ -810,9 +816,12 @@ def set_security_headers(response):
)

for hook in app.config["AFTER_REQUEST_HOOKS"]:
resp = hook(response)
if resp:
return resp
try:
resp = hook(response)
if resp:
return resp
except Exception:
LOGGER.exception("Error in after_request hook")

return response

Expand All @@ -823,7 +832,10 @@ def teardown_request(_):
Thread(target=mark_user_access, args=(current_user, session["session_id"])).start()

for hook in app.config["TEARDOWN_REQUEST_HOOKS"]:
hook()
try:
hook()
except Exception:
LOGGER.exception("Error in teardown_request hook")


### * MISC ROUTES * ###
Expand Down

0 comments on commit 1eebadf

Please sign in to comment.