mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-07-03 08:40:14 +00:00
338 lines
17 KiB
Go
338 lines
17 KiB
Go
package model
|
|
|
|
import "os"
|
|
|
|
type RuntimeEnv int
|
|
|
|
const (
|
|
RuntimeEnvUnknown RuntimeEnv = iota
|
|
RuntimeEnvDocker
|
|
)
|
|
|
|
func DetectRuntimeEnv() RuntimeEnv {
|
|
env := os.Getenv("RUNTIME_ENV")
|
|
switch env {
|
|
case "docker":
|
|
return RuntimeEnvDocker
|
|
default:
|
|
return RuntimeEnvUnknown
|
|
}
|
|
}
|
|
|
|
// Default configuration
|
|
func NewDefaultConfiguration(runtimeEnv RuntimeEnv) *Config {
|
|
cfg := &Config{
|
|
Database: DatabaseConfig{
|
|
Driver: "sqlite",
|
|
Path: "./tinyauth.db",
|
|
},
|
|
Analytics: AnalyticsConfig{
|
|
Enabled: true,
|
|
},
|
|
Resources: ResourcesConfig{
|
|
Enabled: true,
|
|
Path: "./resources",
|
|
},
|
|
Server: ServerConfig{
|
|
Port: 3000,
|
|
Address: "0.0.0.0",
|
|
},
|
|
Auth: AuthConfig{
|
|
SubdomainsEnabled: true,
|
|
SessionExpiry: 86400, // 1 day
|
|
SessionMaxLifetime: 0, // disabled
|
|
LoginTimeout: 300, // 5 minutes
|
|
LoginMaxRetries: 3,
|
|
ACLs: ACLsConfig{
|
|
Policy: "allow",
|
|
},
|
|
LockdownEnabled: true,
|
|
},
|
|
UI: UIConfig{
|
|
Title: "Tinyauth",
|
|
ForgotPasswordMessage: "You can change your password by changing the configuration.",
|
|
BackgroundImage: "/background.jpg",
|
|
WarningsEnabled: true,
|
|
},
|
|
LDAP: LDAPConfig{
|
|
Insecure: false,
|
|
SearchFilter: "(uid=%s)",
|
|
GroupCacheTTL: 900, // 15 minutes
|
|
},
|
|
Log: LogConfig{
|
|
Level: "info",
|
|
Json: false,
|
|
Streams: LogStreams{
|
|
HTTP: LogStreamConfig{
|
|
Enabled: true,
|
|
Level: "",
|
|
},
|
|
App: LogStreamConfig{
|
|
Enabled: true,
|
|
Level: "",
|
|
},
|
|
Audit: LogStreamConfig{
|
|
Enabled: false,
|
|
Level: "",
|
|
},
|
|
},
|
|
},
|
|
OIDC: OIDCConfig{
|
|
PrivateKeyPath: "./tinyauth_oidc_key",
|
|
PublicKeyPath: "./tinyauth_oidc_key.pub",
|
|
},
|
|
Tailscale: TailscaleConfig{
|
|
Dir: "./tailscale_state",
|
|
},
|
|
LabelProvider: "auto",
|
|
}
|
|
|
|
// apply path overrides for docker runtime
|
|
if runtimeEnv == RuntimeEnvDocker {
|
|
cfg.Database.Path = "/data/tinyauth.db"
|
|
cfg.Resources.Path = "/data/resources"
|
|
cfg.OIDC.PrivateKeyPath = "/data/oidc/key.pem"
|
|
cfg.OIDC.PublicKeyPath = "/data/oidc/key.pub"
|
|
cfg.Tailscale.Dir = "/data/tailscale"
|
|
}
|
|
|
|
return cfg
|
|
}
|
|
|
|
type Config struct {
|
|
AppURL string `description:"The base URL where the app is hosted." yaml:"appUrl,omitempty"`
|
|
Database DatabaseConfig `description:"Database configuration." yaml:"database,omitempty"`
|
|
Analytics AnalyticsConfig `description:"Analytics configuration." yaml:"analytics,omitempty"`
|
|
Resources ResourcesConfig `description:"Resources configuration." yaml:"resources,omitempty"`
|
|
Server ServerConfig `description:"Server configuration." yaml:"server,omitempty"`
|
|
Auth AuthConfig `description:"Authentication configuration." yaml:"auth,omitempty"`
|
|
Apps map[string]App `description:"Application ACLs configuration." yaml:"apps,omitempty"`
|
|
OAuth OAuthConfig `description:"OAuth configuration." yaml:"oauth,omitempty"`
|
|
OIDC OIDCConfig `description:"OIDC configuration." yaml:"oidc,omitempty"`
|
|
UI UIConfig `description:"UI customization." yaml:"ui,omitempty"`
|
|
LDAP LDAPConfig `description:"LDAP configuration." yaml:"ldap,omitempty"`
|
|
// Experimental ExperimentalConfig `description:"Experimental features, use with caution." yaml:"experimental,omitempty"`
|
|
LabelProvider string `description:"Label provider to use for ACLs (auto, docker, kubernetes or none to disable). auto detects the environment." yaml:"labelProvider,omitempty"`
|
|
Log LogConfig `description:"Logging configuration." yaml:"log,omitempty"`
|
|
Tailscale TailscaleConfig `description:"Tailscale configuration." yaml:"tailscale,omitempty"`
|
|
ConfigFile string `description:"Path to config file." yaml:"-"`
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Driver string `description:"The database driver to use. Valid values: sqlite, postgres, memory." yaml:"driver,omitempty"`
|
|
Path string `description:"The path to the SQLite database file, or connection URL when driver is postgres." yaml:"path,omitempty"`
|
|
}
|
|
|
|
type AnalyticsConfig struct {
|
|
Enabled bool `description:"Enable periodic version information collection." yaml:"enabled,omitempty"`
|
|
}
|
|
|
|
type ResourcesConfig struct {
|
|
Enabled bool `description:"Enable the resources server." yaml:"enabled,omitempty"`
|
|
Path string `description:"The directory where resources are stored." yaml:"path,omitempty"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Port int `description:"The port on which the server listens." yaml:"port,omitempty"`
|
|
Address string `description:"The address on which the server listens." yaml:"address,omitempty"`
|
|
SocketPath string `description:"The path to the Unix socket." yaml:"socketPath,omitempty"`
|
|
}
|
|
|
|
type AuthConfig struct {
|
|
IP IPConfig `description:"IP whitelisting config options." yaml:"ip,omitempty"`
|
|
Users []string `description:"Comma-separated list of users (username:hashed_password)." yaml:"users,omitempty"`
|
|
SubdomainsEnabled bool `description:"Enable subdomains support." yaml:"subdomainsEnabled,omitempty"`
|
|
UserAttributes map[string]UserAttributes `description:"Map of per-user OIDC attributes (username -> attributes)." yaml:"userAttributes,omitempty"`
|
|
UsersFile string `description:"Path to the users file." yaml:"usersFile,omitempty"`
|
|
SecureCookie bool `description:"Enable secure cookies." yaml:"secureCookie,omitempty"`
|
|
SessionExpiry int `description:"Session expiry time in seconds." yaml:"sessionExpiry,omitempty"`
|
|
SessionMaxLifetime int `description:"Maximum session lifetime in seconds." yaml:"sessionMaxLifetime,omitempty"`
|
|
LoginTimeout int `description:"Login timeout in seconds." yaml:"loginTimeout,omitempty"`
|
|
LoginMaxRetries int `description:"Maximum login retries." yaml:"loginMaxRetries,omitempty"`
|
|
LockdownEnabled bool `description:"Enable lockdown mode after maximum login retries. Lockdown mode limit is calculated automatically." yaml:"lockdownEnabled,omitempty"`
|
|
TrustedProxies []string `description:"Comma-separated list of trusted proxy addresses." yaml:"trustedProxies,omitempty"`
|
|
ACLs ACLsConfig `description:"ACLs configuration." yaml:"acls,omitempty"`
|
|
}
|
|
|
|
type UserAttributes struct {
|
|
Name string `description:"Full name of the user." yaml:"name,omitempty"`
|
|
GivenName string `description:"Given (first) name of the user." yaml:"givenName,omitempty"`
|
|
FamilyName string `description:"Family (last) name of the user." yaml:"familyName,omitempty"`
|
|
MiddleName string `description:"Middle name of the user." yaml:"middleName,omitempty"`
|
|
Nickname string `description:"Nickname of the user." yaml:"nickname,omitempty"`
|
|
Profile string `description:"URL of the user's profile page." yaml:"profile,omitempty"`
|
|
Picture string `description:"URL of the user's profile picture." yaml:"picture,omitempty"`
|
|
Website string `description:"URL of the user's website." yaml:"website,omitempty"`
|
|
Email string `description:"Email address of the user." yaml:"email,omitempty"`
|
|
Gender string `description:"Gender of the user." yaml:"gender,omitempty"`
|
|
Birthdate string `description:"Birthdate of the user (YYYY-MM-DD)." yaml:"birthdate,omitempty"`
|
|
Zoneinfo string `description:"Time zone of the user (e.g. Europe/Athens)." yaml:"zoneinfo,omitempty"`
|
|
Locale string `description:"Locale of the user (e.g. en-US)." yaml:"locale,omitempty"`
|
|
PhoneNumber string `description:"Phone number of the user." yaml:"phoneNumber,omitempty"`
|
|
Address AddressClaim `description:"Address of the user." yaml:"address,omitempty"`
|
|
}
|
|
|
|
type AddressClaim struct {
|
|
Formatted string `description:"Full mailing address, formatted for display." yaml:"formatted,omitempty" json:"formatted,omitempty"`
|
|
StreetAddress string `description:"Street address." yaml:"streetAddress,omitempty" json:"street_address,omitempty"`
|
|
Locality string `description:"City or locality." yaml:"locality,omitempty" json:"locality,omitempty"`
|
|
Region string `description:"State, province, or region." yaml:"region,omitempty" json:"region,omitempty"`
|
|
PostalCode string `description:"Zip or postal code." yaml:"postalCode,omitempty" json:"postal_code,omitempty"`
|
|
Country string `description:"Country." yaml:"country,omitempty" json:"country,omitempty"`
|
|
}
|
|
|
|
type IPConfig struct {
|
|
Allow []string `description:"List of allowed IPs or CIDR ranges." yaml:"allow,omitempty"`
|
|
Block []string `description:"List of blocked IPs or CIDR ranges." yaml:"block,omitempty"`
|
|
Bypass []string `description:"List of IPs or CIDR ranges that bypass authentication entirely." yaml:"bypass,omitempty"`
|
|
}
|
|
|
|
type OAuthConfig struct {
|
|
Whitelist []string `description:"Comma-separated list of allowed OAuth domains." yaml:"whitelist,omitempty"`
|
|
WhitelistFile string `description:"Path to the OAuth whitelist file." yaml:"whitelistFile,omitempty"`
|
|
AutoRedirect string `description:"The OAuth provider to use for automatic redirection." yaml:"autoRedirect,omitempty"`
|
|
Providers map[string]OAuthServiceConfig `description:"OAuth providers configuration." yaml:"providers,omitempty"`
|
|
}
|
|
|
|
type OIDCConfig struct {
|
|
PrivateKeyPath string `description:"Path to the private key file, including file name." yaml:"privateKeyPath,omitempty"`
|
|
PublicKeyPath string `description:"Path to the public key file, including file name." yaml:"publicKeyPath,omitempty"`
|
|
Clients map[string]OIDCClientConfig `description:"OIDC clients configuration." yaml:"clients,omitempty"`
|
|
}
|
|
|
|
type UIConfig struct {
|
|
Title string `description:"The title of the UI." yaml:"title,omitempty"`
|
|
ForgotPasswordMessage string `description:"Message displayed on the forgot password page." yaml:"forgotPasswordMessage,omitempty"`
|
|
BackgroundImage string `description:"Path to the background image." yaml:"backgroundImage,omitempty"`
|
|
WarningsEnabled bool `description:"Enable UI warnings." yaml:"warningsEnabled,omitempty"`
|
|
}
|
|
|
|
type LDAPConfig struct {
|
|
Address string `description:"LDAP server address." yaml:"address,omitempty"`
|
|
BindDN string `description:"Bind DN for LDAP authentication." yaml:"bindDn,omitempty"`
|
|
BindPassword string `description:"Bind password for LDAP authentication." yaml:"bindPassword,omitempty"`
|
|
BindPasswordFile string `description:"Path to the Bind password." yaml:"bindPasswordFile,omitempty"`
|
|
BaseDN string `description:"Base DN for LDAP searches." yaml:"baseDn,omitempty"`
|
|
Insecure bool `description:"Allow insecure LDAP connections." yaml:"insecure,omitempty"`
|
|
SearchFilter string `description:"LDAP search filter." yaml:"searchFilter,omitempty"`
|
|
AuthCert string `description:"Certificate for mTLS authentication." yaml:"authCert,omitempty"`
|
|
AuthKey string `description:"Certificate key for mTLS authentication." yaml:"authKey,omitempty"`
|
|
GroupCacheTTL int `description:"Cache duration for LDAP group membership in seconds." yaml:"groupCacheTTL,omitempty"`
|
|
}
|
|
|
|
type LogConfig struct {
|
|
Level string `description:"Log level (trace, debug, info, warn, error)." yaml:"level,omitempty"`
|
|
Json bool `description:"Enable JSON formatted logs." yaml:"json,omitempty"`
|
|
Streams LogStreams `description:"Configuration for specific log streams." yaml:"streams,omitempty"`
|
|
}
|
|
|
|
type LogStreams struct {
|
|
HTTP LogStreamConfig `description:"HTTP request logging." yaml:"http,omitempty"`
|
|
App LogStreamConfig `description:"Application logging." yaml:"app,omitempty"`
|
|
Audit LogStreamConfig `description:"Audit logging." yaml:"audit,omitempty"`
|
|
}
|
|
|
|
type LogStreamConfig struct {
|
|
Enabled bool `description:"Enable this log stream." yaml:"enabled,omitempty"`
|
|
Level string `description:"Log level for this stream. Use global if empty." yaml:"level,omitempty"`
|
|
}
|
|
|
|
// no experimental features
|
|
type ExperimentalConfig struct{}
|
|
|
|
type TailscaleConfig struct {
|
|
Enabled bool `description:"Enable Tailscale integration." yaml:"enabled,omitempty"`
|
|
Dir string `description:"Tailscale state directory." yaml:"dir,omitempty"`
|
|
Hostname string `description:"Tailscale hostname." yaml:"hostname,omitempty"`
|
|
AuthKey string `description:"Tailscale auth key." yaml:"authKey,omitempty"`
|
|
Ephemeral bool `description:"Use ephemeral Tailscale node." yaml:"ephemeral,omitempty"`
|
|
Funnel bool `description:"Enable Tailscale Funnel." yaml:"funnel,omitempty"`
|
|
Listen bool `description:"Listen on the Tailscale address instead of standard address." yaml:"listen,omitempty"`
|
|
}
|
|
|
|
// OAuth/OIDC config
|
|
|
|
type OAuthServiceConfig struct {
|
|
ClientID string `description:"OAuth client ID." yaml:"clientId,omitempty"`
|
|
ClientSecret string `description:"OAuth client secret." yaml:"clientSecret,omitempty"`
|
|
ClientSecretFile string `description:"Path to the file containing the OAuth client secret." yaml:"clientSecretFile,omitempty"`
|
|
Whitelist []string `description:"Comma-separated list of allowed OAuth domains for this provider." yaml:"whitelist,omitempty"`
|
|
WhitelistFile string `description:"Path to the OAuth whitelist file for this provider." yaml:"whitelistFile,omitempty"`
|
|
Scopes []string `description:"OAuth scopes." yaml:"scopes,omitempty"`
|
|
RedirectURL string `description:"OAuth redirect URL." yaml:"redirectUrl,omitempty"`
|
|
AuthURL string `description:"OAuth authorization URL." yaml:"authUrl,omitempty"`
|
|
TokenURL string `description:"OAuth token URL." yaml:"tokenUrl,omitempty"`
|
|
UserinfoURL string `description:"OAuth userinfo URL." yaml:"userinfoUrl,omitempty"`
|
|
Insecure bool `description:"Allow insecure OAuth connections." yaml:"insecure,omitempty"`
|
|
Name string `description:"Provider name in UI." yaml:"name,omitempty"`
|
|
}
|
|
|
|
type OIDCClientConfig struct {
|
|
ID string `description:"OIDC client ID." yaml:"-"`
|
|
ClientID string `description:"OIDC client ID." yaml:"clientId,omitempty"`
|
|
ClientSecret string `description:"OIDC client secret." yaml:"clientSecret,omitempty"`
|
|
ClientSecretFile string `description:"Path to the file containing the OIDC client secret." yaml:"clientSecretFile,omitempty"`
|
|
TrustedRedirectURIs []string `description:"List of trusted redirect URIs." yaml:"trustedRedirectUris,omitempty"`
|
|
Name string `description:"Client name in UI." yaml:"name,omitempty"`
|
|
}
|
|
|
|
type ACLsConfig struct {
|
|
Policy string `description:"ACL policy for allow-by-default or deny-by-default, available options are allow and deny, default is allow." yaml:"policy,omitempty"`
|
|
}
|
|
|
|
// ACLs
|
|
|
|
type Apps struct {
|
|
Apps map[string]App `description:"App ACLs configuration." yaml:"apps,omitempty"`
|
|
}
|
|
|
|
type App struct {
|
|
Config AppConfig `description:"App configuration." yaml:"config,omitempty"`
|
|
Users AppUsers `description:"User access configuration." yaml:"users,omitempty"`
|
|
OAuth AppOAuth `description:"OAuth access configuration." yaml:"oauth,omitempty"`
|
|
IP AppIP `description:"IP access configuration." yaml:"ip,omitempty"`
|
|
Response AppResponse `description:"Response customization." yaml:"response,omitempty"`
|
|
Path AppPath `description:"Path access configuration." yaml:"path,omitempty"`
|
|
LDAP AppLDAP `description:"LDAP access configuration." yaml:"ldap,omitempty"`
|
|
}
|
|
|
|
type AppConfig struct {
|
|
Domain string `description:"The domain of the app." yaml:"domain,omitempty"`
|
|
}
|
|
|
|
type AppUsers struct {
|
|
Allow string `description:"Comma-separated list of allowed users." yaml:"allow,omitempty"`
|
|
Block string `description:"Comma-separated list of blocked users." yaml:"block,omitempty"`
|
|
}
|
|
|
|
type AppOAuth struct {
|
|
Whitelist string `description:"Comma-separated list of allowed OAuth groups." yaml:"whitelist,omitempty"`
|
|
Groups string `description:"Comma-separated list of required OAuth groups." yaml:"groups,omitempty"`
|
|
}
|
|
|
|
type AppLDAP struct {
|
|
Groups string `description:"Comma-separated list of required LDAP groups." yaml:"groups,omitempty"`
|
|
}
|
|
|
|
type AppIP struct {
|
|
Allow []string `description:"List of allowed IPs or CIDR ranges." yaml:"allow,omitempty"`
|
|
Block []string `description:"List of blocked IPs or CIDR ranges." yaml:"block,omitempty"`
|
|
Bypass []string `description:"List of IPs or CIDR ranges that bypass authentication." yaml:"bypass,omitempty"`
|
|
}
|
|
|
|
type AppResponse struct {
|
|
Headers []string `description:"Custom headers to add to the response." yaml:"headers,omitempty"`
|
|
BasicAuth AppBasicAuth `description:"Basic authentication for the app." yaml:"basicAuth,omitempty"`
|
|
}
|
|
|
|
type AppBasicAuth struct {
|
|
Username string `description:"Basic auth username." yaml:"username,omitempty"`
|
|
Password string `description:"Basic auth password." yaml:"password,omitempty"`
|
|
PasswordFile string `description:"Path to the file containing the basic auth password." yaml:"passwordFile,omitempty"`
|
|
}
|
|
|
|
type AppPath struct {
|
|
Allow string `description:"Comma-separated list of allowed paths." yaml:"allow,omitempty"`
|
|
Block string `description:"Comma-separated list of blocked paths." yaml:"block,omitempty"`
|
|
}
|