auth

package
v0.10.524 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package auth implements local username/password auth + JWT issuing for the Coremetry HTTP API. It deliberately avoids external session storage — JWTs are stateless and self-contained.

Index

Constants

View Source
const (
	// RoleAdmin can do everything (user mgmt, settings, all CRUD).
	// RoleEditor can create/edit content (dashboards, monitors,
	//            alert rules, incidents) but not user mgmt or system
	//            settings.
	// RoleViewer is read-only.
	RoleAdmin  = "admin"
	RoleEditor = "editor"
	RoleViewer = "viewer"

	// CookieName is set on login and cleared on logout. It must be the
	// same on the frontend (login fetch uses credentials: 'include').
	CookieName = "coremetry_session"
)

Variables

This section is empty.

Functions

func CheckPassword

func CheckPassword(hash, plain string) bool

CheckPassword is the constant-time bcrypt compare.

func ContextWithClaims added in v0.10.430

func ContextWithClaims(ctx context.Context, c *Claims) context.Context

ContextWithClaims — v0.10.430: Middleware'in yaptığı iliştirmenin dışa açık hâli; kimliğe bağlı yolları (audit satırı, rol kapısı) middleware kurmadan DAVRANIŞLA test etmek için. Üretim yolu Middleware'dir.

func HashPassword

func HashPassword(plain string) (string, error)

HashPassword wraps bcrypt with the default cost.

func IsAPIToken added in v0.8.444

func IsAPIToken(v string) bool

IsAPIToken — Bearer değerinin servis token'ı olup olmadığı.

func IsValidRole

func IsValidRole(s string) bool

IsValidRole reports whether s is one of the canonical role strings. Used by handlers that accept a role from outside (admin upserting users, LDAP group→role mapping).

func PKCEChallenge

func PKCEChallenge(verifier string) string

PKCEChallenge returns base64url(SHA256(verifier)) — the S256 method from RFC 7636.

func RandomURLToken

func RandomURLToken(nBytes int) string

RandomURLToken returns a base64url-encoded random string of nBytes entropy — used for state, nonce, and PKCE code_verifier.

func RequireAnyRole

func RequireAnyRole(roles []string, h http.HandlerFunc) http.HandlerFunc

RequireAnyRole accepts any of the listed roles. Used for routes that should be open to admin and editor (dashboard/monitor CRUD etc.) — admin-only routes still use RequireRole for clarity.

func RequireRole

func RequireRole(role string, h http.HandlerFunc) http.HandlerFunc

RequireRole gates a handler on a specific role (typically "admin").

func SkipPath

func SkipPath(method, path string) bool

SkipPath reports whether a path should bypass authentication. OTLP ingest endpoints stay open so SDKs without auth headers continue to work; health is open for liveness probes; auth/login + OIDC routes are the entry points so they cannot themselves require auth.

func WeakSecretReason added in v0.10.4

func WeakSecretReason(secret string) string

WeakSecretReason — anahtar zayıfsa SEBEBİNİ döndürür, değilse "".

Dönüş bir SEBEP dizgesi, bool değil: çağıran onu operatöre gösteriyor ve "zayıf" demek tek başına ne yapılacağını söylemiyor.

⚠ ANAHTARIN KENDİSİ ASLA döndürülmüyor, loglanmıyor, API'ye yazılmıyor. Zayıf bir anahtarı teşhis etmek onu yaymak için gerekçe değil; sebep dizgesi anahtarsız tam olarak anlaşılıyor.

Types

type AuthzLookup added in v0.9.352

type AuthzLookup interface {
	LiveAuthz(ctx context.Context, userID string) (role string, ok bool, err error)
}

AuthzLookup resolves the CURRENT authorization state of a user id.

ok=false means "this user must not be let in" — deleted, or disabled. The distinction doesn't matter to the caller and deliberately isn't exposed: both end in 401, and telling them apart would leak whether an account exists.

type Claims

type Claims struct {
	UserID string `json:"uid"`
	Email  string `json:"email"`
	Role   string `json:"role"`
	jwt.RegisteredClaims
}

Claims is the payload embedded in every JWT.

func FromContext

func FromContext(ctx context.Context) *Claims

FromContext returns the authenticated claims set by Middleware. Handlers behind the middleware can rely on the value being non-nil.

type CustomRole added in v0.5.251

