All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Add auth-svc /validate endpoint for token checking Add chat-svc with auth client and Redis task queue Add worker-svc chat handler for task processing Co-Authored-By: Claude Code <claude@anthropic.com>
78 lines
2.2 KiB
Go
78 lines
2.2 KiB
Go
// Package authclient provides a client for validating tokens via the auth-svc.
|
|
package authclient
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"git.threesix.ai/jordan/sp4-debug-1770477266/pkg/auth"
|
|
"git.threesix.ai/jordan/sp4-debug-1770477266/pkg/httpclient"
|
|
"git.threesix.ai/jordan/sp4-debug-1770477266/pkg/logging"
|
|
"git.threesix.ai/jordan/sp4-debug-1770477266/pkg/svc"
|
|
)
|
|
|
|
// ValidateResponse is the envelope response from auth-svc /validate endpoint.
|
|
type ValidateResponse struct {
|
|
Data ValidateData `json:"data"`
|
|
}
|
|
|
|
// ValidateData is the user info returned by auth-svc.
|
|
type ValidateData struct {
|
|
UserID string `json:"user_id"`
|
|
Email string `json:"email,omitempty"`
|
|
Roles []string `json:"roles,omitempty"`
|
|
Scopes []string `json:"scopes,omitempty"`
|
|
}
|
|
|
|
// Client validates tokens by calling auth-svc.
|
|
type Client struct {
|
|
baseURL string
|
|
httpClient *httpclient.Client
|
|
logger *logging.Logger
|
|
}
|
|
|
|
// New creates a new auth client that calls auth-svc/validate.
|
|
// Requires AUTH_SVC_URL environment variable to be set.
|
|
func New(logger *logging.Logger) (*Client, error) {
|
|
baseURL := svc.ServiceURL("auth-svc")
|
|
if baseURL == "" {
|
|
return nil, fmt.Errorf("auth-svc not configured (missing AUTH_SVC_URL env var)")
|
|
}
|
|
|
|
return &Client{
|
|
baseURL: baseURL,
|
|
httpClient: httpclient.New(httpclient.Config{}),
|
|
logger: logger.WithComponent("authclient"),
|
|
}, nil
|
|
}
|
|
|
|
// Validate calls POST /api/auth-svc/validate with the Bearer token.
|
|
// Returns the authenticated user or an error.
|
|
func (c *Client) Validate(ctx context.Context, token string) (*auth.User, error) {
|
|
url := c.baseURL + "/api/auth-svc/validate"
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create request: %w", err)
|
|
}
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
req.Header.Set("Accept", "application/json")
|
|
|
|
resp, err := c.httpClient.Do(req)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("call auth-svc: %w", err)
|
|
}
|
|
|
|
result, err := svc.DecodeResponse[ValidateResponse](resp)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("auth-svc validation failed: %w", err)
|
|
}
|
|
|
|
return &auth.User{
|
|
ID: result.Data.UserID,
|
|
Email: result.Data.Email,
|
|
Roles: result.Data.Roles,
|
|
Scopes: result.Data.Scopes,
|
|
}, nil
|
|
}
|