From 83f6ebe95f74c4b914f518ba2e4011f0f7c8ebf8 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Sun, 12 May 2019 23:22:18 +0200 Subject: [PATCH] gateway: implement updateProject Update project currently handles updating project name and visibility. In future we'll add additional update logic. --- internal/services/gateway/action/project.go | 32 ++++++++++++++ internal/services/gateway/api/project.go | 46 +++++++++++++++++++++ internal/services/gateway/gateway.go | 2 + 3 files changed, 80 insertions(+) diff --git a/internal/services/gateway/action/project.go b/internal/services/gateway/action/project.go index 4d49d29..1352612 100644 --- a/internal/services/gateway/action/project.go +++ b/internal/services/gateway/action/project.go @@ -162,6 +162,38 @@ func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectReq return rp, h.SetupProject(ctx, rs, user, la, rp) } +type UpdateProjectRequest struct { + Name string + Visibility types.Visibility +} + +func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, req *UpdateProjectRequest) (*csapi.Project, error) { + p, resp, err := h.configstoreClient.GetProject(ctx, projectRef) + if err != nil { + return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get project %q", projectRef)) + } + + isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID) + if err != nil { + return nil, errors.Wrapf(err, "failed to determine ownership") + } + if !isProjectOwner { + return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) + } + + p.Name = req.Name + p.Visibility = req.Visibility + + h.log.Infof("updating project") + rp, resp, err := h.configstoreClient.UpdateProject(ctx, p.ID, p.Project) + if err != nil { + return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to update project")) + } + h.log.Infof("project %s updated, ID: %s", p.Name, p.ID) + + return rp, nil +} + func (h *ActionHandler) ProjectUpdateRepoLinkedAccount(ctx context.Context, projectRef string) (*csapi.Project, error) { curUserID := h.CurrentUserID(ctx) diff --git a/internal/services/gateway/api/project.go b/internal/services/gateway/api/project.go index 29bc950..36efb84 100644 --- a/internal/services/gateway/api/project.go +++ b/internal/services/gateway/api/project.go @@ -77,6 +77,52 @@ func (h *CreateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) } } +type UpdateProjectRequest struct { + Name string `json:"name,omitempty"` + Visibility types.Visibility `json:"visibility,omitempty"` +} + +type UpdateProjectHandler struct { + log *zap.SugaredLogger + ah *action.ActionHandler +} + +func NewUpdateProjectHandler(logger *zap.Logger, ah *action.ActionHandler) *UpdateProjectHandler { + return &UpdateProjectHandler{log: logger.Sugar(), ah: ah} +} + +func (h *UpdateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + vars := mux.Vars(r) + projectRef, err := url.PathUnescape(vars["projectref"]) + if err != nil { + httpError(w, util.NewErrBadRequest(err)) + return + } + + var req UpdateProjectRequest + d := json.NewDecoder(r.Body) + if err := d.Decode(&req); err != nil { + httpError(w, util.NewErrBadRequest(err)) + return + } + + areq := &action.UpdateProjectRequest{ + Name: req.Name, + Visibility: req.Visibility, + } + project, err := h.ah.UpdateProject(ctx, projectRef, areq) + if httpError(w, err) { + h.log.Errorf("err: %+v", err) + return + } + + res := createProjectResponse(project) + if err := httpResponse(w, http.StatusCreated, res); err != nil { + h.log.Errorf("err: %+v", err) + } +} + type ProjectReconfigHandler struct { log *zap.SugaredLogger ah *action.ActionHandler diff --git a/internal/services/gateway/gateway.go b/internal/services/gateway/gateway.go index 755ffb6..0fa775f 100644 --- a/internal/services/gateway/gateway.go +++ b/internal/services/gateway/gateway.go @@ -156,6 +156,7 @@ func (g *Gateway) Run(ctx context.Context) error { projectHandler := api.NewProjectHandler(logger, g.ah) createProjectHandler := api.NewCreateProjectHandler(logger, g.ah) + updateProjectHandler := api.NewUpdateProjectHandler(logger, g.ah) deleteProjectHandler := api.NewDeleteProjectHandler(logger, g.ah) projectReconfigHandler := api.NewProjectReconfigHandler(logger, g.ah) projectUpdateRepoLinkedAccountHandler := api.NewProjectUpdateRepoLinkedAccountHandler(logger, g.ah) @@ -231,6 +232,7 @@ func (g *Gateway) Run(ctx context.Context) error { apirouter.Handle("/projects/{projectref}", authForcedHandler(projectHandler)).Methods("GET") apirouter.Handle("/projects", authForcedHandler(createProjectHandler)).Methods("POST") + apirouter.Handle("/projects/{projectref}", authForcedHandler(updateProjectHandler)).Methods("PUT") apirouter.Handle("/projects/{projectref}", authForcedHandler(deleteProjectHandler)).Methods("DELETE") apirouter.Handle("/projects/{projectref}/reconfig", authForcedHandler(projectReconfigHandler)).Methods("PUT") apirouter.Handle("/projects/{projectref}/updaterepolinkedaccount", authForcedHandler(projectUpdateRepoLinkedAccountHandler)).Methods("PUT")