feat(auth): implement web authentication with Keycloak OAuth2

- Add auth routes: /auth/login, /auth/callback, /auth/logout
- Add OAuth2 flow with Keycloak using HTTP-only cookies
- Add web auth dependencies with role checking
- Add profile page (read-only) at /web/profile
- Update header with user menu (sign in/out, profile)
- Filter posts based on user permissions (hide drafts from guests)
- Conditionally show/hide create/edit/delete buttons
- Add authorization rules documentation to AGENTS.md
- Secure post editing/deletion endpoints with auth checks
- Add can_edit, can_delete flags to templates
This commit is contained in:
2026-05-02 15:39:49 +03:00
parent 2aed9f5c8a
commit 0cb706e54b
10 changed files with 915 additions and 26 deletions

View File

@@ -45,16 +45,28 @@
Back to posts
</a>
{% if can_edit or can_delete %}
<div class="flex gap-2" data-testid="post-detail-edit-actions">
{% if can_edit %}
<a href="/posts/{{ post.id }}/edit" class="btn" data-testid="btn-edit-post">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-right: 0.5rem;">
<path d="M11 2L14 5M2 14L3 10L12 1L15 4L6 13L2 14Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Edit
</a>
{% endif %}
{% if can_delete %}
<form action="/posts/{{ post.id }}/delete" method="POST" style="display: inline;" data-testid="form-delete-post">
<button type="submit" class="btn btn-danger" data-testid="btn-delete-post" onclick="return confirm('Are you sure you want to delete this post?');">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-right: 0.5rem;">
<path d="M2 4h12M6 4V2a2 2 0 012-2h0a2 2 0 012 2v2m3 0v10a2 2 0 01-2 2H5a2 2 0 01-2-2V4h9z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Delete
</button>
</form>
{% endif %}
</div>
{% endif %}
</div>
</footer>
</article>