99 lines
2.8 KiB
Go
99 lines
2.8 KiB
Go
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
|
|
}
|