package handler import ( "authorization/internal" "net/http" "strings" "github.com/gin-gonic/gin" ) const ( authorizationHeader = "Authorization" userRoleKey = "user_role" userIdKey = "user_id" ) // userIdentity - базовый middleware, извлекает пользователя из токена // Не проверяет роли, только валидность токена func (h *Handler) userIdentity(c *gin.Context) { header := c.GetHeader(authorizationHeader) if header == "" { newErrorResponse(c, http.StatusUnauthorized, "Пустой header авторизации") c.Abort() return } headerParts := strings.Split(header, " ") if len(headerParts) != 2 || headerParts[0] != "Bearer" { newErrorResponse(c, http.StatusUnauthorized, "Невалидный формат токена") c.Abort() return } userRole, err := h.services.ParseToken(headerParts[1]) if err != nil { newErrorResponse(c, http.StatusUnauthorized, "Невалидный токен") c.Abort() return } c.Set(userRoleKey, userRole) c.Next() } func (h *Handler) requireRole(allowedRoles ...internal.UserRole) gin.HandlerFunc { return func(c *gin.Context) { userRole, exists := c.Get(userRoleKey) if !exists { newErrorResponse(c, http.StatusUnauthorized, "Пользователь не авторизован") c.Abort() return } userRoleStr, ok := userRole.(string) if !ok { newErrorResponse(c, http.StatusInternalServerError, "Ошибка извлечения роли пользователя") c.Abort() return } // Проверяем, есть ли роль пользователя в списке разрешенных for _, allowedRole := range allowedRoles { if userRoleStr == allowedRole.ToString() { c.Next() return } } newErrorResponse(c, http.StatusForbidden, "Недостаточно прав для выполнения запроса") c.Abort() } } // Вспомогательные методы для удобства // requireAdmin - только администраторы func (h *Handler) requireAdmin() gin.HandlerFunc { return h.requireRole(internal.Admin) } // requireTeacher - учителя и администраторы func (h *Handler) requireTeacher() gin.HandlerFunc { return h.requireRole(internal.Teacher, internal.Admin) } func (h *Handler) requireStudent() gin.HandlerFunc { return h.requireRole(internal.Student, internal.Teacher, internal.Admin) }