87 lines
2.4 KiB
Go
87 lines
2.4 KiB
Go
// Package client provides clients for communicating with sibling services.
|
|
package client
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"git.threesix.ai/jordan/sp4-verify-1770325799/pkg/auth"
|
|
"git.threesix.ai/jordan/sp4-verify-1770325799/pkg/svc"
|
|
)
|
|
|
|
// AuthClient communicates with the auth-svc for token validation.
|
|
type AuthClient struct {
|
|
client *svc.Client
|
|
}
|
|
|
|
// ValidateResponse is the response from the auth-svc /validate endpoint.
|
|
type ValidateResponse struct {
|
|
Data struct {
|
|
Valid bool `json:"valid"`
|
|
User *auth.User `json:"user,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// NewAuthClient creates a new client for the auth-svc.
|
|
// Returns an error if AUTH_SVC_URL is not configured.
|
|
func NewAuthClient() (*AuthClient, error) {
|
|
client, err := svc.NewClient("auth-svc")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &AuthClient{client: client}, nil
|
|
}
|
|
|
|
// ValidateToken validates a JWT token by calling auth-svc.
|
|
// Returns the user if valid, or an error if invalid or communication fails.
|
|
func (c *AuthClient) ValidateToken(ctx context.Context, token string) (*auth.User, error) {
|
|
req, err := c.client.NewRequest(ctx, http.MethodGet, "/api/auth-svc/validate", nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create request: %w", err)
|
|
}
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
resp, err := c.client.DoRequest(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("decode response: %w", err)
|
|
}
|
|
|
|
if !result.Data.Valid {
|
|
return nil, fmt.Errorf("token validation failed: %s", result.Data.Error)
|
|
}
|
|
|
|
return result.Data.User, nil
|
|
}
|
|
|
|
// ValidateTokenWithHeader validates a token by forwarding the Authorization header.
|
|
func (c *AuthClient) ValidateTokenWithHeader(ctx context.Context, authHeader string) (*auth.User, error) {
|
|
req, err := c.client.NewRequest(ctx, http.MethodGet, "/api/auth-svc/validate", nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create request: %w", err)
|
|
}
|
|
req.Header.Set("Authorization", authHeader)
|
|
|
|
resp, err := c.client.DoRequest(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("decode response: %w", err)
|
|
}
|
|
|
|
if !result.Data.Valid {
|
|
return nil, fmt.Errorf("token validation failed: %s", result.Data.Error)
|
|
}
|
|
|
|
return result.Data.User, nil
|
|
}
|