auth

package
v1.30.3 Latest Latest
Warning

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

Go to latest
Published: Jan 4, 2026 License: GPL-3.0 Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUserNotFound is returned when a user cannot be found.
	ErrUserNotFound = errors.New("user not found")
	// ErrUserAlreadyExists is returned when attempting to create a user
	// with a username that already exists.
	ErrUserAlreadyExists = errors.New("user already exists")
	// ErrInvalidUsername is returned when the username is invalid.
	ErrInvalidUsername = errors.New("invalid username")
	// ErrInvalidUserID is returned when the user ID is invalid.
	ErrInvalidUserID = errors.New("invalid user ID")
)

Common errors for user store operations.

View Source
var (
	// ErrAPIKeyNotFound is returned when an API key cannot be found.
	ErrAPIKeyNotFound = errors.New("API key not found")
	// ErrAPIKeyAlreadyExists is returned when attempting to create an API key
	// with a name that already exists.
	ErrAPIKeyAlreadyExists = errors.New("API key already exists")
	// ErrInvalidAPIKeyName is returned when the API key name is invalid.
	ErrInvalidAPIKeyName = errors.New("invalid API key name")
	// ErrInvalidAPIKeyID is returned when the API key ID is invalid.
	ErrInvalidAPIKeyID = errors.New("invalid API key ID")
	// ErrInvalidAPIKeyHash is returned when the API key hash is empty.
	ErrInvalidAPIKeyHash = errors.New("invalid API key hash")
	// ErrInvalidRole is returned when the role is not a valid role.
	ErrInvalidRole = errors.New("invalid role")
)

Common errors for API key store operations.

View Source
var (
	// ErrWebhookNotFound is returned when a webhook cannot be found.
	ErrWebhookNotFound = errors.New("webhook not found")
	// ErrWebhookAlreadyExists is returned when attempting to create a webhook
	// for a DAG that already has one.
	ErrWebhookAlreadyExists = errors.New("webhook already exists for this DAG")
	// ErrInvalidWebhookDAGName is returned when the DAG name is invalid.
	ErrInvalidWebhookDAGName = errors.New("invalid webhook DAG name")
	// ErrInvalidWebhookID is returned when the webhook ID is invalid.
	ErrInvalidWebhookID = errors.New("invalid webhook ID")
	// ErrInvalidWebhookTokenHash is returned when the webhook token hash is empty.
	ErrInvalidWebhookTokenHash = errors.New("invalid webhook token hash")
)

Common errors for webhook store operations.

Functions

func WithUser

func WithUser(ctx context.Context, user *User) context.Context

WithUser returns a new context that carries the provided user value.

Types

type APIKey added in v1.29.0

type APIKey struct {
	// ID is the unique identifier for the API key (UUID).
	ID string `json:"id"`
	// Name is a human-readable name for the API key (required).
	Name string `json:"name"`
	// Description is an optional description of the API key's purpose.
	Description string `json:"description,omitempty"`
	// Role determines the API key's permissions.
	Role Role `json:"role"`
	// KeyHash is the bcrypt hash of the API key secret.
	// Excluded from JSON serialization for security.
	KeyHash string `json:"-"`
	// KeyPrefix stores the first 8 characters of the key for identification.
	KeyPrefix string `json:"key_prefix"`
	// CreatedAt is the timestamp when the API key was created.
	CreatedAt time.Time `json:"created_at"`
	// UpdatedAt is the timestamp when the API key was last modified.
	UpdatedAt time.Time `json:"updated_at"`
	// CreatedBy is the user ID of the admin who created the API key.
	CreatedBy string `json:"created_by"`
	// LastUsedAt is the timestamp when the API key was last used for authentication.
	LastUsedAt *time.Time `json:"last_used_at,omitempty"`
}

APIKey represents a standalone API key in the system. API keys are independent entities with their own role assignment, enabling programmatic access with fine-grained permissions.

func NewAPIKey added in v1.29.0

