user

package
v2.8.0 Latest Latest
Warning

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

Go to latest
Published: Aug 13, 2026 License: BSD-3-Clause Imports: 27 Imported by: 0

Documentation

Overview

Package user owns user persistence, password hashing, authorization guards, and the user HTTP surface.

Index

Constants

View Source
const (
	ErrCannotRemoveLastAdmin = errors.Sentinel("cannot remove the last admin user")

	// ErrInsufficientPrivilege is returned when a caller attempts to modify a
	// target whose effective privilege is equal to or higher than the caller's
	// (e.g. a delegated users:update holder trying to edit a global admin).
	ErrInsufficientPrivilege = errors.Sentinel("insufficient privilege to modify this user")
)

Variables

This section is empty.

Functions

func NormalizeOptionalEmail

func NormalizeOptionalEmail(email *string) (*string, error)

func RegisterUsers

func RegisterUsers(api huma.API, userService *UserService, invalidateUserTokenCache func(string), settingsService *settings.SettingsService)

RegisterUsers registers all user management endpoints.

Types

type Argon2Params

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

func DefaultArgon2Params

func DefaultArgon2Params() *Argon2Params

type CreateUserInput

type CreateUserInput struct {
	Body usertypes.CreateUser
}

type CreateUserOutput

type CreateUserOutput struct {
	Body base.ApiResponse[usertypes.User]
}

type DeleteUserInput

type DeleteUserInput struct {
	UserID string `path:"userId" doc:"User ID"`
}

type DeleteUserOutput

type DeleteUserOutput struct {
	Body base.ApiResponse[base.MessageResponse]
}

type Dependencies

type Dependencies struct {
	Service                  *UserService
	InvalidateUserTokenCache func(string)
	Settings                 *settings.SettingsService
}

type GetUserAvatarInput

type GetUserAvatarInput struct {
	UserID string `path:"userId" doc:"User ID"`
}

type GetUserAvatarOutput

type GetUserAvatarOutput struct {
	ContentType         string `header:"Content-Type"`
	CacheControl        string `header:"Cache-Control"`
	XContentTypeOptions string `header:"X-Content-Type-Options"`
	Body                []byte
}

type GetUserInput

type GetUserInput struct {
	UserID string `path:"userId" doc:"User ID"`
}

type GetUserOutput

type GetUserOutput struct {
	Body base.ApiResponse[usertypes.User]
}

type ListUsersInput

type ListUsersInput struct {
	Search string `query:"search" doc:"Search query"`
	Sort   string `query:"sort" doc:"Column to sort by"`
	Order  string `query:"order" default:"asc" doc:"Sort direction"`
	Start  int    `query:"start" default:"0" doc:"Start index"`
	Limit  int    `query:"limit" default:"20" doc:"Items per page"`
}

type ListUsersOutput

type ListUsersOutput struct {
	Body base.Paginated[usertypes.User]
}

type Module

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

func New

func New(deps Dependencies) *Module

func (*Module) RegisterRoutes

func (m *Module) RegisterRoutes(api huma.API)

func (*Module) Service

func (m *Module) Service() *UserService

type UpdateUserInput

type UpdateUserInput struct {
	UserID string `path:"userId" doc:"User ID"`
	Body   usertypes.UpdateUser
}

type UpdateUserOutput

type UpdateUserOutput struct {
	Body base.ApiResponse[usertypes.User]
}

type UserHandler

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

UserHandler handles user management endpoints.

func (*UserHandler) CreateUser

func (h *UserHandler) CreateUser(ctx context.Context, input *CreateUserInput) (*CreateUserOutput, error)

CreateUser creates a new usertypes.

func (*UserHandler) DeleteUser

func (h *UserHandler) DeleteUser(ctx context.Context, input *DeleteUserInput) (*DeleteUserOutput, error)

DeleteUser deletes a usertypes.

func (*UserHandler) GetUser

func (h *UserHandler) GetUser(ctx context.Context, input *GetUserInput) (*GetUserOutput, error)

GetUser returns a user by ID.

func (*UserHandler) GetUserAvatar

func (h *UserHandler) GetUserAvatar(ctx context.Context, input *GetUserAvatarInput) (*GetUserAvatarOutput, error)

GetUserAvatar returns the custom profile picture for a usertypes.

func (*UserHandler) ListUsers

func (h *UserHandler) ListUsers(ctx context.Context, input *ListUsersInput) (*ListUsersOutput, error)

ListUsers returns a paginated list of users.

func (*UserHandler) UpdateUser

func (h *UserHandler) UpdateUser(ctx context.Context, input *UpdateUserInput) (*UpdateUserOutput, error)

UpdateUser updates a usertypes.

type UserService

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

func NewUserService

func NewUserService(db *database.DB) *UserService

func (*UserService) AttachOidcSubjectTransactional

