mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-11 05:35:25 +03:00
implement config for users and settings
This commit is contained in:
parent
5962a2460b
commit
38f25548b1
@ -7,7 +7,7 @@ import secrets
|
|||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from flask import Blueprint, make_response, request
|
from flask import Blueprint, current_app, make_response, request
|
||||||
from joserfc import jwt
|
from joserfc import jwt
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -16,10 +16,7 @@ AuthBp = Blueprint("auth", __name__)
|
|||||||
|
|
||||||
|
|
||||||
ALGORITHM = "pbkdf2_sha256"
|
ALGORITHM = "pbkdf2_sha256"
|
||||||
JWT_COOKIE_NAME = "jwt.cookie"
|
|
||||||
JWT_SECRET = "secret"
|
JWT_SECRET = "secret"
|
||||||
JWT_REFRESH = 120
|
|
||||||
JWT_SESSION_LENGTH = 300
|
|
||||||
|
|
||||||
|
|
||||||
def hash_password(password, salt=None, iterations=260000):
|
def hash_password(password, salt=None, iterations=260000):
|
||||||
@ -55,13 +52,15 @@ def set_jwt_cookie(response, cookie_name, encoded_jwt, expiration):
|
|||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# - on startup, generate a signing secret for jwt if it doesn't exist and save as ".auth-token" in the config folder
|
# - 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")
|
@AuthBp.route("/auth")
|
||||||
def 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
|
jwt_source = None
|
||||||
encoded_token = None
|
encoded_token = None
|
||||||
if "authorization" in request.headers and request.headers[
|
if "authorization" in request.headers and request.headers[
|
||||||
@ -126,10 +125,22 @@ def auth():
|
|||||||
|
|
||||||
@AuthBp.route("/login", methods=["POST"])
|
@AuthBp.route("/login", methods=["POST"])
|
||||||
def login():
|
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()
|
content = request.get_json()
|
||||||
user = content["user"]
|
user = content["user"]
|
||||||
password = content["password"]
|
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):
|
if verify_password(password, password_hash):
|
||||||
expiration = int(time.time()) + JWT_SESSION_LENGTH
|
expiration = int(time.time()) + JWT_SESSION_LENGTH
|
||||||
encoded_jwt = create_encoded_jwt(user, expiration, JWT_SECRET)
|
encoded_jwt = create_encoded_jwt(user, expiration, JWT_SECRET)
|
||||||
|
|||||||
@ -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):
|
class StatsConfig(FrigateBaseModel):
|
||||||
amd_gpu_stats: bool = Field(default=True, title="Enable AMD GPU stats.")
|
amd_gpu_stats: bool = Field(default=True, title="Enable AMD GPU stats.")
|
||||||
intel_gpu_stats: bool = Field(default=True, title="Enable Intel 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):
|
class FrigateConfig(FrigateBaseModel):
|
||||||
mqtt: MqttConfig = Field(title="MQTT Configuration.")
|
mqtt: MqttConfig = Field(title="MQTT configuration.")
|
||||||
database: DatabaseConfig = Field(
|
database: DatabaseConfig = Field(
|
||||||
default_factory=DatabaseConfig, title="Database configuration."
|
default_factory=DatabaseConfig, title="Database configuration."
|
||||||
)
|
)
|
||||||
|
auth: AuthConfig = Field(default_factory=AuthConfig, title="Auth configuration.")
|
||||||
environment_vars: Dict[str, str] = Field(
|
environment_vars: Dict[str, str] = Field(
|
||||||
default_factory=dict, title="Frigate environment variables."
|
default_factory=dict, title="Frigate environment variables."
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user