package api_acladmin import ( "git.oblat.lv/alex/triggerssmith/internal/acl" "git.oblat.lv/alex/triggerssmith/internal/auth" "git.oblat.lv/alex/triggerssmith/internal/config" //"git.oblat.lv/alex/triggerssmith/internal/server" "github.com/go-chi/chi/v5" ) type aclAdminHandler struct { cfg *config.Config a *acl.Service auth *auth.Service } func MustRoute(config *config.Config, aclService *acl.Service, authService *auth.Service) func(chi.Router) { if config == nil { panic("config is nil") } if aclService == nil { panic("aclService is nil") } if authService == nil { panic("authService is nil") } h := &aclAdminHandler{ cfg: config, a: aclService, auth: authService, } // GET /roles — список ролей // POST /roles — создать роль // GET /roles/{roleId} — получить роль // PATCH /roles/{roleId} — обновить роль (если нужно) // DELETE /roles/{roleId} — удалить роль // GET /resources — список ресурсов // POST /resources — создать ресурс // GET /resources/{resId} — получить ресурс // PATCH /resources/{resId} — обновить ресурс // DELETE /resources/{resId} — удалить ресурс // GET /users/{userId}/roles — роли пользователя // POST /users/{userId}/roles — назначить роль пользователю // DELETE /users/{userId}/roles/{roleId} — снять роль // GET /roles/{roleId}/resources — ресурсы роли // POST /roles/{roleId}/resources — назначить ресурс роли // DELETE /roles/{roleId}/resources/{resId} — убрать ресурс return func(r chi.Router) { // Roles r.Get("/roles", h.getRoles) // list all roles r.Post("/roles", h.createRole) // create a new role r.Get("/roles/{roleId}", h.getRole) // get a role by ID r.Patch("/roles/{roleId}", h.updateRole) // update a role by ID r.Delete("/roles/{roleId}", h.deleteRole) // delete a role by ID // // Resources r.Get("/resources", h.getResources) // list all resources r.Post("/resources", h.createResource) // create a new resource r.Get("/resources/{resourceId}", h.getResource) // get a resource by ID r.Patch("/resources/{resourceId}", h.updateResource) // update a resource by ID r.Delete("/resources/{resourceId}", h.deleteResource) // delete a resource by ID // Users // r.Get("/users/{userId}/roles", h.getUserRoles) // get all roles for a user // r.Post("/users/{userId}/roles", h.assignRoleToUser) // assign a role to a user // r.Delete("/users/{userId}/roles/{roleId}", h.removeRoleFromUser) // remove a role from a user // r.Get("/roles", h.getRoles) // r.Post("/create-role", h.createRole) // r.Post("/assign-role", h.assignRoleToUser) // r.Get("/user-roles", h.getUserRoles) // r.Post("/remove-role", h.removeRoleFromUser) // r.Get("/resources", h.getResources) // r.Post("/create-resource", h.createResource) // r.Post("/assign-resource", h.assignResourceToRole) // r.Get("/role-resources", h.getRoleResources) // r.Post("/remove-resource", h.removeResourceFromRole) // r.Get("/permissions", h.getResources) // legacy support // r.Post("/create-permissions", h.createResource) // legacy support // r.Post("/assign-permissions", h.assignResourceToRole) // legacy support // r.Get("/role-permissions", h.getRoleResources) // legacy support // r.Post("/remove-permissions", h.removeResourceFromRole) // legacy support } } // type assignRoleRequest struct { // UserID int `json:"userId"` // RoleID int `json:"roleId"` // } // func (h *aclAdminHandler) assignRoleToUser(w http.ResponseWriter, r *http.Request) { // var req assignRoleRequest // if err := json.NewDecoder(r.Body).Decode(&req); err != nil { // http.Error(w, "Invalid request body", http.StatusBadRequest) // return // } // if req.UserID < 0 || req.RoleID < 0 { // http.Error(w, "Invalid user or role ID", http.StatusBadRequest) // return // } // if err := h.a.AssignRoleToUser(uint(req.RoleID), uint(req.UserID)); err != nil { // http.Error(w, "Failed to assign role to user", http.StatusConflict) // return // } // w.WriteHeader(http.StatusCreated) // } // type getUserRolesResponse getRolesResponse // func (h *aclAdminHandler) getUserRoles(w http.ResponseWriter, r *http.Request) { // uidStr := r.URL.Query().Get("userId") // if uidStr == "" { // http.Error(w, "Missing userId parameter", http.StatusBadRequest) // return // } // userID, err := strconv.Atoi(uidStr) // if err != nil || userID < 0 { // http.Error(w, "Invalid userId parameter", http.StatusBadRequest) // return // } // roles, err := h.a.GetUserRoles(uint(userID)) // if err != nil { // http.Error(w, "Internal server error", http.StatusInternalServerError) // return // } // w.Header().Set("Content-Type", "application/json") // err = json.NewEncoder(w).Encode(func() getUserRolesResponse { // // Transform acl.Role to getUserRolesResponse // resp := make(getUserRolesResponse, 0, len(roles)) // for _, role := range roles { // resp = append(resp, struct { // ID uint `json:"id"` // Name string `json:"name"` // }{ // ID: role.ID, // Name: role.Name, // }) // } // return resp // }()) // if err != nil { // http.Error(w, "Failed to encode response", http.StatusInternalServerError) // return // } // } // type removeRoleRequest struct { // UserID int `json:"userId"` // RoleID int `json:"roleId"` // } // func (h *aclAdminHandler) removeRoleFromUser(w http.ResponseWriter, r *http.Request) { // var req removeRoleRequest // if err := json.NewDecoder(r.Body).Decode(&req); err != nil { // http.Error(w, "Invalid request body", http.StatusBadRequest) // return // } // if req.UserID < 0 || req.RoleID < 0 { // http.Error(w, "Invalid user or role ID", http.StatusBadRequest) // return // } // if err := h.a.RemoveRoleFromUser(uint(req.RoleID), uint(req.UserID)); err != nil { // http.Error(w, "Failed to remove role from user", http.StatusConflict) // return // } // w.WriteHeader(http.StatusNoContent) // } // type getResourcesResponse getRolesResponse // func (h *aclAdminHandler) getResources(w http.ResponseWriter, r *http.Request) { // resources, err := h.a.GetResources() // if err != nil { // http.Error(w, "Internal server error", http.StatusInternalServerError) // return // } // w.Header().Set("Content-Type", "application/json") // err = json.NewEncoder(w).Encode(func() getResourcesResponse { // // Transform acl.Resource to getResourcesResponse // resp := make(getResourcesResponse, 0, len(resources)) // for _, res := range resources { // resp = append(resp, struct { // ID uint `json:"id"` // Name string `json:"name"` // }{ // ID: res.ID, // Name: res.Key, // }) // } // return resp // }()) // if err != nil { // http.Error(w, "Failed to encode response", http.StatusInternalServerError) // return // } // } // type createResourceRequest struct { // Name string `json:"name"` // } // type createResourceResponse struct { // ID uint `json:"id"` // Name string `json:"name"` // } // func (h *aclAdminHandler) createResource(w http.ResponseWriter, r *http.Request) { // var req createResourceRequest // if err := json.NewDecoder(r.Body).Decode(&req); err != nil { // http.Error(w, "Invalid request body", http.StatusBadRequest) // return // } // if req.Name == "" { // http.Error(w, "Name is required", http.StatusBadRequest) // return // } // id, err := h.a.CreateResource(req.Name) // if err != nil { // http.Error(w, "Failed to create resource", http.StatusConflict) // return // } // w.WriteHeader(http.StatusCreated) // w.Header().Set("Content-Type", "application/json") // err = json.NewEncoder(w).Encode(createResourceResponse{ // ID: id, // Name: req.Name, // }) // if err != nil { // http.Error(w, "Failed to encode response", http.StatusInternalServerError) // return // } // } // func (h *aclAdminHandler) assignResourceToRole(w http.ResponseWriter, r *http.Request) { // server.NotImplemented(w) // } // func (h *aclAdminHandler) getRoleResources(w http.ResponseWriter, r *http.Request) { // server.NotImplemented(w) // } // func (h *aclAdminHandler) removeResourceFromRole(w http.ResponseWriter, r *http.Request) { // server.NotImplemented(w) // }