From 33c0a82fb795cead6b9adaa978c7b16dbf1605f3 Mon Sep 17 00:00:00 2001 From: Wilfred Asomani Date: Fri, 18 Aug 2023 13:31:49 +0000 Subject: [PATCH] satellite/console: add create project http endpoint This change adds an HTTP endpoint for creating projects, to be used in place of the GraphQL version. Issue: https://github.com/storj/storj/issues/6195 Change-Id: I0377353418df7c152db6a935e99a3ea7ab4ce625 --- .../console/consoleweb/consoleapi/projects.go | 37 +++++++++++++++++++ .../console/consoleweb/endpoints_test.go | 25 ++++++++----- satellite/console/consoleweb/server.go | 1 + 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/satellite/console/consoleweb/consoleapi/projects.go b/satellite/console/consoleweb/consoleapi/projects.go index e0e68c9b9..e4759e970 100644 --- a/satellite/console/consoleweb/consoleapi/projects.go +++ b/satellite/console/consoleweb/consoleapi/projects.go @@ -204,6 +204,43 @@ func (p *Projects) UpdateProject(w http.ResponseWriter, r *http.Request) { } } +// CreateProject handles creating projects. +func (p *Projects) CreateProject(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + var err error + defer mon.Task()(&ctx)(&err) + + var payload console.UpsertProjectInfo + + err = json.NewDecoder(r.Body).Decode(&payload) + if err != nil { + p.serveJSONError(ctx, w, http.StatusBadRequest, err) + return + } + + if payload.Name == "" { + p.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("project name cannot be empty")) + return + } + + project, err := p.service.CreateProject(ctx, payload) + if err != nil { + if console.ErrUnauthorized.Has(err) { + p.serveJSONError(ctx, w, http.StatusUnauthorized, err) + return + } + + p.serveJSONError(ctx, w, http.StatusInternalServerError, err) + return + } + + w.WriteHeader(http.StatusCreated) + err = json.NewEncoder(w).Encode(project.GetMinimal()) + if err != nil { + p.serveJSONError(ctx, w, http.StatusInternalServerError, err) + } +} + // GetMembersAndInvitations returns the project's members and invitees. func (p *Projects) GetMembersAndInvitations(w http.ResponseWriter, r *http.Request) { ctx := r.Context() diff --git a/satellite/console/consoleweb/endpoints_test.go b/satellite/console/consoleweb/endpoints_test.go index 7264c301d..7fbc0bdf5 100644 --- a/satellite/console/consoleweb/endpoints_test.go +++ b/satellite/console/consoleweb/endpoints_test.go @@ -555,16 +555,23 @@ func TestProjects(t *testing.T) { require.Equal(t, b64Salt, base64.StdEncoding.EncodeToString(salt)) } - { // Get_User_Projects + { // Create_Project + name := "a name" + description := "a description" + resp, body := test.request(http.MethodPost, "/projects", test.toJSON(map[string]interface{}{ + "name": name, + "description": description, + })) + require.Equal(t, http.StatusCreated, resp.StatusCode) - var projects []struct { - ID uuid.UUID `json:"id"` - Name string `json:"name"` - OwnerID uuid.UUID `json:"ownerId"` - Description string `json:"description"` - MemberCount int `json:"memberCount"` - CreatedAt time.Time `json:"createdAt"` - } + var createdProject console.ProjectInfo + require.NoError(t, json.Unmarshal([]byte(body), &createdProject)) + require.Equal(t, name, createdProject.Name) + require.Equal(t, description, createdProject.Description) + } + + { // Get_User_Projects + var projects []console.ProjectInfo resp, body := test.request(http.MethodGet, "/projects", nil) require.Equal(t, http.StatusOK, resp.StatusCode) require.NoError(t, json.Unmarshal([]byte(body), &projects)) diff --git a/satellite/console/consoleweb/server.go b/satellite/console/consoleweb/server.go index 41691aa47..0e6f1bdbb 100644 --- a/satellite/console/consoleweb/server.go +++ b/satellite/console/consoleweb/server.go @@ -278,6 +278,7 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, oidc projectsRouter.Use(server.withCORS) projectsRouter.Use(server.withAuth) projectsRouter.Handle("", http.HandlerFunc(projectsController.GetUserProjects)).Methods(http.MethodGet, http.MethodOptions) + projectsRouter.Handle("", http.HandlerFunc(projectsController.CreateProject)).Methods(http.MethodPost, http.MethodOptions) projectsRouter.Handle("/paged", http.HandlerFunc(projectsController.GetPagedProjects)).Methods(http.MethodGet, http.MethodOptions) projectsRouter.Handle("/{id}", http.HandlerFunc(projectsController.UpdateProject)).Methods(http.MethodPatch, http.MethodOptions) projectsRouter.Handle("/{id}/members", http.HandlerFunc(projectsController.DeleteMembersAndInvitations)).Methods(http.MethodDelete, http.MethodOptions)