auth

package
v2.8.1 Latest Latest
Warning

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

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

Documentation

Overview

Package auth owns authentication, token issuance and verification, login session policy, and the authentication HTTP surface.

Index

Constants

View Source
const (
	ErrInvalidCredentials = errors.Sentinel("invalid credentials")
	ErrLocalAuthDisabled  = errors.Sentinel("local authentication is disabled")
	ErrOidcAuthDisabled   = errors.Sentinel("OIDC authentication is disabled")
	ErrMFARequired        = errors.Sentinel("multi-factor authentication is required")
)

Variables

This section is empty.

Functions

func AgentTokenMatches

func AgentTokenMatches(presented, configured string) bool

AgentTokenMatches compares a presented token against the configured agent token in constant time to avoid timing side channels.

func ClampFederatedTokenTTLSeconds

func ClampFederatedTokenTTLSeconds(ttlSeconds int) int

ClampFederatedTokenTTLSeconds bounds a requested federated-token lifetime to the range Arcane will mint.

func NewHumaMiddleware

func NewHumaMiddleware(api huma.API, authService *AuthService, apiKeyService *apikey.ApiKeyService, permResolver PermissionResolver, envTokenResolver EnvironmentAccessTokenResolver, cfg *config.Config) func(ctx huma.Context, next func(huma.Context))

NewHumaMiddleware creates middleware that validates credentials and enforces security requirements defined on operations. It also resolves the caller's effective PermissionSet via permResolver and stashes it on the request context for downstream middleware.RequirePermission checks.

func RegisterAuth

func RegisterAuth(api huma.API, userService *user.UserService, authService *AuthService, settingsService *settings.SettingsService, beginMFAAuthentication func(context.Context, string, authtypes.SessionMeta, string) (*authtypes.MFAChallenge, error))

RegisterAuth registers authentication routes using Huma.

Types

type ApiKeyValidator

type ApiKeyValidator interface {
	ValidateApiKeyWithID(ctx context.Context, rawKey string) (*common.User, *apikey.ApiKey, error)
}

type AuthHandler

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

func (*AuthHandler) ChangePassword

func (h *AuthHandler) ChangePassword(ctx context.Context, input *ChangePasswordInput) (*ChangePasswordOutput, error)

ChangePassword changes the current user's password.

func (*AuthHandler) DeleteMyAvatar

func (h *AuthHandler) DeleteMyAvatar(ctx context.Context, input *struct{}) (*DeleteMyAvatarOutput, error)

DeleteMyAvatar removes the current user's custom profile picture.

func (*AuthHandler) GetCurrentUser

func (h *AuthHandler) GetCurrentUser(ctx context.Context, input *struct{}) (*GetCurrentUserOutput, error)

GetCurrentUser returns the currently authenticated user's information. Uses ToUserResponseDto (not the generic struct mapper) so the RBAC fields (RoleAssignments, PermissionsByEnv) are resolved via RoleService.

func (*AuthHandler) Login

func (h *AuthHandler) Login(ctx context.Context, input *LoginInput) (*LoginOutput, error)

Login authenticates a user and returns tokens.

func (*AuthHandler) Logout

func (h *AuthHandler) Logout(ctx context.Context, input *struct{}) (*LogoutOutput, error)

Logout clears the authentication session.

func (*AuthHandler) LogoutAllOtherSessions

func (h *AuthHandler) LogoutAllOtherSessions(ctx context.Context, input *struct{}) (*LogoutAllOtherSessionsOutput, error)

LogoutAllOtherSessions revokes every active session for the current user except the session making this request.

func (*AuthHandler) RefreshToken

func (h *AuthHandler) RefreshToken(ctx context.Context, input *RefreshTokenInput) (*RefreshTokenOutput, error)

RefreshToken obtains a new access token using a refresh token.

func (*AuthHandler) UpdateMyProfile

func (h *AuthHandler) UpdateMyProfile(ctx context.Context, input *UpdateMyProfileInput) (*UpdateMyProfileOutput, error)

UpdateMyProfile lets the current user update their own displayName and email. OIDC-managed accounts are read-only here.

func (*AuthHandler) UploadMyAvatar

func (h *AuthHandler) UploadMyAvatar(ctx context.Context, input *UploadMyAvatarInput) (*UploadMyAvatarOutput, error)

