107 lines
2.8 KiB
Go
107 lines
2.8 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"git.kirlllll.ru/volontery/backend/internal/service"
|
|
)
|
|
|
|
// RequirePermission создает middleware для проверки разрешения
|
|
func RequirePermission(userService *service.UserService, permission string) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
userID, ok := GetUserIDFromContext(r.Context())
|
|
if !ok {
|
|
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
hasPermission, err := userService.HasPermission(r.Context(), userID, permission)
|
|
if err != nil {
|
|
http.Error(w, "failed to check permissions", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if !hasPermission {
|
|
http.Error(w, "forbidden: insufficient permissions", http.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|
|
|
|
// RequireRole создает middleware для проверки роли
|
|
func RequireRole(userService *service.UserService, roleName string) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
userID, ok := GetUserIDFromContext(r.Context())
|
|
if !ok {
|
|
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
roles, err := userService.GetUserRoles(r.Context(), userID)
|
|
if err != nil {
|
|
http.Error(w, "failed to check roles", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
hasRole := false
|
|
for _, role := range roles {
|
|
if role.Name == roleName {
|
|
hasRole = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !hasRole {
|
|
http.Error(w, "forbidden: required role not assigned", http.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|
|
|
|
// RequireAnyRole создает middleware для проверки наличия хотя бы одной из ролей
|
|
func RequireAnyRole(userService *service.UserService, roleNames ...string) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
userID, ok := GetUserIDFromContext(r.Context())
|
|
if !ok {
|
|
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
roles, err := userService.GetUserRoles(r.Context(), userID)
|
|
if err != nil {
|
|
http.Error(w, "failed to check roles", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
hasAnyRole := false
|
|
for _, role := range roles {
|
|
for _, requiredRole := range roleNames {
|
|
if role.Name == requiredRole {
|
|
hasAnyRole = true
|
|
break
|
|
}
|
|
}
|
|
if hasAnyRole {
|
|
break
|
|
}
|
|
}
|
|
|
|
if !hasAnyRole {
|
|
http.Error(w, "forbidden: none of the required roles assigned", http.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|