Skip to content

Commit

Permalink
satellite/console: add more cross-user api tests
Browse files Browse the repository at this point in the history
This change adds more endpoints to the cross-user api test.

Issue: #6246

Change-Id: I4c3128c3a932c713b10499a8909836a599b79458
  • Loading branch information
wilfred-asomanii authored and Storj Robot committed Sep 19, 2023
1 parent a2d37bc commit e599df0
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 8 deletions.
6 changes: 6 additions & 0 deletions satellite/console/consoleweb/consoleapi/buckets.go
Expand Up @@ -149,7 +149,13 @@ func (b *Buckets) GetBucketTotals(w http.ResponseWriter, r *http.Request) {
Page: page,
}, before)
if err != nil {
if console.ErrUnauthorized.Has(err) {
b.serveJSONError(ctx, w, http.StatusUnauthorized, err)
return
}

b.serveJSONError(ctx, w, http.StatusInternalServerError, err)
return
}

err = json.NewEncoder(w).Encode(totals)
Expand Down
9 changes: 9 additions & 0 deletions satellite/console/consoleweb/consoleapi/payments.go
Expand Up @@ -270,6 +270,11 @@ func (p *Payments) MakeCreditCardDefault(w http.ResponseWriter, r *http.Request)

err = p.service.Payments().MakeCreditCardDefault(ctx, string(cardID))
if err != nil {
if stripe.ErrCardNotFound.Has(err) {
p.serveJSONError(ctx, w, http.StatusNotFound, err)
return
}

if console.ErrUnauthorized.Has(err) {
p.serveJSONError(ctx, w, http.StatusUnauthorized, err)
return
Expand Down Expand Up @@ -302,6 +307,10 @@ func (p *Payments) RemoveCreditCard(w http.ResponseWriter, r *http.Request) {

err = p.service.Payments().RemoveCreditCard(ctx, cardID)
if err != nil {
if stripe.ErrCardNotFound.Has(err) {
p.serveJSONError(ctx, w, http.StatusNotFound, err)
return
}
if console.ErrUnauthorized.Has(err) {
p.serveJSONError(ctx, w, http.StatusUnauthorized, err)
return
Expand Down
61 changes: 57 additions & 4 deletions satellite/console/consoleweb/endpoints_test.go
Expand Up @@ -16,11 +16,13 @@ import (
"time"

"github.com/stretchr/testify/require"
"go.uber.org/zap"

"storj.io/common/testcontext"
"storj.io/common/uuid"
"storj.io/storj/private/apigen"
"storj.io/storj/private/testplanet"
"storj.io/storj/satellite"
"storj.io/storj/satellite/accounting"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/payments/storjscan/blockchaintest"
Expand Down Expand Up @@ -622,11 +624,15 @@ func TestProjects(t *testing.T) {
func TestWrongUser(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
Reconfigure: testplanet.Reconfigure{
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
config.Console.RateLimit.Burst = 4
},
},
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
test := newTest(t, ctx, planet)
authorizedUser := test.defaultUser()
unauthorizedUser := test.registerUser("user@mail.test", "#$Rnkl12i3nkljfds")
test.login(unauthorizedUser.email, unauthorizedUser.password)

type endpointTest struct {
endpoint string
Expand All @@ -635,10 +641,25 @@ func TestWrongUser(t *testing.T) {
}

baseProjectsUrl := "/projects"
baseApiKeyUrl := "/api-keys"
baseProjectIdUrl := fmt.Sprintf("%s/%s", baseProjectsUrl, test.defaultProjectID())
getProjectResourceUrl := func(resource string) string {
return fmt.Sprintf("%s/%s", baseProjectIdUrl, resource)
}
getIdAppendedApiKeyUrl := func(resource string) string {
return fmt.Sprintf("%s/%s%s", baseApiKeyUrl, resource, test.defaultProjectID())
}

// login and create an api key and credit card to test deletion.
test.login(authorizedUser.email, authorizedUser.password)
resp, body := test.request(http.MethodPost, getIdAppendedApiKeyUrl("create/"), test.toJSON("some name"))
require.Equal(t, http.StatusOK, resp.StatusCode)
var response console.CreateAPIKeyResponse
require.NoError(t, json.Unmarshal([]byte(body), &response))

apiKeyId := response.KeyInfo.ID.String()

test.login(unauthorizedUser.email, unauthorizedUser.password)

testCases := []endpointTest{
{
Expand Down Expand Up @@ -680,20 +701,47 @@ func TestWrongUser(t *testing.T) {
endpoint: getProjectResourceUrl("usage-limits"),
method: http.MethodGet,
},
{
endpoint: "/buckets/bucket-names?projectID=" + test.defaultProjectID(),
method: http.MethodGet,
},
{
endpoint: "/buckets/usage-totals?limit=10&page=1&before=" + time.Now().Format(apigen.DateFormat) + "&projectID=" + test.defaultProjectID(),
method: http.MethodGet,
},
{
endpoint: getProjectResourceUrl("daily-usage") + "?from=100000000&to=200000000000",
method: http.MethodGet,
},
{
endpoint: "/api-keys/create/" + test.defaultProjectID(),
endpoint: getIdAppendedApiKeyUrl("create/"),
method: http.MethodPost,
body: "name",
},
{
endpoint: getIdAppendedApiKeyUrl("delete-by-name?name=name&projectID="),
method: http.MethodDelete,
},
{
endpoint: getIdAppendedApiKeyUrl("list-paged?limit=10&page=1&order=1&orderDirection=1&projectID="),
method: http.MethodGet,
},
{
endpoint: getIdAppendedApiKeyUrl("api-key-names?projectID="),
method: http.MethodGet,
},
{
endpoint: baseApiKeyUrl + "/delete-by-ids",
method: http.MethodDelete,
body: map[string]interface{}{
"ids": []string{apiKeyId},
},
},
}

for _, testCase := range testCases {
t.Run(fmt.Sprintf("Unauthorized on %s", testCase.endpoint), func(t *testing.T) {
resp, body := test.request(testCase.method, testCase.endpoint, test.toJSON(testCase.body))
resp, body = test.request(testCase.method, testCase.endpoint, test.toJSON(testCase.body))
require.Contains(t, body, "not authorized")
require.Equal(t, http.StatusUnauthorized, resp.StatusCode)
})
Expand All @@ -703,7 +751,7 @@ func TestWrongUser(t *testing.T) {
test.login(authorizedUser.email, authorizedUser.password)
for _, testCase := range testCases {
t.Run(fmt.Sprintf("Authorized on %s", testCase.endpoint), func(t *testing.T) {
resp, body := test.request(testCase.method, testCase.endpoint, test.toJSON(testCase.body))
resp, body = test.request(testCase.method, testCase.endpoint, test.toJSON(testCase.body))
require.NotContains(t, body, "not authorized")
require.NotEqual(t, http.StatusUnauthorized, resp.StatusCode)
})
Expand Down Expand Up @@ -762,6 +810,10 @@ func (test *test) url(suffix string) string {
}

func (test *test) toJSON(v interface{}) io.Reader {
if str, ok := v.(string); ok {
return strings.NewReader(str)
}

data, err := json.Marshal(v)
require.NoError(test.t, err)
return strings.NewReader(string(data))
Expand All @@ -784,6 +836,7 @@ func (test *test) login(email, password string) Response {
"email": email,
"password": password,
}))
require.Equal(test.t, http.StatusOK, resp.StatusCode)
cookie := findCookie(resp, "_tokenKey")
require.NotNil(test.t, cookie)

Expand Down
8 changes: 4 additions & 4 deletions satellite/console/service.go
Expand Up @@ -2460,7 +2460,7 @@ func (s *Service) GetAllAPIKeyNamesByProjectID(ctx context.Context, projectID uu

isMember, err := s.isProjectMember(ctx, user.ID, projectID)
if err != nil {
return nil, Error.Wrap(err)
return nil, ErrUnauthorized.Wrap(err)
}

names, err = s.store.APIKeys().GetAllNamesByProjectID(ctx, isMember.project.ID)
Expand All @@ -2483,7 +2483,7 @@ func (s *Service) DeleteAPIKeyByNameAndProjectID(ctx context.Context, name strin

isMember, err := s.isProjectMember(ctx, user.ID, projectID)
if err != nil {
return Error.Wrap(err)
return ErrUnauthorized.Wrap(err)
}

key, err := s.store.APIKeys().GetByNameAndProjectID(ctx, name, isMember.project.ID)
Expand Down Expand Up @@ -2599,7 +2599,7 @@ func (s *Service) GetBucketTotals(ctx context.Context, projectID uuid.UUID, curs

isMember, err := s.isProjectMember(ctx, user.ID, projectID)
if err != nil {
return nil, Error.Wrap(err)
return nil, ErrUnauthorized.Wrap(err)
}

usage, err := s.projectAccounting.GetBucketTotals(ctx, isMember.project.ID, cursor, before)
Expand All @@ -2622,7 +2622,7 @@ func (s *Service) GetAllBucketNames(ctx context.Context, projectID uuid.UUID) (_

isMember, err := s.isProjectMember(ctx, user.ID, projectID)
if err != nil {
return nil, Error.Wrap(err)
return nil, ErrUnauthorized.Wrap(err)
}

listOptions := buckets.ListOptions{
Expand Down
8 changes: 8 additions & 0 deletions satellite/payments/stripe/creditcards.go
Expand Up @@ -5,6 +5,7 @@ package stripe

import (
"context"
"strings"

"github.com/stripe/stripe-go/v72"
"github.com/zeebo/errs"
Expand All @@ -20,6 +21,10 @@ var (
ErrDefaultCard = errs.Class("default card")
// ErrDuplicateCard is returned when a user tries to add duplicate card.
ErrDuplicateCard = errs.Class("duplicate card")

// UnattachedErrString is part of the err string returned by stripe if a payment
// method does not belong to a customer.
UnattachedErrString = "The payment method must be attached to the customer"
)

// creditCards is an implementation of payments.CreditCards.
Expand Down Expand Up @@ -165,6 +170,9 @@ func (creditCards *creditCards) MakeDefault(ctx context.Context, userID uuid.UUI
}

_, err = creditCards.service.stripeClient.Customers().Update(customerID, params)
if err != nil && strings.Contains(err.Error(), UnattachedErrString) {
return ErrCardNotFound.New("this card is not attached to this account.")
}

return Error.Wrap(err)
}
Expand Down

0 comments on commit e599df0

Please sign in to comment.