MM-47228 - restrict guest invitation flow if subscription plan does n… (#21195)
* MM-47228 - restrict guest invitation flow if subscription plan does not support it * fix i18n texts and add unit test * test the scenario where guest invites are blocked by subscription * cover the success scenarios for cloud free trial and paid subscription * fix go vet * use the cloud prefix for the sku * fix unit tests * check the licence value to determine if the guest accounts are enabled * remove unnecessary changes for getting the subscription information * restrict user demotion if guestAccounts is not available in license Co-authored-by: Pablo Velez Vidal <pablo.velez@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
6e9b808efd
Коммит
9a804a96fe
11
api4/team.go
11
api4/team.go
@@ -1462,12 +1462,12 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
graceful := r.URL.Query().Get("graceful") != ""
|
||||
if c.App.Channels().License() == nil {
|
||||
c.Err = model.NewAppError("Api4.InviteGuestsToChannels", "api.team.invate_guests_to_channels.license.error", nil, "", http.StatusNotImplemented)
|
||||
c.Err = model.NewAppError("Api4.InviteGuestsToChannels", "api.team.invite_guests_to_channels.license.error", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
if !*c.App.Config().GuestAccountsSettings.Enable {
|
||||
c.Err = model.NewAppError("Api4.InviteGuestsToChannels", "api.team.invate_guests_to_channels.disabled.error", nil, "", http.StatusNotImplemented)
|
||||
c.Err = model.NewAppError("Api4.InviteGuestsToChannels", "api.team.invite_guests_to_channels.disabled.error", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1485,6 +1485,13 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
guestEnabled := c.App.Channels().License() != nil && *c.App.Channels().License().Features.GuestAccounts
|
||||
|
||||
if !guestEnabled {
|
||||
c.Err = model.NewAppError("Api4.InviteGuestsToChannels", "api.team.invite_guests_to_channels.disabled.error", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
var guestsInvite model.GuestsInvite
|
||||
if err := json.NewDecoder(r.Body).Decode(&guestsInvite); err != nil {
|
||||
c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(err)
|
||||
|
||||
@@ -3361,6 +3361,52 @@ func TestInviteGuestsToTeam(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestInviteGuest(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
guest1 := th.GenerateTestEmail()
|
||||
guest2 := th.GenerateTestEmail()
|
||||
|
||||
emailList := []string{guest1, guest2}
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true })
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableEmailInvitations = true })
|
||||
|
||||
t.Run("Guest Account not available in license returns forbidden", func(t *testing.T) {
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseWithFalseDefaults("guest_accounts"))
|
||||
|
||||
guestsInvite := model.GuestsInvite{
|
||||
Emails: emailList,
|
||||
Channels: []string{th.BasicChannel.Id},
|
||||
Message: "test message",
|
||||
}
|
||||
buf, err := json.Marshal(guestsInvite)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := th.SystemAdminClient.DoAPIPost("/teams/"+th.BasicTeam.Id+"/invite-guests/email", string(buf))
|
||||
|
||||
require.Equal(t, http.StatusForbidden, res.StatusCode)
|
||||
require.True(t, strings.Contains(err.Error(), "Guest accounts are disabled"))
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("Guest Account available in license returns OK", func(t *testing.T) {
|
||||
th.App.Srv().SetLicense(model.NewTestLicense("guest_accounts"))
|
||||
|
||||
guestsInvite := model.GuestsInvite{
|
||||
Emails: emailList,
|
||||
Channels: []string{th.BasicChannel.Id},
|
||||
Message: "test message",
|
||||
}
|
||||
buf, err := json.Marshal(guestsInvite)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := th.SystemAdminClient.DoAPIPost("/teams/"+th.BasicTeam.Id+"/invite-guests/email", string(buf))
|
||||
|
||||
require.Equal(t, http.StatusOK, res.StatusCode)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetTeamInviteInfo(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
@@ -2699,6 +2699,13 @@ func demoteUserToGuest(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
guestEnabled := c.App.Channels().License() != nil && *c.App.Channels().License().Features.GuestAccounts
|
||||
|
||||
if !guestEnabled {
|
||||
c.Err = model.NewAppError("Api4.demoteUserToGuest", "api.team.invite_guests_to_channels.disabled.error", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("demoteUserToGuest", audit.Fail)
|
||||
auditRec.AddEventParameter("user_id", c.Params.UserId)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
|
||||
@@ -5204,6 +5204,26 @@ func TestDemoteUserToGuest(t *testing.T) {
|
||||
th.App.Srv().SetLicense(model.NewTestLicense())
|
||||
|
||||
user := th.BasicUser
|
||||
user2 := th.BasicUser2
|
||||
|
||||
t.Run("Guest Account not available in license returns forbidden", func(t *testing.T) {
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseWithFalseDefaults("guest_accounts"))
|
||||
|
||||
res, err := th.SystemAdminClient.DoAPIPost("/users/"+user2.Id+"/demote", "")
|
||||
|
||||
require.Equal(t, http.StatusForbidden, res.StatusCode)
|
||||
require.True(t, strings.Contains(err.Error(), "Guest accounts are disabled"))
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("Guest Account available in license returns OK", func(t *testing.T) {
|
||||
th.App.Srv().SetLicense(model.NewTestLicense("guest_accounts"))
|
||||
|
||||
res, err := th.SystemAdminClient.DoAPIPost("/users/"+user2.Id+"/demote", "")
|
||||
|
||||
require.Equal(t, http.StatusOK, res.StatusCode)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
|
||||
_, _, err := c.GetUser(user.Id, "")
|
||||
|
||||
16
i18n/en.json
16
i18n/en.json
@@ -2975,22 +2975,22 @@
|
||||
"id": "api.team.invalidate_all_email_invites.app_error",
|
||||
"translation": "Error invalidating email invites."
|
||||
},
|
||||
{
|
||||
"id": "api.team.invate_guests_to_channels.disabled.error",
|
||||
"translation": "Guest accounts are disabled"
|
||||
},
|
||||
{
|
||||
"id": "api.team.invate_guests_to_channels.license.error",
|
||||
"translation": "Your license does not support guest accounts"
|
||||
},
|
||||
{
|
||||
"id": "api.team.invite_guests.channel_in_invalid_team.app_error",
|
||||
"translation": "The channels of the invite must be part of the team of the invite."
|
||||
},
|
||||
{
|
||||
"id": "api.team.invite_guests_to_channels.disabled.error",
|
||||
"translation": "Guest accounts are disabled"
|
||||
},
|
||||
{
|
||||
"id": "api.team.invite_guests_to_channels.invalid_body.app_error",
|
||||
"translation": "Invalid or missing request body."
|
||||
},
|
||||
{
|
||||
"id": "api.team.invite_guests_to_channels.license.error",
|
||||
"translation": "Your license does not support guest accounts"
|
||||
},
|
||||
{
|
||||
"id": "api.team.invite_members.disabled.app_error",
|
||||
"translation": "Email invitations are disabled."
|
||||
|
||||
@@ -326,6 +326,25 @@ func NewTestLicense(features ...string) *License {
|
||||
return ret
|
||||
}
|
||||
|
||||
// NewTestLicense returns a license that expires in the future and set as false the given features.
|
||||
func NewTestLicenseWithFalseDefaults(features ...string) *License {
|
||||
ret := &License{
|
||||
ExpiresAt: GetMillis() + 90*DayInMilliseconds,
|
||||
Customer: &Customer{},
|
||||
Features: &Features{},
|
||||
}
|
||||
ret.Features.SetDefaults()
|
||||
|
||||
featureMap := map[string]bool{}
|
||||
for _, feature := range features {
|
||||
featureMap[feature] = false
|
||||
}
|
||||
featureJson, _ := json.Marshal(featureMap)
|
||||
json.Unmarshal(featureJson, &ret.Features)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func NewTestLicenseSKU(skuShortName string, features ...string) *License {
|
||||
lic := NewTestLicense(features...)
|
||||
lic.SkuShortName = skuShortName
|
||||
|
||||
Ссылка в новой задаче
Block a user