pegasus/backend/handlers_auth.go

71 lines
1.8 KiB
Go
Raw Normal View History

2026-04-11 00:02:59 -03:00
// backend/handlers_auth.go
package main
import (
"encoding/json"
"net/http"
"scm.bstein.dev/bstein/Pegasus/backend/internal"
)
type jellyfinClient interface {
AuthenticateByName(username, password string) (internal.AuthResult, error)
RefreshLibrary(userToken string)
}
func loginHandler(um *internal.UserMap, jf jellyfinClient) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var f struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := json.NewDecoder(r.Body).Decode(&f); err != nil {
http.Error(w, "bad json", http.StatusBadRequest)
return
}
res, err := jf.AuthenticateByName(f.Username, f.Password)
if err != nil {
http.Error(w, "invalid credentials", http.StatusUnauthorized)
return
}
if _, err := um.Resolve(f.Username); err != nil {
internal.Logf("login ok but map missing for %q (JF name=%q)", f.Username, res.User.Name)
http.Error(w, "no mapping", http.StatusForbidden)
return
}
if err := internal.SetSession(w, f.Username, res.AccessToken); err != nil {
http.Error(w, "session error", http.StatusInternalServerError)
return
}
writeJSON(w, map[string]any{"ok": true})
}
}
func logoutHandler() http.HandlerFunc {
return func(w http.ResponseWriter, _ *http.Request) {
internal.ClearSession(w)
writeJSON(w, map[string]any{"ok": true})
}
}
func whoamiHandler(um *internal.UserMap) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cl, err := internal.CurrentUser(r)
if err != nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
dr, err := um.Resolve(cl.Username)
if err != nil {
http.Error(w, "no mapping", http.StatusForbidden)
return
}
all, _ := um.ResolveAll(cl.Username)
writeJSON(w, map[string]any{
"username": cl.Username,
"root": dr,
"roots": all,
})
}
}