trackerauth

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: GPL-2.0 Imports: 32 Imported by: 0

Documentation

Overview

Package trackerauth manages tracker login, cookie import, session validation, and encrypted auxiliary auth state for tracker implementations.

Index

Constants

View Source
const (
	// MaxCookieImportContentBytes is the shared decoded cookie text byte limit for web, Wails, and service imports.
	MaxCookieImportContentBytes = 1024 * 1024

	// StateConfigured means required non-cookie config auth material is present.
	StateConfigured = "configured"
	// StateHasCookies means encrypted cookie storage contains at least one cookie for the tracker.
	StateHasCookies = "has_cookies"
	// StateNotConfigured means no supported auth material is currently configured.
	StateNotConfigured = "not_configured"
	// StateLoginRequired means credentials or imported cookies are required before tracker auth can proceed.
	StateLoginRequired = "login_required"
	// StateEncryptedStorageUnavailable means cookie import cannot be used until web auth material exists.
	StateEncryptedStorageUnavailable = "encrypted_storage_unavailable"
)

Tracker auth status values returned in api.TrackerAuthStatus.State.

View Source
const (
	// SessionStateReady means an adapter returned auth material ready for tracker requests.
	SessionStateReady = "ready"
	// SessionStateAuthRequired means no usable session is available without user auth material.
	SessionStateAuthRequired = "auth_required"
	// SessionStateNeeds2FA means the auth flow is paused until a manual 2FA code is submitted.
	SessionStateNeeds2FA = "needs_2fa"
	// SessionStateUnsupported means the tracker has no supported auth operation for the requested flow.
	SessionStateUnsupported = "unsupported"
)

Variables

View Source
var ErrAuthStateNotFound = errors.New("tracker auth state not found")

ErrAuthStateNotFound is returned when no encrypted tracker auth state exists for a tracker/key pair.

Functions

func CookiesToMap

func CookiesToMap(values []*http.Cookie) map[string]string

CookiesToMap converts HTTP cookies to a name/value map, ignoring nil cookies and blank names or values while preserving cookie value bytes.

func DeleteAuthState

func DeleteAuthState(ctx context.Context, dbPath string, trackerID string, stateKey string) error

DeleteAuthState opens dbPath and deletes value for trackerID/stateKey.

func LoadAuthState

func LoadAuthState(ctx context.Context, dbPath string, trackerID string, stateKey string) (string, error)

LoadAuthState opens dbPath and decrypts value for trackerID/stateKey. It returns ErrAuthStateNotFound when the key has not been saved.

func ParseCookieContent

func ParseCookieContent(fileName string, content string) (map[string]string, error)

ParseCookieContent parses JSON cookie exports or Netscape cookie files into a non-empty name/value map. Raw content above MaxCookieImportContentBytes, malformed JSON-looking payloads, JSON array entries without name and value, and duplicate trimmed cookie names are rejected; cookie values are preserved byte-for-byte after decoding.

func ReadCookieImportContent

func ReadCookieImportContent(r io.Reader) (string, error)

ReadCookieImportContent reads at most MaxCookieImportContentBytes from r and returns the shared parser cap error before allocating a larger payload.

func SaveAuthState

func SaveAuthState(ctx context.Context, dbPath string, trackerID string, stateKey string, value string) error

SaveAuthState opens dbPath, initializes encrypted auth storage, and upserts value for trackerID/stateKey.

Types

type Adapter

type Adapter interface {
	// Capability returns static auth support metadata for the tracker.
	Capability() api.TrackerAuthCapability
	// Status returns local auth state without forcing a remote login.
	Status(ctx context.Context, cfg config.TrackerConfig, dbPath string) (api.TrackerAuthStatus, error)
	// Validate checks whether stored auth material can be used for tracker requests.
	Validate(ctx context.Context, cfg config.TrackerConfig, dbPath string) (Session, error)
	// Login attempts credential-based auth and may persist refreshed auth material.
	Login(ctx context.Context, cfg config.TrackerConfig, dbPath string, req api.TrackerAuthLoginRequest) (Session, error)
	// Submit2FA retries auth with manual 2FA input for a service-verified challenge.
	Submit2FA(ctx context.Context, cfg config.TrackerConfig, dbPath string, req api.TrackerAuthLoginRequest) (Session, error)
	// Delete removes persisted auth material owned by the adapter.
	Delete(ctx context.Context, dbPath string) error
}

