Documentation
¶
Index ¶
- Variables
- func GeneratePassphrase() string
- func GetUser(ctx context.Context) *entity.User
- func GetUserTagIDs(ctx context.Context) []string
- func SetAfterLoginRedirect(w http.ResponseWriter, r *http.Request, path string)
- func WithUser(ctx context.Context, user *entity.User, tagIDs []string) context.Context
- type Handler
- type Middleware
- func (m *Middleware) ClearSessionCookie(w http.ResponseWriter)
- func (m *Middleware) RequireAdmin(next http.Handler) http.Handler
- func (m *Middleware) RequireAuth(next http.Handler) http.Handler
- func (m *Middleware) RequireJobAccess(next http.Handler) http.Handler
- func (m *Middleware) RequireToolAccess(tools []ToolMeta) func(http.Handler) http.Handler
- func (m *Middleware) Session(next http.Handler) http.Handler
- func (m *Middleware) SetSessionCookie(w http.ResponseWriter, userID string, tagIDs []string, secure bool)
- type SecretProvider
- type Service
- func (s *Service) BootstrapAdmin(ctx context.Context, defaultPassword string, alreadyChanged bool) (generated string)
- func (s *Service) CanAccessTool(ctx context.Context, user *entity.User, toolPath string, ...) bool
- func (s *Service) FirstAdmin(ctx context.Context) (*entity.User, error)
- func (s *Service) GetUserByID(ctx context.Context, id string) (*entity.User, error)
- func (s *Service) GetUserFilterTagIDs(ctx context.Context, userID string) []string
- func (s *Service) LoginWithPassword(ctx context.Context, email, password string) (*entity.User, error)
- func (s *Service) SetEmail(ctx context.Context, userID, newEmail string) error
- func (s *Service) SetHomeView(ctx context.Context, userID, view string) error
- func (s *Service) SetPassword(ctx context.Context, userID, currentPassword, newPassword string) error
- func (s *Service) SetTheme(ctx context.Context, userID, themeID string) error
- func (s *Service) UpsertUser(ctx context.Context, email, name, avatar string) (*entity.User, error)
- type ToolMeta
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidCredentials = errors.New("invalid email or password")
Functions ¶
func GeneratePassphrase ¶ added in v0.8.9
func GeneratePassphrase() string
GeneratePassphrase returns five dash-separated CVCVC pseudo-words drawn from crypto/rand. Each word is 5 chars, total 29 chars; entropy ≈ 5 words × log2(17²·5²·17) ≈ 78 bits — plenty for an initial admin password and easier to read aloud than a bare base32 string.
Example: "tokel-bavri-zenpu-makdo-flite"
func GetUserTagIDs ¶
GetUserTagIDs retrieves the filter tag IDs for the authenticated user from context. Populated by the Session middleware from the encrypted cookie.
func SetAfterLoginRedirect ¶ added in v0.4.0
func SetAfterLoginRedirect(w http.ResponseWriter, r *http.Request, path string)
SetAfterLoginRedirect stores a path the next successful login should land on, instead of "/". Paths must start with "/" and not "//". Used by /oauth/authorize when the user isn't logged in yet.
func WithUser ¶ added in v0.4.0
WithUser stamps a user + filter-tag-ID set onto the context using the same keys the cookie-session middleware does. Useful for non-cookie auth paths (MCP bearer middleware, OAuth) that need downstream code (`login.GetUser`, `login.GetUserTagIDs`, `Service.CanAccessTool`) to behave identically.
Types ¶
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
func NewHandler ¶
func NewHandler(svc *Service, midd *Middleware, ssoSvc *sso.Service, cfg appConfig) *Handler
NewHandler wires the login routes. The handler reads SSO config from the sso.Service on every request so admin edits take effect without a restart.
type Middleware ¶
type Middleware struct {
// contains filtered or unexported fields
}
func NewMiddleware ¶
func NewMiddleware(svc *Service, secrets SecretProvider) *Middleware
func (*Middleware) ClearSessionCookie ¶
func (m *Middleware) ClearSessionCookie(w http.ResponseWriter)
ClearSessionCookie wipes the session cookie.
func (*Middleware) RequireAdmin ¶
func (m *Middleware) RequireAdmin(next http.Handler) http.Handler
RequireAdmin returns 403 if the user is not an admin.
func (*Middleware) RequireAuth ¶
func (m *Middleware) RequireAuth(next http.Handler) http.Handler
RequireAuth redirects to /auth/login if there is no authenticated, approved user.
First-login enforcement: admins land on /profile/setup until they rotate the auto-generated password (admin_password_changed=false). The setup form itself + POST endpoint are exempt so the user can actually complete the flow.
func (*Middleware) RequireJobAccess ¶
func (m *Middleware) RequireJobAccess(next http.Handler) http.Handler
RequireJobAccess enforces per-job visibility on /jobs/{key} requests. It reuses the ToolPermission table (stored under "/jobs/{key}") and CanAccessTool logic. Session + RequireAuth must have run first.
func (*Middleware) RequireToolAccess ¶
RequireToolAccess enforces per-tool visibility on requests under /tools/. For each request it finds the tool whose Path is the longest prefix of the request URL, then calls Service.CanAccessTool. Public tools let anyone through; Private tools require an approved login, plus a matching tag when the tool has required tags set. Session must have already populated the user in context.
func (*Middleware) Session ¶
func (m *Middleware) Session(next http.Handler) http.Handler
Session decrypts the AES-GCM session cookie and populates the user and their filter tag IDs into the request context. Tampered or expired cookies are wiped. For guests (no session), it reads the guest theme cookie.
func (*Middleware) SetSessionCookie ¶
func (m *Middleware) SetSessionCookie(w http.ResponseWriter, userID string, tagIDs []string, secure bool)
SetSessionCookie encrypts {userID, tagIDs} with AES-256-GCM and writes the result as an HttpOnly cookie. Callers should fetch filter tag IDs via svc.GetUserFilterTagIDs before calling this.
type SecretProvider ¶
SecretProvider is the minimal interface Middleware needs to read the current session-signing secret + first-login state. configs.Service satisfies it.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func (*Service) BootstrapAdmin ¶
func (s *Service) BootstrapAdmin(ctx context.Context, defaultPassword string, alreadyChanged bool) (generated string)
BootstrapAdmin seeds (or re-seeds) the default admin password while admin_password_changed is still false. Two cases:
- No admin yet → create one per configured admin email and set the password.
- Admin exists but flag is false → reset the password (the operator never completed first-login setup, so whatever hash is on disk is either "admin" or another stale auto-generated value the operator no longer has).
Once admin_password_changed=true, this function is a no-op so a live rotated password is never overwritten on boot.
If defaultPassword is empty, a 5-word passphrase is generated and returned so callers can surface it (logs, tray, INITIAL_CREDENTIALS file). The returned password is "" when nothing changed — either setup is already done or the explicit defaultPassword was used (and the caller already knows it from env).
func (*Service) CanAccessTool ¶
func (*Service) FirstAdmin ¶ added in v0.6.4
FirstAdmin returns the oldest admin user, or nil when no admin exists. Stdio MCP uses this to bind its synthetic context to a real admin so wick_enc_ tokens minted from MCP can be decrypted by that admin in the web UI (per-user keys are HKDF-salted with user.ID).
func (*Service) GetUserByID ¶
func (*Service) GetUserFilterTagIDs ¶
GetUserFilterTagIDs fetches the filter-type tag IDs for a user. Called at login time; the result is embedded in the encrypted session cookie so subsequent requests do not need an extra DB query for tag matching.
func (*Service) LoginWithPassword ¶
func (*Service) SetEmail ¶ added in v0.8.9
SetEmail updates the user's email address. Used by the first-login setup flow so admins can rename the seed account (admin@admin.com) to a real address. Returns ErrEmailTaken when the new email already belongs to a different user.
func (*Service) SetHomeView ¶
SetHomeView updates the user's home-grid view preference.
func (*Service) SetPassword ¶
type ToolMeta ¶
type ToolMeta struct {
Path string
DefaultVisibility entity.ToolVisibility
}
ToolMeta is the minimal info RequireToolAccess needs about each tool. Declared here so the login package doesn't import ui (avoids a cycle).