mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-04 06:21:15 +02:00
Secure websocket endpoints
This commit is contained in:
1 parent
7ce5e19a6e
commit
741fc4a557
5 files changed
+82
-21
No files matched your search
@@ -16,8 +16,9 @@
|
||||
|
||||
import re
|
||||
|
||||
from fastapi import Request, Depends, HTTPException, status
|
||||
from fastapi import Request, Query, Depends, HTTPException, WebSocket, status
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
from typing import Optional
|
||||
|
||||
from gns3server import schemas
|
||||
from gns3server.db.repositories.users import UsersRepository
|
||||
@@ -76,3 +77,53 @@ async def get_current_active_user(
|
||||
)
|
||||
|
||||
return current_user
|
||||
|
||||
|
||||
async def get_current_active_user_from_websocket(
|
||||
websocket: WebSocket,
|
||||
token: str = Query(...),
|
||||
user_repo: UsersRepository = Depends(get_repository(UsersRepository)),
|
||||
rbac_repo: RbacRepository = Depends(get_repository(RbacRepository))
|
||||
) -> Optional[schemas.User]:
|
||||
|
||||
await websocket.accept()
|
||||
|
||||
try:
|
||||
username = auth_service.get_username_from_token(token)
|
||||
user = await user_repo.get_user_by_username(username)
|
||||
|
||||
if user is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=f"Could not validate credentials for '{username}'"
|
||||
)
|
||||
|
||||
# Super admin is always authorized
|
||||
if user.is_superadmin:
|
||||
return user
|
||||
|
||||
if not user.is_active:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=f"'{username}' is not an active user"
|
||||
)
|
||||
|
||||
# remove the prefix (e.g. "/v3") from URL path
|
||||
path = re.sub(r"^/v[0-9]", "", websocket.url.path)
|
||||
|
||||
# there are no HTTP methods for web sockets, assuming "GET"...
|
||||
authorized = await rbac_repo.check_user_is_authorized(user.user_id, "GET", path)
|
||||
if not authorized:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=f"User is not authorized '{user.user_id}' on '{path}'",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
|
||||
return user
|
||||
|
||||
except HTTPException as e:
|
||||
websocket_error = {"action": "log.error", "event": {"message": f"Could not authenticate while connecting to "
|
||||
f"WebSocket: {e.detail}"}}
|
||||
await websocket.send_json(websocket_error)
|
||||
await websocket.close(code=1008)
|
||||
Reference in new issue
Block a user