UploadMyAvatar lets the current user upload a custom profile picture. Accepts PNG, JPEG, or WebP images up to the configured avatar upload limit.

type AuthMiddleware

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

func NewAuthMiddleware

func NewAuthMiddleware(authService *AuthService, cfg *config.Config) *AuthMiddleware

func (*AuthMiddleware) Add

func (*AuthMiddleware) WithAdminNotRequired

func (m *AuthMiddleware) WithAdminNotRequired() *AuthMiddleware

func (*AuthMiddleware) WithAdminRequired

func (m *AuthMiddleware) WithAdminRequired() *AuthMiddleware

func (*AuthMiddleware) WithApiKeyValidator

func (m *AuthMiddleware) WithApiKeyValidator(validator ApiKeyValidator) *AuthMiddleware

func (*AuthMiddleware) WithEnvironmentAccessTokenResolver

func (m *AuthMiddleware) WithEnvironmentAccessTokenResolver(resolver EnvironmentAccessTokenResolver) *AuthMiddleware

func (*AuthMiddleware) WithPermissionResolver

func (m *AuthMiddleware) WithPermissionResolver(resolver PermissionResolver) *AuthMiddleware

type AuthOptions

type AuthOptions struct {
	AdminRequired   bool
	SuccessOptional bool
}

type AuthService

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

func NewAuthService

func NewAuthService(userService *user.UserService, settingsService *settings.SettingsService, eventService *event.EventService, sessionService *session.SessionService, roleService *role.RoleService, jwtSecret string, cfg *config.Config, errorHandler emperror.ErrorHandler) *AuthService

func (*AuthService) AuthenticateLocalPrimary

func (s *AuthService) AuthenticateLocalPrimary(ctx context.Context, username, password string) (*common.User, error)

AuthenticateLocalPrimary validates the local primary factor without creating a session. Callers must complete passkey MFA, when enabled, before issuing a bearer or refresh token.

func (*AuthService) ChangePassword

func (s *AuthService) ChangePassword(ctx context.Context, userID, currentPassword, newPassword, currentSessionID string) error

func (*AuthService) CompleteLogin

func (s *AuthService) CompleteLogin(ctx context.Context, user *common.User, meta auth.SessionMeta, source, mfaMethod string, eventMetadata ...database.JSON) (*TokenPair, error)

CompleteLogin creates the authenticated session after all required factors have succeeded. Source is server-selected and is persisted with the session.

func (*AuthService) GetOidcConfig

func (s *AuthService) GetOidcConfig(ctx context.Context) (*settings.OidcConfig, error)

func (*AuthService) GetOidcConfigurationStatus

func (s *AuthService) GetOidcConfigurationStatus(ctx context.Context) (*auth.OidcStatusInfo, error)

func (*AuthService) GetSessionTimeout

func (s *AuthService) GetSessionTimeout(ctx context.Context) (int, error)

func (*AuthService) InvalidateUserTokenCache

func (s *AuthService) InvalidateUserTokenCache(userID string)

InvalidateUserTokenCache purges all cached token verifications for a user. Call this after admin-initiated role changes, account disable, or user deletion so stale verifications cannot grant access for the cache TTL.

func (*AuthService) IsLocalAuthEnabled

func (s *AuthService) IsLocalAuthEnabled(ctx context.Context) (bool, error)

func (*AuthService) IsOidcEnabled

func (s *AuthService) IsOidcEnabled(ctx context.Context) (bool, error)

func (*AuthService) IssueFederatedToken

func (s *AuthService) IssueFederatedToken(ctx context.Context, user *common.User, credentialID string, ttlSeconds int) (*TokenPair, error)

func (*AuthService) LogLogout

func (s *AuthService) LogLogout(ctx context.Context, user *common.User)

func (*AuthService) Login

func (s *AuthService) Login(ctx context.Context, username, password string, meta auth.SessionMeta) (*common.User, *TokenPair, error)

func (*AuthService) LogoutAllOtherSessions

func (s *AuthService) LogoutAllOtherSessions(ctx context.Context, userID, currentSessionID string) error

LogoutAllOtherSessions revokes every active session for userID except currentSessionID, so the caller stays signed in on their current device.

func (*AuthService) OidcLogin

func (s *AuthService) OidcLogin(ctx context.Context, userInfo auth.OidcUserInfo, tokenResp *auth.OidcTokenResponse, meta auth.SessionMeta) (*common.User, *TokenPair, error)

