1// Copyright (C) 2021 Storj Labs, Inc. 2// See LICENSE for copying information. 3 4package consoleweb_test 5 6import ( 7 "bytes" 8 "fmt" 9 "net/http" 10 "testing" 11 "time" 12 13 "github.com/stretchr/testify/require" 14 "go.uber.org/zap" 15 16 "storj.io/common/testcontext" 17 "storj.io/storj/private/testplanet" 18 "storj.io/storj/satellite" 19 "storj.io/storj/satellite/console" 20) 21 22func TestActivationRouting(t *testing.T) { 23 testplanet.Run(t, testplanet.Config{ 24 SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 0, 25 }, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) { 26 sat := planet.Satellites[0] 27 service := sat.API.Console.Service 28 29 regToken, err := service.CreateRegToken(ctx, 1) 30 require.NoError(t, err) 31 32 user, err := service.CreateUser(ctx, console.CreateUser{ 33 FullName: "User", 34 Email: "u@mail.test", 35 Password: "123a123", 36 }, regToken.Secret) 37 require.NoError(t, err) 38 39 activationToken, err := service.GenerateActivationToken(ctx, user.ID, user.Email) 40 require.NoError(t, err) 41 42 checkActivationRedirect := func(testMsg, redirectURL string, shouldHaveCookie bool) { 43 url := "http://" + sat.API.Console.Listener.Addr().String() + "/activation/?token=" + activationToken 44 45 req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody) 46 require.NoError(t, err, testMsg) 47 48 result, err := http.DefaultClient.Do(req) 49 require.NoError(t, err, testMsg) 50 51 // cookie should be set on successful activation 52 hasCookie := false 53 for _, c := range result.Cookies() { 54 if c.Name == "_tokenKey" { 55 hasCookie = true 56 break 57 } 58 } 59 require.Equal(t, shouldHaveCookie, hasCookie) 60 61 require.Equal(t, http.StatusTemporaryRedirect, result.StatusCode, testMsg) 62 require.Equal(t, redirectURL, result.Header.Get("Location"), testMsg) 63 require.NoError(t, result.Body.Close(), testMsg) 64 } 65 66 http.DefaultClient.CheckRedirect = func(req *http.Request, via []*http.Request) error { 67 return http.ErrUseLastResponse 68 } 69 70 baseURL := "http://" + sat.API.Console.Listener.Addr().String() + "/" 71 loginURL := baseURL + "login" 72 73 // successful activation should set cookie and redirect to home page. 74 checkActivationRedirect("Activation - Fresh Token", baseURL, true) 75 // unsuccessful redirect should not set cookie and redirect to login page. 76 checkActivationRedirect("Activation - Used Token", loginURL+"?activated=false", false) 77 }) 78} 79 80func TestUserIDRateLimiter(t *testing.T) { 81 numLimits := 2 82 testplanet.Run(t, testplanet.Config{ 83 SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 0, 84 Reconfigure: testplanet.Reconfigure{ 85 Satellite: func(log *zap.Logger, index int, config *satellite.Config) { 86 config.Console.RateLimit.NumLimits = numLimits 87 }, 88 }, 89 }, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) { 90 sat := planet.Satellites[0] 91 92 applyCouponStatus := func(token string) int { 93 urlLink := "http://" + sat.API.Console.Listener.Addr().String() + "/api/v0/payments/coupon/apply" 94 95 req, err := http.NewRequestWithContext(ctx, http.MethodPatch, urlLink, bytes.NewBufferString("PROMO_CODE")) 96 require.NoError(t, err) 97 98 req.AddCookie(&http.Cookie{ 99 Name: "_tokenKey", 100 Path: "/", 101 Value: token, 102 Expires: time.Now().AddDate(0, 0, 1), 103 }) 104 105 result, err := http.DefaultClient.Do(req) 106 require.NoError(t, err) 107 require.NoError(t, result.Body.Close()) 108 109 return result.StatusCode 110 } 111 112 var firstToken string 113 for userNum := 1; userNum <= numLimits+1; userNum++ { 114 t.Run(fmt.Sprintf("TestUserIDRateLimit_%d", userNum), func(t *testing.T) { 115 user, err := sat.AddUser(ctx, console.CreateUser{ 116 FullName: fmt.Sprintf("Test User %d", userNum), 117 Email: fmt.Sprintf("test%d@mail.test", userNum), 118 }, 1) 119 require.NoError(t, err) 120 121 // sat.AddUser sets password to full name. 122 token, err := sat.API.Console.Service.Token(ctx, console.AuthUser{Email: user.Email, Password: user.FullName}) 123 require.NoError(t, err) 124 125 if userNum == 1 { 126 firstToken = token 127 } 128 129 // Expect burst number of successes. 130 for burstNum := 0; burstNum < sat.Config.Console.RateLimit.Burst; burstNum++ { 131 require.NotEqual(t, http.StatusTooManyRequests, applyCouponStatus(token)) 132 } 133 134 // Expect failure. 135 require.Equal(t, http.StatusTooManyRequests, applyCouponStatus(token)) 136 }) 137 } 138 139 // Expect original user to work again because numLimits == 2. 140 for burstNum := 0; burstNum < sat.Config.Console.RateLimit.Burst; burstNum++ { 141 require.NotEqual(t, http.StatusTooManyRequests, applyCouponStatus(firstToken)) 142 } 143 require.Equal(t, http.StatusTooManyRequests, applyCouponStatus(firstToken)) 144 }) 145} 146