func NewAPIKey(name, description string, role Role, keyHash, keyPrefix, createdBy string) (*APIKey, error)

NewAPIKey creates an APIKey with a new UUID and sets CreatedAt and UpdatedAt to the current UTC time. It validates that required fields are not empty and the role is valid. Returns an error if validation fails.

func (*APIKey) ToStorage added in v1.29.0

func (k *APIKey) ToStorage() *APIKeyForStorage

ToStorage converts an APIKey to APIKeyForStorage for persistence. NOTE: When adding new fields to APIKey or APIKeyForStorage, ensure both ToStorage and ToAPIKey are updated to maintain field synchronization.

type APIKeyForStorage added in v1.29.0

type APIKeyForStorage struct {
	ID          string     `json:"id"`
	Name        string     `json:"name"`
	Description string     `json:"description,omitempty"`
	Role        Role       `json:"role"`
	KeyHash     string     `json:"key_hash"`
	KeyPrefix   string     `json:"key_prefix"`
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
	CreatedBy   string     `json:"created_by"`
	LastUsedAt  *time.Time `json:"last_used_at,omitempty"`
}

APIKeyForStorage is used for JSON serialization to persistent storage. It includes the key hash which is excluded from the regular APIKey JSON.

func (*APIKeyForStorage) ToAPIKey added in v1.29.0

func (s *APIKeyForStorage) ToAPIKey() *APIKey

ToAPIKey converts APIKeyForStorage back to APIKey. NOTE: When adding new fields to APIKey or APIKeyForStorage, ensure both ToStorage and ToAPIKey are updated to maintain field synchronization.

type APIKeyStore added in v1.29.0

type APIKeyStore interface {
	// Create stores a new API key.
	// Returns ErrAPIKeyAlreadyExists if an API key with the same name exists.
	Create(ctx context.Context, key *APIKey) error

	// GetByID retrieves an API key by its unique ID.
	// Returns ErrAPIKeyNotFound if the API key does not exist.
	GetByID(ctx context.Context, id string) (*APIKey, error)

	// List returns all API keys in the store.
	List(ctx context.Context) ([]*APIKey, error)

	// Update modifies an existing API key.
	// Returns ErrAPIKeyNotFound if the API key does not exist.
	Update(ctx context.Context, key *APIKey) error

	// Delete removes an API key by its ID.
	// Returns ErrAPIKeyNotFound if the API key does not exist.
	Delete(ctx context.Context, id string) error

	// UpdateLastUsed updates the LastUsedAt timestamp for an API key.
	// This is called when the API key is used for authentication.
	UpdateLastUsed(ctx context.Context, id string) error
}

APIKeyStore defines the interface for API key persistence operations. Implementations must be safe for concurrent use.

type Role

type Role string

Role represents a user's role in the system. Roles determine what actions a user can perform.

Role hierarchy (most to least privileged):

  • admin: Full system access including user management
  • manager: Can create, edit, delete, run, and stop DAGs
  • operator: Can run and stop DAGs (execute only)
  • viewer: Read-only access to DAGs and status
const (
	// RoleAdmin has full access to all resources including user management.
	RoleAdmin Role = "admin"
	// RoleManager can create, edit, delete, run, and stop DAGs.
	RoleManager Role = "manager"
	// RoleOperator can run and stop DAGs (execute only, no edit).
	RoleOperator Role = "operator"
	// RoleViewer can only view DAGs and execution history (read-only).
	RoleViewer Role = "viewer"
)

func AllRoles

func AllRoles() []Role

AllRoles returns a copy of all valid roles.

func ParseRole

func ParseRole(s string) (Role, error)

ParseRole converts a string to a Role. ParseRole converts the input string to a Role and verifies it is one of the known roles. If the input is not "admin", "manager", "operator", or "viewer", it returns an error describing the valid options.

func (Role) CanExecute

func (r Role) CanExecute() bool