type CustomRole struct {
	Name  string   `json:"name"`
	Pages []string `json:"pages"`
}

CustomRole is an admin-defined subset of viewer's page access. Each role names a set of sidebar paths the user is allowed to see; the frontend filters the sidebar + redirects direct-URL access to the first visible page. Custom roles only apply when the user's base role is viewer — admin/editor get no further restriction.

type LookupUser added in v0.4.90

type LookupUser struct {
	ID    string
	Email string
	Role  string
}

LookupUser is the minimal shape exchanged through UserLookup. chstore.User has more fields (password hash, created_at, etc.) that the trusted-header path doesn't touch, so the interface only requires this slice.

type OIDCClaims

type OIDCClaims struct {
	Email         string `json:"email"`
	EmailVerified bool   `json:"email_verified"`
	Subject       string `json:"-"`
	Nonce         string `json:"-"`
}

OIDCClaims is the subset of id_token claims we care about.

type OIDCService

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

OIDCService is the optional SSO layer. nil when disabled — every call site checks Enabled() before invoking other methods.

func NewOIDCService

func NewOIDCService(ctx context.Context, cfg config.OIDCConfig) (*OIDCService, error)

NewOIDCService runs OIDC discovery against the issuer. Returns (nil, nil) when disabled. Returns an error when enabled but the issuer is unreachable / misconfigured — the caller decides whether to abort startup or just log and continue with local-only auth.

func (*OIDCService) AllowEmail

func (o *OIDCService) AllowEmail(email string) bool

AllowEmail enforces the optional domain whitelist. Empty list = allow all.

func (*OIDCService) AuthURL

func (o *OIDCService) AuthURL(state, nonce, codeChallenge string) string

AuthURL builds the IdP redirect URL with PKCE + nonce + state.

func (*OIDCService) DefaultRole

func (o *OIDCService) DefaultRole() string

func (*OIDCService) DisplayName

func (o *OIDCService) DisplayName() string

func (*OIDCService) Enabled

func (o *OIDCService) Enabled() bool

Enabled is true when the service is configured. Safe on a nil receiver.

func (*OIDCService) Exchange

func (o *OIDCService) Exchange(ctx context.Context, code, codeVerifier, expectedNonce string) (*OIDCClaims, error)

Exchange completes the auth code flow: token exchange, id_token verify, nonce check, claim extraction, domain whitelist.

type Service

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

Service issues, validates and exposes JWTs.

func NewService

func NewService(secret string, ttl time.Duration) *Service

NewService is the constructor. If secret is empty a random one is generated — fine for first-run dev, but logged so operators can pin it.

func (*Service) CustomRolePages added in v0.5.251

func (s *Service) CustomRolePages(name string) []string

CustomRolePages returns the page list for a named role, or nil if the role isn't found. nil is the signal for "this user has no page restriction" — callers MUST distinguish nil (unrestricted) from empty slice (restricted to zero pages, effectively no access).

func (*Service) CustomRoles added in v0.5.251

func (s *Service) CustomRoles() []CustomRole

CustomRoles returns a snapshot copy of the current role catalog ordered by name. The caller can freely mutate the returned slice.

func (*Service) DeleteCustomRole added in v0.5.251

func (s *Service) DeleteCustomRole(ctx context.Context, store customRoleStore, name string) error

DeleteCustomRole removes a role by name. Persists the updated catalog. Caller is responsible for clearing the custom_role field on any user assigned to it (the API handler does this — see deleteCustomRole in internal/api/api.go).

func (*Service) EnableAPITokens added in v0.8.444

func (s *Service) EnableAPITokens(ctx context.Context, src TokenSource)

EnableAPITokens — boot'ta bağlar ve tazeleme döngüsünü başlatır.

func (*Service) EnableTrustedHeader added in v0.4.90

func (s *Service) EnableTrustedHeader(opts TrustedHeaderOptions, trustedProxies []string, store UserLookup) error

EnableTrustedHeader turns on oauth2-proxy / IAP header trust. trustedProxies is a list of CIDR strings (e.g. "10.0.0.0/8", "172.16.0.0/12") — the headers are honoured only when the request originates from one of these blocks. An empty list is a config error: it'd let any caller spoof the email header. Returns an error in that case so main.go can fail fast at boot instead of silently leaving the door open.

func (*Service) InvalidateAuthz added in v0.9.352

