IT Assets: add role-based auth system and portal user sync
Auth: - Fix local login (was redirecting to portal; now authenticates AdminUser directly) - Portal SSO still takes priority in production via nginx headers Role system (admin | editor | readonly): - New app/utils/decorators.py with editor_required and admin_required decorators - All write routes protected with editor_required (create/edit/delete/import/mask) - Settings user management protected with admin_required - Sidebar hides write-only links for readonly users - Dashboard quick actions and list page buttons hidden for readonly Settings page: - Role colour badges (admin=red, editor=blue, readonly=grey) - Inline role changer per user (dropdown auto-submit) - Reset password modal per user - Delete user button with confirmation - Add user form includes role selector with legend Portal user sync: - New /internal/sync-user endpoint receives user pre-creation from portal - INTERNAL_SYNC_SECRET added to config - portal/config.py: added internal_url for itassets app so _sync_user_to_app works
This commit is contained in:
@@ -127,40 +127,48 @@
|
||||
class="nav-link {% if request.blueprint == 'users' %}active{% endif %}">
|
||||
<i class="bi bi-people-fill"></i> Users
|
||||
</a>
|
||||
{% if current_user.is_editor %}
|
||||
<a href="{{ url_for('users.import_page') }}"
|
||||
class="nav-link {% if request.endpoint == 'users.import_page' %}active{% endif %}">
|
||||
<i class="bi bi-cloud-download"></i> Import Users
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<div class="nav-section">Hardware</div>
|
||||
<a href="{{ url_for('assets.index') }}"
|
||||
class="nav-link {% if request.blueprint == 'assets' %}active{% endif %}">
|
||||
<i class="bi bi-laptop"></i> Assets
|
||||
</a>
|
||||
{% if current_user.is_editor %}
|
||||
<a href="{{ url_for('assets.create') }}"
|
||||
class="nav-link {% if request.endpoint == 'assets.create' %}active{% endif %}">
|
||||
<i class="bi bi-plus-circle"></i> Add Asset
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<div class="nav-section">Assignments</div>
|
||||
<a href="{{ url_for('assignments.index') }}"
|
||||
class="nav-link {% if request.blueprint == 'assignments' %}active{% endif %}">
|
||||
<i class="bi bi-arrow-left-right"></i> Assignments
|
||||
</a>
|
||||
{% if current_user.is_editor %}
|
||||
<a href="{{ url_for('assignments.create') }}"
|
||||
class="nav-link {% if request.endpoint == 'assignments.create' %}active{% endif %}">
|
||||
<i class="bi bi-plus-circle"></i> Assign Asset
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<div class="nav-section">Documents</div>
|
||||
<a href="{{ url_for('paperwork.index') }}"
|
||||
class="nav-link {% if request.blueprint == 'paperwork' %}active{% endif %}">
|
||||
<i class="bi bi-file-earmark-text"></i> Paperwork
|
||||
</a>
|
||||
{% if current_user.is_editor %}
|
||||
<a href="{{ url_for('paperwork.create') }}"
|
||||
class="nav-link {% if request.endpoint == 'paperwork.create' %}active{% endif %}">
|
||||
<i class="bi bi-file-earmark-plus"></i> New Document
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('doc_templates.index') }}"
|
||||
class="nav-link {% if request.blueprint == 'doc_templates' %}active{% endif %}">
|
||||
<i class="bi bi-file-earmark-word"></i> Templates
|
||||
@@ -179,6 +187,9 @@
|
||||
<div class="sidebar-footer">
|
||||
<i class="bi bi-person-circle me-1"></i>
|
||||
<strong>{{ current_user.username }}</strong>
|
||||
<span class="badge ms-1 {% if current_user.role == 'admin' %}bg-danger{% elif current_user.role == 'editor' %}bg-primary{% else %}bg-secondary{% endif %}" style="font-size:.65rem;">
|
||||
{{ current_user.role }}
|
||||
</span>
|
||||
<a href="{{ url_for('auth.logout') }}" class="ms-2 text-warning text-decoration-none">
|
||||
<i class="bi bi-box-arrow-right"></i>
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user