Support monitoring TG role permissions
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 38s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 38s
This commit is contained in:
@@ -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")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user