fix error in gitignore
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
"""Secure live-stream access.
|
||||
|
||||
Camera credentials are never exposed. A customer can request short-lived,
|
||||
HMAC-signed access tokens for streams authorized for their own orders; the
|
||||
`verify` endpoint validates the token and returns the stream URL.
|
||||
"""
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import time
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from apps.live_monitoring.models import Camera, WorkflowStepCamera
|
||||
from apps.orders.models import ProcessingOrder
|
||||
from apps.workflows.models import WorkflowStep
|
||||
|
||||
|
||||
class StreamAccessService:
|
||||
def can_access(self, user, camera: Camera) -> bool:
|
||||
if not user or not user.is_authenticated:
|
||||
return False
|
||||
if user.is_superuser:
|
||||
return True
|
||||
version_ids = ProcessingOrder.objects.filter(customer__user=user).values_list(
|
||||
"workflow_version_id", flat=True
|
||||
)
|
||||
step_ids = WorkflowStep.objects.filter(
|
||||
version_id__in=version_ids, live_monitoring_enabled=True
|
||||
).values_list("id", flat=True)
|
||||
return WorkflowStepCamera.objects.filter(camera=camera, step_id__in=step_ids).exists()
|
||||
|
||||
def issue_token(self, camera: Camera, ttl: int = 3600) -> tuple:
|
||||
payload = {"camera": str(camera.id), "exp": int(time.time()) + ttl}
|
||||
raw = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().rstrip("=")
|
||||
sig = hmac.new(settings.SECRET_KEY.encode(), raw.encode(), hashlib.sha256).hexdigest()
|
||||
return f"{raw}.{sig}", payload["exp"]
|
||||
|
||||
def verify_token(self, token: str):
|
||||
try:
|
||||
raw, sig = token.split(".", 1)
|
||||
except (ValueError, AttributeError):
|
||||
return None
|
||||
expected = hmac.new(settings.SECRET_KEY.encode(), raw.encode(), hashlib.sha256).hexdigest()
|
||||
if not hmac.compare_digest(expected, sig):
|
||||
return None
|
||||
try:
|
||||
pad = raw + "=" * (-len(raw) % 4)
|
||||
payload = json.loads(base64.urlsafe_b64decode(pad).decode())
|
||||
except Exception:
|
||||
return None
|
||||
if payload.get("exp", 0) < int(time.time()):
|
||||
return None
|
||||
return payload
|
||||
Reference in New Issue
Block a user