Help us shape the future of Go! Take the 2026 Go Developer Survey

user

package
v1.0.2 Latest Latest
Warning

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

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

Documentation

Overview

Package user provides user domain models and repository interfaces.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUserNotFound       = errors.New("user not found")
	ErrEmailAlreadyExists = errors.New("email already exists")
	ErrInvalidRole        = errors.New("invalid role")
	// ErrLastOwner is returned when a change would leave the site without an owner.
	ErrLastOwner = errors.New("cannot remove or demote the last owner")
)

Common errors.

Functions

func ValidRole

func ValidRole(r Role) bool

ValidRole checks if a role is valid.

Types

type CreateUserInput

type CreateUserInput struct {
	Email    string
	Password string
	Role     Role
	Name     string
}

CreateUserInput represents input for creating a new user.

type PostgresRepository

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

PostgresRepository implements Repository using PostgreSQL.

func NewPostgresRepository

func NewPostgresRepository(db *database.DB) *PostgresRepository

NewPostgresRepository creates a new PostgreSQL user repository.

func (*PostgresRepository) Count

func (r *PostgresRepository) Count(ctx context.Context) (int, error)

Count returns the total number of users.

Path B PR 2b/3: dropped the tenantID parameter (see List).

func (*PostgresRepository) Create

func (r *PostgresRepository) Create(ctx context.Context, input *CreateUserInput, passwordHash string) (*User, error)

Create inserts a new user into the database. Multi-tenancy was removed in Path B; hatamoto_users has no tenant_id column and the User model has no TenantID field.

func (*PostgresRepository) Delete

func (r *PostgresRepository) Delete(ctx context.Context, id uuid.UUID) error

Delete removes a user from the database.

func (*PostgresRepository) GetByEmail

func (r *PostgresRepository) GetByEmail(ctx context.Context, email string) (*User, error)

GetByEmail retrieves a user by email address.

func (*PostgresRepository) GetByID

func (r *PostgresRepository) GetByID(ctx context.Context, id uuid.UUID) (*User, error)

GetByID retrieves a user by ID.

func (*PostgresRepository) List

func (r *PostgresRepository) List(ctx context.Context, limit, offset int) ([]*User, error)

List retrieves users with pagination.

Path B PR 2b/3: dropped the tenantID parameter — there's a single tenant so per-tenant filtering is meaningless. Callers must update their call sites accordingly.

func (*PostgresRepository) ListByEmail

func (r *PostgresRepository) ListByEmail(ctx context.Context, email string) ([]*User, error)

ListByEmail retrieves all users with the given email. Pre-Path-B this scanned across tenants for the multi-tenant cross-account login feature; post-strip the result set is at most 1 row but the API contract stays the same so callers (auth.Service) don't need adjusting.

func (*PostgresRepository) RecordFailedLogin

func (r *PostgresRepository) RecordFailedLogin(ctx context.Context, id uuid.UUID, maxAttempts int, lockFor time.Duration) error

RecordFailedLogin increments the failure counter and locks the account once the threshold is reached, in a single statement.

func (*PostgresRepository) ResetFailedLogins

func (r *PostgresRepository) ResetFailedLogins(ctx context.Context, id uuid.UUID) error

ResetFailedLogins clears the failure counter and unlocks the account.

func (*PostgresRepository) SetPassword

func (r *PostgresRepository) SetPassword(ctx context.Context, id uuid.UUID, passwordHash string) error

SetPassword replaces a user's password hash and clears any login lockout.

func (*PostgresRepository) Update

func (r *PostgresRepository) Update(ctx context.Context, id uuid.UUID, input *UpdateUserInput) (*User, error)

Update modifies a user's information.

func (*PostgresRepository) UpdateLastLogin

func (r *PostgresRepository) UpdateLastLogin(ctx context.Context, id uuid.UUID) error

UpdateLastLogin updates the user's last login timestamp.

type Repository

type Repository interface {
	Create(ctx context.Context, input *CreateUserInput, passwordHash string) (*User, error)
	GetByID(ctx context.Context, id uuid.UUID) (*User, error)
	GetByEmail(ctx context.Context, email string) (*User, error)
	ListByEmail(ctx context.Context, email string) ([]*User, error)
	Update(ctx context.Context, id uuid.UUID, input *UpdateUserInput) (*User, error)
	UpdateLastLogin(ctx context.Context, id uuid.UUID) error
	// RecordFailedLogin increments the consecutive-failure counter and, once it
	// reaches maxAttempts, sets locked_until to now()+lockFor.
	RecordFailedLogin(ctx context.Context, id uuid.UUID, maxAttempts int, lockFor time.Duration) error
	// ResetFailedLogins clears the failure counter and any lock (called on a
	// successful login).
	ResetFailedLogins(ctx context.Context, id uuid.UUID) error
	Delete(ctx context.Context, id uuid.UUID) error
	List(ctx context.Context, limit, offset int) ([]*User, error)
	Count(ctx context.Context) (int, error)
}

Repository defines the interface for user data operations.

Path B PR 2b/3: List and Count no longer take a tenantID — there is only one tenant. The signature change forces callers off the legacy code path rather than silently ignoring the argument.

type Role

type Role string

Role is a user's role: owner (everything) or editor (content).

const (
	RoleOwner  Role = "owner"
	RoleEditor Role = "editor"
)

Available user roles.

func ParseRole

func ParseRole(s string) (Role, error)

ParseRole parses a string into a Role.

type UpdateUserInput

type UpdateUserInput struct {
	Name      *string
	AvatarURL *string
	Role      *Role
}

UpdateUserInput represents input for updating a user.

type User

type User struct {
	ID           uuid.UUID  `json:"id"`
	Email        string     `json:"email"`
	PasswordHash string     `json:"-"` // Never expose
	Role         Role       `json:"role"`
	Name         *string    `json:"name,omitempty"`
	AvatarURL    *string    `json:"avatar_url,omitempty"`
	LastLoginAt  *time.Time `json:"last_login_at,omitempty"`
	// Login-lockout state (migration 004). Never serialized to clients.
	FailedLoginAttempts int        `json:"-"`
	LockedUntil         *time.Time `json:"-"`
	CreatedAt           time.Time  `json:"created_at"`
	UpdatedAt           time.Time  `json:"updated_at"`
}

User represents a tenant user.

Jump to

Keyboard shortcuts

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