Adapter validates and mutates tracker-specific auth material.

type AuthRequiredError

type AuthRequiredError struct {
	TrackerID string
	Reason    string
	Err       error
}

AuthRequiredError reports that no usable session is available and caller-supplied auth material is required.

func (*AuthRequiredError) Error

func (e *AuthRequiredError) Error() string

func (*AuthRequiredError) Unwrap

func (e *AuthRequiredError) Unwrap() error

type AuthStateStore

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

AuthStateStore persists encrypted tracker auth state in the shared SQLite database.

func NewAuthStateStore

func NewAuthStateStore(db *sql.DB) (*AuthStateStore, error)

NewAuthStateStore wraps db for encrypted tracker auth state operations.

func (*AuthStateStore) Delete

func (s *AuthStateStore) Delete(ctx context.Context, trackerID string, stateKey string) error

Delete removes encrypted value for trackerID/stateKey.

func (*AuthStateStore) Load

func (s *AuthStateStore) Load(ctx context.Context, trackerID string, stateKey string, encKey []byte) (string, error)

Load decrypts value for trackerID/stateKey with encKey. It returns ErrAuthStateNotFound when the key has not been saved.

func (*AuthStateStore) Save

func (s *AuthStateStore) Save(ctx context.Context, trackerID string, stateKey string, value string, encKey []byte) error

Save encrypts value with encKey and upserts it for trackerID/stateKey. encKey must be a 32-byte key from cookie encryption storage.

type Challenge

type Challenge struct {
	// ID is the opaque token returned to the UI and later supplied to Submit2FA.
	ID string
	// TrackerID is the normalized tracker code that owns the challenge.
	TrackerID string
	// OwnerKey binds the challenge to the config generation that created it.
	OwnerKey string
	// ExpiresAt is the UTC deadline after which the challenge is discarded.
	ExpiresAt time.Time
}

Challenge identifies one manual 2FA continuation for a tracker auth login.

type ChallengeManager

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

ChallengeManager stores time-limited manual 2FA challenges and rejects continuations whose owner key no longer matches the creating config.

func NewChallengeManager

func NewChallengeManager(ttl time.Duration) *ChallengeManager

NewChallengeManager returns a challenge manager with ttl, using the default TTL when ttl is not positive.

func (*ChallengeManager) Consume

func (m *ChallengeManager) Consume(challengeID string, trackerID string, ownerKey ...string) (Challenge, error)

Consume validates that challengeID belongs to trackerID and ownerKey, removes it, and returns the consumed challenge.

func (*ChallengeManager) Create

func (m *ChallengeManager) Create(ctx context.Context, trackerID string, ownerKey ...string) string

Create registers a challenge for trackerID and returns its opaque ID. The optional owner key is stored with the challenge so later submissions can be rejected after a config change.

func (*ChallengeManager) Get

func (m *ChallengeManager) Get(challengeID string) (Challenge, bool)

Get returns an active challenge by ID after pruning expired challenges.

type EnsureRequest

type EnsureRequest struct {
	// TrackerID is the tracker code to validate; comparisons are case-insensitive.
	TrackerID string
	// Config supplies credentials, URLs, passkeys, and OTP settings for the tracker.
	Config config.TrackerConfig
	// DBPath points at the application database used for encrypted cookie and state storage.
	DBPath string
	// AutoLogin allows EnsureSession to attempt credential login after a confirmed invalid stored session.
	AutoLogin bool
	// Login carries optional adapter-specific login input, such as a one-time 2FA code.
	Login api.TrackerAuthLoginRequest
}

EnsureRequest describes one tracker auth validation or login attempt.

type Needs2FAError

type Needs2FAError struct {
	TrackerID string
	// ChallengeID is set when the caller can continue the flow with Submit2FA.
	ChallengeID string
	Reason      string
	Err         error
}

Needs2FAError reports that a manual 2FA code is required before auth can continue.

func (*Needs2FAError) Error

func (e *Needs2FAError) Error() string

func (*Needs2FAError) Unwrap

func (e *Needs2FAError) Unwrap() error

type Service

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

Service reports and manages persisted tracker auth material for configured trackers.

func NewService

func NewService(cfg config.Config) *Service

NewService builds a tracker auth service with default remote adapters and the shared manual 2FA challenge manager.

func NewServiceWithLogger

func NewServiceWithLogger(cfg config.Config, logger api.Logger) *Service

