interactiveclient

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package interactiveclient — use-cases of InternalInteractiveClientService (IAM-INT-1): the lifecycle of the OAuth2 client through which a HUMAN completes an interactive sign-in ceremony.

Clean Architecture: this package defines the narrow ports below and depends on nothing but domain + the corelib operation envelope. Concrete adapters (pgx, the identity provider's admin API) live in internal/repo and internal/clients and are wired in cmd/kaname/wiring.go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CreateUseCase

type CreateUseCase struct {
	// contains filtered or unexported fields
}

CreateUseCase — registers the client at the identity provider, then records it.

func NewCreateUseCase

func NewCreateUseCase(r clientRepo, p providerClients, ops operations.Repo, audiences []string, logger *slog.Logger) *CreateUseCase

NewCreateUseCase — constructor. `audiences` comes from iam's own configuration (Р2): the caller never supplies it and it is echoed output-only.

func (*CreateUseCase) Execute

Execute — validate → persist Operation → register at provider → insert row.

WHY THE PROVIDER IS CONTACTED BEFORE THE ROW IS WRITTEN, AND WHAT PAYS FOR IT. The row must carry the provider's client id, so registration comes first. If the insert then fails — most often because the name is taken — the client that was just registered is deregistered again. Without that compensation an orphan would remain at the provider that the platform has no record of and no way to name: nothing would ever remove it, and it would keep accepting ceremonies.

The Operation row is persisted BEFORE either side effect, so the id the caller receives is always pollable; a failure is recorded on it as a terminal error rather than leaving the caller polling a row that does not exist.

func (*CreateUseCase) WithCompensationEmitter

func (uc *CreateUseCase) WithCompensationEmitter(c providerCompensationEmitter) *CreateUseCase

WithCompensationEmitter wires the durable sink for compensating intents. Composition-root only.

type DeleteUseCase

type DeleteUseCase struct {
	// contains filtered or unexported fields
}

DeleteUseCase — removes the client at the provider and its row.

func NewDeleteUseCase

func NewDeleteUseCase(r clientRepo, p providerClients, ops operations.Repo, logger *slog.Logger) *DeleteUseCase

NewDeleteUseCase — constructor.

func (*DeleteUseCase) Execute

func (uc *DeleteUseCase) Execute(ctx context.Context, id string) (*operationpb.Operation, error)

Execute — idempotent by construction.

Deleting an already-absent client succeeds and reports the same code as the first delete: the caller asked for the client to be gone, and it is. The row is removed first and the provider-side deregistration follows only when a row was actually taken — otherwise a repeated Delete would keep asking the provider to remove something already removed.

type GetUseCase

type GetUseCase struct {
	// contains filtered or unexported fields
}

GetUseCase — sync read of one client.

func NewGetUseCase

func NewGetUseCase(r clientRepo) *GetUseCase

NewGetUseCase — constructor.

func (*GetUseCase) Execute

func (uc *GetUseCase) Execute(ctx context.Context, id string) (domain.InteractiveClient, error)

Execute — direct-read lane: a well-formed id with no row is NOT_FOUND.

type Handler

type Handler struct {
	iamv1.UnimplementedInternalInteractiveClientServiceServer
	// contains filtered or unexported fields
}

Handler implements iamv1.InternalInteractiveClientServiceServer.

func NewHandler

NewHandler assembles the Handler. Composition root: cmd/kaname/wiring.go.

func (*Handler) Create

Create — async; returns the Operation envelope.

func (*Handler) Delete

Delete — async; returns the Operation envelope.

func (*Handler) Get

Get — sync read of one client.

func (*Handler) List

List — sync cursor-paginated read.

func (*Handler) Update

Update — async; returns the Operation envelope.

type ListResult

type ListResult struct {
	Clients       []domain.InteractiveClient
	NextPageToken string
}

ListResult — one page plus the cursor for the next.

type ListUseCase

type ListUseCase struct {
	// contains filtered or unexported fields
}

ListUseCase — sync cursor-paginated read.

func NewListUseCase

func NewListUseCase(r clientRepo) *ListUseCase

NewListUseCase — constructor.

func (*ListUseCase) Execute

func (uc *ListUseCase) Execute(ctx context.Context, pageSize int64, pageToken, filter string) (ListResult, error)

Execute — pagination format is validated FIRST, so a garbage token or an out-of-range page size is INVALID_ARGUMENT independently of what the caller holds and of what the store contains. `page_size` out of range is REJECTED, never clamped: silent clamping returns a different page than the one asked for and the caller never learns of it.

type ProviderClient

type ProviderClient struct {
	ClientID                string
	GrantTypes              []string
	TokenEndpointAuthMethod string
	Audiences               []string
}

ProviderClient — what the provider gives back.

type ProviderClientSpec

type ProviderClientSpec struct {
	Name                   string
	RedirectURIs           []string
	PostLogoutRedirectURIs []string
	Audiences              []string
	// GrantTypes — decided by the use-case, forwarded verbatim. The adapter does
	// not choose: this resource exists to register exactly one shape, and a
	// default living in the adapter is how the other three registration paths
	// ended up all meaning `client_credentials`.
	GrantTypes []string
}

ProviderClientSpec — what iam asks the provider to register. The caller of the RPC supplies only the first two fields' worth of intent; everything else is iam's decision (Р2 — the audience is stamped, never accepted).

type UpdateUseCase

type UpdateUseCase struct {
	// contains filtered or unexported fields
}

UpdateUseCase — applies the mutable fields.

func NewUpdateUseCase

func NewUpdateUseCase(r clientRepo, ops operations.Repo, logger *slog.Logger) *UpdateUseCase

NewUpdateUseCase — constructor.

func (*UpdateUseCase) Execute

Execute — mask discipline, then the write.

Jump to

Keyboard shortcuts

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