Some checks failed
ci / go (push) Has been cancelled
ci / admin-ui (push) Has been cancelled
ci / runtime-sdk (push) Has been cancelled
ci / helm (push) Has been cancelled
ci / openapi (push) Has been cancelled
ci / container (push) Has been cancelled
ci / release-config (push) Has been cancelled
ci / shared styling (push) Has been cancelled
ci / security (push) Has been cancelled
ci / all green (push) Has been cancelled
75 lines
2.6 KiB
Go
75 lines
2.6 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/urpi/go-bananas/internal/domain"
|
|
"github.com/urpi/go-bananas/internal/store"
|
|
)
|
|
|
|
// PreferenceHandlers serves the caller's own interface preferences.
|
|
//
|
|
// A preference belongs to the account rather than to a browser, so it is stored
|
|
// against the identity subject and travels with the person to another device. It
|
|
// is deliberately not part of the session token: the token is issued by the
|
|
// identity provider and this service does not control its claims, so a choice made
|
|
// here has to be read back from this API.
|
|
type PreferenceHandlers struct {
|
|
store *store.Store
|
|
log Logger
|
|
}
|
|
|
|
// NewPreferenceHandlers builds the preference handler set.
|
|
func NewPreferenceHandlers(st *store.Store, log Logger) *PreferenceHandlers {
|
|
return &PreferenceHandlers{store: st, log: log}
|
|
}
|
|
|
|
// Get returns the caller's preferences, or the empty preference when they have
|
|
// chosen nothing yet.
|
|
func (h *PreferenceHandlers) Get(w http.ResponseWriter, r *http.Request) {
|
|
identity := mustIdentity(r.Context())
|
|
|
|
prefs, err := h.store.Preferences(r.Context(), identity.Subject)
|
|
if err != nil {
|
|
h.log.Error("read preferences", "subject", identity.Subject, "error", err)
|
|
writeProblem(w, r, err)
|
|
return
|
|
}
|
|
writeJSON(w, r, http.StatusOK, prefs)
|
|
}
|
|
|
|
// Update records the caller's preferences and echoes back what was stored, so the
|
|
// client renders the server's decision rather than its own input.
|
|
//
|
|
// An empty selectedTheme clears the choice. Clearing through the same endpoint
|
|
// rather than a second route keeps the write surface to one path, which matters
|
|
// because this endpoint is the only thing that writes the row.
|
|
func (h *PreferenceHandlers) Update(w http.ResponseWriter, r *http.Request) {
|
|
identity := mustIdentity(r.Context())
|
|
|
|
var request domain.UserPreferences
|
|
if err := decodeJSON(r, &request); err != nil {
|
|
writeProblem(w, r, err)
|
|
return
|
|
}
|
|
|
|
stored, err := h.store.SetPreferences(r.Context(), identity.Subject, request)
|
|
if err != nil {
|
|
h.log.Warn("update preferences", "subject", identity.Subject, "error", err)
|
|
writeProblem(w, r, err)
|
|
return
|
|
}
|
|
writeJSON(w, r, http.StatusOK, stored)
|
|
}
|
|
|
|
// Reset forgets the caller's preferences and returns them to their defaults.
|
|
func (h *PreferenceHandlers) Reset(w http.ResponseWriter, r *http.Request) {
|
|
identity := mustIdentity(r.Context())
|
|
|
|
if _, err := h.store.ClearPreferences(r.Context(), identity.Subject); err != nil {
|
|
h.log.Error("clear preferences", "subject", identity.Subject, "error", err)
|
|
writeProblem(w, r, err)
|
|
return
|
|
}
|
|
writeJSON(w, r, http.StatusOK, domain.UserPreferences{})
|
|
}
|