package routes import ( "bssapp-backend/auth" "bssapp-backend/internal/auditlog" "bssapp-backend/permissions" "database/sql" "encoding/json" "fmt" "log" "net/http" "strconv" "strings" "github.com/gorilla/mux" ) /* ===================================================== GET USER OVERRIDES GET /api/users/{id}/permissions ===================================================== */ func GetUserPermissionsHandler(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // ✅ Auth kontrolü yeterli (Yetki middleware'de) claims, ok := auth.GetClaimsFromContext(r.Context()) if !ok || claims == nil { http.Error(w, "unauthorized", http.StatusUnauthorized) return } idStr := mux.Vars(r)["id"] id, err := strconv.ParseInt(idStr, 10, 64) if err != nil || id <= 0 { http.Error(w, "invalid id", http.StatusBadRequest) return } repo := permissions.NewPermissionRepository(db) rows, err := repo.GetUserOverridesByUserID(id) if err != nil { http.Error(w, "db error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(rows) } } /* ===================================================== SAVE USER OVERRIDES POST /api/users/{id}/permissions ===================================================== */ func SaveUserPermissionsHandler(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // ✅ Auth kontrolü yeterli claims, ok := auth.GetClaimsFromContext(r.Context()) if !ok || claims == nil { http.Error(w, "unauthorized", http.StatusUnauthorized) return } userIDStr := mux.Vars(r)["id"] userID, err := strconv.ParseInt(userIDStr, 10, 64) if err != nil || userID <= 0 { http.Error(w, "invalid id", http.StatusBadRequest) return } /* ================= PAYLOAD ================= */ var list []permissions.UserPermissionRequest if err := json.NewDecoder(r.Body).Decode(&list); err != nil { http.Error(w, "bad payload", http.StatusBadRequest) return } repo := permissions.NewPermissionRepository(db) /* ================= OLD ================= */ oldRows, _ := repo.GetUserOverridesByUserID(userID) oldMap := map[string]bool{} for _, p := range oldRows { key := p.Module + ":" + p.Action oldMap[key] = p.Allowed } /* ================= NEW ================= */ newMap := map[string]bool{} for _, p := range list { key := p.Module + ":" + p.Action newMap[key] = p.Allowed } /* ================= DIFF ================= */ var changes []map[string]any for key, newVal := range newMap { oldVal := oldMap[key] if oldVal != newVal { parts := strings.Split(key, ":") if len(parts) != 2 { continue } changes = append(changes, map[string]any{ "module": parts[0], "action": parts[1], "before": oldVal, "after": newVal, }) } } /* ================= SAVE ================= */ if err := repo.SaveUserOverrides(userID, list); err != nil { http.Error(w, "db error", http.StatusInternalServerError) return } /* ================= AUDIT ================= */ if len(changes) > 0 && claims != nil { var targetUsername string _ = db.QueryRow(` SELECT username FROM mk_dfusr WHERE id = $1 `, userID).Scan(&targetUsername) auditlog.Enqueue(r.Context(), auditlog.ActivityLog{ ActionType: "user_permission_change", ActionCategory: "permission", ActionTarget: fmt.Sprintf( "/api/users/%d/permissions", userID, ), Description: "user permission overrides updated", Username: claims.Username, RoleCode: claims.RoleCode, DfUsrID: int64(claims.ID), TargetDfUsrID: userID, TargetUsername: targetUsername, ChangeBefore: map[string]any{ "permissions": oldRows, }, ChangeAfter: map[string]any{ "changes": changes, }, IsSuccess: true, }) } /* ================= RESPONSE ================= */ w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]any{ "success": true, }) } } /* ===================================================== OPTIONAL METHOD ===================================================== */ func (h *PermissionHandler) SaveUserOverrides(w http.ResponseWriter, r *http.Request) { claims, ok := auth.GetClaimsFromContext(r.Context()) if !ok || claims == nil { http.Error(w, "unauthorized", http.StatusUnauthorized) return } userID, _ := strconv.ParseInt(mux.Vars(r)["id"], 10, 64) var list []permissions.UserPermissionRequest if err := json.NewDecoder(r.Body).Decode(&list); err != nil { http.Error(w, "bad payload", 400) return } log.Println("➡️ SAVE USER PERMISSIONS") log.Println("USER ID:", userID) log.Println("ITEM COUNT:", len(list)) if err := h.Repo.SaveUserOverrides(userID, list); err != nil { log.Println("🔥 USER PERMISSION SAVE ERROR") log.Println("ERROR:", err) http.Error(w, err.Error(), 500) return } json.NewEncoder(w).Encode(map[string]bool{ "success": true, }) }