Added user profile page, prepped for TOTP 2fa
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user