86 lines
2.6 KiB
Go
86 lines
2.6 KiB
Go
package handlers
|
|
|
|
import (
|
|
"authorization/helper"
|
|
"authorization/middleware"
|
|
"authorization/models"
|
|
"authorization/services"
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
)
|
|
|
|
var authService *models.CachedAuthorizationService
|
|
|
|
// InitAuthService initializes the authorization service with caching
|
|
func InitAuthService() {
|
|
authService = services.NewCachedAuthorizationService()
|
|
}
|
|
|
|
// AuthorizeHandler godoc
|
|
// @Summary Check user authorization (RBAC + ABAC)
|
|
// @Description Validates if a user has permission to perform an action on a resource using Role-Based and Attribute-Based Access Control
|
|
// @Tags authorization
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param request body models.AuthorizationContext true "Authorization context with resource data"
|
|
// @Success 200 {object} models.AuthorizationResult
|
|
// @Failure 400 {object} map[string]string
|
|
// @Failure 401 {object} map[string]string
|
|
// @Failure 403 {object} models.AuthorizationResult
|
|
// @Security BearerToken
|
|
// @Router /v1/auth/check [post]
|
|
func AuthorizeHandler(w http.ResponseWriter, r *http.Request) {
|
|
// Get claims from JWT middleware
|
|
claims, ok := middleware.GetClaims(r)
|
|
if !ok {
|
|
helper.RespondWithError(w, http.StatusUnauthorized, "Unauthorized")
|
|
return
|
|
}
|
|
|
|
var ctx models.AuthorizationContext
|
|
|
|
err := json.NewDecoder(r.Body).Decode(&ctx)
|
|
if err != nil {
|
|
helper.RespondWithError(w, http.StatusBadRequest, "Invalid request payload")
|
|
return
|
|
}
|
|
|
|
// Validate request
|
|
if ctx.UserID == "" || ctx.Resource == "" || ctx.Action == "" {
|
|
helper.RespondWithError(w, http.StatusBadRequest, "Missing required fields: user_id, resource, action")
|
|
return
|
|
}
|
|
|
|
log.Print("Authorization request for user=", ctx.UserID, ", resource=", ctx.Resource, ", action=", ctx.Action)
|
|
log.Print("JWT claims user=", claims.UserID, ", username=", claims.Username, ", role=", claims.RoleID)
|
|
// Verify JWT user matches request user (security check)
|
|
if ctx.UserID != claims.UserID {
|
|
helper.RespondWithError(w, http.StatusForbidden, "User ID mismatch")
|
|
return
|
|
}
|
|
|
|
// Initialize maps if nil
|
|
if ctx.ResourceData == nil {
|
|
ctx.ResourceData = make(map[string]string)
|
|
}
|
|
if ctx.Environment == nil {
|
|
ctx.Environment = make(map[string]string)
|
|
}
|
|
|
|
// Perform authorization
|
|
result, err := services.AuthorizeWithCache(authService, &ctx)
|
|
if err != nil {
|
|
helper.LogError(err, "Authorization service error")
|
|
helper.RespondWithError(w, http.StatusInternalServerError, "Authorization check failed")
|
|
return
|
|
}
|
|
|
|
// Return result
|
|
if result.Allowed {
|
|
helper.RespondWithJSON(w, http.StatusOK, result)
|
|
} else {
|
|
helper.RespondWithJSON(w, http.StatusForbidden, result)
|
|
}
|
|
}
|