Skip to content

Commit

Permalink
satellite/console: make project invites exclusive to paid tier
Browse files Browse the repository at this point in the history
This change makes the project member invitation feature exclusive to
the paid tier.

Change-Id: I13c967c8381d49b2d131e15799ad48487b0f6c74
  • Loading branch information
jewharton committed Oct 17, 2023
1 parent 524e074 commit 2cf4784
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 7 deletions.
16 changes: 10 additions & 6 deletions satellite/console/consoleweb/consoleapi/projects.go
Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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)
}
}

Expand Down
4 changes: 4 additions & 0 deletions satellite/console/consoleweb/server_test.go
Expand Up @@ -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)

Expand Down
5 changes: 5 additions & 0 deletions satellite/console/service.go
Expand Up @@ -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 (
Expand Down Expand Up @@ -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
Expand Down
20 changes: 19 additions & 1 deletion satellite/console/service_test.go
Expand Up @@ -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",
Expand All @@ -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)
Expand All @@ -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))
Expand Down

0 comments on commit 2cf4784

Please sign in to comment.