implement config for users and settings

This commit is contained in:
Blake Blackshear 2024-05-06 05:59:07 -05:00
parent 5962a2460b
commit 38f25548b1
2 changed files with 44 additions and 8 deletions

View File

@ -7,7 +7,7 @@ import secrets
import time
from datetime import datetime
from flask import Blueprint, make_response, request
from flask import Blueprint, current_app, make_response, request
from joserfc import jwt
logger = logging.getLogger(__name__)
@ -16,10 +16,7 @@ AuthBp = Blueprint("auth", __name__)
ALGORITHM = "pbkdf2_sha256"
JWT_COOKIE_NAME = "jwt.cookie"
JWT_SECRET = "secret"
JWT_REFRESH = 120
JWT_SESSION_LENGTH = 300
def hash_password(password, salt=None, iterations=260000):
@ -55,13 +52,15 @@ def set_jwt_cookie(response, cookie_name, encoded_jwt, expiration):
# TODO:
# - on startup, generate a signing secret for jwt if it doesn't exist and save as ".auth-token" in the config folder
# - add users to config
# - create login page
# -
@AuthBp.route("/auth")
def auth():
JWT_COOKIE_NAME = current_app.frigate_config.auth.cookie_name
JWT_REFRESH = current_app.frigate_config.auth.refresh_time
JWT_SESSION_LENGTH = current_app.frigate_config.auth.session_length
jwt_source = None
encoded_token = None
if "authorization" in request.headers and request.headers[
@ -126,10 +125,22 @@ def auth():
@AuthBp.route("/login", methods=["POST"])
def login():
password_hash = "pbkdf2_sha256$260000$2e68caab677bb466138d21d18ac94033$3VZhLOSiY9AqD2Y37DgVOerx4L2wi6nPyruoVXd06VQ="
JWT_COOKIE_NAME = current_app.frigate_config.auth.cookie_name
JWT_SESSION_LENGTH = current_app.frigate_config.auth.session_length
content = request.get_json()
user = content["user"]
password = content["password"]
password_hash = next(
(
u.password_hash
for u in current_app.frigate_config.auth.users
if u.user == user
),
None,
)
# if the user wasn't found in the config
if password_hash is None:
make_response({"message": "Login failed"}, 400)
if verify_password(password, password_hash):
expiration = int(time.time()) + JWT_SESSION_LENGTH
encoded_jwt = create_encoded_jwt(user, expiration, JWT_SECRET)

View File

@ -116,6 +116,30 @@ class UIConfig(FrigateBaseModel):
)
class UserConfig(FrigateBaseModel):
user: str = Field(title="Username")
password_hash: str = Field(
title="Password hashed and salted using hashlib.pbkdf2_hmac"
)
class AuthConfig(FrigateBaseModel):
enabled: bool = Field(default=False, title="Enable authentication")
# TODO: validation for cookie names
cookie_name: str = Field(
default="jwt.token", title="Name for jwt token cookie", pattern=r"^[a-z]_*$"
)
session_length: int = Field(
default=86400, title="Session length for jwt session tokens", ge=60
)
refresh_time: int = Field(
default=43200,
title="Refresh the session if it is going to expire in this many seconds",
ge=30,
)
users: Optional[List[UserConfig]] = Field(default=[], title="Users")
class StatsConfig(FrigateBaseModel):
amd_gpu_stats: bool = Field(default=True, title="Enable AMD GPU stats.")
intel_gpu_stats: bool = Field(default=True, title="Enable Intel GPU stats.")
@ -1245,10 +1269,11 @@ def verify_motion_and_detect(camera_config: CameraConfig) -> ValueError | None:
class FrigateConfig(FrigateBaseModel):
mqtt: MqttConfig = Field(title="MQTT Configuration.")
mqtt: MqttConfig = Field(title="MQTT configuration.")
database: DatabaseConfig = Field(
default_factory=DatabaseConfig, title="Database configuration."
)
auth: AuthConfig = Field(default_factory=AuthConfig, title="Auth configuration.")
environment_vars: Dict[str, str] = Field(
default_factory=dict, title="Frigate environment variables."
)