satellite/{console,web}: make bucket endpoints support publicID

This change adds support for project public id to the bucket-names and
usage-report endpoints.

Issue: https://github.com/storj/storj/issues/5578

Change-Id: I2429ebebe52dfc8217fc40f4691e7bc473b805fb
This commit is contained in:
Wilfred Asomani 2023-02-13 18:19:20 +00:00 committed by Storj Robot
parent 94d341bcf3
commit 4a67b57103
6 changed files with 82 additions and 36 deletions

View File

@ -43,10 +43,23 @@ func (b *Buckets) AllBucketNames(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
projectIDString := r.URL.Query().Get("projectID")
publicIDString := r.URL.Query().Get("publicID")
projectID, err := uuid.FromString(projectIDString)
if err != nil {
b.serveJSONError(w, http.StatusInternalServerError, err)
var projectID uuid.UUID
if projectIDString != "" {
projectID, err = uuid.FromString(projectIDString)
if err != nil {
b.serveJSONError(w, http.StatusBadRequest, err)
return
}
} else if publicIDString != "" {
projectID, err = uuid.FromString(publicIDString)
if err != nil {
b.serveJSONError(w, http.StatusBadRequest, err)
return
}
} else {
b.serveJSONError(w, http.StatusBadRequest, errs.New("Project ID was not provided."))
return
}

View File

@ -69,37 +69,46 @@ func Test_AllBucketNames(t *testing.T) {
client := http.Client{}
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+planet.Satellites[0].API.Console.Listener.Addr().String()+"/api/v0/buckets/bucket-names?projectID="+project.ID.String(), nil)
require.NoError(t, err)
testRequest := func(req *http.Request) {
expire := time.Now().AddDate(0, 0, 1)
cookie := http.Cookie{
Name: "_tokenKey",
Path: "/",
Value: tokenInfo.Token.String(),
Expires: expire,
}
expire := time.Now().AddDate(0, 0, 1)
cookie := http.Cookie{
Name: "_tokenKey",
Path: "/",
Value: tokenInfo.Token.String(),
Expires: expire,
req.AddCookie(&cookie)
result, err := client.Do(req)
require.NoError(t, err)
require.Equal(t, http.StatusOK, result.StatusCode)
body, err := io.ReadAll(result.Body)
require.NoError(t, err)
var output []string
err = json.Unmarshal(body, &output)
require.NoError(t, err)
require.Equal(t, bucket1.Name, output[0])
require.Equal(t, bucket2.Name, output[1])
defer func() {
err = result.Body.Close()
require.NoError(t, err)
}()
}
req.AddCookie(&cookie)
result, err := client.Do(req)
// test using Project.ID
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+planet.Satellites[0].API.Console.Listener.Addr().String()+"/api/v0/buckets/bucket-names?projectID="+project.ID.String(), nil)
require.NoError(t, err)
require.Equal(t, http.StatusOK, result.StatusCode)
testRequest(req)
body, err := io.ReadAll(result.Body)
// test using Project.PublicID
req, err = http.NewRequestWithContext(ctx, "GET", "http://"+planet.Satellites[0].API.Console.Listener.Addr().String()+"/api/v0/buckets/bucket-names?publicID="+project.PublicID.String(), nil)
require.NoError(t, err)
var output []string
err = json.Unmarshal(body, &output)
require.NoError(t, err)
require.Equal(t, bucket1.Name, output[0])
require.Equal(t, bucket2.Name, output[1])
defer func() {
err = result.Body.Close()
require.NoError(t, err)
}()
testRequest(req)
})
}

View File

