Support monitoring TG role permissions
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 38s

This commit is contained in:
Grendgi
2026-06-05 15:23:42 +03:00
parent 00d246599f
commit 276753f338
3 changed files with 27 additions and 9 deletions

View File

@@ -54,6 +54,7 @@ type app struct {
type accessScope struct {
IsAdmin bool
CanManage bool
CanAuth bool
DeptID string
}
@@ -213,6 +214,7 @@ func (a *app) handleAccessMe(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]any{
"is_admin": scope.IsAdmin,
"can_manage_department": scope.CanManage,
"can_auth_telegram": scope.CanAuth,
"department_id": nullableString(scope.DeptID),
})
}
@@ -1192,7 +1194,7 @@ func (a *app) promptExists(ctx context.Context, deptID, vertical, section string
func (a *app) proxyPython(w http.ResponseWriter, r *http.Request, path string) {
scope := readAccess(r)
if strings.Contains(path, "/auth/") && !scope.IsAdmin {
if strings.Contains(path, "/auth/") && !scope.CanAuth {
writeError(w, http.StatusNotFound, "not found")
return
}
@@ -1251,9 +1253,12 @@ func (a *app) readScope(w http.ResponseWriter, r *http.Request, manage bool) (ac
func readAccess(r *http.Request) accessScope {
admin := r.Header.Get("X-User-Is-Admin") == "1"
deptHead := r.Header.Get("X-User-Is-Department-Head") == "1"
canManage := r.Header.Get("X-Monitoring-TG-Can-Manage") == "1"
canAuth := r.Header.Get("X-Monitoring-TG-Can-Auth") == "1"
return accessScope{
IsAdmin: admin,
CanManage: admin || deptHead,
CanManage: admin || deptHead || canManage,
CanAuth: admin || canAuth,
DeptID: strings.TrimSpace(r.Header.Get("X-User-Department-Id")),
}
}

View File

@@ -17,8 +17,16 @@ def is_department_head_request(request: Request) -> bool:
return request.headers.get("x-user-is-department-head") == "1"
def can_manage_monitoring_tg(request: Request) -> bool:
return request.headers.get("x-monitoring-tg-can-manage") == "1"
def can_auth_monitoring_tg(request: Request) -> bool:
return is_admin_request(request) or request.headers.get("x-monitoring-tg-can-auth") == "1"
def can_manage_department(request: Request) -> bool:
return is_admin_request(request) or is_department_head_request(request)
return is_admin_request(request) or is_department_head_request(request) or can_manage_monitoring_tg(request)
def require_department_manager(request: Request) -> None:
@@ -34,3 +42,8 @@ def require_admin(request: Request) -> None:
"""
if not is_admin_request(request):
raise HTTPException(status_code=404)
def require_telegram_auth_manager(request: Request) -> None:
if not can_auth_monitoring_tg(request):
raise HTTPException(status_code=404)

View File

@@ -8,8 +8,8 @@ from sqlalchemy.ext.asyncio import AsyncSession
from parser_bot.access import (
is_admin_request,
portal_department_id,
require_admin,
require_department_manager,
require_telegram_auth_manager,
)
from parser_bot.config import settings
from parser_bot.db.models import Channel, Section
@@ -72,7 +72,7 @@ async def _require_channel_scope(
raise HTTPException(status_code=404)
@router.get("/auth/status", response_model=AuthStatus, dependencies=[Depends(require_admin)])
@router.get("/auth/status", response_model=AuthStatus, dependencies=[Depends(require_telegram_auth_manager)])
async def auth_status() -> AuthStatus:
authorized = await tg.is_authorized()
username = await tg.current_username() if authorized else None
@@ -85,7 +85,7 @@ async def auth_status() -> AuthStatus:
)
@router.post("/auth/send-code", status_code=204, dependencies=[Depends(require_admin)])
@router.post("/auth/send-code", status_code=204, dependencies=[Depends(require_telegram_auth_manager)])
async def auth_send_code() -> None:
try:
await tg.send_login_code()
@@ -96,7 +96,7 @@ async def auth_send_code() -> None:
@router.post(
"/auth/submit-code",
response_model=AuthCodeResult,
dependencies=[Depends(require_admin)],
dependencies=[Depends(require_telegram_auth_manager)],
)
async def auth_submit_code(payload: AuthCode) -> AuthCodeResult:
try:
@@ -106,7 +106,7 @@ async def auth_submit_code(payload: AuthCode) -> AuthCodeResult:
return AuthCodeResult(needs_password=needs_password)
@router.post("/auth/submit-password", status_code=204, dependencies=[Depends(require_admin)])
@router.post("/auth/submit-password", status_code=204, dependencies=[Depends(require_telegram_auth_manager)])
async def auth_submit_password(payload: AuthPassword) -> None:
try:
await tg.submit_login_password(payload.password)
@@ -114,7 +114,7 @@ async def auth_submit_password(payload: AuthPassword) -> None:
raise HTTPException(status_code=400, detail=str(exc))
@router.post("/auth/logout", status_code=204, dependencies=[Depends(require_admin)])
@router.post("/auth/logout", status_code=204, dependencies=[Depends(require_telegram_auth_manager)])
async def auth_logout() -> None:
await tg.logout()