mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-11-04 08:05:42 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			dc67be2ba0
			...
			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