auth

package
v0.27.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2026 License: CC0-1.0 Imports: 15 Imported by: 0

Documentation

Overview

Package auth implements PKCE + localhost-callback login for the CLI and bearer middleware for all other RPCs.

Index

Constants

View Source
const (
	StatePending  = "PENDING"
	StateApproved = "APPROVED"
	StateExpired  = "EXPIRED"
	StateUsed     = "USED"
)

State constants written to auth_codes.state.

Variables

View Source
var AppTokenRPCs = map[string]struct{}{
	"/prosa.v1.AnalyticsService/GetReport": {},
}

AppTokenRPCs are the read-only procedures available to app tokens.

View Source
var ErrUnknownToken = errors.New("unknown or revoked token")

ErrUnknownToken is returned when a bearer doesn't map to a live row.

View Source
var PublicRPCs = map[string]struct{}{
	"/prosa.v1.HealthService/Check":      {},
	"/prosa.v1.AuthService/BeginLogin":   {},
	"/prosa.v1.AuthService/ExchangeCode": {},
}

PublicRPCs are the procedure paths that skip bearer enforcement. Anything not in this set must present a valid Authorization header.

Functions

func DeviceFromContext

func DeviceFromContext(ctx context.Context) (string, bool)

DeviceFromContext returns the device id stamped by Interceptor. The caller MUST treat a missing value as an unauthenticated condition.

func HashBearer

func HashBearer(bearer string) string

HashBearer returns the canonical sha256 hash we store.

func Interceptor

func Interceptor(svc *Service) connect.UnaryInterceptorFunc

Interceptor is a Connect unary interceptor that pulls the bearer from the request, resolves it to a device_id, and stamps the context. Public RPCs pass through untouched. Admin callers (panel) present `Authorization: Admin <PROSA_ADMIN_TOKEN>` and get an owner-flagged context with no device id.

func IsOwner

func IsOwner(ctx context.Context) bool

IsOwner returns true when the caller authenticated via the admin header (panel-to-server).

Types

type AppToken

type AppToken struct {
	ID   string
	Name string
}

AppToken is the context projection for a live application token.

func AppTokenFromContext

func AppTokenFromContext(ctx context.Context) (AppToken, bool)

AppTokenFromContext returns the app token stamped by Interceptor.

type AppTokenRecord

type AppTokenRecord struct {
	ID         string
	Name       string
	CreatedAt  time.Time
	LastUsedAt *time.Time
	RevokedAt  *time.Time
}

AppTokenRecord is the database projection used by the owner management RPCs.

type ApproveResult

type ApproveResult struct {
	Code        string
	RedirectURI string
	ClientState string
}

ApproveResult is returned after the panel approves a login attempt.

type BeginResult

type BeginResult struct {
	RequestID    string
	AuthorizeURL string
	ExpiresIn    int32
}

BeginResult is the projection of BeginLoginResponse.

type ExchangeResult

type ExchangeResult struct {
	Token    string
	DeviceID string
}

ExchangeResult is the projection of ExchangeCodeResponse.

type LoginRequest

type LoginRequest struct {
	Hostname    string
	Fingerprint string
	ExpiresAt   time.Time
	State       string
}

LoginRequest is the projection of GetLoginRequestResponse.

type Service

type Service struct {
	Pool         *pgxpool.Pool
	AdminToken   string
	PanelBaseURL string
	ExpiresIn    time.Duration
}

Service is the login state machine and bearer lookup.

func New

func New(pool *pgxpool.Pool, adminToken, panelBaseURL string) *Service

New wires the service with sensible defaults.

func (*Service) AppTokenFromBearer

func (s *Service) AppTokenFromBearer(ctx context.Context, bearer string) (AppToken, error)

AppTokenFromBearer resolves a live app token from an Authorization secret.

func (*Service) Approve

func (s *Service) Approve(ctx context.Context, requestID string) (ApproveResult, error)

Approve flips PENDING → APPROVED and mints a one-time auth code.

func (*Service) Begin

func (s *Service) Begin(ctx context.Context, hostname, fingerprint, challenge, redirectURI, clientState string) (BeginResult, error)

Begin inserts a fresh PENDING auth_codes row.

func (*Service) CreateAppToken

func (s *Service) CreateAppToken(ctx context.Context, name string) (AppTokenRecord, string, error)

CreateAppToken inserts a new app token and returns its plaintext secret once.

func (*Service) DeviceFromBearer

func (s *Service) DeviceFromBearer(ctx context.Context, bearer string) (string, error)

DeviceFromBearer looks up the device_id bound to a bearer presented in an Authorization header. Returns ErrUnknownToken when no row matches OR when the row was revoked.

func (*Service) Exchange

func (s *Service) Exchange(ctx context.Context, code, verifier, redirectURI string) (ExchangeResult, error)

Exchange verifies PKCE and issues the device bearer.

func (*Service) GetRequest

func (s *Service) GetRequest(ctx context.Context, requestID string) (LoginRequest, error)

GetRequest returns metadata for the panel confirmation page.

func (*Service) IsAdminToken

func (s *Service) IsAdminToken(tok string) bool

IsAdminToken is a constant-time comparison helper used by the interceptor; exposed so handlers that want to gate explicit admin paths (e.g. ApproveLogin) can reuse the same check.

func (*Service) ListAppTokens

func (s *Service) ListAppTokens(ctx context.Context) ([]AppTokenRecord, error)

ListAppTokens returns app tokens newest first, including revoked rows.

func (*Service) RevokeAppToken

func (s *Service) RevokeAppToken(ctx context.Context, id string) error

RevokeAppToken marks a token revoked. Unknown ids are treated as no-ops.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL