Documentation
¶
Index ¶
- Constants
- func CheckPassword(password, hash string) bool
- func HashPassword(password string) (string, error)
- func LoadUser(ctx context.Context, db bun.IDB, opts LoadUserOptions) (*models.User, error)
- func RegisterRoutes(e *echo.Group, authService *Service, demoMode bool, pdfRenderKey string)
- func RequireLibraryAccessFor(c echo.Context, libraryID int) error
- func RequireUser(c echo.Context) (*models.User, error)
- func SessionCookieName(namespace string) string
- func SetUser(c echo.Context, user *models.User)
- type JWTClaims
- type LoadUserOptions
- type LoginPayload
- type MeResponse
- type Middleware
- func (m *Middleware) Authenticate(next echo.HandlerFunc) echo.HandlerFunc
- func (m *Middleware) BasicAuth(next echo.HandlerFunc) echo.HandlerFunc
- func (m *Middleware) RequireAnyPermission(permissions ...Permission) echo.MiddlewareFunc
- func (m *Middleware) RequireLibraryAccess(paramName string) echo.MiddlewareFunc
- func (m *Middleware) RequirePermission(resource, operation string) echo.MiddlewareFunc
- type Permission
- type Service
- func (s *Service) Authenticate(ctx context.Context, username, password string) (*models.User, error)
- func (s *Service) CountUsers(ctx context.Context) (int, error)
- func (s *Service) CreateFirstAdmin(ctx context.Context, username string, email *string, password string) (*models.User, error)
- func (s *Service) GenerateToken(user *models.User) (string, error)
- func (s *Service) GetUserByID(ctx context.Context, id int) (*models.User, error)
- func (s *Service) ValidateToken(tokenString string) (*JWTClaims, error)
- type ServiceOption
- type SetupPayload
- type StatusResponse
Constants ¶
const (
// BcryptCost is the cost factor for bcrypt hashing.
BcryptCost = 12
)
const (
// CookieName is the name of the session cookie without a namespace.
CookieName = "shisho_session"
)
Variables ¶
This section is empty.
Functions ¶
func CheckPassword ¶
CheckPassword compares a password with a hash.
func HashPassword ¶
HashPassword hashes a password using bcrypt.
func LoadUser ¶ added in v0.1.0
LoadUser loads one user with Role, Role.Permissions and LibraryAccess, the relations every permission and library access check reads. It is the one loader behind login, session and Basic Auth authentication, API key owners, and user administration. When no user matches it returns an error wrapping sql.ErrNoRows.
func RegisterRoutes ¶
RegisterRoutes registers all auth routes. The server builds authService, because the auth middleware every other route family uses wraps it too. pdfRenderKey is reported by GET /auth/status (see StatusResponse), and so is demoMode, which is a bool rather than the config because pkg/config imports pkg/auth.
func RequireLibraryAccessFor ¶ added in v0.1.0
RequireLibraryAccessFor checks that the context's user can access libraryID. It returns 401 when there is no user and 403 when the user lacks access. Use it when the library ID comes from a loaded entity rather than a route param (for a param, mount RequireLibraryAccess instead).
func RequireUser ¶ added in v0.1.0
RequireUser returns the user an authenticating middleware stored in the context, or a 401 when there is none. Handlers call it instead of reading the context themselves, so a route registered without its middleware fails closed rather than skipping the checks that need a user.
func SessionCookieName ¶ added in v0.2.0
SessionCookieName returns the session cookie name for a cookie namespace. Browsers scope cookies by host but not port, so development worktrees on one host each set a namespace to keep their sessions apart.
Types ¶
type JWTClaims ¶
type JWTClaims struct {
UserID int `json:"user_id"`
Username string `json:"username"`
jwt.RegisteredClaims
}
JWTClaims represents the claims in a JWT token.
type LoadUserOptions ¶ added in v0.1.0
type LoadUserOptions struct {
ID *int
// Username matches case-insensitively.
Username *string
// IncludeInactive also returns a deactivated user. Every authenticating
// path leaves it false; user administration sets it.
IncludeInactive bool
}
LoadUserOptions selects the user LoadUser loads. Set exactly one of ID and Username.
type LoginPayload ¶
type LoginPayload struct {
Username string `json:"username" validate:"required,min=3,max=50"`
Password string `json:"password" validate:"required,min=8"`
}
LoginPayload represents the login request body.
type MeResponse ¶
type MeResponse struct {
ID int `json:"id"`
Username string `json:"username"`
Email *string `json:"email,omitempty"`
RoleID int `json:"role_id"`
RoleName string `json:"role_name"`
Permissions []string `json:"permissions"`
LibraryAccess *[]int `json:"library_access"` // nil = all libraries, empty = none, populated = specific libraries
MustChangePassword bool `json:"must_change_password"`
}
MeResponse represents the current user response.
type Middleware ¶
type Middleware struct {
// contains filtered or unexported fields
}
Middleware provides authentication middleware.
func NewMiddleware ¶
func NewMiddleware(authService *Service) *Middleware
NewMiddleware creates a new auth middleware.
func (*Middleware) Authenticate ¶
func (m *Middleware) Authenticate(next echo.HandlerFunc) echo.HandlerFunc
Authenticate extracts and validates the JWT from the cookie. If valid, it verifies the user is still active and adds user info to the context. If not authenticated, it returns 401.
func (*Middleware) BasicAuth ¶
func (m *Middleware) BasicAuth(next echo.HandlerFunc) echo.HandlerFunc
BasicAuth provides HTTP Basic Auth for OPDS endpoints.
func (*Middleware) RequireAnyPermission ¶ added in v0.1.0
func (m *Middleware) RequireAnyPermission(permissions ...Permission) echo.MiddlewareFunc
RequireAnyPermission returns middleware that allows the request when the user holds at least one of the permissions. Must be used after Authenticate middleware.
func (*Middleware) RequireLibraryAccess ¶
func (m *Middleware) RequireLibraryAccess(paramName string) echo.MiddlewareFunc
RequireLibraryAccess returns middleware that checks if the user can access the library specified by the :libraryId or :id route parameter. Must be used after Authenticate middleware.
func (*Middleware) RequirePermission ¶
func (m *Middleware) RequirePermission(resource, operation string) echo.MiddlewareFunc
RequirePermission returns middleware that checks if the user has the required permission. Must be used after Authenticate middleware.
type Permission ¶ added in v0.1.0
type Permission = errcodes.Permission
Permission names one resource and operation for RequireAnyPermission.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service handles authentication operations.
func NewService ¶
func NewService(db *bun.DB, jwtSecret string, sessionDuration time.Duration, opts ...ServiceOption) *Service
NewService creates a new auth service.
func (*Service) Authenticate ¶
func (s *Service) Authenticate(ctx context.Context, username, password string) (*models.User, error)
Authenticate validates credentials and returns the user if valid.
func (*Service) CountUsers ¶
CountUsers returns the total number of users.
func (*Service) CreateFirstAdmin ¶
func (s *Service) CreateFirstAdmin(ctx context.Context, username string, email *string, password string) (*models.User, error)
CreateFirstAdmin creates the first admin user during setup.
func (*Service) GenerateToken ¶
GenerateToken creates a new JWT token for the user.
func (*Service) GetUserByID ¶
GetUserByID retrieves an active user by ID with relations for a session. A missing or deactivated user is errcodes.UserInactive; any other failure is returned as is, so callers report it as a server fault.
type ServiceOption ¶ added in v0.2.0
type ServiceOption func(*Service)
ServiceOption configures optional Service behavior.
func WithCookieNamespace ¶ added in v0.2.0
func WithCookieNamespace(namespace string) ServiceOption
WithCookieNamespace makes the session cookie name SessionCookieName(namespace).
type SetupPayload ¶
type SetupPayload struct {
Username string `json:"username" validate:"required,min=3,max=50"`
Email *string `json:"email" validate:"omitempty,email"`
Password string `json:"password" validate:"required,min=8"`
}
SetupPayload represents the initial setup request body.
type StatusResponse ¶
type StatusResponse struct {
DemoMode bool `json:"demo_mode"`
NeedsSetup bool `json:"needs_setup"`
// PDFRenderKey identifies the PDF render settings (see
// pdfpages.RenderKey). PDF page URLs carry it so a browser does not keep
// showing pages rendered at old settings after a restart.
PDFRenderKey string `json:"pdf_render_key"`
}
StatusResponse represents the auth status response: the server-wide state the app needs before and after sign-in.