NewServiceWithLogger builds a tracker auth service that writes auth operation outcomes to logger without logging cookie values, credentials, 2FA codes, or challenge identifiers. Nil logger uses api.NopLogger.

func (*Service) Capabilities

func (s *Service) Capabilities(_ context.Context) (caps []api.TrackerAuthCapability, err error)

Capabilities returns tracker auth support metadata for built-in trackers and configured custom trackers.

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, trackerID string) (status api.TrackerAuthStatus, err error)

Delete removes tracker-specific auth state and generic cookies, then returns the refreshed local auth status. AR auth-state and cookie cleanup failures restore the previous AR auth state before returning the error even when the caller's context has been canceled.

func (*Service) EnsureSession

func (s *Service) EnsureSession(ctx context.Context, req EnsureRequest) (Session, error)

EnsureSession validates stored tracker auth, optionally attempts credential login, and returns the ready session or a typed auth error. When AutoLogin is false, it returns AuthRequiredError without calling tracker adapter validation or login.

func (*Service) ImportCookies

func (s *Service) ImportCookies(ctx context.Context, trackerID string, fileName string, content string) (status api.TrackerAuthStatus, err error)

ImportCookies parses supplied cookie content, saves it for trackerID, and returns refreshed auth status from persisted cookie/auth state. Parser errors leave existing stored cookies unchanged. BTN imports still report a missing API-key prerequisite when cookies alone do not make the tracker upload-ready.

func (*Service) Login

func (s *Service) Login(ctx context.Context, trackerID string, req api.TrackerAuthLoginRequest) (status api.TrackerAuthStatus, err error)

Login runs credential-based tracker auth when supported and returns status for missing credentials, unsupported remote login, or 2FA. Trackers with separate API prerequisites, such as BTN, keep the narrower prerequisite status when credential login cannot proceed or completes without making the tracker ready.

func (*Service) Status

func (s *Service) Status(ctx context.Context, trackerID string) (status api.TrackerAuthStatus, err error)

Status returns local tracker auth state derived from config, encrypted cookie storage, and stored cookies.

func (*Service) Submit2FA

func (s *Service) Submit2FA(ctx context.Context, challengeID string, code string) (status api.TrackerAuthStatus, err error)

Submit2FA completes an active manual 2FA challenge. Adapter failures return refreshed status without consuming the challenge; only failures classified with ValidationError.Submitted2FARejected keep the challenge visible for another try. Successful challenge completion clears the challenge fields but does not override separate tracker prerequisites such as BTN's API key.

func (*Service) Validate

func (s *Service) Validate(ctx context.Context, trackerID string) (status api.TrackerAuthStatus, err error)

Validate returns tracker auth status after a remote validation check when the tracker has an adapter. Confirmed-invalid stored sessions are deleted and reported as login-required status without returning an error. BTN session success remains login-required until the API token needed for torrent resolution is configured.

type Session

type Session struct {
	// TrackerID is the normalized tracker code that produced the session.
	TrackerID string
	// State reports whether the session is ready, blocked by auth, paused for 2FA, or unsupported.
	State string
	// Cookies contains session cookies returned by adapters that expose cookie maps.
	Cookies map[string]string
	// Token contains tracker-specific CSRF/auth tokens when an adapter exposes one.
	Token string
	// ChallengeID identifies a pending manual 2FA continuation.
	ChallengeID string
	// Message contains caller-visible detail about the current auth state.
	Message string
}

Session is the normalized result returned by a tracker auth adapter.

type UnsupportedAuthError

type UnsupportedAuthError struct {
	TrackerID string
	Reason    string
	Err       error
}

UnsupportedAuthError reports that the requested auth operation is not implemented for the tracker.

func (*UnsupportedAuthError) Error

func (e *UnsupportedAuthError) Error() string

func (*UnsupportedAuthError) Unwrap

func (e *UnsupportedAuthError) Unwrap() error

type ValidationError

type ValidationError struct {
	TrackerID string
	// ConfirmedInvalid means stored auth material is known bad and may be deleted.
	ConfirmedInvalid bool
	// Transient means stored auth material should be preserved because the failure may be temporary.
	Transient bool
	// Submitted2FARejected means an adapter proved a submitted manual 2FA code reached the tracker and was rejected.
	Submitted2FARejected bool
	Reason               string
	Err                  error
}

ValidationError reports a failed remote or local validation check.

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Jump to

Keyboard shortcuts

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