Implement Microsoft Entra ID (Azure AD) authentication with user and admin roles. Features: - OAuth 2.0 authentication flow using MSAL - User and admin role-based access control - Tenant ownership and access management - Server-side session storage - Protected routes with authentication decorators Authentication: - Users authenticate via Microsoft organizational accounts - Admin role automatically assigned to DEFAULT_ADMIN_EMAIL - User profiles synced from Microsoft Graph API Access Control: - Admins: Full access to all tenants and server settings - Users: Can create and manage their own tenants only - Tenant association: Auto-created when user adds products - API endpoints remain open for AR application access Database Changes: - New users table with email, azure_oid, name, and role - New user_tenants table for many-to-many tenant ownership - Case-insensitive admin email comparison Configuration: - Environment-based config via .env file - Azure AD credentials (client ID, secret, tenant ID) - Configurable redirect URI and admin email - Updated to Flask 2.2.5 for compatibility
33 lines
1.5 KiB
HTML
33 lines
1.5 KiB
HTML
{% extends "layout.html" %}
|
|
|
|
{% block title %}Access Denied - KCAP Demo Server{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row justify-content-center mt-5">
|
|
<div class="col-md-6">
|
|
<div class="card border-danger">
|
|
<div class="card-header bg-danger text-white">
|
|
<h4 class="mb-0"><i class="bi bi-shield-exclamation"></i> Access Denied</h4>
|
|
</div>
|
|
<div class="card-body text-center">
|
|
<i class="bi bi-shield-exclamation" style="font-size: 4rem; color: #dc3545;"></i>
|
|
<h5 class="mt-3">You don't have permission to access this resource</h5>
|
|
<p class="text-muted">
|
|
This page requires special permissions that your account doesn't have.
|
|
Please contact an administrator if you believe this is an error.
|
|
</p>
|
|
<hr>
|
|
<div class="d-grid gap-2 d-md-block">
|
|
<a href="/" class="btn btn-primary"><i class="bi bi-house"></i> Go to Home</a>
|
|
{% if session.user %}
|
|
<a href="/auth/logout" class="btn btn-outline-secondary"><i class="bi bi-box-arrow-right"></i> Logout</a>
|
|
{% else %}
|
|
<a href="/auth/login" class="btn btn-outline-primary"><i class="bi bi-box-arrow-in-right"></i> Login</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|