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:
parent
524e074a8c
commit
2cf4784b20
@ -473,11 +473,13 @@ func (p *Projects) InviteUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
_, err = p.service.InviteNewProjectMember(ctx, id, email)
|
_, err = p.service.InviteNewProjectMember(ctx, id, email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
status := http.StatusInternalServerError
|
||||||
if console.ErrUnauthorized.Has(err) || console.ErrNoMembership.Has(err) {
|
if console.ErrUnauthorized.Has(err) || console.ErrNoMembership.Has(err) {
|
||||||
p.serveJSONError(ctx, w, http.StatusUnauthorized, err)
|
status = http.StatusUnauthorized
|
||||||
return
|
} 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)
|
_, err = p.service.ReinviteProjectMembers(ctx, id, data.Emails)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
status := http.StatusInternalServerError
|
||||||
if console.ErrUnauthorized.Has(err) || console.ErrNoMembership.Has(err) {
|
if console.ErrUnauthorized.Has(err) || console.ErrNoMembership.Has(err) {
|
||||||
p.serveJSONError(ctx, w, http.StatusUnauthorized, err)
|
status = http.StatusUnauthorized
|
||||||
return
|
} else if console.ErrNotPaidTier.Has(err) {
|
||||||
|
status = http.StatusPaymentRequired
|
||||||
}
|
}
|
||||||
p.serveJSONError(ctx, w, http.StatusInternalServerError, err)
|
p.serveJSONError(ctx, w, status, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +94,10 @@ func TestInvitedRouting(t *testing.T) {
|
|||||||
}, 1)
|
}, 1)
|
||||||
require.NoError(t, err)
|
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")
|
project, err := sat.AddProject(ctx, owner.ID, "Test Project")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ const (
|
|||||||
projInviteExistsErrMsg = "An invitation for '%s' already exists"
|
projInviteExistsErrMsg = "An invitation for '%s' already exists"
|
||||||
projInviteDoesntExistErrMsg = "An invitation for '%s' does not exist"
|
projInviteDoesntExistErrMsg = "An invitation for '%s' does not exist"
|
||||||
newInviteLimitErrMsg = "Only one new invitation can be sent at a time"
|
newInviteLimitErrMsg = "Only one new invitation can be sent at a time"
|
||||||
|
paidTierInviteErrMsg = "Only paid tier users can invite project members"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -3774,6 +3775,10 @@ func (s *Service) inviteProjectMembers(ctx context.Context, sender *User, projec
|
|||||||
}
|
}
|
||||||
projectID = isMember.project.ID
|
projectID = isMember.project.ID
|
||||||
|
|
||||||
|
if !sender.PaidTier {
|
||||||
|
return nil, ErrNotPaidTier.New(paidTierInviteErrMsg)
|
||||||
|
}
|
||||||
|
|
||||||
var users []*User
|
var users []*User
|
||||||
var newUserEmails []string
|
var newUserEmails []string
|
||||||
var unverifiedUsers []User
|
var unverifiedUsers []User
|
||||||
|
@ -2166,6 +2166,15 @@ func TestProjectInvitations(t *testing.T) {
|
|||||||
return invite
|
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) {
|
setInviteDate := func(t *testing.T, ctx context.Context, invite *console.ProjectInvitation, createdAt time.Time) {
|
||||||
result, err := sat.DB.Testing().RawDB().ExecContext(ctx,
|
result, err := sat.DB.Testing().RawDB().ExecContext(ctx,
|
||||||
"UPDATE project_invitations SET created_at = $1 WHERE project_id = $2 AND email = $3",
|
"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")
|
project, err := sat.AddProject(ctx, user.ID, "Test Project")
|
||||||
require.NoError(t, err)
|
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.
|
// expect reinvitation to fail due to lack of preexisting invitation record.
|
||||||
invites, err := service.ReinviteProjectMembers(ctx, project.ID, []string{user2.Email})
|
invites, err := service.ReinviteProjectMembers(ctx, project.ID, []string{user2.Email})
|
||||||
require.True(t, console.ErrProjectInviteInvalid.Has(err))
|
require.True(t, console.ErrProjectInviteInvalid.Has(err))
|
||||||
require.Empty(t, invites)
|
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.NoError(t, err)
|
||||||
require.NotNil(t, invite)
|
require.NotNil(t, invite)
|
||||||
|
|
||||||
|
// inviting while being a paid tier user should succeed.
|
||||||
invites, err = service.GetUserProjectInvitations(ctx2)
|
invites, err = service.GetUserProjectInvitations(ctx2)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, invites, 1)
|
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).
|
// prevent unauthorized users from inviting others (user2 is not a member of the project yet).
|
||||||
const testEmail = "other@mail.com"
|
const testEmail = "other@mail.com"
|
||||||
|
ctx2 = upgradeToPaidTier(t, ctx2, user2)
|
||||||
_, err = service.InviteNewProjectMember(ctx2, project.ID, testEmail)
|
_, err = service.InviteNewProjectMember(ctx2, project.ID, testEmail)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.True(t, console.ErrNoMembership.Has(err))
|
require.True(t, console.ErrNoMembership.Has(err))
|
||||||
|
Loading…
Reference in New Issue
Block a user