package api import ( "encoding/json" "errors" "net/http" "codeberg.org/SquidSE/ClusterCanvas/service/internal/settings" ) const ( minIdleTimeoutMinutes = 1 maxIdleTimeoutMinutes = 240 // 4 hours minSessionLifetimeHours = 1 minReauthGraceMinutes = 0 ) type securityResponse struct { Security settings.SecuritySettings `json:"security"` } type putSecurityRequest struct { Security settings.SecuritySettings `json:"security"` } func securityGetHandler(configDir string) http.HandlerFunc { return func(writer http.ResponseWriter, request *http.Request) { settingsPayload, err := loadSettingsOrDefault(configDir) if err != nil { writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()}) return } writeJSON(writer, http.StatusOK, securityResponse{ Security: effectiveSecurity(settingsPayload.Security), }) } } func securityPutHandler(configDir string) http.HandlerFunc { return func(writer http.ResponseWriter, request *http.Request) { if err := authorizeSecurityWrite(request); err != nil { writeJSON(writer, http.StatusForbidden, apiErrorResponse{Error: err.Error()}) return } var payload putSecurityRequest if err := json.NewDecoder(request.Body).Decode(&payload); err != nil { writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: "invalid JSON body"}) return } if err := validateSecuritySettings(payload.Security); err != nil { writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: err.Error()}) return } settingsPayload, err := loadSettingsOrDefault(configDir) if err != nil { writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()}) return } settingsPayload.Security = payload.Security if err := settings.SaveSettings(configDir, settingsPayload); err != nil { writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()}) return } writeJSON(writer, http.StatusOK, securityResponse{Security: settingsPayload.Security}) } } func authorizeSecurityWrite(_ *http.Request) error { // TODO: integrate authz middleware. return nil } func effectiveSecurity(security settings.SecuritySettings) settings.SecuritySettings { if err := validateSecuritySettings(security); err != nil { return settings.DefaultSecuritySettings() } return security } func validateSecuritySettings(security settings.SecuritySettings) error { if security.IdleTimeoutMinutes < minIdleTimeoutMinutes || security.IdleTimeoutMinutes > maxIdleTimeoutMinutes { return errors.New("idle_timeout_minutes must be between 1 and 240") } if security.SessionLifetimeHours < minSessionLifetimeHours { return errors.New("session_lifetime_hours must be at least 1") } if security.ReauthGraceMinutes < minReauthGraceMinutes { return errors.New("reauth_grace_minutes must be at least 0") } return nil }