76 lines
2.6 KiB
Go
76 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{})
|
||
|
|
}
|