Record auth audits and surface them in Activity, poll sidebar counts without resetting idle, and add a profile logout path plus theme red/green/blue tokens so failure badges render.
67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"codeberg.org/SquidSE/ClusterCanvas/service/internal/auth"
|
|
"codeberg.org/SquidSE/ClusterCanvas/service/internal/settings"
|
|
)
|
|
|
|
type authLogsResponse struct {
|
|
Events []settings.AuthAuditEvent `json:"events"`
|
|
}
|
|
|
|
func (app *App) authLogsListHandler(writer http.ResponseWriter, request *http.Request) {
|
|
if err := app.authorizeLogsRead(request); err != nil {
|
|
writeJSON(writer, http.StatusForbidden, apiErrorResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
store, err := settings.LoadAuthAuditOrEmpty(app.ConfigDir)
|
|
if err != nil {
|
|
writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
filtered := make([]settings.AuthAuditEvent, 0, len(store.Events))
|
|
for index := len(store.Events) - 1; index >= 0; index-- {
|
|
filtered = append(filtered, store.Events[index])
|
|
}
|
|
|
|
writeJSON(writer, http.StatusOK, authLogsResponse{Events: filtered})
|
|
}
|
|
|
|
func appendAuthAudit(
|
|
configDir string,
|
|
action string,
|
|
outcome settings.AuthAuditOutcome,
|
|
category settings.AuthAuditCategory,
|
|
actor string,
|
|
target string,
|
|
detail string,
|
|
) {
|
|
eventID, err := auth.NewUUID()
|
|
if err != nil {
|
|
return
|
|
}
|
|
_ = settings.AppendAuthAuditEvent(configDir, settings.AuthAuditEvent{
|
|
ID: eventID,
|
|
At: time.Now().UTC(),
|
|
Action: action,
|
|
Outcome: outcome,
|
|
Category: category,
|
|
Actor: actor,
|
|
Target: target,
|
|
Detail: detail,
|
|
})
|
|
}
|
|
|
|
func actorUsernameFromRequest(request *http.Request) string {
|
|
user, ok := UserFromContext(request.Context())
|
|
if !ok {
|
|
return ""
|
|
}
|
|
return user.Username
|
|
}
|