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, "-") partCount := len(parts) var finalRequest int var finalExpiration int if partCount == 4 { requested := parts[2] requestedNum, _ := strconv.Atoi(requested) finalRequest = requestedNum expiration := parts[3] expirationNum, _ := strconv.Atoi(expiration) finalExpiration = expirationNum } else { requested := parts[3] requestedNum, _ := strconv.Atoi(requested) finalRequest = requestedNum expiration := parts[4] expirationNum, _ := strconv.Atoi(expiration) finalExpiration = expirationNum } unix := strconv.FormatInt(time.Now().UTC().Unix(), 10) unixNum, _ := strconv.Atoi(unix) if finalRequest > finalExpiration { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid OCBO Token Value"}) c.Abort() return } if unixNum > finalExpiration { c.JSON(http.StatusUnauthorized, gin.H{"error": "OCBO Token Expired"}) c.Abort() return } c.Next() } }