Skip to content
Snippets Groups Projects
Select Git revision
  • dd5838f013cd813d80e3895089badcb3167d2459
  • main default protected
  • v1.298.0
  • v1.297.0
  • v1.296.0
  • v1.295.0
  • v1.294.0
  • v1.293.0
  • v1.292.0
  • v1.291.0
  • v1.290.0
  • v1.289.0
  • v1.288.0
  • v1.287.0
  • v1.286.0
  • v1.285.0
  • v1.284.0
  • v1.283.0
  • v1.282.0
  • v1.281.0
  • v1.280.0
  • v1.279.0
22 results

session.go

Blame
  • session.go 4.43 KiB
    package auth
    
    import (
    	"crypto/hmac"
    	"crypto/sha256"
    	"encoding/hex"
    	"encoding/json"
    	"github.com/aws/aws-lambda-go/events"
    	"github.com/google/uuid"
    	"github.com/thoas/go-funk"
    	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/date_utils"
    	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/handler_utils"
    	"time"
    )
    
    type SessionToken struct {
    	IP          string    `json:"ip"`
    	UserAgent   string    `json:"user_agent"`
    	TimeCreated time.Time `json:"time_created"`
    	Token       string    `json:"session_token"`
    }
    
    // SignSessionTokenWithKey signs the session token string using the secret.
    func SignSessionTokenWithKey(secretKey string, sessionTokenString string) string {
    	signer := hmac.New(sha256.New, []byte(secretKey))
    	signer.Write([]byte(sessionTokenString))
    	return hex.EncodeToString(signer.Sum(nil))
    }
    
    // GetSessionTokenString creates a unique session token string from the API request.
    func GetSessionTokenString(request events.APIGatewayProxyRequest) (string, error) {
    	sessionToken := SessionToken{
    		IP:          request.RequestContext.Identity.SourceIP,
    		UserAgent:   handler_utils.FindHeaderValue(request.Headers, "user-agent"),
    		TimeCreated: date_utils.CurrentDate().Round(time.Second),
    		Token:       uuid.New().String(),
    	}
    	sessionTokenBytes, err := json.Marshal(sessionToken)
    	return string(sessionTokenBytes), err
    }
    
    // GetSignedSessionTokenString creates a unique session token string from the API request and signs it using the secret.
    func GetSignedSessionTokenString(request events.APIGatewayProxyRequest, secretKey string) (string, error) {
    	sessionTokenBytes, err := GetSessionTokenString(request)
    	if err != nil {
    		return "", err
    	}
    
    	return SignSessionTokenWithKey(secretKey, sessionTokenBytes), nil
    }
    
    // ValidateJWTWithSessionTokens attempts to validate the JWT string by signing each session token using the secret, and
    // using the resulting signed session token to validate the JWT. If the JWT can be validated using a session token, the
    // JsonWebToken is returned, otherwise nil is returned. If the JWT is expired, nil is returned along with the session token.
    func ValidateJWTWithSessionTokens(jsonWebTokenString string, secretKey string, sessionTokens []string) (validJsonWebToken *JsonWebToken, expiredSessionToken *string) {
    	// Test each session token to find one that is valid
    	for _, sessionToken := range sessionTokens {
    		jsonWebToken, err := ValidateJWTWithSessionToken(jsonWebTokenString, secretKey, sessionToken)
    		if err == nil {
    			return &jsonWebToken, nil
    		} else if err.Error() == "token has expired" {
    			return nil, &sessionToken
    		}
    	}
    
    	return nil, nil
    }
    
    // FindAndRemoveCurrentSessionToken attempts to validate the JWT string by signing each session token using the secret,
    // and using the resulting signed session token to validate the JWT. If the JWT is successfully validated with one of