mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 05:21:57 +00:00
102 lines
2.9 KiB
Go
102 lines
2.9 KiB
Go
package middleware
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"gitlab.com/mbugroup/lti-api.git/internal/config"
|
|
"gitlab.com/mbugroup/lti-api.git/internal/modules/sso/session"
|
|
service "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
|
"gitlab.com/mbugroup/lti-api.git/internal/sso"
|
|
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
func Auth(userService service.UserService, requiredRights ...string) fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
authHeader := c.Get("Authorization")
|
|
token := strings.TrimSpace(strings.TrimPrefix(authHeader, "Bearer "))
|
|
|
|
if token == "" {
|
|
cookieName := config.SSOAccessCookieName
|
|
if cookieName == "" {
|
|
cookieName = "access"
|
|
}
|
|
token = strings.TrimSpace(c.Cookies(cookieName))
|
|
}
|
|
|
|
if token == "" {
|
|
return fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
|
}
|
|
|
|
verification, err := sso.VerifyAccessToken(token)
|
|
if err != nil {
|
|
return fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
|
}
|
|
|
|
if len(config.SSOAllowedAudiences) > 0 {
|
|
allowed := make(map[string]struct{}, len(config.SSOAllowedAudiences))
|
|
for _, aud := range config.SSOAllowedAudiences {
|
|
aud = strings.TrimSpace(aud)
|
|
if aud != "" {
|
|
allowed[aud] = struct{}{}
|
|
}
|
|
}
|
|
audienceValid := false
|
|
for _, aud := range verification.Claims.Audience {
|
|
if _, ok := allowed[aud]; ok {
|
|
audienceValid = true
|
|
break
|
|
}
|
|
}
|
|
if !audienceValid {
|
|
return fiber.NewError(fiber.StatusUnauthorized, "invalid audience")
|
|
}
|
|
}
|
|
|
|
if revoker := session.GetRevocationStore(); revoker != nil {
|
|
if fingerprint := session.TokenFingerprint(token); fingerprint != "" {
|
|
revoked, err := revoker.IsRevoked(c.Context(), fingerprint)
|
|
if err != nil {
|
|
utils.Log.WithError(err).Warn("failed to check token revocation")
|
|
return fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
|
}
|
|
if revoked {
|
|
return fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
|
}
|
|
}
|
|
}
|
|
|
|
user, err := userService.GetBySSOUserID(c, verification.UserID)
|
|
if err != nil || user == nil {
|
|
return fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
|
}
|
|
|
|
c.Locals("user", user)
|
|
c.Locals("token_claims", verification.Claims)
|
|
|
|
// if len(requiredRights) > 0 {
|
|
// userRights, hasRights := config.RoleRights[user.Role]
|
|
// if (!hasRights || !hasAllRights(userRights, requiredRights)) && c.Params("userId") != userID {
|
|
// return fiber.NewError(fiber.StatusForbidden, "You don't have permission to access this resource")
|
|
// }
|
|
// }
|
|
|
|
return c.Next()
|
|
}
|
|
}
|
|
|
|
// func hasAllRights(userRights, requiredRights []string) bool {
|
|
// rightSet := make(map[string]struct{}, len(userRights))
|
|
// for _, right := range userRights {
|
|
// rightSet[right] = struct{}{}
|
|
// }
|
|
|
|
// for _, right := range requiredRights {
|
|
// if _, exists := rightSet[right]; !exists {
|
|
// return false
|
|
// }
|
|
// }
|
|
// return true
|
|
// }
|