loginflow

package
v3.13.2 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package loginflow holds the persistent state for the login flow. It stores one client authorization per pending enrolment and runs the atomic state transitions (approve, consume) that the flow needs. It does not authenticate anyone; its only job is to track an authorization until an appauth credential is minted.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClientDescription

func ClientDescription(ua string) string

ClientDescription turns a raw User-Agent into a short, human-readable label for the confirmation page and the connected-clients list, e.g. "Nextcloud Sync Client v3.13.0 (on Linux)". It recognises the Nextcloud desktop sync client (which sends a "mirall/<version>" token) and falls back to the raw string for anything it does not know.

func HashToken

func HashToken(token string) []byte

HashToken returns SHA256(token). Client authorizations are stored and looked up by this hash; the raw login and poll tokens are never persisted.

Types

type ClientAuthorization

type ClientAuthorization struct {
	LoginHash  []byte     // SHA256(logintoken)
	PollHash   []byte     // SHA256(polltoken)
	ClientID   string     // UUIDv4, surfaced to audit / management API
	UserAgent  string     // raw User-Agent from Init
	CreatedAt  time.Time  // set at Init
	ExpiresAt  time.Time  // PENDING lifetime
	ApprovedAt *time.Time // nil = PENDING; non-nil = APPROVED
	UserID     string     // set on approval, opaque user id
	Username   string     // set on approval, login name for the poll response
	DeviceName string     // set on approval, becomes the app password label
}

ClientAuthorization is one pending or approved enrolment attempt by a client.

func (*ClientAuthorization) Approved

func (ca *ClientAuthorization) Approved() bool

Approved reports whether the authorization has been granted.

func (*ClientAuthorization) Expired

func (ca *ClientAuthorization) Expired() bool

Expired reports whether the authorization has passed its PENDING lifetime.

type Manager

type Manager interface {
	// Create inserts a new PENDING authorization.
	Create(ctx context.Context, ca *ClientAuthorization) error
	// GetByLogin returns the authorization for a login hash, including expired
	// ones so the caller can tell "gone" from "unknown". Returns
	// errtypes.NotFound if no live (non-deleted) row exists.
	GetByLogin(ctx context.Context, loginHash []byte) (*ClientAuthorization, error)
	// GetByPoll is GetByLogin keyed by poll hash.
	GetByPoll(ctx context.Context, pollHash []byte) (*ClientAuthorization, error)
	// Approve records the user's consent, once: who granted, and what they named
	// the device. Returns errtypes.Conflict if the authorization was already
	// granted, already denied, or has expired.
	Approve(ctx context.Context, loginHash []byte, userID, username, deviceName string) error
	// Consume hands out an approved authorization once and only once, so two
	// polls can never mint two app passwords from one approval. The winner gets
	// the user to mint for. Returns errtypes.NotFound if the authorization was
	// never approved, is already consumed, or has expired.
	Consume(ctx context.Context, pollHash []byte) (*ClientAuthorization, error)
	// Deny soft-deletes a PENDING authorization. It is a no-op if no PENDING row
	// exists.
	Deny(ctx context.Context, loginHash []byte) error
}

Manager stores client authorizations and runs their state transitions.

Directories

Path Synopsis
sql
Package sql is a GORM-backed store for client authorizations.
Package sql is a GORM-backed store for client authorizations.

Jump to

Keyboard shortcuts

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