Enforce admin-only for bulk and purge actions
Move admin checks from individual bulk actions to the main handler for `bulk.rs` and `case_actions.rs`. This consolidates the authorization logic for these sensitive operations. Additionally, refine the HTML template to conditionally render bulk action UI elements and the purge form only when the user is an admin. This ensures that non-admin users do not see or have access to these administrative functions. Update tests to reflect these changes, ensuring that non-admin users are correctly rejected for these actions and that the UI is properly hidden.
This commit is contained in:
@@ -15,7 +15,9 @@ section h2 .count { font-weight: normal; font-size: 0.85em; color: #888; }
|
||||
.pending { color: #888; font-style: italic; }
|
||||
|
||||
.case-list { list-style: none; padding: 0; margin: 0; }
|
||||
.case-row { display: grid; grid-template-columns: auto 1fr auto; gap: 0.6em 1em; align-items: center; padding: 0.7em 1em; border: 1px solid #ccc; border-radius: 4px; margin: 0.5em 0; }
|
||||
.case-row { display: grid; grid-template-columns: 1fr auto; gap: 0.6em 1em; align-items: center; padding: 0.7em 1em; border: 1px solid #ccc; border-radius: 4px; margin: 0.5em 0; }
|
||||
.case-list.has-bulk .case-row { grid-template-columns: auto 1fr auto; }
|
||||
html.admin-view-off .case-list.has-bulk .case-row { grid-template-columns: 1fr auto; }
|
||||
.case-row.done { border-left: 4px solid #7ed321; }
|
||||
.case-row.open { border-left: 4px solid #4a90e2; }
|
||||
.case-row .check { align-self: start; padding-top: 0.25em; }
|
||||
@@ -101,10 +103,10 @@ try {
|
||||
{% for g in groups %}
|
||||
<section>
|
||||
<h2 class="date-group" data-iso="{{ g.label }}"><span class="date-label">{{ g.label }}</span><span class="count">{{ g.open_count }}/{{ g.total_count }} Fälle</span></h2>
|
||||
<ul class="case-list">
|
||||
<ul class="case-list{% if is_admin %} has-bulk{% endif %}">
|
||||
{% for case in g.cases %}
|
||||
<li class="case-row {% if case.is_closed %}closed{% else if case.has_document %}done{% else %}open{% endif %}">
|
||||
<div class="check"><input type="checkbox" name="case_id" value="{{ case.case_id }}"{% if case.is_closed %} disabled{% endif %}></div>
|
||||
{% if is_admin %}<div class="check admin-only"><input type="checkbox" name="case_id" value="{{ case.case_id }}"{% if case.is_closed %} disabled{% endif %}></div>{% endif %}
|
||||
<div class="body">
|
||||
<div class="line1">
|
||||
<a class="case-link" href="/web/cases/{{ case.case_id }}{% if case.is_closed %}?show_closed=1{% endif %}"><span class="time"><time datetime="{{ case.recorded_at_iso }}">{{ case.time_hms_utc }}</time></span> — {% call ol::render(case.oneliner) %}{% if case.has_failed_recording %} <span class="status-badge fehler">Fehler</span>{% else if case.has_document %} <span class="status-badge done">ausgewertet</span>{% else if !case.is_closed %} <span class="status-badge open">offen</span>{% endif %}{% if case.analyzing %} <span class="label analyzing">wird analysiert</span>{% endif %}{% if case.is_closed %} <span class="closed-badge">geschlossen{% match case.days_until_purge %}{% when Some with (d) %} — wird in {{ d }} Tagen entfernt{% when None %}{% endmatch %}</span>{% endif %}</a>
|
||||
@@ -127,16 +129,16 @@ try {
|
||||
</ul>
|
||||
</section>
|
||||
{% endfor %}
|
||||
<div class="bulk-bar">
|
||||
{% if is_admin %}<div class="bulk-bar admin-only">
|
||||
<span>Auswahl:</span>
|
||||
<button type="button" onclick="const b=document.querySelectorAll('input[name=case_id]');const all=Array.from(b).every(c=>c.checked);b.forEach(c=>c.checked=!all);this.textContent=all?'Alles auswählen':'Keine auswählen'">Alles auswählen</button>
|
||||
{% if is_admin %}<button type="submit" name="action" value="analyze" class="admin-only">Analysieren</button>
|
||||
<button type="submit" name="action" value="reset" class="admin-only">Reset</button>{% endif %}
|
||||
<button type="submit" name="action" value="analyze">Analysieren</button>
|
||||
<button type="submit" name="action" value="reset">Reset</button>
|
||||
<button type="submit" name="action" value="close">Schließen</button>
|
||||
</div>
|
||||
</div>{% endif %}
|
||||
</form>
|
||||
{% if show_closed && any_closed %}
|
||||
<form class="bulk-bar purge" method="post" action="/web/cases/purge-closed" onsubmit="return confirm('Alle geschlossenen Fälle UNWIDERRUFLICH löschen? Diese Aktion kann nicht rückgängig gemacht werden.')">
|
||||
{% if is_admin && show_closed && any_closed %}
|
||||
<form class="bulk-bar purge admin-only" method="post" action="/web/cases/purge-closed" onsubmit="return confirm('Alle geschlossenen Fälle UNWIDERRUFLICH löschen? Diese Aktion kann nicht rückgängig gemacht werden.')">
|
||||
<input type="hidden" name="confirm" value="yes">
|
||||
<span>Geschlossene Fälle:</span>
|
||||
<button type="submit">Alle geschlossenen unwiderruflich löschen</button>
|
||||
|
||||
Reference in New Issue
Block a user