func (s *UserService) AttachOidcSubjectTransactional(ctx context.Context, userID string, subject string, updateFn func(u *models.User)) (*models.User, error)

AttachOidcSubjectTransactional safely links an OIDC subject to the given user inside a DB transaction. It uses a row lock (FOR UPDATE) to prevent concurrent merges from racing and validates that the user isn't already linked to a different subject. The provided updateFn can mutate the user (e.g., roles, display name, tokens, last login) before persisting.

Note: The clause.Locking{Strength: "UPDATE"} statement is used to acquire a row-level lock. This MUST be done inside a transaction to ensure the lock is held until the update is committed.

func (*UserService) CreateDefaultAdmin

func (s *UserService) CreateDefaultAdmin(ctx context.Context) error

func (*UserService) CreateUser

func (s *UserService) CreateUser(ctx context.Context, user *models.User) (*models.User, error)

func (*UserService) DeleteAvatar

func (s *UserService) DeleteAvatar(ctx context.Context, userID string) error

DeleteAvatar removes the avatar for a user.

func (*UserService) DeleteUser

func (s *UserService) DeleteUser(ctx context.Context, id string, actorPerms *authz.PermissionSet) error

DeleteUser removes the user with the given id. actorPerms identifies the caller performing the deletion; authenticated global-admin callers must also be present in ctx. Pass nil for internal service-to-service calls. A non-admin caller may not delete a global admin target.

func (*UserService) GetAvatar

func (s *UserService) GetAvatar(ctx context.Context, userID string) ([]byte, string, error)

GetAvatar returns the raw avatar data and MIME type for a user. Returns (nil, "", nil) when the user has no custom avatar.

func (*UserService) GetUser

func (s *UserService) GetUser(ctx context.Context, userID string) (*models.User, error)

func (*UserService) GetUserByEmail

func (s *UserService) GetUserByEmail(ctx context.Context, email string) (*models.User, error)

GetUserByEmail returns the user with the given email. The schema does not enforce email uniqueness, so a lookup matching more than one account returns common.ErrAmbiguousUserEmail instead of arbitrarily selecting one.

func (*UserService) GetUserByID

func (s *UserService) GetUserByID(ctx context.Context, id string) (*models.User, error)

func (*UserService) GetUserByOidcSubjectId

func (s *UserService) GetUserByOidcSubjectId(ctx context.Context, subjectId string) (*models.User, error)

func (*UserService) GetUserByUsername

func (s *UserService) GetUserByUsername(ctx context.Context, username string) (*models.User, error)

func (*UserService) HashPassword

func (s *UserService) HashPassword(password string) (string, error)

func (*UserService) ListUsersPaginated

func (s *UserService) ListUsersPaginated(ctx context.Context, params pagination.QueryParams) ([]user.User, pagination.Response, error)

func (*UserService) ResolveUserPermissions

func (s *UserService) ResolveUserPermissions(ctx context.Context, userID string) (*authz.PermissionSet, error)

ResolveUserPermissions returns the effective PermissionSet for the given user ID, or nil when no role.RoleService is wired (RBAC disabled paths).

func (*UserService) SetPassword

func (s *UserService) SetPassword(ctx context.Context, user *models.User, password string) (*models.User, error)

SetPassword hashes and persists a new password for the given user and clears the first-login password-change requirement for trusted internal callers.

func (*UserService) SetPasswordAndRevokeSessionsExcept

func (s *UserService) SetPasswordAndRevokeSessionsExcept(ctx context.Context, user *models.User, password, exceptSessionID string) (*models.User, error)

SetPasswordAndRevokeSessionsExcept atomically sets a new password, clears the first-login password-change requirement, and revokes every session for the user except exceptSessionID. Pass an empty exceptSessionID to revoke all sessions. This is for trusted internal callers.

func (*UserService) ToUserResponseDto

func (s *UserService) ToUserResponseDto(ctx context.Context, u models.User) (user.User, error)

func (*UserService) UpdateUser

func (s *UserService) UpdateUser(ctx context.Context, user *models.User, actorPerms *authz.PermissionSet) (*models.User, error)

UpdateUser persists the given user. actorPerms identifies the caller performing the change; authenticated global-admin callers must also be present in ctx. Pass nil for internal service-to-service calls.

func (*UserService) UploadAvatar

func (s *UserService) UploadAvatar(ctx context.Context, userID string, data []byte, mimeType string) error

UploadAvatar stores avatar bytes for a user, replacing any existing avatar.

func (*UserService) ValidatePassword

func (s *UserService) ValidatePassword(encodedHash, password string) error

func (*UserService) WithRoleService

func (s *UserService) WithRoleService(roleService *role.RoleService) *UserService

WithRoleService wires the role.RoleService dependency. Separated from the constructor so the bootstrap can construct UserService first (role.RoleService itself has no UserService dependency).

Jump to

Keyboard shortcuts

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