Files
nmon/internal/api/me.go

39 lines
1.4 KiB
Go

package api
import (
"context"
"net/http"
"github.com/danielgtaylor/huma/v2"
"github.com/v10networks/nmon/internal/auth"
)
// MeView is the caller as nmon sees them.
type MeView struct {
User string `json:"user" doc:"Stable subject: the IDP subject, the token name, \"breakglass\" or \"dev\"."`
Name string `json:"name" doc:"Display name; may be empty."`
Role string `json:"role" enum:"viewer,admin"`
Via string `json:"via" enum:"session,token,breakglass,dev" doc:"How the caller proved who they are."`
CSRF string `json:"csrf" doc:"Send as X-CSRF-Token on every state-changing request made with the session cookie; empty for tokens."`
DevOpen bool `json:"dev_open" doc:"Authentication is off: every caller is the admin \"dev\"."`
}
func (s *server) registerMe(api huma.API) {
huma.Register(api, huma.Operation{
OperationID: "get-me", Method: http.MethodGet, Path: "/api/v1/me", Tags: []string{"auth"},
Summary: "Who am I", Description: "The authenticated caller, their role and the CSRF token to send with writes.",
Errors: []int{http.StatusUnauthorized},
}, s.getMe)
}
func (s *server) getMe(ctx context.Context, _ *struct{}) (*struct{ Body MeView }, error) {
p, ok := auth.FromContext(ctx)
if !ok {
return nil, huma.Error401Unauthorized("authentication required")
}
return &struct{ Body MeView }{MeView{
User: p.User, Name: p.Name, Role: string(p.Role), Via: string(p.Via), CSRF: p.CSRF, DevOpen: p.Via == auth.ViaDev,
}}, nil
}