MIF_E31222379_BE/middleware/additional_middleware.go

199 lines
5.1 KiB
Go

package middleware
/*
import (
"fmt"
"time"
"rijig/utils"
"github.com/gofiber/fiber/v2"
)
func RateLimitByUser(maxRequests int, duration time.Duration) fiber.Handler {
return func(c *fiber.Ctx) error {
claims, err := GetUserFromContext(c)
if err != nil {
return err
}
key := fmt.Sprintf("rate_limit:%s:%s", claims.UserID, c.Route().Path)
count, err := utils.IncrementCounter(key, duration)
if err != nil {
return c.Next()
}
if count > int64(maxRequests) {
ttl, _ := utils.GetTTL(key)
return c.Status(fiber.StatusTooManyRequests).JSON(fiber.Map{
"error": "Rate limit exceeded",
"message": "Terlalu banyak permintaan, silakan coba lagi nanti",
"retry_after": int64(ttl.Seconds()),
"limit": maxRequests,
"remaining": 0,
})
}
c.Set("X-RateLimit-Limit", fmt.Sprintf("%d", maxRequests))
c.Set("X-RateLimit-Remaining", fmt.Sprintf("%d", maxRequests-int(count)))
c.Set("X-RateLimit-Reset", fmt.Sprintf("%d", time.Now().Add(duration).Unix()))
return c.Next()
}
}
func SessionValidation() fiber.Handler {
return func(c *fiber.Ctx) error {
claims, err := GetUserFromContext(c)
if err != nil {
return err
}
if claims.SessionID == "" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "Invalid session",
"message": "Session tidak valid",
})
}
sessionKey := fmt.Sprintf("session:%s", claims.SessionID)
var sessionData map[string]interface{}
err = utils.GetCache(sessionKey, &sessionData)
if err != nil {
if err.Error() == "ErrCacheMiss" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "Session not found",
"message": "Session tidak ditemukan, silakan login kembali",
})
}
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "Session error",
"message": "Terjadi kesalahan saat validasi session",
})
}
if sessionData["user_id"] != claims.UserID {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "Session mismatch",
"message": "Session tidak sesuai dengan user",
})
}
if expiryInterface, exists := sessionData["expires_at"]; exists {
if expiry, ok := expiryInterface.(float64); ok {
if time.Now().Unix() > int64(expiry) {
utils.DeleteCache(sessionKey)
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "Session expired",
"message": "Session telah berakhir, silakan login kembali",
})
}
}
}
return c.Next()
}
}
func RequireApprovedRegistration() fiber.Handler {
return func(c *fiber.Ctx) error {
claims, err := GetUserFromContext(c)
if err != nil {
return err
}
if claims.RegistrationStatus == utils.RegStatusRejected {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
"error": "Registration rejected",
"message": "Registrasi Anda ditolak, silakan hubungi admin",
})
}
if claims.RegistrationStatus == utils.RegStatusPending {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
"error": "Registration pending",
"message": "Registrasi Anda masih menunggu persetujuan admin",
})
}
if claims.RegistrationStatus != utils.RegStatusComplete {
progress := utils.GetUserRegistrationProgress(claims.UserID)
nextStep := utils.GetNextRegistrationStep(claims.Role, progress)
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
"error": "Registration incomplete",
"message": "Silakan lengkapi registrasi terlebih dahulu",
"registration_status": claims.RegistrationStatus,
"next_step": nextStep,
})
}
return c.Next()
}
}
func ConditionalAuth(condition func(*utils.JWTClaims) bool, errorMessage string) fiber.Handler {
return func(c *fiber.Ctx) error {
claims, err := GetUserFromContext(c)
if err != nil {
return err
}
if !condition(claims) {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
"error": "Condition not met",
"message": errorMessage,
})
}
return c.Next()
}
}
func RequireSpecificRole(role string) fiber.Handler {
return ConditionalAuth(
func(claims *utils.JWTClaims) bool {
return claims.Role == role
},
fmt.Sprintf("Akses ini hanya untuk role %s", role),
)
}
func RequireCompleteRegistrationAndSpecificRole(role string) fiber.Handler {
return ConditionalAuth(
func(claims *utils.JWTClaims) bool {
return claims.Role == role && utils.IsRegistrationComplete(claims.RegistrationStatus)
},
fmt.Sprintf("Akses ini hanya untuk role %s dengan registrasi lengkap", role),
)
}
func DeviceValidation() fiber.Handler {
return func(c *fiber.Ctx) error {
claims, err := GetUserFromContext(c)
if err != nil {
return err
}
deviceID := c.Get("X-Device-ID")
if deviceID == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Device ID required",
"message": "Device ID diperlukan",
})
}
if claims.DeviceID != deviceID {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "Device mismatch",
"message": "Token tidak valid untuk device ini",
})
}
return c.Next()
}
}
*/