storj/satellite/console/consoleweb/endpoints_test.go
Moby von Briesen 8d1a765fd6 satellite/console: Partially revert change to remove graphql
This partially reverts commit 516241e406.

Endpoints are added to the backend, as there are some customers who may
use these endpoints, even though they are no longer necessary for the
satellite UI.

Change-Id: I52a99912d9eacf269fbb2ddca603e53c4af6d6bf
2023-09-07 20:50:24 +00:00

828 lines
25 KiB
Go

// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
package consoleweb_test
import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
"storj.io/common/testcontext"
"storj.io/common/uuid"
"storj.io/storj/private/apigen"
"storj.io/storj/private/testplanet"
"storj.io/storj/satellite/accounting"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/payments/storjscan/blockchaintest"
)
func TestAuth(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
test := newTest(t, ctx, planet)
user := test.defaultUser()
{ // Register User
_ = test.registerUser("user@mail.test", "#$Rnkl12i3nkljfds")
}
{ // Login_GetToken_Fail
resp, body := test.request(
http.MethodPost, "/auth/token",
strings.NewReader(`{"email":"wrong@invalid.test","password":"wrong"}`))
require.Nil(t, findCookie(resp, "_tokenKey"))
require.Equal(t, http.StatusUnauthorized, resp.StatusCode)
_ = body
// TODO: require.Contains(t, body, "unauthorized")
}
{ // Login_GetToken_Pass
test.login(user.email, user.password)
}
{ // Login_ChangePassword_IncorrectCurrentPassword
resp, body := test.request(
http.MethodPost, "/auth/account/change-password",
test.toJSON(map[string]string{
"email": user.email,
"password": user.password + "1",
"newPassword": user.password + "2",
}))
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
_ = body
//TODO: require.Contains(t, body, "password was incorrect")
}
{ // Login_ChangePassword
resp, _ := test.request(
http.MethodPost, "/auth/account/change-password`",
test.toJSON(map[string]string{
"email": user.email,
"password": user.password,
"newPassword": user.password,
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
}
var oldCookies []*http.Cookie
{ // Get_AccountInfo
resp, body := test.request(http.MethodGet, "/auth/account", nil)
require.Equal(test.t, http.StatusOK, resp.StatusCode)
require.Contains(test.t, body, "fullName")
oldCookies = resp.Cookies()
var userIdentifier struct{ ID string }
require.NoError(test.t, json.Unmarshal([]byte(body), &userIdentifier))
require.NotEmpty(test.t, userIdentifier.ID)
}
{ // Get_FreezeStatus
resp, body := test.request(http.MethodGet, "/auth/account/freezestatus", nil)
require.Equal(test.t, http.StatusOK, resp.StatusCode)
require.Contains(test.t, body, "frozen")
require.Contains(test.t, body, "warned")
var freezestatus struct {
Frozen bool
Warned bool
}
require.NoError(test.t, json.Unmarshal([]byte(body), &freezestatus))
require.Equal(test.t, http.StatusOK, resp.StatusCode)
require.False(test.t, freezestatus.Frozen)
require.False(test.t, freezestatus.Warned)
}
{ // Test_UserSettings
type expectedSettings struct {
SessionDuration *time.Duration
OnboardingStart bool
OnboardingEnd bool
PassphrasePrompt bool
OnboardingStep *string
}
testGetSettings := func(expected expectedSettings) {
resp, body := test.request(http.MethodGet, "/auth/account/settings", nil)
var settings struct {
SessionDuration *time.Duration
OnboardingStart bool
OnboardingEnd bool
PassphrasePrompt bool
OnboardingStep *string
}
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NoError(test.t, json.Unmarshal([]byte(body), &settings))
require.Equal(test.t, expected.OnboardingStart, settings.OnboardingStart)
require.Equal(test.t, expected.OnboardingEnd, settings.OnboardingEnd)
require.Equal(test.t, expected.PassphrasePrompt, settings.PassphrasePrompt)
require.Equal(test.t, expected.OnboardingStep, settings.OnboardingStep)
require.Equal(test.t, expected.SessionDuration, settings.SessionDuration)
}
testGetSettings(expectedSettings{
SessionDuration: nil,
OnboardingStart: true,
OnboardingEnd: true,
PassphrasePrompt: true,
OnboardingStep: nil,
})
step := "cli"
duration := time.Duration(15) * time.Minute
resp, _ := test.request(http.MethodPatch, "/auth/account/settings",
test.toJSON(map[string]interface{}{
"sessionDuration": duration,
"onboardingStart": true,
"onboardingEnd": false,
"passphrasePrompt": false,
"onboardingStep": step,
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
testGetSettings(expectedSettings{
SessionDuration: &duration,
OnboardingStart: true,
OnboardingEnd: false,
PassphrasePrompt: false,
OnboardingStep: &step,
})
resp, _ = test.request(http.MethodPatch, "/auth/account/settings",
test.toJSON(map[string]interface{}{
"sessionDuration": nil,
"onboardingStart": nil,
"onboardingEnd": nil,
"onboardingStep": nil,
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
// having passed nil to /auth/account/settings shouldn't have changed existing values.
testGetSettings(expectedSettings{
SessionDuration: &duration,
OnboardingStart: true,
OnboardingEnd: false,
PassphrasePrompt: false,
OnboardingStep: &step,
})
// having passed 0 as sessionDuration to /auth/account/settings should nullify it.
resp, _ = test.request(http.MethodPatch, "/auth/account/settings",
test.toJSON(map[string]interface{}{
"sessionDuration": 0,
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
testGetSettings(expectedSettings{
SessionDuration: nil,
OnboardingStart: true,
OnboardingEnd: false,
OnboardingStep: &step,
})
}
{ // Logout
resp, _ := test.request(http.MethodPost, "/auth/logout", nil)
cookie := findCookie(resp, "_tokenKey")
require.NotNil(t, cookie)
require.Equal(t, "", cookie.Value)
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_AccountInfo shouldn't succeed after logging out
resp, body := test.request(http.MethodGet, "/auth/account", nil)
// TODO: wrong error text
// require.Contains(test.t, body, "unauthorized")
require.Contains(test.t, body, "error")
require.Equal(test.t, http.StatusUnauthorized, resp.StatusCode)
}
{ // Get_AccountInfo shouldn't succeed with reused session cookie
satURL, err := url.Parse(test.url(""))
require.NoError(t, err)
test.client.Jar.SetCookies(satURL, oldCookies)
resp, body := test.request(http.MethodGet, "/auth/account", nil)
require.Contains(test.t, body, "error")
require.Equal(test.t, http.StatusUnauthorized, resp.StatusCode)
}
{ // repeated login attempts should end in too many requests
hitRateLimiter := false
for i := 0; i < 30; i++ {
resp, _ := test.request(
http.MethodPost, "/auth/token",
strings.NewReader(`{"email":"wrong@invalid.test","password":"wrong"}`))
require.Nil(t, findCookie(resp, "_tokenKey"))
if resp.StatusCode != http.StatusUnauthorized {
require.Equal(t, http.StatusTooManyRequests, resp.StatusCode)
hitRateLimiter = true
break
}
}
require.True(t, hitRateLimiter, "did not hit rate limiter")
}
})
}
func TestPayments(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
test := newTest(t, ctx, planet)
user := test.defaultUser()
{ // Unauthorized
for _, path := range []string{
"/payments/cards",
"/payments/account/balance",
"/payments/billing-history",
"/payments/invoice-history",
"/payments/account/charges?from=1619827200&to=1620844320",
} {
resp, body := test.request(http.MethodGet, path, nil)
require.Contains(t, body, "unauthorized", path)
require.Equal(t, http.StatusUnauthorized, resp.StatusCode, path)
}
}
test.login(user.email, user.password)
{ // Get_PaymentCards_EmptyReturn
resp, body := test.request(http.MethodGet, "/payments/cards", nil)
require.JSONEq(t, "[]", body)
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_AccountBalance
resp, body := test.request(http.MethodGet, "/payments/account/balance", nil)
require.Contains(t, body, "freeCredits")
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_BillingHistory
resp, body := test.request(http.MethodGet, "/payments/billing-history", nil)
require.JSONEq(t, "[]", body)
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_InvoiceHistory
resp, body := test.request(http.MethodGet, "/payments/invoice-history?limit=1", nil)
require.Contains(t, body, "items")
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_AccountChargesByDateRange
resp, body := test.request(http.MethodGet, "/payments/account/charges?from=1619827200&to=1620844320", nil)
require.Contains(t, body, "egress")
require.Equal(t, http.StatusOK, resp.StatusCode)
}
})
}
func TestWalletPayments(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
test := newTest(t, ctx, planet)
sat := planet.Satellites[0]
userData := test.defaultUser()
test.login(userData.email, userData.password)
user, err := sat.DB.Console().Users().GetByEmail(ctx, userData.email)
require.NoError(t, err)
wallet := blockchaintest.NewAddress()
err = sat.DB.Wallets().Add(ctx, user.ID, wallet)
require.NoError(t, err)
resp, _ := test.request(http.MethodGet, "/payments/wallet/payments", nil)
require.Equal(t, http.StatusOK, resp.StatusCode)
})
}
func TestBuckets(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
test := newTest(t, ctx, planet)
user := test.defaultUser()
{ // Unauthorized
for _, path := range []string{
"/buckets/bucket-names?projectID=" + test.defaultProjectID(),
} {
resp, body := test.request(http.MethodGet, path, nil)
require.Contains(t, body, "unauthorized", path)
require.Equal(t, http.StatusUnauthorized, resp.StatusCode, path)
}
}
test.login(user.email, user.password)
{ // Get_BucketNamesByProjectId
resp, body := test.request(http.MethodGet, "/buckets/bucket-names?projectID="+test.defaultProjectID(), nil)
// TODO: this should be []
require.JSONEq(t, "null", body)
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // get bucket usages
params := url.Values{
"projectID": {test.defaultProjectID()},
"before": {time.Now().Add(time.Second).Format(apigen.DateFormat)},
"limit": {"1"},
"search": {""},
"page": {"1"},
}
resp, body := test.request(http.MethodGet, "/buckets/usage-totals?"+params.Encode(), nil)
require.Equal(t, http.StatusOK, resp.StatusCode)
var page accounting.BucketUsagePage
require.NoError(t, json.Unmarshal([]byte(body), &page))
require.Empty(t, page.BucketUsages)
const bucketName = "my-bucket"
require.NoError(t, planet.Uplinks[0].CreateBucket(ctx, planet.Satellites[0], bucketName))
resp, body = test.request(http.MethodGet, "/buckets/usage-totals?"+params.Encode(), nil)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NoError(t, json.Unmarshal([]byte(body), &page))
require.NotEmpty(t, page.BucketUsages)
require.Equal(t, bucketName, page.BucketUsages[0].BucketName)
}
})
}
func TestAPIKeys(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
test := newTest(t, ctx, planet)
user := test.defaultUser()
test.login(user.email, user.password)
{ // Post_GenerateApiKey
resp, body := test.request(http.MethodPost, "/graphql",
test.toJSON(map[string]interface{}{
"variables": map[string]interface{}{
"projectId": test.defaultProjectID(),
"name": user.email,
},
"query": `
mutation ($projectId: String!, $name: String!) {
createAPIKey(projectID: $projectId, name: $name) {
key
keyInfo {
id
name
createdAt
__typename
}
__typename
}
}`}))
require.Contains(t, body, "createAPIKey")
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_APIKeyInfoByProjectId
resp, body := test.request(http.MethodPost, "/graphql",
test.toJSON(map[string]interface{}{
"variables": map[string]interface{}{
"orderDirection": 1,
"projectId": test.defaultProjectID(),
"limit": 6,
"search": ``,
"page": 1,
"order": 1,
},
"query": `
query ($projectId: String!, $limit: Int!, $search: String!, $page: Int!, $order: Int!, $orderDirection: Int!) {
project(id: $projectId) {
apiKeys(cursor: {limit: $limit, search: $search, page: $page, order: $order, orderDirection: $orderDirection}) {
apiKeys {
id
name
createdAt
__typename
}
search
limit
order
pageCount
currentPage
totalCount
__typename
}
__typename
}
}`}))
require.Contains(t, body, "apiKeysPage")
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_ProjectAPIKeys
var projects console.APIKeyPage
path := "/api-keys/list-paged?projectID=" + test.defaultProjectID() + "&search=''&limit=6&page=1&order=1&orderDirection=1"
resp, body := test.request(http.MethodGet, path, nil)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NoError(t, json.Unmarshal([]byte(body), &projects))
require.Contains(t, body, "apiKeys")
}
{ // Post_Create_APIKey
var response console.CreateAPIKeyResponse
path := "/api-keys/create/" + test.defaultProjectID()
resp, body := test.request(http.MethodPost, path,
test.toJSON(map[string]interface{}{
"name": "testCreatedKey",
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
err := json.Unmarshal([]byte(body), &response)
require.NoError(t, err)
require.Contains(t, body, "key")
require.Contains(t, body, "keyInfo")
require.NotNil(t, response.KeyInfo)
}
{ // Delete_APIKeys_By_IDs
var response *console.CreateAPIKeyResponse
path := "/api-keys/create/" + test.defaultProjectID()
resp, body := test.request(http.MethodPost, path,
test.toJSON(map[string]interface{}{
"name": "testCreatedKey1",
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NoError(t, json.Unmarshal([]byte(body), &response))
path = "/api-keys/delete-by-ids"
resp, body = test.request(http.MethodDelete, path,
test.toJSON(map[string]interface{}{
"ids": []string{response.KeyInfo.ID.String()},
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
require.Empty(t, body)
}
})
}
func TestProjects(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
test := newTest(t, ctx, planet)
user := test.defaultUser()
test.login(user.email, user.password)
{ // Get_ProjectId
resp, body := test.request(http.MethodPost, "/graphql",
test.toJSON(map[string]interface{}{
"query": `
{
myProjects {
name
id
description
createdAt
ownerId
__typename
}
}`}))
require.Contains(t, body, test.defaultProjectID())
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_Salt
projectID := test.defaultProjectID()
id, err := uuid.FromString(projectID)
require.NoError(t, err)
// get salt from endpoint
var b64Salt string
resp, body := test.request(http.MethodGet, fmt.Sprintf("/projects/%s/salt", test.defaultProjectID()), nil)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NoError(t, json.Unmarshal([]byte(body), &b64Salt))
// get salt from db and base64 encode it
salt, err := planet.Satellites[0].DB.Console().Projects().GetSalt(ctx, id)
require.NoError(t, err)
require.Equal(t, b64Salt, base64.StdEncoding.EncodeToString(salt))
}
{ // 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 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))
require.NotEmpty(t, projects)
}
{ // Get_ProjectInfo
resp, body := test.request(http.MethodPost, "/graphql",
test.toJSON(map[string]interface{}{
"variables": map[string]interface{}{
"projectId": test.defaultProjectID(),
"before": "2021-05-12T18:32:30.533Z",
"limit": 7,
"search": "",
"page": 1,
},
"query": `
query ($projectId: String!, $before: DateTime!, $limit: Int!, $search: String!, $page: Int!) {
project(id: $projectId) {
bucketUsages(before: $before, cursor: {limit: $limit, search: $search, page: $page}) {
bucketUsages {
bucketName
storage
egress
objectCount
segmentCount
since
before
__typename
}
search
limit
offset
pageCount
currentPage
totalCount
__typename
}
__typename
}
}`}))
require.Contains(t, body, "bucketUsagePage")
require.Equal(t, http.StatusOK, resp.StatusCode)
}
{ // Get_ProjectUsageLimitById
resp, body := test.request(http.MethodGet, `/projects/`+test.defaultProjectID()+`/usage-limits`, nil)
require.Equal(t, http.StatusOK, resp.StatusCode)
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)
}
{ // Post_ProjectRenameInvalid
resp, body := test.request(http.MethodPatch, fmt.Sprintf("/projects/%s", test.defaultProjectID()),
test.toJSON(map[string]interface{}{
"name": "My Second Project with a long name",
}))
require.Contains(t, body, "error")
require.Equal(t, http.StatusInternalServerError, resp.StatusCode)
}
{ // Post_ProjectRename
resp, _ := test.request(http.MethodPatch, fmt.Sprintf("/projects/%s", test.defaultProjectID()),
test.toJSON(map[string]interface{}{
"name": "new name",
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
}
})
}
func TestWrongUser(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
}, 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
method string
body interface{}
}
baseProjectsUrl := "/projects"
baseProjectIdUrl := fmt.Sprintf("%s/%s", baseProjectsUrl, test.defaultProjectID())
getProjectResourceUrl := func(resource string) string {
return fmt.Sprintf("%s/%s", baseProjectIdUrl, resource)
}
testCases := []endpointTest{
{
endpoint: baseProjectIdUrl,
method: http.MethodPatch,
body: map[string]interface{}{
"name": "new name",
},
},
{
endpoint: getProjectResourceUrl("members") + "?emails=" + "some@email.com",
method: http.MethodDelete,
},
{
endpoint: getProjectResourceUrl("salt"),
method: http.MethodGet,
},
{
endpoint: getProjectResourceUrl("members"),
method: http.MethodGet,
},
{
endpoint: getProjectResourceUrl("invite"),
method: http.MethodPost,
body: map[string]interface{}{
"emails": []string{"some@email.com"},
},
},
{
endpoint: getProjectResourceUrl("usage-limits"),
method: http.MethodGet,
},
{
endpoint: getProjectResourceUrl("daily-usage") + "?from=100000000&to=200000000000",
method: http.MethodGet,
},
{
endpoint: "/api-keys/create/" + test.defaultProjectID(),
method: http.MethodPost,
body: "name",
},
}
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))
require.Contains(t, body, "not authorized")
require.Equal(t, http.StatusUnauthorized, resp.StatusCode)
})
}
// login with correct user to make sure they have access.
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))
require.NotContains(t, body, "not authorized")
require.NotEqual(t, http.StatusUnauthorized, resp.StatusCode)
})
}
})
}
type test struct {
t *testing.T
ctx *testcontext.Context
planet *testplanet.Planet
client *http.Client
}
func newTest(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) test {
jar, err := cookiejar.New(nil)
require.NoError(t, err)
return test{t: t, ctx: ctx, planet: planet, client: &http.Client{Jar: jar}}
}
type registeredUser struct {
id string
email string
password string
}
func (test *test) request(method string, path string, data io.Reader) (resp Response, body string) {
req, err := http.NewRequestWithContext(test.ctx, method, test.url(path), data)
require.NoError(test.t, err)
req.Header = map[string][]string{
"sec-ch-ua": {`" Not A;Brand";v="99"`, `"Chromium";v="90"`, `"Google Chrome";v="90"`},
"sec-ch-ua-mobile": {"?0"},
"User-Agent": {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"},
"Content-Type": {"application/json"},
"Accept": {"*/*"},
}
return test.do(req)
}
// Response is a wrapper for http.Request to prevent false-positive with bodyclose check.
type Response struct{ *http.Response }
func (test *test) do(req *http.Request) (_ Response, body string) {
resp, err := test.client.Do(req)
require.NoError(test.t, err)
data, err := io.ReadAll(resp.Body)
require.NoError(test.t, err)
require.NoError(test.t, resp.Body.Close())
return Response{resp}, string(data)
}
func (test *test) url(suffix string) string {
return test.planet.Satellites[0].ConsoleURL() + "/api/v0" + suffix
}
func (test *test) toJSON(v interface{}) io.Reader {
data, err := json.Marshal(v)
require.NoError(test.t, err)
return strings.NewReader(string(data))
}
func (test *test) defaultUser() registeredUser {
user := test.planet.Uplinks[0].User[test.planet.Satellites[0].ID()]
return registeredUser{
email: user.Email,
password: user.Password,
}
}
func (test *test) defaultProjectID() string { return test.planet.Uplinks[0].Projects[0].ID.String() }
func (test *test) login(email, password string) Response {
resp, body := test.request(
http.MethodPost, "/auth/token",
test.toJSON(map[string]string{
"email": email,
"password": password,
}))
cookie := findCookie(resp, "_tokenKey")
require.NotNil(test.t, cookie)
var tokenInfo struct {
Token string `json:"token"`
}
require.NoError(test.t, json.Unmarshal([]byte(body), &tokenInfo))
require.Equal(test.t, http.StatusOK, resp.StatusCode)
require.Equal(test.t, tokenInfo.Token, cookie.Value)
return resp
}
func (test *test) registerUser(email, password string) registeredUser {
resp, body := test.request(
http.MethodPost, "/auth/register",
test.toJSON(map[string]interface{}{
"secret": "",
"password": password,
"fullName": "Chester Cheeto",
"shortName": "",
"email": email,
"partner": "",
"partnerId": "",
"isProfessional": false,
"position": "",
"companyName": "",
"employeeCount": "",
"haveSalesContact": false,
}))
require.Equal(test.t, http.StatusOK, resp.StatusCode)
time.Sleep(time.Second) // TODO: hack-fix, register activates account asynchronously
return registeredUser{
id: body,
email: email,
password: password,
}
}
func findCookie(response Response, name string) *http.Cookie {
for _, c := range response.Cookies() {
if c.Name == name {
return c
}
}
return nil
}