Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lx9FNLG2CqeBbVGGd9bFsP
39 lines
1.4 KiB
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
|
|
}
|