mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-10-31 14:15:50 +00:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			402e7e565d
			...
			feat/multi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | df10eb65ce | ||
|   | 8bf5a6067e | 
							
								
								
									
										17
									
								
								cmd/root.go
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								cmd/root.go
									
									
									
									
									
								
							| @@ -105,12 +105,8 @@ var rootCmd = &cobra.Command{ | ||||
|  | ||||
| 		// Create api config | ||||
| 		apiConfig := types.APIConfig{ | ||||
| 			Port:          config.Port, | ||||
| 			Address:       config.Address, | ||||
| 			Secret:        config.Secret, | ||||
| 			CookieSecure:  config.CookieSecure, | ||||
| 			SessionExpiry: config.SessionExpiry, | ||||
| 			Domain:        domain, | ||||
| 			Port:    config.Port, | ||||
| 			Address: config.Address, | ||||
| 		} | ||||
|  | ||||
| 		// Create docker service | ||||
| @@ -121,7 +117,14 @@ var rootCmd = &cobra.Command{ | ||||
| 		HandleError(err, "Failed to initialize docker") | ||||
|  | ||||
| 		// Create auth service | ||||
| 		auth := auth.NewAuth(docker, users, oauthWhitelist, config.SessionExpiry) | ||||
| 		auth := auth.NewAuth(types.AuthConfig{ | ||||
| 			Domain:         domain, | ||||
| 			Secret:         config.Secret, | ||||
| 			SessionExpiry:  config.SessionExpiry, | ||||
| 			CookieSecure:   config.CookieSecure, | ||||
| 			Users:          users, | ||||
| 			OAuthWhitelist: oauthWhitelist, | ||||
| 		}, docker) | ||||
|  | ||||
| 		// Create OAuth providers service | ||||
| 		providers := providers.NewProviders(oauthConfig) | ||||
|   | ||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							| @@ -3,7 +3,6 @@ module tinyauth | ||||
| go 1.23.2 | ||||
|  | ||||
| require ( | ||||
| 	github.com/gin-contrib/sessions v1.0.2 | ||||
| 	github.com/gin-gonic/gin v1.10.0 | ||||
| 	github.com/go-playground/validator/v10 v10.24.0 | ||||
| 	github.com/google/go-querystring v1.1.0 | ||||
| @@ -58,9 +57,8 @@ require ( | ||||
| 	github.com/go-playground/universal-translator v0.18.1 // indirect | ||||
| 	github.com/goccy/go-json v0.10.4 // indirect | ||||
| 	github.com/gogo/protobuf v1.3.2 // indirect | ||||
| 	github.com/gorilla/context v1.1.2 // indirect | ||||
| 	github.com/gorilla/securecookie v1.1.2 // indirect | ||||
| 	github.com/gorilla/sessions v1.2.2 // indirect | ||||
| 	github.com/gorilla/sessions v1.2.2 | ||||
| 	github.com/hashicorp/hcl v1.0.0 // indirect | ||||
| 	github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||||
| 	github.com/json-iterator/go v1.1.12 // indirect | ||||
|   | ||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							| @@ -65,8 +65,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos | ||||
| github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= | ||||
| github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= | ||||
| github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= | ||||
| github.com/gin-contrib/sessions v1.0.2 h1:UaIjUvTH1cMeOdj3in6dl+Xb6It8RiKRF9Z1anbUyCA= | ||||
| github.com/gin-contrib/sessions v1.0.2/go.mod h1:KxKxWqWP5LJVDCInulOl4WbLzK2KSPlLesfZ66wRvMs= | ||||
| github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= | ||||
| github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= | ||||
| github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= | ||||
| @@ -99,8 +97,6 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= | ||||
| github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= | ||||
| github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
| github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o= | ||||
| github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM= | ||||
| github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= | ||||
| github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= | ||||
| github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= | ||||
|   | ||||
| @@ -11,23 +11,21 @@ import ( | ||||
| 	"tinyauth/internal/handlers" | ||||
| 	"tinyauth/internal/types" | ||||
|  | ||||
| 	"github.com/gin-contrib/sessions" | ||||
| 	"github.com/gin-contrib/sessions/cookie" | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| ) | ||||
|  | ||||
| func NewAPI(config types.APIConfig, handlers *handlers.Handlers) *API { | ||||
| 	return &API{ | ||||
| 		Config:   config, | ||||
| 		Handlers: handlers, | ||||
| 		Config:   config, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type API struct { | ||||
| 	Config   types.APIConfig | ||||
| 	Router   *gin.Engine | ||||
| 	Handlers *handlers.Handlers | ||||
| 	Config   types.APIConfig | ||||
| } | ||||
|  | ||||
| func (api *API) Init() { | ||||
| @@ -51,21 +49,6 @@ func (api *API) Init() { | ||||
| 	log.Debug().Msg("Setting up file server") | ||||
| 	fileServer := http.FileServer(http.FS(dist)) | ||||
|  | ||||
| 	// Setup cookie store | ||||
| 	log.Debug().Msg("Setting up cookie store") | ||||
| 	store := cookie.NewStore([]byte(api.Config.Secret)) | ||||
|  | ||||
| 	// Use session middleware | ||||
| 	store.Options(sessions.Options{ | ||||
| 		Domain:   api.Config.Domain, | ||||
| 		Path:     "/", | ||||
| 		HttpOnly: true, | ||||
| 		Secure:   api.Config.CookieSecure, | ||||
| 		MaxAge:   api.Config.SessionExpiry, | ||||
| 	}) | ||||
|  | ||||
| 	router.Use(sessions.Sessions("tinyauth", store)) | ||||
|  | ||||
| 	// UI middleware | ||||
| 	router.Use(func(c *gin.Context) { | ||||
| 		// If not an API request, serve the UI | ||||
|   | ||||
| @@ -19,13 +19,16 @@ import ( | ||||
| 	"github.com/magiconair/properties/assert" | ||||
| ) | ||||
|  | ||||
| // User | ||||
| var User = types.User{ | ||||
| 	Username: "user", | ||||
| 	Password: "$2a$10$AvGHLTYv3xiRJ0xV9xs3XeVIlkGTygI9nqIamFYB5Xu.5.0UWF7B6", // pass | ||||
| } | ||||
|  | ||||
| // Simple API config for tests | ||||
| var apiConfig = types.APIConfig{ | ||||
| 	Port:          8080, | ||||
| 	Address:       "0.0.0.0", | ||||
| 	Secret:        "super-secret-api-thing-for-tests", // It is 32 chars long | ||||
| 	CookieSecure:  false, | ||||
| 	SessionExpiry: 3600, | ||||
| 	Port:    8080, | ||||
| 	Address: "0.0.0.0", | ||||
| } | ||||
|  | ||||
| // Simple handlers config for tests | ||||
| @@ -38,15 +41,21 @@ var handlersConfig = types.HandlersConfig{ | ||||
| 	GenericName:     "Generic", | ||||
| } | ||||
|  | ||||
| // Simple auth config for tests | ||||
| var authConfig = types.AuthConfig{ | ||||
| 	Domain:        "localhost", | ||||
| 	Secret:        "super-secret-api-thing-for-tests", // It is 32 chars long | ||||
| 	CookieSecure:  false, | ||||
| 	SessionExpiry: 3600, | ||||
| 	Users: types.Users{ | ||||
| 		User, | ||||
| 	}, | ||||
| 	OAuthWhitelist: []string{}, | ||||
| } | ||||
|  | ||||
| // Cookie | ||||
| var cookie string | ||||
|  | ||||
| // User | ||||
| var user = types.User{ | ||||
| 	Username: "user", | ||||
| 	Password: "$2a$10$AvGHLTYv3xiRJ0xV9xs3XeVIlkGTygI9nqIamFYB5Xu.5.0UWF7B6", // pass | ||||
| } | ||||
|  | ||||
| // We need all this to be able to test the API | ||||
| func getAPI(t *testing.T) *api.API { | ||||
| 	// Create docker service | ||||
| @@ -61,12 +70,7 @@ func getAPI(t *testing.T) *api.API { | ||||
| 	} | ||||
|  | ||||
| 	// Create auth service | ||||
| 	auth := auth.NewAuth(docker, types.Users{ | ||||
| 		{ | ||||
| 			Username: user.Username, | ||||
| 			Password: user.Password, | ||||
| 		}, | ||||
| 	}, nil, apiConfig.SessionExpiry) | ||||
| 	auth := auth.NewAuth(authConfig, docker) | ||||
|  | ||||
| 	// Create providers service | ||||
| 	providers := providers.NewProviders(types.OAuthConfig{}) | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package auth | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"slices" | ||||
| 	"strings" | ||||
| @@ -8,31 +9,27 @@ import ( | ||||
| 	"tinyauth/internal/docker" | ||||
| 	"tinyauth/internal/types" | ||||
|  | ||||
| 	"github.com/gin-contrib/sessions" | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/gorilla/sessions" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"golang.org/x/crypto/bcrypt" | ||||
| ) | ||||
|  | ||||
| func NewAuth(docker *docker.Docker, userList types.Users, oauthWhitelist []string, sessionExpiry int) *Auth { | ||||
| func NewAuth(config types.AuthConfig, docker *docker.Docker) *Auth { | ||||
| 	return &Auth{ | ||||
| 		Docker:         docker, | ||||
| 		Users:          userList, | ||||
| 		OAuthWhitelist: oauthWhitelist, | ||||
| 		SessionExpiry:  sessionExpiry, | ||||
| 		Docker: docker, | ||||
| 		Config: config, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type Auth struct { | ||||
| 	Users          types.Users | ||||
| 	Docker         *docker.Docker | ||||
| 	OAuthWhitelist []string | ||||
| 	SessionExpiry  int | ||||
| 	Docker *docker.Docker | ||||
| 	Config types.AuthConfig | ||||
| } | ||||
|  | ||||
| func (auth *Auth) GetUser(username string) *types.User { | ||||
| 	// Loop through users and return the user if the username matches | ||||
| 	for _, user := range auth.Users { | ||||
| 	for _, user := range auth.Config.Users { | ||||
| 		if user.Username == username { | ||||
| 			return &user | ||||
| 		} | ||||
| @@ -47,12 +44,12 @@ func (auth *Auth) CheckPassword(user types.User, password string) bool { | ||||
|  | ||||
| func (auth *Auth) EmailWhitelisted(emailSrc string) bool { | ||||
| 	// If the whitelist is empty, allow all emails | ||||
| 	if len(auth.OAuthWhitelist) == 0 { | ||||
| 	if len(auth.Config.OAuthWhitelist) == 0 { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	// Loop through the whitelist and return true if the email matches | ||||
| 	for _, email := range auth.OAuthWhitelist { | ||||
| 	for _, email := range auth.Config.OAuthWhitelist { | ||||
| 		if email == emailSrc { | ||||
| 			return true | ||||
| 		} | ||||
| @@ -62,11 +59,35 @@ func (auth *Auth) EmailWhitelisted(emailSrc string) bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (auth *Auth) CreateSessionCookie(c *gin.Context, data *types.SessionCookie) { | ||||
| func (auth *Auth) GetCookieStore() *sessions.CookieStore { | ||||
| 	// Create a new cookie store | ||||
| 	store := sessions.NewCookieStore([]byte(auth.Config.Secret)) | ||||
|  | ||||
| 	// Configure the cookie store | ||||
| 	store.Options = &sessions.Options{ | ||||
| 		Path:     "/", | ||||
| 		Domain:   fmt.Sprintf(".%s", auth.Config.Domain), | ||||
| 		Secure:   auth.Config.CookieSecure, | ||||
| 		MaxAge:   auth.Config.SessionExpiry, | ||||
| 		HttpOnly: true, | ||||
| 	} | ||||
|  | ||||
| 	// Set the cookie store | ||||
| 	return store | ||||
| } | ||||
|  | ||||
| func (auth *Auth) CreateSessionCookie(c *gin.Context, data *types.SessionCookie) error { | ||||
| 	log.Debug().Msg("Creating session cookie") | ||||
|  | ||||
| 	// Get cookie store | ||||
| 	store := auth.GetCookieStore() | ||||
|  | ||||
| 	// Get session | ||||
| 	sessions := sessions.Default(c) | ||||
| 	sessions, err := store.Get(c.Request, "tinyauth") | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msg("Setting session cookie") | ||||
|  | ||||
| @@ -76,43 +97,73 @@ func (auth *Auth) CreateSessionCookie(c *gin.Context, data *types.SessionCookie) | ||||
| 	if data.TotpPending { | ||||
| 		sessionExpiry = 3600 | ||||
| 	} else { | ||||
| 		sessionExpiry = auth.SessionExpiry | ||||
| 		sessionExpiry = auth.Config.SessionExpiry | ||||
| 	} | ||||
|  | ||||
| 	// Set data | ||||
| 	sessions.Set("username", data.Username) | ||||
| 	sessions.Set("provider", data.Provider) | ||||
| 	sessions.Set("expiry", time.Now().Add(time.Duration(sessionExpiry)*time.Second).Unix()) | ||||
| 	sessions.Set("totpPending", data.TotpPending) | ||||
| 	sessions.Values["username"] = data.Username | ||||
| 	sessions.Values["provider"] = data.Provider | ||||
| 	sessions.Values["expiry"] = time.Now().Add(time.Duration(sessionExpiry) * time.Second).Unix() | ||||
| 	sessions.Values["totpPending"] = data.TotpPending | ||||
|  | ||||
| 	// Save session | ||||
| 	sessions.Save() | ||||
| 	err = sessions.Save(c.Request, c.Writer) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// Return nil | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (auth *Auth) DeleteSessionCookie(c *gin.Context) { | ||||
| func (auth *Auth) DeleteSessionCookie(c *gin.Context) error { | ||||
| 	log.Debug().Msg("Deleting session cookie") | ||||
|  | ||||
| 	// Get cookie store | ||||
| 	store := auth.GetCookieStore() | ||||
|  | ||||
| 	// Get session | ||||
| 	sessions := sessions.Default(c) | ||||
| 	sessions, err := store.Get(c.Request, "tinyauth") | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// Clear session | ||||
| 	sessions.Clear() | ||||
| 	for key := range sessions.Values { | ||||
| 		delete(sessions.Values, key) | ||||
| 	} | ||||
|  | ||||
| 	// Save session | ||||
| 	sessions.Save() | ||||
| 	err = sessions.Save(c.Request, c.Writer) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// Return nil | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (auth *Auth) GetSessionCookie(c *gin.Context) types.SessionCookie { | ||||
| func (auth *Auth) GetSessionCookie(c *gin.Context) (types.SessionCookie, error) { | ||||
| 	log.Debug().Msg("Getting session cookie") | ||||
|  | ||||
| 	// Get cookie store | ||||
| 	store := auth.GetCookieStore() | ||||
|  | ||||
| 	// Get session | ||||
| 	sessions := sessions.Default(c) | ||||
| 	sessions, err := store.Get(c.Request, "tinyauth") | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return types.SessionCookie{}, err | ||||
| 	} | ||||
|  | ||||
| 	// Get data | ||||
| 	cookieUsername := sessions.Get("username") | ||||
| 	cookieProvider := sessions.Get("provider") | ||||
| 	cookieExpiry := sessions.Get("expiry") | ||||
| 	cookieTotpPending := sessions.Get("totpPending") | ||||
| 	cookieUsername := sessions.Values["username"] | ||||
| 	cookieProvider := sessions.Values["provider"] | ||||
| 	cookieExpiry := sessions.Values["expiry"] | ||||
| 	cookieTotpPending := sessions.Values["totpPending"] | ||||
|  | ||||
| 	// Convert interfaces to correct types | ||||
| 	username, usernameOk := cookieUsername.(string) | ||||
| @@ -123,7 +174,7 @@ func (auth *Auth) GetSessionCookie(c *gin.Context) types.SessionCookie { | ||||
| 	// Check if the cookie is invalid | ||||
| 	if !usernameOk || !providerOk || !expiryOk || !totpPendingOk { | ||||
| 		log.Warn().Msg("Session cookie invalid") | ||||
| 		return types.SessionCookie{} | ||||
| 		return types.SessionCookie{}, nil | ||||
| 	} | ||||
|  | ||||
| 	// Check if the cookie has expired | ||||
| @@ -134,7 +185,7 @@ func (auth *Auth) GetSessionCookie(c *gin.Context) types.SessionCookie { | ||||
| 		auth.DeleteSessionCookie(c) | ||||
|  | ||||
| 		// Return empty cookie | ||||
| 		return types.SessionCookie{} | ||||
| 		return types.SessionCookie{}, nil | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Str("username", username).Str("provider", provider).Int64("expiry", expiry).Bool("totpPending", totpPending).Msg("Parsed cookie") | ||||
| @@ -144,12 +195,12 @@ func (auth *Auth) GetSessionCookie(c *gin.Context) types.SessionCookie { | ||||
| 		Username:    username, | ||||
| 		Provider:    provider, | ||||
| 		TotpPending: totpPending, | ||||
| 	} | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func (auth *Auth) UserAuthConfigured() bool { | ||||
| 	// If there are users, return true | ||||
| 	return len(auth.Users) > 0 | ||||
| 	return len(auth.Config.Users) > 0 | ||||
| } | ||||
|  | ||||
| func (auth *Auth) ResourceAllowed(c *gin.Context, context types.UserContext) (bool, error) { | ||||
|   | ||||
| @@ -19,20 +19,20 @@ import ( | ||||
|  | ||||
| func NewHandlers(config types.HandlersConfig, auth *auth.Auth, hooks *hooks.Hooks, providers *providers.Providers, docker *docker.Docker) *Handlers { | ||||
| 	return &Handlers{ | ||||
| 		Config:    config, | ||||
| 		Auth:      auth, | ||||
| 		Hooks:     hooks, | ||||
| 		Providers: providers, | ||||
| 		Docker:    docker, | ||||
| 		Config:    config, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type Handlers struct { | ||||
| 	Config    types.HandlersConfig | ||||
| 	Auth      *auth.Auth | ||||
| 	Hooks     *hooks.Hooks | ||||
| 	Providers *providers.Providers | ||||
| 	Docker    *docker.Docker | ||||
| 	Config    types.HandlersConfig | ||||
| } | ||||
|  | ||||
| func (h *Handlers) AuthHandler(c *gin.Context) { | ||||
|   | ||||
| @@ -23,7 +23,13 @@ type Hooks struct { | ||||
|  | ||||
| func (hooks *Hooks) UseUserContext(c *gin.Context) types.UserContext { | ||||
| 	// Get session cookie and basic auth | ||||
| 	cookie := hooks.Auth.GetSessionCookie(c) | ||||
| 	cookie, err := hooks.Auth.GetSessionCookie(c) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		log.Error().Err(err).Msg("Failed to get session cookie") | ||||
| 		return types.UserContext{} | ||||
| 	} | ||||
|  | ||||
| 	basic := hooks.Auth.GetBasicAuth(c) | ||||
|  | ||||
| 	// Check if basic auth is set | ||||
|   | ||||
| @@ -14,10 +14,10 @@ func NewOAuth(config oauth2.Config) *OAuth { | ||||
| } | ||||
|  | ||||
| type OAuth struct { | ||||
| 	Config   oauth2.Config | ||||
| 	Verifier string | ||||
| 	Context  context.Context | ||||
| 	Token    *oauth2.Token | ||||
| 	Verifier string | ||||
| 	Config   oauth2.Config | ||||
| } | ||||
|  | ||||
| func (oauth *OAuth) Init() { | ||||
|   | ||||
| @@ -17,11 +17,11 @@ func NewProviders(config types.OAuthConfig) *Providers { | ||||
| } | ||||
|  | ||||
| type Providers struct { | ||||
| 	Config    types.OAuthConfig | ||||
| 	Github    *oauth.OAuth | ||||
| 	Google    *oauth.OAuth | ||||
| 	Tailscale *oauth.OAuth | ||||
| 	Generic   *oauth.OAuth | ||||
| 	Config    types.OAuthConfig | ||||
| } | ||||
|  | ||||
| func (providers *Providers) Init() { | ||||
|   | ||||
							
								
								
									
										49
									
								
								internal/types/api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								internal/types/api.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| package types | ||||
|  | ||||
| // LoginQuery is the query parameters for the login endpoint | ||||
| type LoginQuery struct { | ||||
| 	RedirectURI string `url:"redirect_uri"` | ||||
| } | ||||
|  | ||||
| // LoginRequest is the request body for the login endpoint | ||||
| type LoginRequest struct { | ||||
| 	Username string `json:"username"` | ||||
| 	Password string `json:"password"` | ||||
| } | ||||
|  | ||||
| // OAuthRequest is the request for the OAuth endpoint | ||||
| type OAuthRequest struct { | ||||
| 	Provider string `uri:"provider" binding:"required"` | ||||
| } | ||||
|  | ||||
| // UnauthorizedQuery is the query parameters for the unauthorized endpoint | ||||
| type UnauthorizedQuery struct { | ||||
| 	Username string `url:"username"` | ||||
| 	Resource string `url:"resource"` | ||||
| } | ||||
|  | ||||
| // TailscaleQuery is the query parameters for the tailscale endpoint | ||||
| type TailscaleQuery struct { | ||||
| 	Code int `url:"code"` | ||||
| } | ||||
|  | ||||
| // Proxy is the uri parameters for the proxy endpoint | ||||
| type Proxy struct { | ||||
| 	Proxy string `uri:"proxy" binding:"required"` | ||||
| } | ||||
|  | ||||
| // User Context response is the response for the user context endpoint | ||||
| type UserContextResponse struct { | ||||
| 	Status      int    `json:"status"` | ||||
| 	Message     string `json:"message"` | ||||
| 	IsLoggedIn  bool   `json:"isLoggedIn"` | ||||
| 	Username    string `json:"username"` | ||||
| 	Provider    string `json:"provider"` | ||||
| 	Oauth       bool   `json:"oauth"` | ||||
| 	TotpPending bool   `json:"totpPending"` | ||||
| } | ||||
|  | ||||
| // Totp request is the request for the totp endpoint | ||||
| type TotpRequest struct { | ||||
| 	Code string `json:"code"` | ||||
| } | ||||
							
								
								
									
										79
									
								
								internal/types/config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								internal/types/config.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| package types | ||||
|  | ||||
| // Config is the configuration for the tinyauth server | ||||
| type Config struct { | ||||
| 	Port                      int    `mapstructure:"port" validate:"required"` | ||||
| 	Address                   string `validate:"required,ip4_addr" mapstructure:"address"` | ||||
| 	Secret                    string `validate:"required,len=32" mapstructure:"secret"` | ||||
| 	SecretFile                string `mapstructure:"secret-file"` | ||||
| 	AppURL                    string `validate:"required,url" mapstructure:"app-url"` | ||||
| 	Users                     string `mapstructure:"users"` | ||||
| 	UsersFile                 string `mapstructure:"users-file"` | ||||
| 	CookieSecure              bool   `mapstructure:"cookie-secure"` | ||||
| 	GithubClientId            string `mapstructure:"github-client-id"` | ||||
| 	GithubClientSecret        string `mapstructure:"github-client-secret"` | ||||
| 	GithubClientSecretFile    string `mapstructure:"github-client-secret-file"` | ||||
| 	GoogleClientId            string `mapstructure:"google-client-id"` | ||||
| 	GoogleClientSecret        string `mapstructure:"google-client-secret"` | ||||
| 	GoogleClientSecretFile    string `mapstructure:"google-client-secret-file"` | ||||
| 	TailscaleClientId         string `mapstructure:"tailscale-client-id"` | ||||
| 	TailscaleClientSecret     string `mapstructure:"tailscale-client-secret"` | ||||
| 	TailscaleClientSecretFile string `mapstructure:"tailscale-client-secret-file"` | ||||
| 	GenericClientId           string `mapstructure:"generic-client-id"` | ||||
| 	GenericClientSecret       string `mapstructure:"generic-client-secret"` | ||||
| 	GenericClientSecretFile   string `mapstructure:"generic-client-secret-file"` | ||||
| 	GenericScopes             string `mapstructure:"generic-scopes"` | ||||
| 	GenericAuthURL            string `mapstructure:"generic-auth-url"` | ||||
| 	GenericTokenURL           string `mapstructure:"generic-token-url"` | ||||
| 	GenericUserURL            string `mapstructure:"generic-user-url"` | ||||
| 	GenericName               string `mapstructure:"generic-name"` | ||||
| 	DisableContinue           bool   `mapstructure:"disable-continue"` | ||||
| 	OAuthWhitelist            string `mapstructure:"oauth-whitelist"` | ||||
| 	SessionExpiry             int    `mapstructure:"session-expiry"` | ||||
| 	LogLevel                  int8   `mapstructure:"log-level" validate:"min=-1,max=5"` | ||||
| 	Title                     string `mapstructure:"app-title"` | ||||
| 	EnvFile                   string `mapstructure:"env-file"` | ||||
| } | ||||
|  | ||||
| // APIConfig is the configuration for the API | ||||
| type APIConfig struct { | ||||
| 	Port    int | ||||
| 	Address string | ||||
| } | ||||
|  | ||||
| // OAuthConfig is the configuration for the providers | ||||
| type OAuthConfig struct { | ||||
| 	GithubClientId        string | ||||
| 	GithubClientSecret    string | ||||
| 	GoogleClientId        string | ||||
| 	GoogleClientSecret    string | ||||
| 	TailscaleClientId     string | ||||
| 	TailscaleClientSecret string | ||||
| 	GenericClientId       string | ||||
| 	GenericClientSecret   string | ||||
| 	GenericScopes         []string | ||||
| 	GenericAuthURL        string | ||||
| 	GenericTokenURL       string | ||||
| 	GenericUserURL        string | ||||
| 	AppURL                string | ||||
| } | ||||
|  | ||||
| // Server configuration | ||||
| type HandlersConfig struct { | ||||
| 	AppURL          string | ||||
| 	Domain          string | ||||
| 	CookieSecure    bool | ||||
| 	DisableContinue bool | ||||
| 	GenericName     string | ||||
| 	Title           string | ||||
| } | ||||
|  | ||||
| // Auth configuration | ||||
| type AuthConfig struct { | ||||
| 	Domain         string | ||||
| 	Secret         string | ||||
| 	CookieSecure   bool | ||||
| 	SessionExpiry  int | ||||
| 	Users          Users | ||||
| 	OAuthWhitelist []string | ||||
| } | ||||
| @@ -2,17 +2,6 @@ package types | ||||
|  | ||||
| import "tinyauth/internal/oauth" | ||||
|  | ||||
| // LoginQuery is the query parameters for the login endpoint | ||||
| type LoginQuery struct { | ||||
| 	RedirectURI string `url:"redirect_uri"` | ||||
| } | ||||
|  | ||||
| // LoginRequest is the request body for the login endpoint | ||||
| type LoginRequest struct { | ||||
| 	Username string `json:"username"` | ||||
| 	Password string `json:"password"` | ||||
| } | ||||
|  | ||||
| // User is the struct for a user | ||||
| type User struct { | ||||
| 	Username   string | ||||
| @@ -23,82 +12,6 @@ type User struct { | ||||
| // Users is a list of users | ||||
| type Users []User | ||||
|  | ||||
| // Config is the configuration for the tinyauth server | ||||
| type Config struct { | ||||
| 	Port                      int    `mapstructure:"port" validate:"required"` | ||||
| 	Address                   string `validate:"required,ip4_addr" mapstructure:"address"` | ||||
| 	Secret                    string `validate:"required,len=32" mapstructure:"secret"` | ||||
| 	SecretFile                string `mapstructure:"secret-file"` | ||||
| 	AppURL                    string `validate:"required,url" mapstructure:"app-url"` | ||||
| 	Users                     string `mapstructure:"users"` | ||||
| 	UsersFile                 string `mapstructure:"users-file"` | ||||
| 	CookieSecure              bool   `mapstructure:"cookie-secure"` | ||||
| 	GithubClientId            string `mapstructure:"github-client-id"` | ||||
| 	GithubClientSecret        string `mapstructure:"github-client-secret"` | ||||
| 	GithubClientSecretFile    string `mapstructure:"github-client-secret-file"` | ||||
| 	GoogleClientId            string `mapstructure:"google-client-id"` | ||||
| 	GoogleClientSecret        string `mapstructure:"google-client-secret"` | ||||
| 	GoogleClientSecretFile    string `mapstructure:"google-client-secret-file"` | ||||
| 	TailscaleClientId         string `mapstructure:"tailscale-client-id"` | ||||
| 	TailscaleClientSecret     string `mapstructure:"tailscale-client-secret"` | ||||
| 	TailscaleClientSecretFile string `mapstructure:"tailscale-client-secret-file"` | ||||
| 	GenericClientId           string `mapstructure:"generic-client-id"` | ||||
| 	GenericClientSecret       string `mapstructure:"generic-client-secret"` | ||||
| 	GenericClientSecretFile   string `mapstructure:"generic-client-secret-file"` | ||||
| 	GenericScopes             string `mapstructure:"generic-scopes"` | ||||
| 	GenericAuthURL            string `mapstructure:"generic-auth-url"` | ||||
| 	GenericTokenURL           string `mapstructure:"generic-token-url"` | ||||
| 	GenericUserURL            string `mapstructure:"generic-user-url"` | ||||
| 	GenericName               string `mapstructure:"generic-name"` | ||||
| 	DisableContinue           bool   `mapstructure:"disable-continue"` | ||||
| 	OAuthWhitelist            string `mapstructure:"oauth-whitelist"` | ||||
| 	SessionExpiry             int    `mapstructure:"session-expiry"` | ||||
| 	LogLevel                  int8   `mapstructure:"log-level" validate:"min=-1,max=5"` | ||||
| 	Title                     string `mapstructure:"app-title"` | ||||
| 	EnvFile                   string `mapstructure:"env-file"` | ||||
| } | ||||
|  | ||||
| // UserContext is the context for the user | ||||
| type UserContext struct { | ||||
| 	Username    string | ||||
| 	IsLoggedIn  bool | ||||
| 	OAuth       bool | ||||
| 	Provider    string | ||||
| 	TotpPending bool | ||||
| } | ||||
|  | ||||
| // APIConfig is the configuration for the API | ||||
| type APIConfig struct { | ||||
| 	Port          int | ||||
| 	Address       string | ||||
| 	Secret        string | ||||
| 	CookieSecure  bool | ||||
| 	SessionExpiry int | ||||
| 	Domain        string | ||||
| } | ||||
|  | ||||
| // OAuthConfig is the configuration for the providers | ||||
| type OAuthConfig struct { | ||||
| 	GithubClientId        string | ||||
| 	GithubClientSecret    string | ||||
| 	GoogleClientId        string | ||||
| 	GoogleClientSecret    string | ||||
| 	TailscaleClientId     string | ||||
| 	TailscaleClientSecret string | ||||
| 	GenericClientId       string | ||||
| 	GenericClientSecret   string | ||||
| 	GenericScopes         []string | ||||
| 	GenericAuthURL        string | ||||
| 	GenericTokenURL       string | ||||
| 	GenericUserURL        string | ||||
| 	AppURL                string | ||||
| } | ||||
|  | ||||
| // OAuthRequest is the request for the OAuth endpoint | ||||
| type OAuthRequest struct { | ||||
| 	Provider string `uri:"provider" binding:"required"` | ||||
| } | ||||
|  | ||||
| // OAuthProviders is the struct for the OAuth providers | ||||
| type OAuthProviders struct { | ||||
| 	Github    *oauth.OAuth | ||||
| @@ -106,12 +19,6 @@ type OAuthProviders struct { | ||||
| 	Microsoft *oauth.OAuth | ||||
| } | ||||
|  | ||||
| // UnauthorizedQuery is the query parameters for the unauthorized endpoint | ||||
| type UnauthorizedQuery struct { | ||||
| 	Username string `url:"username"` | ||||
| 	Resource string `url:"resource"` | ||||
| } | ||||
|  | ||||
| // SessionCookie is the cookie for the session (exculding the expiry) | ||||
| type SessionCookie struct { | ||||
| 	Username    string | ||||
| @@ -127,25 +34,13 @@ type TinyauthLabels struct { | ||||
| 	Headers        map[string]string | ||||
| } | ||||
|  | ||||
| // TailscaleQuery is the query parameters for the tailscale endpoint | ||||
| type TailscaleQuery struct { | ||||
| 	Code int `url:"code"` | ||||
| } | ||||
|  | ||||
| // Proxy is the uri parameters for the proxy endpoint | ||||
| type Proxy struct { | ||||
| 	Proxy string `uri:"proxy" binding:"required"` | ||||
| } | ||||
|  | ||||
| // User Context response is the response for the user context endpoint | ||||
| type UserContextResponse struct { | ||||
| 	Status      int    `json:"status"` | ||||
| 	Message     string `json:"message"` | ||||
| 	IsLoggedIn  bool   `json:"isLoggedIn"` | ||||
| 	Username    string `json:"username"` | ||||
| 	Provider    string `json:"provider"` | ||||
| 	Oauth       bool   `json:"oauth"` | ||||
| 	TotpPending bool   `json:"totpPending"` | ||||
| // UserContext is the context for the user | ||||
| type UserContext struct { | ||||
| 	Username    string | ||||
| 	IsLoggedIn  bool | ||||
| 	OAuth       bool | ||||
| 	Provider    string | ||||
| 	TotpPending bool | ||||
| } | ||||
|  | ||||
| // App Context is the response for the app context endpoint | ||||
| @@ -157,18 +52,3 @@ type AppContext struct { | ||||
| 	Title               string   `json:"title"` | ||||
| 	GenericName         string   `json:"genericName"` | ||||
| } | ||||
|  | ||||
| // Totp request is the request for the totp endpoint | ||||
| type TotpRequest struct { | ||||
| 	Code string `json:"code"` | ||||
| } | ||||
|  | ||||
| // Server configuration | ||||
| type HandlersConfig struct { | ||||
| 	AppURL          string | ||||
| 	Domain          string | ||||
| 	CookieSecure    bool | ||||
| 	DisableContinue bool | ||||
| 	GenericName     string | ||||
| 	Title           string | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user