satellite: add get user paged projects http endpoint
This change adds an endpoint to get a user's projects, similar to the OwnedProjects GraphQL query. The console.ProjectInfo struct has been renamed to UpsertProjectInfo to more accurately reflect its use. Issue: https://github.com/storj/storj/issues/6135 Change-Id: I802fe4694a5cc75a9df2b565476f6e6f473431d4
This commit is contained in:
parent
b21041d6f9
commit
34e1caa55a
@ -261,7 +261,7 @@ func (system *Satellite) AddProject(ctx context.Context, ownerID uuid.UUID, name
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err)
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
project, err := system.API.Console.Service.CreateProject(ctx, console.ProjectInfo{
|
project, err := system.API.Console.Service.CreateProject(ctx, console.UpsertProjectInfo{
|
||||||
Name: name,
|
Name: name,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -28,8 +28,8 @@ var ErrApikeysAPI = errs.Class("consoleapi apikeys api")
|
|||||||
var ErrUsersAPI = errs.Class("consoleapi users api")
|
var ErrUsersAPI = errs.Class("consoleapi users api")
|
||||||
|
|
||||||
type ProjectManagementService interface {
|
type ProjectManagementService interface {
|
||||||
GenCreateProject(ctx context.Context, request console.ProjectInfo) (*console.Project, api.HTTPError)
|
GenCreateProject(ctx context.Context, request console.UpsertProjectInfo) (*console.Project, api.HTTPError)
|
||||||
GenUpdateProject(ctx context.Context, id uuid.UUID, request console.ProjectInfo) (*console.Project, api.HTTPError)
|
GenUpdateProject(ctx context.Context, id uuid.UUID, request console.UpsertProjectInfo) (*console.Project, api.HTTPError)
|
||||||
GenDeleteProject(ctx context.Context, id uuid.UUID) api.HTTPError
|
GenDeleteProject(ctx context.Context, id uuid.UUID) api.HTTPError
|
||||||
GenGetUsersProjects(ctx context.Context) ([]console.Project, api.HTTPError)
|
GenGetUsersProjects(ctx context.Context) ([]console.Project, api.HTTPError)
|
||||||
GenGetSingleBucketUsageRollup(ctx context.Context, projectID uuid.UUID, bucket string, since, before time.Time) (*accounting.BucketUsageRollup, api.HTTPError)
|
GenGetSingleBucketUsageRollup(ctx context.Context, projectID uuid.UUID, bucket string, since, before time.Time) (*accounting.BucketUsageRollup, api.HTTPError)
|
||||||
@ -126,7 +126,7 @@ func (h *ProjectManagementHandler) handleGenCreateProject(w http.ResponseWriter,
|
|||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
payload := console.ProjectInfo{}
|
payload := console.UpsertProjectInfo{}
|
||||||
if err = json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
if err = json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
||||||
api.ServeError(h.log, w, http.StatusBadRequest, err)
|
api.ServeError(h.log, w, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
@ -170,7 +170,7 @@ func (h *ProjectManagementHandler) handleGenUpdateProject(w http.ResponseWriter,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
payload := console.ProjectInfo{}
|
payload := console.UpsertProjectInfo{}
|
||||||
if err = json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
if err = json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
||||||
api.ServeError(h.log, w, http.StatusBadRequest, err)
|
api.ServeError(h.log, w, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
|
@ -35,7 +35,7 @@ func main() {
|
|||||||
MethodName: "GenCreateProject",
|
MethodName: "GenCreateProject",
|
||||||
RequestName: "createProject",
|
RequestName: "createProject",
|
||||||
Response: &console.Project{},
|
Response: &console.Project{},
|
||||||
Request: console.ProjectInfo{},
|
Request: console.UpsertProjectInfo{},
|
||||||
})
|
})
|
||||||
|
|
||||||
g.Patch("/update/{id}", &apigen.Endpoint{
|
g.Patch("/update/{id}", &apigen.Endpoint{
|
||||||
@ -44,7 +44,7 @@ func main() {
|
|||||||
MethodName: "GenUpdateProject",
|
MethodName: "GenUpdateProject",
|
||||||
RequestName: "updateProject",
|
RequestName: "updateProject",
|
||||||
Response: console.Project{},
|
Response: console.Project{},
|
||||||
Request: console.ProjectInfo{},
|
Request: console.UpsertProjectInfo{},
|
||||||
PathParams: []apigen.Param{
|
PathParams: []apigen.Param{
|
||||||
apigen.NewParam("id", uuid.UUID{}),
|
apigen.NewParam("id", uuid.UUID{}),
|
||||||
},
|
},
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -44,29 +45,18 @@ func (p *Projects) GetUserProjects(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
projects, err := p.service.GetUsersProjects(ctx)
|
projects, err := p.service.GetUsersProjects(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if console.ErrUnauthorized.Has(err) {
|
||||||
|
p.serveJSONError(ctx, w, http.StatusUnauthorized, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
p.serveJSONError(ctx, w, http.StatusInternalServerError, err)
|
p.serveJSONError(ctx, w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonProject struct {
|
response := make([]console.ProjectInfo, 0)
|
||||||
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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
response := make([]jsonProject, 0)
|
|
||||||
for _, project := range projects {
|
for _, project := range projects {
|
||||||
response = append(response, jsonProject{
|
response = append(response, project.GetMinimal())
|
||||||
ID: project.PublicID,
|
|
||||||
Name: project.Name,
|
|
||||||
OwnerID: project.OwnerID,
|
|
||||||
Description: project.Description,
|
|
||||||
MemberCount: project.MemberCount,
|
|
||||||
CreatedAt: project.CreatedAt,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.NewEncoder(w).Encode(response)
|
err = json.NewEncoder(w).Encode(response)
|
||||||
@ -75,6 +65,79 @@ func (p *Projects) GetUserProjects(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPagedProjects returns paged projects for a user.
|
||||||
|
func (p *Projects) GetPagedProjects(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
var err error
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
query := r.URL.Query()
|
||||||
|
|
||||||
|
limitParam := query.Get("limit")
|
||||||
|
if limitParam == "" {
|
||||||
|
p.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("parameter 'limit' is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
limit, err := strconv.ParseUint(limitParam, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
p.serveJSONError(ctx, w, http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pageParam := query.Get("page")
|
||||||
|
if pageParam == "" {
|
||||||
|
p.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("parameter 'page' is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
page, err := strconv.ParseUint(pageParam, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
p.serveJSONError(ctx, w, http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if page == 0 {
|
||||||
|
p.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("parameter 'page' can not be 0"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor := console.ProjectsCursor{
|
||||||
|
Limit: int(limit),
|
||||||
|
Page: int(page),
|
||||||
|
}
|
||||||
|
|
||||||
|
projectsPage, err := p.service.GetUsersOwnedProjectsPage(ctx, cursor)
|
||||||
|
if err != nil {
|
||||||
|
if console.ErrUnauthorized.Has(err) {
|
||||||
|
p.serveJSONError(ctx, w, http.StatusUnauthorized, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.serveJSONError(ctx, w, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pageToSend := console.ProjectInfoPage{
|
||||||
|
Limit: projectsPage.Limit,
|
||||||
|
Offset: projectsPage.Offset,
|
||||||
|
PageCount: projectsPage.PageCount,
|
||||||
|
CurrentPage: projectsPage.CurrentPage,
|
||||||
|
TotalCount: projectsPage.TotalCount,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, project := range projectsPage.Projects {
|
||||||
|
pageToSend.Projects = append(pageToSend.Projects, project.GetMinimal())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.NewEncoder(w).Encode(pageToSend)
|
||||||
|
if err != nil {
|
||||||
|
p.serveJSONError(ctx, w, http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetSalt returns the project's salt.
|
// GetSalt returns the project's salt.
|
||||||
func (p *Projects) GetSalt(w http.ResponseWriter, r *http.Request) {
|
func (p *Projects) GetSalt(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
@ -206,7 +206,7 @@ func TestGraphqlMutation(t *testing.T) {
|
|||||||
var projectIDField string
|
var projectIDField string
|
||||||
var projectPublicIDField string
|
var projectPublicIDField string
|
||||||
t.Run("Create project mutation", func(t *testing.T) {
|
t.Run("Create project mutation", func(t *testing.T) {
|
||||||
projectInfo := console.ProjectInfo{
|
projectInfo := console.UpsertProjectInfo{
|
||||||
Name: "Project name",
|
Name: "Project name",
|
||||||
Description: "desc",
|
Description: "desc",
|
||||||
}
|
}
|
||||||
|
@ -450,16 +450,16 @@ func graphqlProjectUsage() *graphql.Object {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromMapProjectInfo creates console.ProjectInfo from input args.
|
// fromMapProjectInfo creates console.UpsertProjectInfo from input args.
|
||||||
func fromMapProjectInfo(args map[string]interface{}) (project console.ProjectInfo) {
|
func fromMapProjectInfo(args map[string]interface{}) (project console.UpsertProjectInfo) {
|
||||||
project.Name, _ = args[FieldName].(string)
|
project.Name, _ = args[FieldName].(string)
|
||||||
project.Description, _ = args[FieldDescription].(string)
|
project.Description, _ = args[FieldDescription].(string)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromMapProjectInfoProjectLimits creates console.ProjectInfo from input args.
|
// fromMapProjectInfoProjectLimits creates console.UpsertProjectInfo from input args.
|
||||||
func fromMapProjectInfoProjectLimits(projectInfo, projectLimits map[string]interface{}) (project console.ProjectInfo, err error) {
|
func fromMapProjectInfoProjectLimits(projectInfo, projectLimits map[string]interface{}) (project console.UpsertProjectInfo, err error) {
|
||||||
project.Name, _ = projectInfo[FieldName].(string)
|
project.Name, _ = projectInfo[FieldName].(string)
|
||||||
project.Description, _ = projectInfo[FieldDescription].(string)
|
project.Description, _ = projectInfo[FieldDescription].(string)
|
||||||
storageLimit, err := strconv.Atoi(projectLimits[FieldStorageLimit].(string))
|
storageLimit, err := strconv.Atoi(projectLimits[FieldStorageLimit].(string))
|
||||||
|
@ -188,7 +188,7 @@ func TestGraphqlQuery(t *testing.T) {
|
|||||||
return result.Data
|
return result.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
createdProject, err := service.CreateProject(userCtx, console.ProjectInfo{
|
createdProject, err := service.CreateProject(userCtx, console.UpsertProjectInfo{
|
||||||
Name: "TestProject",
|
Name: "TestProject",
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -396,7 +396,7 @@ func TestGraphqlQuery(t *testing.T) {
|
|||||||
assert.True(t, foundKey2)
|
assert.True(t, foundKey2)
|
||||||
})
|
})
|
||||||
|
|
||||||
project2, err := service.CreateProject(userCtx, console.ProjectInfo{
|
project2, err := service.CreateProject(userCtx, console.UpsertProjectInfo{
|
||||||
Name: "Project2",
|
Name: "Project2",
|
||||||
Description: "Test desc",
|
Description: "Test desc",
|
||||||
})
|
})
|
||||||
|
@ -590,6 +590,14 @@ func TestProjects(t *testing.T) {
|
|||||||
require.Contains(t, body, "storageLimit")
|
require.Contains(t, body, "storageLimit")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ // Get_OwnedProjects - HTTP
|
||||||
|
var projects console.ProjectInfoPage
|
||||||
|
resp, body := test.request(http.MethodGet, "/projects/paged?limit=6&page=1", nil)
|
||||||
|
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
require.NoError(t, json.Unmarshal([]byte(body), &projects))
|
||||||
|
require.NotEmpty(t, projects.Projects)
|
||||||
|
}
|
||||||
|
|
||||||
{ // Get_OwnedProjects
|
{ // Get_OwnedProjects
|
||||||
resp, body := test.request(http.MethodPost, "/graphql",
|
resp, body := test.request(http.MethodPost, "/graphql",
|
||||||
test.toJSON(map[string]interface{}{
|
test.toJSON(map[string]interface{}{
|
||||||
|
@ -276,6 +276,7 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, oidc
|
|||||||
projectsRouter.Use(server.withCORS)
|
projectsRouter.Use(server.withCORS)
|
||||||
projectsRouter.Use(server.withAuth)
|
projectsRouter.Use(server.withAuth)
|
||||||
projectsRouter.Handle("", http.HandlerFunc(projectsController.GetUserProjects)).Methods(http.MethodGet, http.MethodOptions)
|
projectsRouter.Handle("", http.HandlerFunc(projectsController.GetUserProjects)).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
projectsRouter.Handle("/paged", http.HandlerFunc(projectsController.GetPagedProjects)).Methods(http.MethodGet, http.MethodOptions)
|
||||||
projectsRouter.Handle("/{id}/salt", http.HandlerFunc(projectsController.GetSalt)).Methods(http.MethodGet, http.MethodOptions)
|
projectsRouter.Handle("/{id}/salt", http.HandlerFunc(projectsController.GetSalt)).Methods(http.MethodGet, http.MethodOptions)
|
||||||
projectsRouter.Handle("/{id}/invite", http.HandlerFunc(projectsController.InviteUsers)).Methods(http.MethodPost, http.MethodOptions)
|
projectsRouter.Handle("/{id}/invite", http.HandlerFunc(projectsController.InviteUsers)).Methods(http.MethodPost, http.MethodOptions)
|
||||||
projectsRouter.Handle("/{id}/invite-link", http.HandlerFunc(projectsController.GetInviteLink)).Methods(http.MethodGet, http.MethodOptions)
|
projectsRouter.Handle("/{id}/invite-link", http.HandlerFunc(projectsController.GetInviteLink)).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
@ -114,8 +114,8 @@ type Project struct {
|
|||||||
DefaultPlacement storj.PlacementConstraint `json:"defaultPlacement"`
|
DefaultPlacement storj.PlacementConstraint `json:"defaultPlacement"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProjectInfo holds data needed to create/update Project.
|
// UpsertProjectInfo holds data needed to create/update Project.
|
||||||
type ProjectInfo struct {
|
type UpsertProjectInfo struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
StorageLimit memory.Size `json:"storageLimit"`
|
StorageLimit memory.Size `json:"storageLimit"`
|
||||||
@ -123,6 +123,16 @@ type ProjectInfo struct {
|
|||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProjectInfo holds data sent via user facing http endpoints.
|
||||||
|
type ProjectInfo 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"`
|
||||||
|
}
|
||||||
|
|
||||||
// ProjectsCursor holds info for project
|
// ProjectsCursor holds info for project
|
||||||
// cursor pagination.
|
// cursor pagination.
|
||||||
type ProjectsCursor struct {
|
type ProjectsCursor struct {
|
||||||
@ -146,6 +156,19 @@ type ProjectsPage struct {
|
|||||||
TotalCount int64
|
TotalCount int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProjectInfoPage is similar to ProjectsPage
|
||||||
|
// except the Projects field is ProjectInfo and is sent over HTTP API.
|
||||||
|
type ProjectInfoPage struct {
|
||||||
|
Projects []ProjectInfo `json:"projects"`
|
||||||
|
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
Offset int64 `json:"offset"`
|
||||||
|
|
||||||
|
PageCount int `json:"pageCount"`
|
||||||
|
CurrentPage int `json:"currentPage"`
|
||||||
|
TotalCount int64 `json:"totalCount"`
|
||||||
|
}
|
||||||
|
|
||||||
// ValidateNameAndDescription validates project name and description strings.
|
// ValidateNameAndDescription validates project name and description strings.
|
||||||
// Project name must have more than 0 and less than 21 symbols.
|
// Project name must have more than 0 and less than 21 symbols.
|
||||||
// Project description can't have more than hundred symbols.
|
// Project description can't have more than hundred symbols.
|
||||||
@ -164,3 +187,15 @@ func ValidateNameAndDescription(name string, description string) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMinimal returns a ProjectInfo copy of a project.
|
||||||
|
func (p Project) GetMinimal() ProjectInfo {
|
||||||
|
return ProjectInfo{
|
||||||
|
ID: p.PublicID,
|
||||||
|
Name: p.Name,
|
||||||
|
OwnerID: p.OwnerID,
|
||||||
|
Description: p.Description,
|
||||||
|
MemberCount: p.MemberCount,
|
||||||
|
CreatedAt: p.CreatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1601,7 +1601,7 @@ func (s *Service) GetUsersOwnedProjectsPage(ctx context.Context, cursor Projects
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateProject is a method for creating new project.
|
// CreateProject is a method for creating new project.
|
||||||
func (s *Service) CreateProject(ctx context.Context, projectInfo ProjectInfo) (p *Project, err error) {
|
func (s *Service) CreateProject(ctx context.Context, projectInfo UpsertProjectInfo) (p *Project, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
user, err := s.getUserAndAuditLog(ctx, "create project")
|
user, err := s.getUserAndAuditLog(ctx, "create project")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1664,7 +1664,7 @@ func (s *Service) CreateProject(ctx context.Context, projectInfo ProjectInfo) (p
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenCreateProject is a method for creating new project for generated api.
|
// GenCreateProject is a method for creating new project for generated api.
|
||||||
func (s *Service) GenCreateProject(ctx context.Context, projectInfo ProjectInfo) (p *Project, httpError api.HTTPError) {
|
func (s *Service) GenCreateProject(ctx context.Context, projectInfo UpsertProjectInfo) (p *Project, httpError api.HTTPError) {
|
||||||
var err error
|
var err error
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
@ -1809,7 +1809,7 @@ func (s *Service) GenDeleteProject(ctx context.Context, projectID uuid.UUID) (ht
|
|||||||
|
|
||||||
// UpdateProject is a method for updating project name and description by id.
|
// UpdateProject is a method for updating project name and description by id.
|
||||||
// projectID here may be project.PublicID or project.ID.
|
// projectID here may be project.PublicID or project.ID.
|
||||||
func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, updatedProject ProjectInfo) (p *Project, err error) {
|
func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, updatedProject UpsertProjectInfo) (p *Project, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
user, err := s.getUserAndAuditLog(ctx, "update project name and description", zap.String("projectID", projectID.String()))
|
user, err := s.getUserAndAuditLog(ctx, "update project name and description", zap.String("projectID", projectID.String()))
|
||||||
@ -1899,7 +1899,7 @@ func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, update
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenUpdateProject is a method for updating project name and description by id for generated api.
|
// GenUpdateProject is a method for updating project name and description by id for generated api.
|
||||||
func (s *Service) GenUpdateProject(ctx context.Context, projectID uuid.UUID, projectInfo ProjectInfo) (p *Project, httpError api.HTTPError) {
|
func (s *Service) GenUpdateProject(ctx context.Context, projectID uuid.UUID, projectInfo UpsertProjectInfo) (p *Project, httpError api.HTTPError) {
|
||||||
var err error
|
var err error
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
@ -2953,7 +2953,7 @@ func (s *Service) checkProjectLimit(ctx context.Context, userID uuid.UUID) (curr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// checkProjectName is used to check if user has used project name before.
|
// checkProjectName is used to check if user has used project name before.
|
||||||
func (s *Service) checkProjectName(ctx context.Context, projectInfo ProjectInfo, userID uuid.UUID) (passesNameCheck bool, err error) {
|
func (s *Service) checkProjectName(ctx context.Context, projectInfo UpsertProjectInfo, userID uuid.UUID) (passesNameCheck bool, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
passesCheck := true
|
passesCheck := true
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ func TestService(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("CreateProject", func(t *testing.T) {
|
t.Run("CreateProject", func(t *testing.T) {
|
||||||
// Creating a project with a previously used name should fail
|
// Creating a project with a previously used name should fail
|
||||||
createdProject, err := service.CreateProject(userCtx1, console.ProjectInfo{
|
createdProject, err := service.CreateProject(userCtx1, console.UpsertProjectInfo{
|
||||||
Name: up1Proj.Name,
|
Name: up1Proj.Name,
|
||||||
})
|
})
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
@ -169,7 +169,7 @@ func TestService(t *testing.T) {
|
|||||||
userCtx, err := sat.UserContext(ctx, user.ID)
|
userCtx, err := sat.UserContext(ctx, user.ID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
p, err := service.CreateProject(userCtx, console.ProjectInfo{
|
p, err := service.CreateProject(userCtx, console.UpsertProjectInfo{
|
||||||
Name: "eu-project",
|
Name: "eu-project",
|
||||||
Description: "project with eu1 default placement",
|
Description: "project with eu1 default placement",
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
@ -188,7 +188,7 @@ func TestService(t *testing.T) {
|
|||||||
_, userCtx1 := getOwnerAndCtx(ctx, up1Proj)
|
_, userCtx1 := getOwnerAndCtx(ctx, up1Proj)
|
||||||
|
|
||||||
// Updating own project should work
|
// Updating own project should work
|
||||||
updatedProject, err := service.UpdateProject(userCtx1, up1Proj.ID, console.ProjectInfo{
|
updatedProject, err := service.UpdateProject(userCtx1, up1Proj.ID, console.UpsertProjectInfo{
|
||||||
Name: updatedName,
|
Name: updatedName,
|
||||||
Description: updatedDescription,
|
Description: updatedDescription,
|
||||||
StorageLimit: updatedStorageLimit,
|
StorageLimit: updatedStorageLimit,
|
||||||
@ -207,7 +207,7 @@ func TestService(t *testing.T) {
|
|||||||
require.Equal(t, updatedBandwidthLimit, *updatedProject.UserSpecifiedBandwidthLimit)
|
require.Equal(t, updatedBandwidthLimit, *updatedProject.UserSpecifiedBandwidthLimit)
|
||||||
|
|
||||||
// Updating someone else project details should not work
|
// Updating someone else project details should not work
|
||||||
updatedProject, err = service.UpdateProject(userCtx1, up2Proj.ID, console.ProjectInfo{
|
updatedProject, err = service.UpdateProject(userCtx1, up2Proj.ID, console.UpsertProjectInfo{
|
||||||
Name: "newName",
|
Name: "newName",
|
||||||
Description: "TestUpdate",
|
Description: "TestUpdate",
|
||||||
StorageLimit: memory.Size(100),
|
StorageLimit: memory.Size(100),
|
||||||
@ -226,7 +226,7 @@ func TestService(t *testing.T) {
|
|||||||
err = sat.DB.Console().Projects().Update(ctx, up1Proj)
|
err = sat.DB.Console().Projects().Update(ctx, up1Proj)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
updateInfo := console.ProjectInfo{
|
updateInfo := console.UpsertProjectInfo{
|
||||||
Name: "a b c",
|
Name: "a b c",
|
||||||
Description: "1 2 3",
|
Description: "1 2 3",
|
||||||
StorageLimit: memory.Size(123),
|
StorageLimit: memory.Size(123),
|
||||||
@ -266,7 +266,7 @@ func TestService(t *testing.T) {
|
|||||||
require.Equal(t, updateInfo.BandwidthLimit, *project.BandwidthLimit)
|
require.Equal(t, updateInfo.BandwidthLimit, *project.BandwidthLimit)
|
||||||
|
|
||||||
// attempting to update a project with a previously used name should fail
|
// attempting to update a project with a previously used name should fail
|
||||||
updatedProject, err = service.UpdateProject(userCtx1, up2Proj.ID, console.ProjectInfo{
|
updatedProject, err = service.UpdateProject(userCtx1, up2Proj.ID, console.UpsertProjectInfo{
|
||||||
Name: up1Proj.Name,
|
Name: up1Proj.Name,
|
||||||
})
|
})
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
@ -276,7 +276,7 @@ func TestService(t *testing.T) {
|
|||||||
_, err = service.AddProjectMembers(userCtx1, up1Proj.ID, []string{user2.Email})
|
_, err = service.AddProjectMembers(userCtx1, up1Proj.ID, []string{user2.Email})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// Members should not be able to update project.
|
// Members should not be able to update project.
|
||||||
_, err = service.UpdateProject(userCtx2, up1Proj.ID, console.ProjectInfo{
|
_, err = service.UpdateProject(userCtx2, up1Proj.ID, console.UpsertProjectInfo{
|
||||||
Name: updatedName,
|
Name: updatedName,
|
||||||
})
|
})
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
@ -765,7 +765,7 @@ func TestPaidTier(t *testing.T) {
|
|||||||
require.Equal(t, usageConfig.Segment.Paid, *proj1.SegmentLimit)
|
require.Equal(t, usageConfig.Segment.Paid, *proj1.SegmentLimit)
|
||||||
|
|
||||||
// expect new project to be created with paid tier usage limits
|
// expect new project to be created with paid tier usage limits
|
||||||
proj2, err := service.CreateProject(userCtx, console.ProjectInfo{Name: "Project 2"})
|
proj2, err := service.CreateProject(userCtx, console.UpsertProjectInfo{Name: "Project 2"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, usageConfig.Storage.Paid, *proj2.StorageLimit)
|
require.Equal(t, usageConfig.Storage.Paid, *proj2.StorageLimit)
|
||||||
})
|
})
|
||||||
@ -821,7 +821,7 @@ func TestUpdateProjectExceedsLimits(t *testing.T) {
|
|||||||
require.Equal(t, usageConfig.Segment.Free, *proj.SegmentLimit)
|
require.Equal(t, usageConfig.Segment.Free, *proj.SegmentLimit)
|
||||||
|
|
||||||
// update project name should succeed
|
// update project name should succeed
|
||||||
_, err = service.UpdateProject(userCtx1, projectID, console.ProjectInfo{
|
_, err = service.UpdateProject(userCtx1, projectID, console.UpsertProjectInfo{
|
||||||
Name: updatedName,
|
Name: updatedName,
|
||||||
Description: updatedDescription,
|
Description: updatedDescription,
|
||||||
})
|
})
|
||||||
@ -838,7 +838,7 @@ func TestUpdateProjectExceedsLimits(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// try to update project name should succeed
|
// try to update project name should succeed
|
||||||
_, err = service.UpdateProject(userCtx1, projectID, console.ProjectInfo{
|
_, err = service.UpdateProject(userCtx1, projectID, console.UpsertProjectInfo{
|
||||||
Name: "updatedName",
|
Name: "updatedName",
|
||||||
Description: "updatedDescription",
|
Description: "updatedDescription",
|
||||||
})
|
})
|
||||||
@ -2020,7 +2020,7 @@ func TestServiceGenMethods(t *testing.T) {
|
|||||||
updatedStorageLimit := memory.Size(100)
|
updatedStorageLimit := memory.Size(100)
|
||||||
updatedBandwidthLimit := memory.Size(100)
|
updatedBandwidthLimit := memory.Size(100)
|
||||||
|
|
||||||
info := console.ProjectInfo{
|
info := console.UpsertProjectInfo{
|
||||||
Name: updatedName,
|
Name: updatedName,
|
||||||
Description: updatedDescription,
|
Description: updatedDescription,
|
||||||
StorageLimit: updatedStorageLimit,
|
StorageLimit: updatedStorageLimit,
|
||||||
@ -2076,7 +2076,7 @@ func TestServiceGenMethods(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// create empty project for easy deletion
|
// create empty project for easy deletion
|
||||||
p, err := s.CreateProject(tt.ctx, console.ProjectInfo{
|
p, err := s.CreateProject(tt.ctx, console.UpsertProjectInfo{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Description: "bar",
|
Description: "bar",
|
||||||
})
|
})
|
||||||
|
@ -131,7 +131,7 @@ func TestOIDC(t *testing.T) {
|
|||||||
|
|
||||||
authed := console.WithUser(ctx, user)
|
authed := console.WithUser(ctx, user)
|
||||||
|
|
||||||
project, err := sat.API.Console.Service.CreateProject(authed, console.ProjectInfo{
|
project, err := sat.API.Console.Service.CreateProject(authed, console.UpsertProjectInfo{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -69,14 +69,6 @@ export class Project {
|
|||||||
defaultPlacement: number;
|
defaultPlacement: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProjectInfo {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
storageLimit: MemorySize;
|
|
||||||
bandwidthLimit: MemorySize;
|
|
||||||
createdAt: Time;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ResponseUser {
|
export class ResponseUser {
|
||||||
id: UUID;
|
id: UUID;
|
||||||
fullName: string;
|
fullName: string;
|
||||||
@ -94,11 +86,19 @@ export class ResponseUser {
|
|||||||
mfaRecoveryCodeCount: number;
|
mfaRecoveryCodeCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class UpsertProjectInfo {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
storageLimit: MemorySize;
|
||||||
|
bandwidthLimit: MemorySize;
|
||||||
|
createdAt: Time;
|
||||||
|
}
|
||||||
|
|
||||||
export class projectsHttpApiV0 {
|
export class projectsHttpApiV0 {
|
||||||
private readonly http: HttpClient = new HttpClient();
|
private readonly http: HttpClient = new HttpClient();
|
||||||
private readonly ROOT_PATH: string = '/api/v0/projects';
|
private readonly ROOT_PATH: string = '/api/v0/projects';
|
||||||
|
|
||||||
public async createProject(request: ProjectInfo): Promise<Project> {
|
public async createProject(request: UpsertProjectInfo): Promise<Project> {
|
||||||
const path = `${this.ROOT_PATH}/create`;
|
const path = `${this.ROOT_PATH}/create`;
|
||||||
const response = await this.http.post(path, JSON.stringify(request));
|
const response = await this.http.post(path, JSON.stringify(request));
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
@ -108,7 +108,7 @@ export class projectsHttpApiV0 {
|
|||||||
throw new Error(err.error);
|
throw new Error(err.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateProject(request: ProjectInfo, id: UUID): Promise<Project> {
|
public async updateProject(request: UpsertProjectInfo, id: UUID): Promise<Project> {
|
||||||
const path = `${this.ROOT_PATH}/update/${id}`;
|
const path = `${this.ROOT_PATH}/update/${id}`;
|
||||||
const response = await this.http.patch(path, JSON.stringify(request));
|
const response = await this.http.patch(path, JSON.stringify(request));
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
Loading…
Reference in New Issue
Block a user