CanExecute returns true if the role can run or stop DAGs.

func (Role) CanWrite

func (r Role) CanWrite() bool

CanWrite returns true if the role can create, edit, or delete DAGs.

func (Role) IsAdmin

func (r Role) IsAdmin() bool

IsAdmin returns true if the role has administrative privileges (user management).

func (Role) String

func (r Role) String() string

String returns the string representation of the role.

func (Role) Valid

func (r Role) Valid() bool

Valid returns true if the role is a known valid role.

type User

type User struct {
	// ID is the unique identifier for the user (UUID).
	ID string `json:"id"`
	// Username is the unique login name.
	Username string `json:"username"`
	// PasswordHash is the bcrypt hash of the password.
	// Excluded from JSON serialization for security.
	PasswordHash string `json:"-"`
	// Role determines the user's permissions.
	Role Role `json:"role"`
	// CreatedAt is the timestamp when the user was created.
	CreatedAt time.Time `json:"created_at"`
	// UpdatedAt is the timestamp when the user was last modified.
	UpdatedAt time.Time `json:"updated_at"`
}

User represents a user in the system.

func NewUser

func NewUser(username string, passwordHash string, role Role) *User

NewUser creates a User with a new UUID and sets CreatedAt and UpdatedAt to the current UTC time. The provided username, passwordHash, and role are assigned to the corresponding fields.

func UserFromContext

func UserFromContext(ctx context.Context) (*User, bool)

UserFromContext retrieves the authenticated user from the context. It returns the user and true if a *User value is present for the package's userContextKey, or nil and false otherwise.

func (*User) ToStorage

func (u *User) ToStorage() *UserForStorage

ToStorage converts a User to UserForStorage for persistence.

type UserForStorage

