From 57da00befad374751cf8e37f1ac640597f822796 Mon Sep 17 00:00:00 2001 From: Patrick Alvin Alcala Date: Mon, 10 Nov 2025 13:05:07 +0800 Subject: [PATCH] Added token checker --- backend/middleware/tokenChecker.go | 102 +++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 backend/middleware/tokenChecker.go diff --git a/backend/middleware/tokenChecker.go b/backend/middleware/tokenChecker.go new file mode 100644 index 0000000..012aa8f --- /dev/null +++ b/backend/middleware/tokenChecker.go @@ -0,0 +1,102 @@ +package middleware + +import ( + "log" + "net/http" + "os" + + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "errors" + "strconv" + "strings" + "time" + + "github.com/gin-gonic/gin" + _ "github.com/go-sql-driver/mysql" + "github.com/joho/godotenv" +) + +func decrypt(encrypted string) (string, error) { + err := godotenv.Load() + if err != nil { + log.Fatal("Error loading .env file") + } + + privateKey := os.Getenv("PRIVATE_KEY") + + cipherText, err := base64.StdEncoding.DecodeString(encrypted) + if err != nil { + return "", errors.New("cannot decode encrypted text") + } + + block, _ := pem.Decode([]byte(privateKey)) + if block == nil { + return "", errors.New("private key error") + } + priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return "", err + } + result, err := rsa.DecryptPKCS1v15(rand.Reader, priv, cipherText) + if err != nil { + return "", err + } + return string(result), nil +} + +func TokenChecker() gin.HandlerFunc { + return func(c *gin.Context) { + token := c.GetHeader("OCBO-Token") + start := strings.Index(token, "ocbo=") + len("ocbo=") + end := strings.LastIndex(token, "token") + + if token == "" { + c.JSON(http.StatusUnauthorized, gin.H{"error": "The request is missing an OCBO Token"}) + c.Abort() + return + } + + if start == -1 || end == -1 || start >= end { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid OCBO Token format"}) + c.Abort() + return + } + + extractedToken := token[start:end] + extractedToken = strings.ReplaceAll(extractedToken, "~", "/") + + decrypted, err := decrypt(extractedToken) + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid OCBO Token Value"}) + c.Abort() + return + } + + parts := strings.Split(decrypted, "-") + requested := parts[2] + requestedNum, _ := strconv.Atoi(requested) + expiration := parts[3] + expirationNum, _ := strconv.Atoi(expiration) + + unix := strconv.FormatInt(time.Now().UTC().Unix(), 10) + unixNum, _ := strconv.Atoi(unix) + + if requestedNum > expirationNum { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid OCBO Token Value"}) + c.Abort() + return + } + + if unixNum > expirationNum { + c.JSON(http.StatusUnauthorized, gin.H{"error": "OCBO Token Expired"}) + c.Abort() + return + } + + c.Next() + } +}