package handlers import ( "context" "net/http" "time" "github.com/orchard9/rdev/internal/auth" "github.com/orchard9/rdev/internal/domain" "github.com/orchard9/rdev/internal/service" "github.com/orchard9/rdev/pkg/api" ) // MeHandler handles the /me endpoint. type MeHandler struct { authService *auth.Service projectService *service.ProjectService } // NewMeHandler creates a new me handler. func NewMeHandler(authService *auth.Service, projectService *service.ProjectService) *MeHandler { return &MeHandler{ authService: authService, projectService: projectService, } } // Mount registers the /me route. func (h *MeHandler) Mount(r api.Router) { r.Get("/me", h.Get) } // MeResponse is the JSON response for GET /me. type MeResponse struct { ID string `json:"id"` Name string `json:"name"` KeyPrefix string `json:"key_prefix"` Scopes []string `json:"scopes"` ProjectAccess string `json:"project_access"` // "unrestricted" | "restricted" Projects []ProjectSummary `json:"projects,omitempty"` AllowedIPs []string `json:"allowed_ips,omitempty"` CreatedAt string `json:"created_at"` ExpiresAt *string `json:"expires_at,omitempty"` Active bool `json:"active"` } // ProjectSummary is a lightweight project view for embedding in /me. type ProjectSummary struct { ID string `json:"id"` Name string `json:"name"` Status string `json:"status"` } // Get returns the current key's identity, scopes, and project access. // GET /me func (h *MeHandler) Get(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), TimeoutFastLookup) defer cancel() apiKey := auth.GetAPIKey(ctx) if apiKey == nil { api.WriteUnauthorized(w, r, "Not authenticated") return } resp := MeResponse{ ID: string(apiKey.ID), Name: apiKey.Name, KeyPrefix: apiKey.KeyPrefix, Scopes: auth.ScopesToStrings(apiKey.Scopes), ProjectAccess: "unrestricted", AllowedIPs: apiKey.AllowedIPs, CreatedAt: apiKey.CreatedAt.Format(time.RFC3339), Active: apiKey.IsActive(), } // Populate projects list when key is restricted (non-admin with explicit project_ids) if apiKey.ProjectIDs != nil && !apiKey.HasScope(domain.ScopeAdmin) { resp.ProjectAccess = "restricted" if h.projectService != nil { projects, _ := h.projectService.List(ctx, apiKey.ProjectIDs) resp.Projects = make([]ProjectSummary, len(projects)) for i, p := range projects { resp.Projects[i] = ProjectSummary{ ID: string(p.ID), Name: p.Name, Status: string(p.Status), } } } } if apiKey.ExpiresAt != nil { s := apiKey.ExpiresAt.Format(time.RFC3339) resp.ExpiresAt = &s } api.WriteSuccess(w, r, resp) }