func (s *Service) InvalidateAuthz(userID string)

InvalidateAuthz forgets a user's cached role. Every user mutation calls it.

func (*Service) Issue

func (s *Service) Issue(userID, email, role string) (string, time.Time, error)

Issue signs a JWT for the given identity.

func (*Service) LoadPersistedCustomRoles added in v0.5.251

func (s *Service) LoadPersistedCustomRoles(ctx context.Context, store customRoleStore) error

LoadPersistedCustomRoles hydrates the in-memory custom-role catalog from system_settings. Missing blob = empty catalog. Called once at boot from main(); safe to call again on demand.

func (*Service) Middleware

func (s *Service) Middleware(next http.Handler) http.Handler

Middleware enforces a valid JWT (cookie or Bearer) for every protected endpoint. Failures return 401 with a JSON error so the SPA can redirect.

Trusted-header fallback: when EnableTrustedHeader was called at boot AND the JWT path fails AND the request originates from a configured trusted-proxy CIDR, the email header is honoured. The middleware looks up (or auto-provisions, if enabled) a user and mints a JWT cookie inline so the rest of the SPA's stateful flow keeps working.

func (*Service) Parse

func (s *Service) Parse(token string) (*Claims, error)

Parse validates a JWT and returns its claims.

func (*Service) RefreshAPITokens added in v0.8.444

func (s *Service) RefreshAPITokens(ctx context.Context)

RefreshAPITokens — cache'i kaynaktan yeniler; create/revoke sonrası API handler'ı da çağırır (anında etki).

func (*Service) SetAuthzLookup added in v0.9.352

func (s *Service) SetAuthzLookup(l AuthzLookup)

SetAuthzLookup wires the live resolver. Called once from main(); when it is never called the middleware keeps the pre-v0.9.352 behaviour (trust the token), so tests and dev builds are unaffected.

func (*Service) StartCustomRoleRefresh added in v0.5.318

func (s *Service) StartCustomRoleRefresh(ctx context.Context, store customRoleStore, interval time.Duration)

StartCustomRoleRefresh — v0.5.318. Runs a background goroutine that re-reads the custom-role catalog from the shared chstore every `interval` (default 30s when ≤0). In a multi-pod cluster the previous load-once-at-boot pattern meant a role created on pod A wasn't visible to a session served by pod B until B's process restarted. Polling closes that gap to a bounded staleness window without requiring pub/sub infrastructure.

Returns when ctx is cancelled. Errors are logged but never fatal — a transient CH blip leaves the previous catalog in place rather than clearing it.

func (*Service) TTL

func (s *Service) TTL() time.Duration

TTL returns the configured token lifetime — needed for cookie MaxAge.

func (*Service) UpsertCustomRole added in v0.5.251

func (s *Service) UpsertCustomRole(ctx context.Context, store customRoleStore, role CustomRole) error

UpsertCustomRole writes a single role (create or replace by name). Persists the updated catalog atomically — partial writes don't occur because the whole catalog is one system_settings blob.

type TokenInfo added in v0.8.444

type TokenInfo struct {
	ID   string
	Name string
	Role string
}

TokenInfo — cache'teki tek kayıt (chstore.APIToken'ın auth dilimi; import döngüsü olmasın diye kendi tipi).

type TokenSource added in v0.8.444

type TokenSource interface {
	ActiveHashes(ctx context.Context) (map[string]TokenInfo, error)
}

TokenSource — chstore'un ihtiyaç duyulan dilimi.

type TrustedHeaderOptions added in v0.4.90

type TrustedHeaderOptions struct {
	Enabled       bool
	EmailHeader   string
	UserHeader    string
	GroupsHeader  string
	AutoProvision bool
	DefaultRole   string
}

TrustedHeaderOptions is the auth.Service-side mirror of the config.TrustedHeaderConfig. Kept separate so the auth package stays free of the internal/config import cycle.

type UserLookup added in v0.4.90

type UserLookup interface {
	GetUserByEmail(ctx context.Context, email string) (*LookupUser, error)
	UpsertUser(ctx context.Context, u LookupUser) error
}

UserLookup is the small store interface the trusted-header path needs — find an existing user by email, or upsert a new row when AutoProvision is on. Implemented by *chstore.Store (the API layer wires it in main.go).

Jump to

Keyboard shortcuts

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