first commit
This commit is contained in:
		
							
								
								
									
										136
									
								
								internal/middleware/auth.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								internal/middleware/auth.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
package middleware
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	config "learnsteam/cslms-api/configs"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/golang-jwt/jwt/v5"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Auth(permission string) gin.HandlerFunc {
 | 
			
		||||
	return func(c *gin.Context) {
 | 
			
		||||
		sub, err := UserID(c.Request)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
 | 
			
		||||
			c.Abort()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		role, err := Role(c.Request)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
 | 
			
		||||
			c.Abort()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if permission != "member" && *role != permission {
 | 
			
		||||
			fmt.Println("permission", permission, "role", *role)
 | 
			
		||||
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
 | 
			
		||||
			c.Abort()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Println("token", extract(c.Request))
 | 
			
		||||
		fmt.Println("sub", sub)
 | 
			
		||||
 | 
			
		||||
		c.Set("token", extract(c.Request))
 | 
			
		||||
		c.Set("sub", sub)
 | 
			
		||||
		c.Set("role", role)
 | 
			
		||||
		c.Next()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Permission(permission *string) gin.HandlerFunc {
 | 
			
		||||
	return func(c *gin.Context) {
 | 
			
		||||
		sub, err := UserID(c.Request)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
 | 
			
		||||
			c.Abort()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		role, err := Role(c.Request)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
 | 
			
		||||
			c.Abort()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if role != permission {
 | 
			
		||||
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
 | 
			
		||||
			c.Abort()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Println("token", extract(c.Request))
 | 
			
		||||
		fmt.Println("sub", sub)
 | 
			
		||||
 | 
			
		||||
		c.Set("token", extract(c.Request))
 | 
			
		||||
		c.Set("sub", sub)
 | 
			
		||||
		c.Set("role", role)
 | 
			
		||||
		c.Next()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func extract(r *http.Request) string {
 | 
			
		||||
	authorization := r.Header.Get("Authorization")
 | 
			
		||||
	strArr := strings.Split(authorization, " ")
 | 
			
		||||
	if len(strArr) == 2 {
 | 
			
		||||
		return strArr[1]
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func verify(r *http.Request) (*jwt.Token, error) {
 | 
			
		||||
	tokenString := extract(r)
 | 
			
		||||
	jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
 | 
			
		||||
		if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
 | 
			
		||||
			return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
 | 
			
		||||
		}
 | 
			
		||||
		return []byte(config.SECRET_KEY), nil
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return jwtToken, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func UserID(r *http.Request) (int64, error) {
 | 
			
		||||
	jwtToken, err := verify(r)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return -1, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	claims, ok := jwtToken.Claims.(jwt.MapClaims)
 | 
			
		||||
	if !ok || !jwtToken.Valid {
 | 
			
		||||
		return -1, errors.New("refresh token is invalid")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sub := claims["sub"].(float64)
 | 
			
		||||
	user_id := int64(sub)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return -1, err
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println(user_id)
 | 
			
		||||
 | 
			
		||||
	return user_id, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Role(r *http.Request) (*string, error) {
 | 
			
		||||
	jwtToken, err := verify(r)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	claims, ok := jwtToken.Claims.(jwt.MapClaims)
 | 
			
		||||
	if !ok || !jwtToken.Valid {
 | 
			
		||||
		return nil, errors.New("refresh token is invalid")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	role := claims["role"].(string)
 | 
			
		||||
 | 
			
		||||
	return &role, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								internal/middleware/transaction.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								internal/middleware/transaction.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
package middleware
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func StatusInList(status int, statusList []int) bool {
 | 
			
		||||
	for _, i := range statusList {
 | 
			
		||||
		for i == status {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Transaction(db *gorm.DB) gin.HandlerFunc {
 | 
			
		||||
	return func(c *gin.Context) {
 | 
			
		||||
		txHandle := db.Begin()
 | 
			
		||||
		log.Print("begining database transaction")
 | 
			
		||||
 | 
			
		||||
		defer func() {
 | 
			
		||||
			if r := recover(); r != nil {
 | 
			
		||||
				txHandle.Rollback()
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
 | 
			
		||||
		c.Set("db_trx", txHandle)
 | 
			
		||||
		c.Next()
 | 
			
		||||
 | 
			
		||||
		if StatusInList(c.Writer.Status(), []int{http.StatusOK, http.StatusCreated}) {
 | 
			
		||||
			log.Print("committing transactions")
 | 
			
		||||
			if err := txHandle.Commit().Error; err != nil {
 | 
			
		||||
				log.Print("transaction commit error: ", err)
 | 
			
		||||
			} else {
 | 
			
		||||
				log.Print("rollback transaction due to status code: ", c.Writer.Status())
 | 
			
		||||
				txHandle.Rollback()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user