feat(cloud-console): add user authentication and administration

This commit is contained in:
2026-07-13 17:54:53 +08:00
parent 035b177128
commit cdef630e67
35 changed files with 4126 additions and 113 deletions
@@ -34,6 +34,13 @@ class CloudControlConfig:
enrollment_credentials: tuple[EnrollmentCredential, ...] = ()
cors_allowed_origins: tuple[str, ...] = ()
console_static_dir: str | None = None
user_session_idle_seconds: int = 28_800
user_session_absolute_seconds: int = 604_800
login_failure_limit: int = 5
login_failure_window_seconds: int = 900
login_block_seconds: int = 900
session_cookie_secure: bool = False
trust_proxy_headers: bool = False
def load_control_config(
@@ -98,6 +105,31 @@ def load_control_config(
console_static_dir=_parse_optional_string(
values.get("CLOUD_CONSOLE_STATIC_DIR")
),
user_session_idle_seconds=_positive_int(
values,
"CLOUD_USER_SESSION_IDLE_SECONDS",
28_800,
),
user_session_absolute_seconds=_positive_int(
values,
"CLOUD_USER_SESSION_ABSOLUTE_SECONDS",
604_800,
),
login_failure_limit=_positive_int(values, "CLOUD_LOGIN_FAILURE_LIMIT", 5),
login_failure_window_seconds=_positive_int(
values,
"CLOUD_LOGIN_FAILURE_WINDOW_SECONDS",
900,
),
login_block_seconds=_positive_int(values, "CLOUD_LOGIN_BLOCK_SECONDS", 900),
session_cookie_secure=_parse_bool(
values.get("CLOUD_SESSION_COOKIE_SECURE"),
default=environment == "production",
),
trust_proxy_headers=_parse_bool(
values.get("CLOUD_TRUST_PROXY_HEADERS"),
default=False,
),
)
validate_control_config(config)
return config
@@ -112,6 +144,14 @@ def validate_control_config(config: CloudControlConfig) -> None:
raise CloudConfigurationError(
"production requires at least one configured bearer credential"
)
if config.user_session_absolute_seconds < config.user_session_idle_seconds:
raise CloudConfigurationError(
"CLOUD_USER_SESSION_ABSOLUTE_SECONDS must be at least the idle TTL"
)
if config.environment == "production" and not config.session_cookie_secure:
raise CloudConfigurationError(
"production requires secure user session cookies"
)
def _parse_credentials(