mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-10-31 06:05:43 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			v4.0.1-bet
			...
			fix/sessio
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | acc3ad97cd | ||
|   | 5409aa5f7f | ||
|   | ebcf6e6aa6 | 
							
								
								
									
										12
									
								
								cmd/root.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								cmd/root.go
									
									
									
									
									
								
							| @@ -74,6 +74,15 @@ var rootCmd = &cobra.Command{ | ||||
| 		csrfCookieName := fmt.Sprintf("%s-%s", constants.CsrfCookieName, cookieId) | ||||
| 		redirectCookieName := fmt.Sprintf("%s-%s", constants.RedirectCookieName, cookieId) | ||||
|  | ||||
| 		// Generate HMAC and encryption secrets | ||||
| 		log.Debug().Msg("Deriving HMAC and encryption secrets") | ||||
|  | ||||
| 		hmacSecret, err := utils.DeriveKey(config.Secret, "hmac") | ||||
| 		HandleError(err, "Failed to derive HMAC secret") | ||||
|  | ||||
| 		encryptionSecret, err := utils.DeriveKey(config.Secret, "encryption") | ||||
| 		HandleError(err, "Failed to derive encryption secret") | ||||
|  | ||||
| 		// Create OAuth config | ||||
| 		oauthConfig := types.OAuthConfig{ | ||||
| 			GithubClientId:      config.GithubClientId, | ||||
| @@ -115,13 +124,14 @@ var rootCmd = &cobra.Command{ | ||||
| 		authConfig := types.AuthConfig{ | ||||
| 			Users:             users, | ||||
| 			OauthWhitelist:    config.OAuthWhitelist, | ||||
| 			Secret:            config.Secret, | ||||
| 			CookieSecure:      config.CookieSecure, | ||||
| 			SessionExpiry:     config.SessionExpiry, | ||||
| 			Domain:            domain, | ||||
| 			LoginTimeout:      config.LoginTimeout, | ||||
| 			LoginMaxRetries:   config.LoginMaxRetries, | ||||
| 			SessionCookieName: sessionCookieName, | ||||
| 			HMACSecret:        hmacSecret, | ||||
| 			EncryptionSecret:  encryptionSecret, | ||||
| 		} | ||||
|  | ||||
| 		// Create hooks config | ||||
|   | ||||
| @@ -44,7 +44,8 @@ var handlersConfig = types.HandlersConfig{ | ||||
| var authConfig = types.AuthConfig{ | ||||
| 	Users:             types.Users{}, | ||||
| 	OauthWhitelist:    "", | ||||
| 	Secret:            "super-secret-api-thing-for-tests", // It is 32 chars long | ||||
| 	HMACSecret:        "super-secret-api-thing-for-test1", | ||||
| 	EncryptionSecret:  "super-secret-api-thing-for-test2", | ||||
| 	CookieSecure:      false, | ||||
| 	SessionExpiry:     3600, | ||||
| 	LoginTimeout:      0, | ||||
|   | ||||
| @@ -33,7 +33,7 @@ type Auth struct { | ||||
|  | ||||
| func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) { | ||||
| 	// Create cookie store | ||||
| 	store := sessions.NewCookieStore([]byte(auth.Config.Secret)) | ||||
| 	store := sessions.NewCookieStore([]byte(auth.Config.HMACSecret), []byte(auth.Config.EncryptionSecret)) | ||||
|  | ||||
| 	// Configure cookie store | ||||
| 	store.Options = &sessions.Options{ | ||||
| @@ -46,9 +46,21 @@ func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) { | ||||
|  | ||||
| 	// Get session | ||||
| 	session, err := store.Get(c.Request, auth.Config.SessionCookieName) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		log.Error().Err(err).Msg("Failed to get session") | ||||
| 		return nil, err | ||||
| 		log.Warn().Err(err).Msg("Invalid session, clearing cookie and retrying") | ||||
|  | ||||
| 		// Delete the session cookie if there is an error | ||||
| 		c.SetCookie(auth.Config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.Config.Domain), auth.Config.CookieSecure, true) | ||||
|  | ||||
| 		// Try to get the session again | ||||
| 		session, err = store.Get(c.Request, auth.Config.SessionCookieName) | ||||
|  | ||||
| 		if err != nil { | ||||
| 			// If we still can't get the session, log the error and return nil | ||||
| 			log.Error().Err(err).Msg("Failed to get session") | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return session, nil | ||||
|   | ||||
| @@ -80,12 +80,13 @@ type AuthConfig struct { | ||||
| 	Users             Users | ||||
| 	OauthWhitelist    string | ||||
| 	SessionExpiry     int | ||||
| 	Secret            string | ||||
| 	CookieSecure      bool | ||||
| 	Domain            string | ||||
| 	LoginTimeout      int | ||||
| 	LoginMaxRetries   int | ||||
| 	SessionCookieName string | ||||
| 	HMACSecret        string | ||||
| 	EncryptionSecret  string | ||||
| } | ||||
|  | ||||
| // HooksConfig is the configuration for the hooks service | ||||
|   | ||||
| @@ -1,8 +1,11 @@ | ||||
| package utils | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/sha256" | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| @@ -11,6 +14,7 @@ import ( | ||||
| 	"tinyauth/internal/types" | ||||
|  | ||||
| 	"github.com/traefik/paerser/parser" | ||||
| 	"golang.org/x/crypto/hkdf" | ||||
|  | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| @@ -405,3 +409,32 @@ func FilterIP(filter string, ip string) (bool, error) { | ||||
| 	// If the filter is not a CIDR range or a single IP, return false | ||||
| 	return false, nil | ||||
| } | ||||
|  | ||||
| func DeriveKey(secret string, info string) (string, error) { | ||||
| 	// Create hashing function | ||||
| 	hash := sha256.New | ||||
|  | ||||
| 	// Create a new key using the secret and info | ||||
| 	hkdf := hkdf.New(hash, []byte(secret), nil, []byte(info)) // I am not using a salt because I just want two different keys from one secret, maybe bad practice | ||||
|  | ||||
| 	// Create a new key | ||||
| 	key := make([]byte, 24) | ||||
|  | ||||
| 	// Read the key from the HKDF | ||||
| 	_, err := io.ReadFull(hkdf, key) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	// Verify the key is not empty | ||||
| 	if bytes.Equal(key, make([]byte, 24)) { | ||||
| 		return "", errors.New("derived key is empty") | ||||
| 	} | ||||
|  | ||||
| 	// Encode the key to base64 | ||||
| 	encodedKey := base64.StdEncoding.EncodeToString(key) | ||||
|  | ||||
| 	// Return the key as a base64 encoded string | ||||
| 	return encodedKey, nil | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user