Add activity logs, sidebar badges, and logout with working alert colors.
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.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user