satellite/admin: extend user update query

Extended user update query so prod owner can change user's paid tier status, bandwidth, storage and segment limits.

Change-Id: I82768afd1e50f653a50f7020310ce1e91578d746
This commit is contained in:
Vitalii 2022-04-19 16:07:44 +03:00 committed by Vitalii Shpital
parent abc9e2493f
commit 318f4dc688
3 changed files with 75 additions and 11 deletions

View File

@ -330,7 +330,19 @@ Blank fields will not be updated.`,
['full name', new InputText('text', false)],
['short name', new InputText('text', false)],
['partner ID', new InputText('text', false)],
['password hash', new InputText('text', false)]
['password hash', new InputText('text', false)],
['project limit (max number)', new InputText('number', false)],
['project storage limit (in bytes)', new InputText('number', false)],
['project bandwidth limit (in bytes)', new InputText('number', false)],
['project segment limit (max number)', new InputText('number', false)],
[
'paid tier',
new Select(false, false, [
{ text: '', value: '' },
{ text: 'true', value: 'true' },
{ text: 'false', value: 'false' }
])
]
],
func: async (
currentEmail: string,
@ -338,14 +350,24 @@ Blank fields will not be updated.`,
fullName?: string,
shortName?: string,
partnerID?: string,
passwordHash?: string
passwordHash?: string,
projectLimit?: number,
projectStorageLimit?: number,
projectBandwidthLimit?: number,
projectSegmentLimit?: number,
paidTierStr?: boolean
): Promise<null> => {
return this.fetch('PUT', `users/${currentEmail}`, null, {
email,
fullName,
shortName,
partnerID,
passwordHash
passwordHash,
projectLimit,
projectStorageLimit,
projectBandwidthLimit,
projectSegmentLimit,
paidTierStr
}) as Promise<null>;
}
}

View File

@ -10,6 +10,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"strconv"
"github.com/gorilla/mux"
"golang.org/x/crypto/bcrypt"
@ -225,7 +226,12 @@ func (server *Server) updateUser(w http.ResponseWriter, r *http.Request) {
return
}
var input console.User
type UserWithPaidTier struct {
console.User
PaidTierStr string `json:"paidTierStr"`
}
var input UserWithPaidTier
err = json.Unmarshal(body, &input)
if err != nil {
@ -252,6 +258,25 @@ func (server *Server) updateUser(w http.ResponseWriter, r *http.Request) {
if input.ProjectLimit > 0 {
user.ProjectLimit = input.ProjectLimit
}
if input.ProjectStorageLimit > 0 {
user.ProjectStorageLimit = input.ProjectStorageLimit
}
if input.ProjectBandwidthLimit > 0 {
user.ProjectBandwidthLimit = input.ProjectBandwidthLimit
}
if input.ProjectSegmentLimit > 0 {
user.ProjectSegmentLimit = input.ProjectSegmentLimit
}
if input.PaidTierStr != "" {
status, err := strconv.ParseBool(input.PaidTierStr)
if err != nil {
sendJSONError(w, "failed to parse paid tier status",
err.Error(), http.StatusBadRequest)
return
}
user.PaidTier = status
}
err = server.db.Console().Users().Update(ctx, user)
if err != nil {

View File

@ -157,7 +157,7 @@ func TestUserUpdate(t *testing.T) {
require.NoError(t, err)
t.Run("OK", func(t *testing.T) {
// Updat user data.
// Update user data.
link := fmt.Sprintf("http://"+address.String()+"/api/users/%s", user.Email)
body := `{"email":"alice+2@mail.test", "shortName":"Newbie"}`
responseBody := assertReq(ctx, t, link, http.MethodPut, body, http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
@ -173,19 +173,36 @@ func TestUserUpdate(t *testing.T) {
require.Equal(t, user.Status, updatedUser.Status)
require.Equal(t, user.ProjectLimit, updatedUser.ProjectLimit)
// Update rate limit.
// Update project limit.
link = "http://" + address.String() + "/api/users/alice+2@mail.test"
newLimit := 50
body = fmt.Sprintf(`{"projectLimit":%d}`, newLimit)
responseBody = assertReq(ctx, t, link, http.MethodPut, body, http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
require.Len(t, responseBody, 0)
updatedUserRate, err := planet.Satellites[0].DB.Console().Users().Get(ctx, user.ID)
updatedUserProjectLimit, err := planet.Satellites[0].DB.Console().Users().Get(ctx, user.ID)
require.NoError(t, err)
require.Equal(t, updatedUser.Email, updatedUserRate.Email)
require.Equal(t, updatedUser.ID, updatedUserRate.ID)
require.Equal(t, updatedUser.Status, updatedUserRate.Status)
require.Equal(t, newLimit, updatedUserRate.ProjectLimit)
require.Equal(t, updatedUser.Email, updatedUserProjectLimit.Email)
require.Equal(t, updatedUser.ID, updatedUserProjectLimit.ID)
require.Equal(t, updatedUser.Status, updatedUserProjectLimit.Status)
require.Equal(t, newLimit, updatedUserProjectLimit.ProjectLimit)
// Update paid tier status and usage.
link = "http://" + address.String() + "/api/users/alice+2@mail.test"
newUsageLimit := int64(1000)
body1 := fmt.Sprintf(`{"projectStorageLimit":%d, "projectBandwidthLimit":%d, "projectSegmentLimit":%d, "paidTierStr":"true"}`, newUsageLimit, newUsageLimit, newUsageLimit)
responseBody = assertReq(ctx, t, link, http.MethodPut, body1, http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
require.Len(t, responseBody, 0)
updatedUserStatusAndUsageLimits, err := planet.Satellites[0].DB.Console().Users().Get(ctx, user.ID)
require.NoError(t, err)
require.Equal(t, updatedUser.Email, updatedUserStatusAndUsageLimits.Email)
require.Equal(t, updatedUser.ID, updatedUserStatusAndUsageLimits.ID)
require.Equal(t, updatedUser.Status, updatedUserStatusAndUsageLimits.Status)
require.True(t, updatedUserStatusAndUsageLimits.PaidTier)
require.Equal(t, newUsageLimit, updatedUserStatusAndUsageLimits.ProjectStorageLimit)
require.Equal(t, newUsageLimit, updatedUserStatusAndUsageLimits.ProjectBandwidthLimit)
require.Equal(t, newUsageLimit, updatedUserStatusAndUsageLimits.ProjectSegmentLimit)
})
t.Run("Not found", func(t *testing.T) {