diff --git a/internal/services/gateway/action/projectgroup.go b/internal/services/gateway/action/projectgroup.go index 68486bf..c2c1f54 100644 --- a/internal/services/gateway/action/projectgroup.go +++ b/internal/services/gateway/action/projectgroup.go @@ -103,3 +103,24 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, req *CreateProje return rp, nil } + +func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectRef string) error { + p, resp, err := h.configstoreClient.GetProjectGroup(ctx, projectRef) + if err != nil { + return ErrFromRemote(resp, errors.Wrapf(err, "failed to get project %q", projectRef)) + } + + isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID) + if err != nil { + return errors.Wrapf(err, "failed to determine ownership") + } + if !isProjectOwner { + return util.NewErrForbidden(errors.Errorf("user not authorized")) + } + + resp, err = h.configstoreClient.DeleteProjectGroup(ctx, projectRef) + if err != nil { + return ErrFromRemote(resp, err) + } + return nil +} diff --git a/internal/services/gateway/api/client.go b/internal/services/gateway/api/client.go index 0873208..a306e2b 100644 --- a/internal/services/gateway/api/client.go +++ b/internal/services/gateway/api/client.go @@ -144,6 +144,10 @@ func (c *Client) CreateProjectGroup(ctx context.Context, req *CreateProjectGroup return project, resp, err } +func (c *Client) DeleteProjectGroup(ctx context.Context, projectGroupRef string) (*http.Response, error) { + return c.getResponse(ctx, "DELETE", fmt.Sprintf("/projectgroups/%s", url.PathEscape(projectGroupRef)), nil, jsonContent, nil) +} + func (c *Client) CreateProject(ctx context.Context, req *CreateProjectRequest) (*ProjectResponse, *http.Response, error) { reqj, err := json.Marshal(req) if err != nil { diff --git a/internal/services/gateway/api/projectgroup.go b/internal/services/gateway/api/projectgroup.go index 94d7b2a..2e4b0b8 100644 --- a/internal/services/gateway/api/projectgroup.go +++ b/internal/services/gateway/api/projectgroup.go @@ -81,6 +81,35 @@ func (h *CreateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req } } +type DeleteProjectGroupHandler struct { + log *zap.SugaredLogger + ah *action.ActionHandler +} + +func NewDeleteProjectGroupHandler(logger *zap.Logger, ah *action.ActionHandler) *DeleteProjectGroupHandler { + return &DeleteProjectGroupHandler{log: logger.Sugar(), ah: ah} +} + +func (h *DeleteProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + vars := mux.Vars(r) + projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) + if err != nil { + httpError(w, util.NewErrBadRequest(err)) + return + } + + err = h.ah.DeleteProjectGroup(ctx, projectGroupRef) + if httpError(w, err) { + h.log.Errorf("err: %+v", err) + return + } + + if err := httpResponse(w, http.StatusNoContent, nil); err != nil { + h.log.Errorf("err: %+v", err) + } +} + type ProjectGroupHandler struct { log *zap.SugaredLogger ah *action.ActionHandler diff --git a/internal/services/gateway/gateway.go b/internal/services/gateway/gateway.go index 0fa775f..98f234b 100644 --- a/internal/services/gateway/gateway.go +++ b/internal/services/gateway/gateway.go @@ -153,6 +153,7 @@ func (g *Gateway) Run(ctx context.Context) error { projectGroupSubgroupsHandler := api.NewProjectGroupSubgroupsHandler(logger, g.ah) projectGroupProjectsHandler := api.NewProjectGroupProjectsHandler(logger, g.ah) createProjectGroupHandler := api.NewCreateProjectGroupHandler(logger, g.ah) + deleteProjectGroupHandler := api.NewDeleteProjectGroupHandler(logger, g.ah) projectHandler := api.NewProjectHandler(logger, g.ah) createProjectHandler := api.NewCreateProjectHandler(logger, g.ah) @@ -228,7 +229,7 @@ func (g *Gateway) Run(ctx context.Context) error { apirouter.Handle("/projectgroups/{projectgroupref}/subgroups", authForcedHandler(projectGroupSubgroupsHandler)).Methods("GET") apirouter.Handle("/projectgroups/{projectgroupref}/projects", authForcedHandler(projectGroupProjectsHandler)).Methods("GET") apirouter.Handle("/projectgroups", authForcedHandler(createProjectGroupHandler)).Methods("POST") - //apirouter.Handle("/projectgroups/{projectgroupref}", authForcedHandler(deleteProjectGroupHandler)).Methods("DELETE") + apirouter.Handle("/projectgroups/{projectgroupref}", authForcedHandler(deleteProjectGroupHandler)).Methods("DELETE") apirouter.Handle("/projects/{projectref}", authForcedHandler(projectHandler)).Methods("GET") apirouter.Handle("/projects", authForcedHandler(createProjectHandler)).Methods("POST")