satellite/console: make project invites exclusive to paid tier

This change makes the project member invitation feature exclusive to
the paid tier.

Change-Id: I13c967c8381d49b2d131e15799ad48487b0f6c74
This commit is contained in:
Jeremy Wharton 2023-10-16 23:43:39 -05:00
parent 524e074a8c
commit 2cf4784b20
4 changed files with 38 additions and 7 deletions

View File

@ -473,11 +473,13 @@ func (p *Projects) InviteUser(w http.ResponseWriter, r *http.Request) {
_, err = p.service.InviteNewProjectMember(ctx, id, email)
if err != nil {
status := http.StatusInternalServerError
if console.ErrUnauthorized.Has(err) || console.ErrNoMembership.Has(err) {
p.serveJSONError(ctx, w, http.StatusUnauthorized, err)
return
status = http.StatusUnauthorized
} else if console.ErrNotPaidTier.Has(err) {
status = http.StatusPaymentRequired
}
p.serveJSONError(ctx, w, http.StatusInternalServerError, err)
p.serveJSONError(ctx, w, status, err)
}
}
@ -513,11 +515,13 @@ func (p *Projects) ReinviteUsers(w http.ResponseWriter, r *http.Request) {
_, err = p.service.ReinviteProjectMembers(ctx, id, data.Emails)
if err != nil {
status := http.StatusInternalServerError
if console.ErrUnauthorized.Has(err) || console.ErrNoMembership.Has(err) {
p.serveJSONError(ctx, w, http.StatusUnauthorized, err)
return
status = http.StatusUnauthorized
} else if console.ErrNotPaidTier.Has(err) {
status = http.StatusPaymentRequired
}
p.serveJSONError(ctx, w, http.StatusInternalServerError, err)
p.serveJSONError(ctx, w, status, err)
}
}

View File

@ -94,6 +94,10 @@ func TestInvitedRouting(t *testing.T) {
}, 1)
require.NoError(t, err)
paid := true
err = sat.DB.Console().Users().Update(ctx, owner.ID, console.UpdateUserRequest{PaidTier: &paid})
require.NoError(t, err)
project, err := sat.AddProject(ctx, owner.ID, "Test Project")
require.NoError(t, err)

View File

@ -81,6 +81,7 @@ const (
projInviteExistsErrMsg = "An invitation for '%s' already exists"
projInviteDoesntExistErrMsg = "An invitation for '%s' does not exist"
newInviteLimitErrMsg = "Only one new invitation can be sent at a time"
paidTierInviteErrMsg = "Only paid tier users can invite project members"
)
var (
@ -3774,6 +3775,10 @@ func (s *Service) inviteProjectMembers(ctx context.Context, sender *User, projec
}
projectID = isMember.project.ID
if !sender.PaidTier {
return nil, ErrNotPaidTier.New(paidTierInviteErrMsg)
}
var users []*User
var newUserEmails []string
var unverifiedUsers []User

View File

@ -2166,6 +2166,15 @@ func TestProjectInvitations(t *testing.T) {
return invite
}
upgradeToPaidTier := func(t *testing.T, ctx context.Context, user *console.User) context.Context {
paid := true
err := sat.DB.Console().Users().Update(ctx, user.ID, console.UpdateUserRequest{PaidTier: &paid})
require.NoError(t, err)
ctx, err = sat.UserContext(ctx, user.ID)
require.NoError(t, err)
return ctx
}
setInviteDate := func(t *testing.T, ctx context.Context, invite *console.ProjectInvitation, createdAt time.Time) {
result, err := sat.DB.Testing().RawDB().ExecContext(ctx,
"UPDATE project_invitations SET created_at = $1 WHERE project_id = $2 AND email = $3",
@ -2189,15 +2198,23 @@ func TestProjectInvitations(t *testing.T) {
project, err := sat.AddProject(ctx, user.ID, "Test Project")
require.NoError(t, err)
// inviting without being a paid tier user should fail.
invite, err := service.InviteNewProjectMember(ctx, project.ID, user2.Email)
require.True(t, console.ErrNotPaidTier.Has(err))
require.Nil(t, invite)
ctx = upgradeToPaidTier(t, ctx, user)
// expect reinvitation to fail due to lack of preexisting invitation record.
invites, err := service.ReinviteProjectMembers(ctx, project.ID, []string{user2.Email})
require.True(t, console.ErrProjectInviteInvalid.Has(err))
require.Empty(t, invites)
invite, err := service.InviteNewProjectMember(ctx, project.ID, user2.Email)
invite, err = service.InviteNewProjectMember(ctx, project.ID, user2.Email)
require.NoError(t, err)
require.NotNil(t, invite)
// inviting while being a paid tier user should succeed.
invites, err = service.GetUserProjectInvitations(ctx2)
require.NoError(t, err)
require.Len(t, invites, 1)
@ -2208,6 +2225,7 @@ func TestProjectInvitations(t *testing.T) {
// prevent unauthorized users from inviting others (user2 is not a member of the project yet).
const testEmail = "other@mail.com"
ctx2 = upgradeToPaidTier(t, ctx2, user2)
_, err = service.InviteNewProjectMember(ctx2, project.ID, testEmail)
require.Error(t, err)
require.True(t, console.ErrNoMembership.Has(err))