type UserForStorage struct {
	ID           string    `json:"id"`
	Username     string    `json:"username"`
	PasswordHash string    `json:"password_hash"`
	Role         Role      `json:"role"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

UserForStorage is used for JSON serialization to persistent storage. It includes the password hash which is excluded from the regular User JSON.

func (*UserForStorage) ToUser

func (s *UserForStorage) ToUser() *User

ToUser converts UserForStorage back to User.

type UserStore

type UserStore interface {
	// Create stores a new user.
	// Returns ErrUserAlreadyExists if a user with the same username exists.
	Create(ctx context.Context, user *User) error

	// GetByID retrieves a user by their unique ID.
	// Returns ErrUserNotFound if the user does not exist.
	GetByID(ctx context.Context, id string) (*User, error)

	// GetByUsername retrieves a user by their username.
	// Returns ErrUserNotFound if the user does not exist.
	GetByUsername(ctx context.Context, username string) (*User, error)

	// List returns all users in the store.
	List(ctx context.Context) ([]*User, error)

	// Update modifies an existing user.
	// Returns ErrUserNotFound if the user does not exist.
	Update(ctx context.Context, user *User) error

	// Delete removes a user by their ID.
	// Returns ErrUserNotFound if the user does not exist.
	Delete(ctx context.Context, id string) error

	// Count returns the total number of users.
	Count(ctx context.Context) (int64, error)
}

UserStore defines the interface for user persistence operations. Implementations must be safe for concurrent use.

type Webhook added in v1.29.0

type Webhook struct {
	// ID is the unique identifier for the webhook (UUID).
	ID string `json:"id"`
	// DAGName is the file name of the DAG this webhook triggers.
	// This serves as a unique constraint - one webhook per DAG.
	DAGName string `json:"dagName"`
	// TokenHash is the bcrypt hash of the webhook token secret.
	// Excluded from JSON serialization for security.
	TokenHash string `json:"-"`
	// TokenPrefix stores the first 8 characters of the token for identification.
	TokenPrefix string `json:"tokenPrefix"`
	// Enabled indicates whether the webhook is active.
	Enabled bool `json:"enabled"`
	// CreatedAt is the timestamp when the webhook was created.
	CreatedAt time.Time `json:"createdAt"`
	// UpdatedAt is the timestamp when the webhook was last modified.
	UpdatedAt time.Time `json:"updatedAt"`
	// CreatedBy is the user ID of the admin who created the webhook.
	CreatedBy string `json:"createdBy"`
	// LastUsedAt is the timestamp when the webhook was last triggered.
	LastUsedAt *time.Time `json:"lastUsedAt,omitempty"`
}

Webhook represents a webhook configuration for triggering a specific DAG. Each DAG can have at most one webhook. The token is stored as a bcrypt hash.

func NewWebhook added in v1.29.0

func NewWebhook(dagName, tokenHash, tokenPrefix, createdBy string) (*Webhook, error)

NewWebhook creates a Webhook with a new UUID and sets CreatedAt and UpdatedAt to the current UTC time. It validates that required fields are not empty. Returns an error if validation fails.

func (*Webhook) ToStorage added in v1.29.0

func (w *Webhook) ToStorage() *WebhookForStorage

ToStorage converts a Webhook to WebhookForStorage for persistence. NOTE: When adding new fields to Webhook or WebhookForStorage, ensure both ToStorage and ToWebhook are updated to maintain field synchronization.

type WebhookForStorage added in v1.29.0

type WebhookForStorage struct {
	ID          string     `json:"id"`
	DAGName     string     `json:"dagName"`
	TokenHash   string     `json:"tokenHash"`
	TokenPrefix string     `json:"tokenPrefix"`
	Enabled     bool       `json:"enabled"`
	CreatedAt   time.Time  `json:"createdAt"`
	UpdatedAt   time.Time  `json:"updatedAt"`
	CreatedBy   string     `json:"createdBy"`
	LastUsedAt  *time.Time `json:"lastUsedAt,omitempty"`
}

WebhookForStorage is used for JSON serialization to persistent storage. It includes the token hash which is excluded from the regular Webhook JSON.

func (*WebhookForStorage) ToWebhook added in v1.29.0

func (s *WebhookForStorage) ToWebhook() *Webhook

ToWebhook converts WebhookForStorage back to Webhook. NOTE: When adding new fields to Webhook or WebhookForStorage, ensure both ToStorage and ToWebhook are updated to maintain field synchronization.

type WebhookStore added in v1.29.0

type WebhookStore interface {
	// Create stores a new webhook.
	// Returns ErrWebhookAlreadyExists if a webhook for the DAG already exists.
	Create(ctx context.Context, webhook *Webhook) error

	// GetByID retrieves a webhook by its unique ID.
	// Returns ErrWebhookNotFound if the webhook does not exist.
	GetByID(ctx context.Context, id string) (*Webhook, error)

	// GetByDAGName retrieves the webhook for a specific DAG.
	// Returns ErrWebhookNotFound if no webhook exists for the DAG.
	GetByDAGName(ctx context.Context, dagName string) (*Webhook, error)

	// List returns all webhooks in the store.
	List(ctx context.Context) ([]*Webhook, error)

	// Update modifies an existing webhook.
	// Returns ErrWebhookNotFound if the webhook does not exist.
	Update(ctx context.Context, webhook *Webhook) error

	// Delete removes a webhook by its ID.
	// Returns ErrWebhookNotFound if the webhook does not exist.
	Delete(ctx context.Context, id string) error

	// DeleteByDAGName removes a webhook by its DAG name.
	// Returns ErrWebhookNotFound if no webhook exists for the DAG.
	DeleteByDAGName(ctx context.Context, dagName string) error

	// UpdateLastUsed updates the LastUsedAt timestamp for a webhook.
	// This is called when the webhook is triggered.
	UpdateLastUsed(ctx context.Context, id string) error
}

WebhookStore defines the interface for webhook persistence operations. Implementations must be safe for concurrent use. Each DAG can have at most one webhook (1:1 relationship).

Jump to

Keyboard shortcuts

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