mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-05-21 11:40:14 +00:00
feat: tailscale integration (#847)
This commit is contained in:
@@ -65,6 +65,9 @@ func NewDefaultConfiguration() *Config {
|
||||
Experimental: ExperimentalConfig{
|
||||
ConfigFile: "",
|
||||
},
|
||||
Tailscale: TailscaleConfig{
|
||||
Dir: "./tailscale_state",
|
||||
},
|
||||
LabelProvider: "auto",
|
||||
}
|
||||
}
|
||||
@@ -84,6 +87,7 @@ type Config struct {
|
||||
Experimental ExperimentalConfig `description:"Experimental features, use with caution." yaml:"experimental"`
|
||||
LabelProvider string `description:"Label provider to use for ACLs (auto, docker, kubernetes or none to disable). auto detects the environment." yaml:"labelProvider"`
|
||||
Log LogConfig `description:"Logging configuration." yaml:"log"`
|
||||
Tailscale TailscaleConfig `description:"Tailscale configuration." yaml:"tailscale"`
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
@@ -207,6 +211,16 @@ type ExperimentalConfig struct {
|
||||
ConfigFile string `description:"Path to config file." yaml:"-"`
|
||||
}
|
||||
|
||||
type TailscaleConfig struct {
|
||||
Enabled bool `description:"Enable Tailscale integration." yaml:"enabled"`
|
||||
Dir string `description:"Tailscale state directory." yaml:"dir"`
|
||||
Hostname string `description:"Tailscale hostname." yaml:"hostname"`
|
||||
AuthKey string `description:"Tailscale auth key." yaml:"authKey"`
|
||||
Ephemeral bool `description:"Use ephemeral Tailscale node." yaml:"ephemeral"`
|
||||
}
|
||||
|
||||
// OAuth/OIDC config
|
||||
|
||||
type OAuthServiceConfig struct {
|
||||
ClientID string `description:"OAuth client ID." yaml:"clientId"`
|
||||
ClientSecret string `description:"OAuth client secret." yaml:"clientSecret"`
|
||||
|
||||
@@ -21,3 +21,5 @@ const SessionCookieName = "tinyauth-session"
|
||||
const CSRFCookieName = "tinyauth-csrf"
|
||||
const RedirectCookieName = "tinyauth-redirect"
|
||||
const OAuthSessionCookieName = "tinyauth-oauth"
|
||||
|
||||
const GracefulShutdownTimeout = 5 // seconds
|
||||
|
||||
+59
-58
@@ -19,6 +19,7 @@ const (
|
||||
ProviderBasicAuth
|
||||
ProviderOAuth
|
||||
ProviderLDAP
|
||||
ProviderTailscale
|
||||
)
|
||||
|
||||
type UserContext struct {
|
||||
@@ -27,6 +28,7 @@ type UserContext struct {
|
||||
Local *LocalContext
|
||||
OAuth *OAuthContext
|
||||
LDAP *LDAPContext
|
||||
Tailscale *TailscaleContext
|
||||
}
|
||||
|
||||
type BaseContext struct {
|
||||
@@ -54,6 +56,13 @@ type LDAPContext struct {
|
||||
Groups []string
|
||||
}
|
||||
|
||||
type TailscaleContext struct {
|
||||
BaseContext
|
||||
UserID string
|
||||
// for future use
|
||||
Tags []string
|
||||
}
|
||||
|
||||
func (c *UserContext) IsAuthenticated() bool {
|
||||
return c.Authenticated
|
||||
}
|
||||
@@ -74,6 +83,10 @@ func (c *UserContext) IsBasicAuth() bool {
|
||||
return c.Provider == ProviderBasicAuth && c.Local != nil
|
||||
}
|
||||
|
||||
func (c *UserContext) IsTailscale() bool {
|
||||
return c.Provider == ProviderTailscale && c.Tailscale != nil
|
||||
}
|
||||
|
||||
func (c *UserContext) NewFromGin(ginctx *gin.Context) (*UserContext, error) {
|
||||
userContextValue, exists := ginctx.Get("context")
|
||||
|
||||
@@ -87,7 +100,7 @@ func (c *UserContext) NewFromGin(ginctx *gin.Context) (*UserContext, error) {
|
||||
return nil, errors.New("invalid user context type")
|
||||
}
|
||||
|
||||
if userContext.LDAP == nil && userContext.Local == nil && userContext.OAuth == nil {
|
||||
if userContext.LDAP == nil && userContext.Local == nil && userContext.OAuth == nil && userContext.Tailscale == nil {
|
||||
return nil, errors.New("incomplete user context")
|
||||
}
|
||||
|
||||
@@ -121,6 +134,15 @@ func (c *UserContext) NewFromSession(session *repository.Session) (*UserContext,
|
||||
Email: session.Email,
|
||||
},
|
||||
}
|
||||
case "tailscale":
|
||||
c.Provider = ProviderTailscale
|
||||
c.Tailscale = &TailscaleContext{
|
||||
BaseContext: BaseContext{
|
||||
Username: session.Username,
|
||||
Name: session.Name,
|
||||
Email: session.Email,
|
||||
},
|
||||
}
|
||||
// By default we assume an unknown name which is oauth
|
||||
default:
|
||||
c.Provider = ProviderOAuth
|
||||
@@ -145,85 +167,55 @@ func (c *UserContext) NewFromSession(session *repository.Session) (*UserContext,
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *UserContext) GetUsername() string {
|
||||
func (c *UserContext) getBaseContext() *BaseContext {
|
||||
switch c.Provider {
|
||||
case ProviderLocal:
|
||||
case ProviderLocal, ProviderBasicAuth:
|
||||
if c.Local == nil {
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
return c.Local.Username
|
||||
return &c.Local.BaseContext
|
||||
case ProviderLDAP:
|
||||
if c.LDAP == nil {
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
return c.LDAP.Username
|
||||
case ProviderBasicAuth:
|
||||
if c.Local == nil {
|
||||
return ""
|
||||
}
|
||||
return c.Local.Username
|
||||
return &c.LDAP.BaseContext
|
||||
case ProviderOAuth:
|
||||
if c.OAuth == nil {
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
return c.OAuth.Username
|
||||
return &c.OAuth.BaseContext
|
||||
case ProviderTailscale:
|
||||
if c.Tailscale == nil {
|
||||
return nil
|
||||
}
|
||||
return &c.Tailscale.BaseContext
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *UserContext) GetUsername() string {
|
||||
base := c.getBaseContext()
|
||||
if base == nil {
|
||||
return ""
|
||||
}
|
||||
return base.Username
|
||||
}
|
||||
|
||||
func (c *UserContext) GetEmail() string {
|
||||
switch c.Provider {
|
||||
case ProviderLocal:
|
||||
if c.Local == nil {
|
||||
return ""
|
||||
}
|
||||
return c.Local.Email
|
||||
case ProviderLDAP:
|
||||
if c.LDAP == nil {
|
||||
return ""
|
||||
}
|
||||
return c.LDAP.Email
|
||||
case ProviderBasicAuth:
|
||||
if c.Local == nil {
|
||||
return ""
|
||||
}
|
||||
return c.Local.Email
|
||||
case ProviderOAuth:
|
||||
if c.OAuth == nil {
|
||||
return ""
|
||||
}
|
||||
return c.OAuth.Email
|
||||
default:
|
||||
base := c.getBaseContext()
|
||||
if base == nil {
|
||||
return ""
|
||||
}
|
||||
return base.Email
|
||||
}
|
||||
|
||||
func (c *UserContext) GetName() string {
|
||||
switch c.Provider {
|
||||
case ProviderLocal:
|
||||
if c.Local == nil {
|
||||
return ""
|
||||
}
|
||||
return c.Local.Name
|
||||
case ProviderLDAP:
|
||||
if c.LDAP == nil {
|
||||
return ""
|
||||
}
|
||||
return c.LDAP.Name
|
||||
case ProviderBasicAuth:
|
||||
if c.Local == nil {
|
||||
return ""
|
||||
}
|
||||
return c.Local.Name
|
||||
case ProviderOAuth:
|
||||
if c.OAuth == nil {
|
||||
return ""
|
||||
}
|
||||
return c.OAuth.Name
|
||||
default:
|
||||
base := c.getBaseContext()
|
||||
if base == nil {
|
||||
return ""
|
||||
}
|
||||
return base.Name
|
||||
}
|
||||
|
||||
func (c *UserContext) GetProviderID() string {
|
||||
@@ -234,6 +226,8 @@ func (c *UserContext) GetProviderID() string {
|
||||
return "ldap"
|
||||
case ProviderOAuth:
|
||||
return c.OAuth.ID
|
||||
case ProviderTailscale:
|
||||
return "tailscale"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
@@ -252,3 +246,10 @@ func (c *UserContext) OAuthName() string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *UserContext) TailscaleNodeName() string {
|
||||
if c.Tailscale != nil {
|
||||
return c.Tailscale.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ type RuntimeConfig struct {
|
||||
OAuthWhitelist []string
|
||||
ConfiguredProviders []Provider
|
||||
OIDCClients []OIDCClientConfig
|
||||
TrustedDomains []string
|
||||
}
|
||||
|
||||
type Provider struct {
|
||||
|
||||
Reference in New Issue
Block a user