feat: RBAC multi-user role-based access control
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 1m14s

- Add rbac.py with User model, LDAP group-to-role mapping, page/write dependencies
- Proxy auth reads Remote-Groups header to resolve role from LDAP groups
- JWT tokens carry role claim, /me returns role + allowed pages
- Per-router page access control and viewer write protection
- Terminal WebSocket RBAC check
- Frontend filters sidebar links and routes by allowed pages
- Admin-only Settings page and RBAC override endpoints
- Mount rbac.json in docker-compose for page config persistence
This commit is contained in:
Gan, Jimmy
2026-03-01 14:13:43 +08:00
parent 15ad628425
commit 9992105b49
10 changed files with 342 additions and 65 deletions
+10 -4
View File
@@ -31,6 +31,7 @@ def create_refresh_token(data: dict):
return jwt.encode(to_encode, config.SECRET_KEY, algorithm=config.ALGORITHM)
async def get_current_user(token: str = Depends(oauth2_scheme)):
from rbac import User, get_pages
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
@@ -41,13 +42,16 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
if payload.get("type") != "access":
raise credentials_exception
username: str = payload.get("sub")
if username is None or username != config.ADMIN_USER:
role: str = payload.get("role", "admin")
if username is None:
raise credentials_exception
except jwt.PyJWTError:
raise credentials_exception
return username
pages = get_pages(username, role)
return User(username=username, role=role, pages=pages)
async def get_current_user_ws(token: str):
from rbac import User, get_pages
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
@@ -57,11 +61,13 @@ async def get_current_user_ws(token: str):
if payload.get("type") != "access":
raise credentials_exception
username: str = payload.get("sub")
if username is None or username != config.ADMIN_USER:
role: str = payload.get("role", "admin")
if username is None:
raise credentials_exception
except jwt.PyJWTError:
raise credentials_exception
return username
pages = get_pages(username, role)
return User(username=username, role=role, pages=pages)
# TOTP Persistence
AUTH_FILE = config.VOLUME_ROOT + "/docker/nas-dashboard/auth.json"