@ -580,11 +580,28 @@ func (server *Server) bucketUsageReportHandler(w http.ResponseWriter, r *http.Re
}
// parse query params
projectID, err := uuid.FromString(r.URL.Query().Get("projectID"))
if err != nil {
projectIDString := r.URL.Query().Get("projectID")
publicIDString := r.URL.Query().Get("publicID")
var projectID uuid.UUID
if projectIDString != "" {
projectID, err = uuid.FromString(projectIDString)
if err != nil {
server.serveError(w, http.StatusBadRequest)
return
}
} else if publicIDString != "" {
projectID, err = uuid.FromString(publicIDString)
if err != nil {
server.serveError(w, http.StatusBadRequest)
return
}
} else {
server.log.Error("bucket usage report error", zap.Error(errs.New("Project ID was not provided.")))
server.serveError(w, http.StatusBadRequest)
return
}
sinceStamp, err := strconv.ParseInt(r.URL.Query().Get("since"), 10, 64)
if err != nil {
server.serveError(w, http.StatusBadRequest)

View File

@ -2416,6 +2416,7 @@ func (s *Service) GetBucketTotals(ctx context.Context, projectID uuid.UUID, curs
}
// GetAllBucketNames retrieves all bucket names of a specific project.
// projectID here may be Project.ID or Project.PublicID.
func (s *Service) GetAllBucketNames(ctx context.Context, projectID uuid.UUID) (_ []string, err error) {
defer mon.Task()(&ctx)(&err)
@ -2424,7 +2425,7 @@ func (s *Service) GetAllBucketNames(ctx context.Context, projectID uuid.UUID) (_
return nil, Error.Wrap(err)
}
_, err = s.isProjectMember(ctx, user.ID, projectID)
isMember, err := s.isProjectMember(ctx, user.ID, projectID)
if err != nil {
return nil, Error.Wrap(err)
}
@ -2437,7 +2438,7 @@ func (s *Service) GetAllBucketNames(ctx context.Context, projectID uuid.UUID) (_
All: true,
}
bucketsList, err := s.buckets.ListBuckets(ctx, projectID, listOptions, allowedBuckets)
bucketsList, err := s.buckets.ListBuckets(ctx, isMember.project.ID, listOptions, allowedBuckets)
if err != nil {
return nil, Error.Wrap(err)
}
@ -2451,6 +2452,7 @@ func (s *Service) GetAllBucketNames(ctx context.Context, projectID uuid.UUID) (_
}
// GetBucketUsageRollups retrieves summed usage rollups for every bucket of particular project for a given period.
// projectID here may be Project.ID or Project.PublicID.
func (s *Service) GetBucketUsageRollups(ctx context.Context, projectID uuid.UUID, since, before time.Time) (_ []accounting.BucketUsageRollup, err error) {
defer mon.Task()(&ctx)(&err)
@ -2459,12 +2461,12 @@ func (s *Service) GetBucketUsageRollups(ctx context.Context, projectID uuid.UUID
return nil, Error.Wrap(err)
}
_, err = s.isProjectMember(ctx, user.ID, projectID)
isMember, err := s.isProjectMember(ctx, user.ID, projectID)
if err != nil {
return nil, Error.Wrap(err)
}
result, err := s.projectAccounting.GetBucketUsageRollups(ctx, projectID, since, before)
result, err := s.projectAccounting.GetBucketUsageRollups(ctx, isMember.project.ID, since, before)
if err != nil {
return nil, Error.Wrap(err)
}

View File

@ -358,6 +358,11 @@ func TestService(t *testing.T) {
require.Equal(t, bucket1.Name, bucketNames[0])
require.Equal(t, bucket2.Name, bucketNames[1])
bucketNames, err = service.GetAllBucketNames(userCtx2, up2Pro1.PublicID)
require.NoError(t, err)
require.Equal(t, bucket1.Name, bucketNames[0])
require.Equal(t, bucket2.Name, bucketNames[1])
// Getting someone else buckets should not work
bucketsForUnauthorizedUser, err := service.GetAllBucketNames(userCtx1, up2Pro1.ID)
require.Error(t, err)

View File

@ -65,7 +65,7 @@ export class BucketsApiGql extends BaseGql implements BucketsApi {
* @throws Error
*/
public async getAllBucketNames(projectId: string): Promise<string[]> {
const path = `${this.ROOT_PATH}/bucket-names?projectID=${projectId}`;
const path = `${this.ROOT_PATH}/bucket-names?publicID=${projectId}`;
const response = await this.client.get(path);
if (!response.ok) {