func (*AuthService) PrepareOidcLogin

func (s *AuthService) PrepareOidcLogin(ctx context.Context, userInfo auth.OidcUserInfo, tokenResp *auth.OidcTokenResponse) (*common.User, bool, error)

PrepareOidcLogin reconciles the provider identity without creating a session. The caller must complete passkey MFA, when enabled, before issuing tokens.

func (*AuthService) RefreshToken

func (s *AuthService) RefreshToken(ctx context.Context, refreshToken string, meta auth.SessionMeta) (*TokenPair, error)

func (*AuthService) RevokeSession

func (s *AuthService) RevokeSession(ctx context.Context, sessionID string) error

func (*AuthService) VerifyToken

func (s *AuthService) VerifyToken(ctx context.Context, accessToken string) (*common.User, string, error)

type AuthSettings

type AuthSettings struct {
	LocalAuthEnabled bool                 `json:"localAuthEnabled"`
	OidcEnabled      bool                 `json:"oidcEnabled"`
	SessionTimeout   int                  `json:"sessionTimeout"`
	Oidc             *settings.OidcConfig `json:"oidc,omitempty"`
}

type ChangePasswordInput

type ChangePasswordInput struct {
	Body authtypes.PasswordChange
}

type ChangePasswordOutput

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

type DeleteMyAvatarOutput

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

type Dependencies

type Dependencies struct {
	Service                *AuthService
	User                   *user.UserService
	Settings               *settings.SettingsService
	BeginMFAAuthentication func(context.Context, string, authtypes.SessionMeta, string) (*authtypes.MFAChallenge, error)
}

type EnvironmentAccessTokenResolver

type EnvironmentAccessTokenResolver interface {
	ResolveEnvironmentByAccessToken(ctx context.Context, token string) (*environment.Environment, error)
}

type GetCurrentUserOutput

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

type LoginInput

type LoginInput struct {
	UserAgent string `header:"User-Agent"`
	Body      authtypes.Login
}

type LoginOutput

type LoginOutput struct {
	SetCookie []string `header:"Set-Cookie" doc:"Session cookie"`
	Body      base.ApiResponse[authtypes.AuthenticationResponse]
}

type LogoutAllOtherSessionsOutput

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

type LogoutOutput

type LogoutOutput struct {
	SetCookie []string `header:"Set-Cookie" doc:"Cleared session cookie"`
	Body      base.ApiResponse[base.MessageResponse]
}

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() *AuthService

type PermissionResolver

type PermissionResolver interface {
	ResolvePermissions(ctx context.Context, user *common.User) (*authz.PermissionSet, error)
	ResolveApiKeyPermissions(ctx context.Context, apiKeyID string) (*authz.PermissionSet, error)
}

PermissionResolver resolves a caller's effective permission set. Implemented by role.RoleService; kept as an interface so tests can stub it.

type RefreshTokenInput

type RefreshTokenInput struct {
	UserAgent string `header:"User-Agent"`
	Body      authtypes.Refresh
}

type RefreshTokenOutput

type RefreshTokenOutput struct {
	SetCookie []string `header:"Set-Cookie" doc:"Updated session cookie"`
	Body      base.ApiResponse[authtypes.TokenRefreshResponse]
}

type TokenPair

type TokenPair struct {
	AccessToken  string    `json:"accessToken"`
	RefreshToken string    `json:"refreshToken"`
	ExpiresAt    time.Time `json:"expiresAt"`
}

type UpdateMyProfileBody

type UpdateMyProfileBody struct {
	DisplayName *string                `json:"displayName,omitempty"`
	Email       *string                `json:"email,omitempty"`
	Locale      *string                `json:"locale,omitempty"`
	TimeFormat  *usertypes.TimeFormat  `json:"timeFormat,omitempty" enum:"auto,12h,24h"`
	FontSize    *int                   `json:"fontSize,omitempty" minimum:"12" maximum:"20"`
	Preferences *usertypes.Preferences `json:"preferences,omitempty"`
}

type UpdateMyProfileInput

type UpdateMyProfileInput struct {
	Body UpdateMyProfileBody
}

type UpdateMyProfileOutput

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

type UploadMyAvatarInput

type UploadMyAvatarInput struct {
	RawBody multipart.Form `contentType:"multipart/form-data"`
}

type UploadMyAvatarOutput

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

Jump to

Keyboard shortcuts

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