mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-11-03 23:55:44 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			v4.0.1
			...
			6647c6cd78
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					6647c6cd78 | ||
| 
						 | 
					7231efcbc3 | ||
| 
						 | 
					5482430907 | 
@@ -2,6 +2,7 @@ package bootstrap
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
@@ -13,11 +14,13 @@ import (
 | 
				
			|||||||
	"tinyauth/internal/config"
 | 
						"tinyauth/internal/config"
 | 
				
			||||||
	"tinyauth/internal/controller"
 | 
						"tinyauth/internal/controller"
 | 
				
			||||||
	"tinyauth/internal/middleware"
 | 
						"tinyauth/internal/middleware"
 | 
				
			||||||
 | 
						"tinyauth/internal/model"
 | 
				
			||||||
	"tinyauth/internal/service"
 | 
						"tinyauth/internal/service"
 | 
				
			||||||
	"tinyauth/internal/utils"
 | 
						"tinyauth/internal/utils"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gin-gonic/gin"
 | 
						"github.com/gin-gonic/gin"
 | 
				
			||||||
	"github.com/rs/zerolog/log"
 | 
						"github.com/rs/zerolog/log"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Controller interface {
 | 
					type Controller interface {
 | 
				
			||||||
@@ -277,6 +280,10 @@ func (app *BootstrapApp) Setup() error {
 | 
				
			|||||||
		go app.heartbeat()
 | 
							go app.heartbeat()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Start DB cleanup routine
 | 
				
			||||||
 | 
						log.Debug().Msg("Starting database cleanup routine")
 | 
				
			||||||
 | 
						go app.dbCleanup(database)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Start server
 | 
						// Start server
 | 
				
			||||||
	address := fmt.Sprintf("%s:%d", app.config.Address, app.config.Port)
 | 
						address := fmt.Sprintf("%s:%d", app.config.Address, app.config.Port)
 | 
				
			||||||
	log.Info().Msgf("Starting server on %s", address)
 | 
						log.Info().Msgf("Starting server on %s", address)
 | 
				
			||||||
@@ -338,3 +345,17 @@ func (app *BootstrapApp) heartbeat() {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (app *BootstrapApp) dbCleanup(db *gorm.DB) {
 | 
				
			||||||
 | 
						ticker := time.NewTicker(time.Duration(30) * time.Minute)
 | 
				
			||||||
 | 
						defer ticker.Stop()
 | 
				
			||||||
 | 
						ctx := context.Background()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for ; true; <-ticker.C {
 | 
				
			||||||
 | 
							log.Debug().Msg("Cleaning up old database sessions")
 | 
				
			||||||
 | 
							_, err := gorm.G[model.Session](db).Where("expiry < ?", time.Now().UnixMilli()).Delete(ctx)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error().Err(err).Msg("Failed to cleanup old sessions")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,6 +72,7 @@ func (controller *OAuthController) oauthURLHandler(c *gin.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						service.GenerateVerifier()
 | 
				
			||||||
	state := service.GenerateState()
 | 
						state := service.GenerateState()
 | 
				
			||||||
	authURL := service.GetAuthURL(state)
 | 
						authURL := service.GetAuthURL(state)
 | 
				
			||||||
	c.SetCookie(controller.config.CSRFCookieName, state, int(time.Hour.Seconds()), "/", fmt.Sprintf(".%s", controller.config.CookieDomain), controller.config.SecureCookie, true)
 | 
						c.SetCookie(controller.config.CSRFCookieName, state, int(time.Hour.Seconds()), "/", fmt.Sprintf(".%s", controller.config.CookieDomain), controller.config.SecureCookie, true)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
package service
 | 
					package service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@@ -41,6 +43,7 @@ type AuthService struct {
 | 
				
			|||||||
	loginMutex    sync.RWMutex
 | 
						loginMutex    sync.RWMutex
 | 
				
			||||||
	ldap          *LdapService
 | 
						ldap          *LdapService
 | 
				
			||||||
	database      *gorm.DB
 | 
						database      *gorm.DB
 | 
				
			||||||
 | 
						ctx           context.Context
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, database *gorm.DB) *AuthService {
 | 
					func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, database *gorm.DB) *AuthService {
 | 
				
			||||||
@@ -54,6 +57,7 @@ func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapS
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (auth *AuthService) Init() error {
 | 
					func (auth *AuthService) Init() error {
 | 
				
			||||||
 | 
						auth.ctx = context.Background()
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -213,7 +217,7 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio
 | 
				
			|||||||
		OAuthName:   data.OAuthName,
 | 
							OAuthName:   data.OAuthName,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = auth.database.Create(&session).Error
 | 
						err = gorm.G[model.Session](auth.database).Create(auth.ctx, &session)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -231,10 +235,10 @@ func (auth *AuthService) DeleteSessionCookie(c *gin.Context) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res := auth.database.Unscoped().Where("uuid = ?", cookie).Delete(&model.Session{})
 | 
						_, err = gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).Delete(auth.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if res.Error != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return res.Error
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.SetCookie(auth.config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.config.CookieDomain), auth.config.SecureCookie, true)
 | 
						c.SetCookie(auth.config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.config.CookieDomain), auth.config.SecureCookie, true)
 | 
				
			||||||
@@ -249,15 +253,13 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie,
 | 
				
			|||||||
		return config.SessionCookie{}, err
 | 
							return config.SessionCookie{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var session model.Session
 | 
						session, err := gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).First(auth.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res := auth.database.Unscoped().Where("uuid = ?", cookie).First(&session)
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return config.SessionCookie{}, err
 | 
				
			||||||
	if res.Error != nil {
 | 
					 | 
				
			||||||
		return config.SessionCookie{}, res.Error
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if res.RowsAffected == 0 {
 | 
						if errors.Is(err, gorm.ErrRecordNotFound) {
 | 
				
			||||||
		return config.SessionCookie{}, fmt.Errorf("session not found")
 | 
							return config.SessionCookie{}, fmt.Errorf("session not found")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,10 +59,8 @@ func (generic *GenericOAuthService) Init() error {
 | 
				
			|||||||
	ctx := context.Background()
 | 
						ctx := context.Background()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
 | 
						ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
 | 
				
			||||||
	verifier := oauth2.GenerateVerifier()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	generic.context = ctx
 | 
						generic.context = ctx
 | 
				
			||||||
	generic.verifier = verifier
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,6 +74,12 @@ func (generic *GenericOAuthService) GenerateState() string {
 | 
				
			|||||||
	return state
 | 
						return state
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (generic *GenericOAuthService) GenerateVerifier() string {
 | 
				
			||||||
 | 
						verifier := oauth2.GenerateVerifier()
 | 
				
			||||||
 | 
						generic.verifier = verifier
 | 
				
			||||||
 | 
						return verifier
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (generic *GenericOAuthService) GetAuthURL(state string) string {
 | 
					func (generic *GenericOAuthService) GetAuthURL(state string) string {
 | 
				
			||||||
	return generic.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(generic.verifier))
 | 
						return generic.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(generic.verifier))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,10 +53,7 @@ func (github *GithubOAuthService) Init() error {
 | 
				
			|||||||
	httpClient := &http.Client{}
 | 
						httpClient := &http.Client{}
 | 
				
			||||||
	ctx := context.Background()
 | 
						ctx := context.Background()
 | 
				
			||||||
	ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
 | 
						ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
 | 
				
			||||||
	verifier := oauth2.GenerateVerifier()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	github.context = ctx
 | 
						github.context = ctx
 | 
				
			||||||
	github.verifier = verifier
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,6 +67,12 @@ func (github *GithubOAuthService) GenerateState() string {
 | 
				
			|||||||
	return state
 | 
						return state
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (github *GithubOAuthService) GenerateVerifier() string {
 | 
				
			||||||
 | 
						verifier := oauth2.GenerateVerifier()
 | 
				
			||||||
 | 
						github.verifier = verifier
 | 
				
			||||||
 | 
						return verifier
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (github *GithubOAuthService) GetAuthURL(state string) string {
 | 
					func (github *GithubOAuthService) GetAuthURL(state string) string {
 | 
				
			||||||
	return github.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(github.verifier))
 | 
						return github.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(github.verifier))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,10 +48,7 @@ func (google *GoogleOAuthService) Init() error {
 | 
				
			|||||||
	httpClient := &http.Client{}
 | 
						httpClient := &http.Client{}
 | 
				
			||||||
	ctx := context.Background()
 | 
						ctx := context.Background()
 | 
				
			||||||
	ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
 | 
						ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
 | 
				
			||||||
	verifier := oauth2.GenerateVerifier()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	google.context = ctx
 | 
						google.context = ctx
 | 
				
			||||||
	google.verifier = verifier
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -65,6 +62,12 @@ func (oauth *GoogleOAuthService) GenerateState() string {
 | 
				
			|||||||
	return state
 | 
						return state
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (google *GoogleOAuthService) GenerateVerifier() string {
 | 
				
			||||||
 | 
						verifier := oauth2.GenerateVerifier()
 | 
				
			||||||
 | 
						google.verifier = verifier
 | 
				
			||||||
 | 
						return verifier
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (google *GoogleOAuthService) GetAuthURL(state string) string {
 | 
					func (google *GoogleOAuthService) GetAuthURL(state string) string {
 | 
				
			||||||
	return google.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(google.verifier))
 | 
						return google.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(google.verifier))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ import (
 | 
				
			|||||||
type OAuthService interface {
 | 
					type OAuthService interface {
 | 
				
			||||||
	Init() error
 | 
						Init() error
 | 
				
			||||||
	GenerateState() string
 | 
						GenerateState() string
 | 
				
			||||||
 | 
						GenerateVerifier() string
 | 
				
			||||||
	GetAuthURL(state string) string
 | 
						GetAuthURL(state string) string
 | 
				
			||||||
	VerifyCode(code string) error
 | 
						VerifyCode(code string) error
 | 
				
			||||||
	Userinfo() (config.Claims, error)
 | 
						Userinfo() (config.Claims, error)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user