[MM-42713] - Remove cloud user limit restrictions (#19835)

* [MM-42713] - Remove cloud user limit restrictions

* remove unused code

* fix translations

* feedback impl-1

* enterprise code clean up

* feedback impl-2

* fix mocks

* fix translations

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Allan Guwatudde
2022-03-31 18:24:38 +03:00
коммит произвёл GitHub
родитель 67d57fc400
Коммит fa56ee9d9a
29 изменённых файлов: 0 добавлений и 1866 удалений

Просмотреть файл

@@ -269,9 +269,6 @@ type AppIface interface {
SearchAllChannels(term string, opts model.ChannelSearchOpts) (model.ChannelListWithTeamData, int64, *model.AppError)
// SearchAllTeams returns a team list and the total count of the results
SearchAllTeams(searchOpts *model.TeamSearch) ([]*model.Team, int64, *model.AppError)
// SendAdminUpgradeRequestEmail takes the username of user trying to alert admins and then applies rate limit of n (number of admins) emails per user per day
// before sending the emails.
SendAdminUpgradeRequestEmail(username string, subscription *model.Subscription, action string) *model.AppError
// SendNoCardPaymentFailedEmail
SendNoCardPaymentFailedEmail() *model.AppError
// SessionHasPermissionToManageBot returns nil if the session has access to manage the given bot.
@@ -411,9 +408,7 @@ type AppIface interface {
CancelJob(jobId string) *model.AppError
ChannelMembersToRemove(teamID *string) ([]*model.ChannelMember, *model.AppError)
Channels() *Channels
CheckAndSendUserLimitWarningEmails(c *request.Context) *model.AppError
CheckCanInviteToSharedChannel(channelId string) error
CheckCloudAccountAtLimit() (bool, *model.AppError)
CheckForClientSideCert(r *http.Request) (string, string, string)
CheckIntegrity() <-chan model.IntegrityCheckResult
CheckMandatoryS3Fields(settings *model.FileSettings) *model.AppError
@@ -598,7 +593,6 @@ type AppIface interface {
GetEmojiByName(emojiName string) (*model.Emoji, *model.AppError)
GetEmojiImage(emojiId string) ([]byte, string, *model.AppError)
GetEmojiList(page, perPage int, sort string) ([]*model.Emoji, *model.AppError)
GetErrorListForEmailsOverLimit(emailList []string, cloudUserLimit int64) ([]string, []*model.EmailInviteWithError, *model.AppError)
GetFile(fileID string) ([]byte, *model.AppError)
GetFileInfo(fileID string) (*model.FileInfo, *model.AppError)
GetFileInfos(page, perPage int, opt *model.GetFileInfosOptions) ([]*model.FileInfo, *model.AppError)
@@ -733,7 +727,6 @@ type AppIface interface {
GetStatus(userID string) (*model.Status, *model.AppError)
GetStatusFromCache(userID string) *model.Status
GetStatusesByIds(userIDs []string) (map[string]interface{}, *model.AppError)
GetSubscriptionStats() (*model.SubscriptionStats, *model.AppError)
GetSystemBot() (*model.Bot, *model.AppError)
GetTeam(teamID string) (*model.Team, *model.AppError)
GetTeamByInviteId(inviteId string) (*model.Team, *model.AppError)

Просмотреть файл

@@ -4,11 +4,8 @@
package app
import (
"fmt"
"net/http"
"time"
"github.com/mattermost/mattermost-server/v6/app/request"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
)
@@ -23,175 +20,6 @@ func (a *App) getSysAdminsEmailRecipients() ([]*model.User, *model.AppError) {
return a.GetUsers(userOptions)
}
// SendAdminUpgradeRequestEmail takes the username of user trying to alert admins and then applies rate limit of n (number of admins) emails per user per day
// before sending the emails.
func (a *App) SendAdminUpgradeRequestEmail(username string, subscription *model.Subscription, action string) *model.AppError {
if a.Srv().License() == nil || (a.Srv().License() != nil && !*a.Srv().License().Features.Cloud) {
return nil
}
if subscription != nil && subscription.IsPaidTier == "true" {
return nil
}
year, month, day := time.Now().Date()
key := fmt.Sprintf("%s-%d-%s-%d", action, day, month, year)
if a.Srv().EmailService.GetPerDayEmailRateLimiter() == nil {
return model.NewAppError("app.SendAdminUpgradeRequestEmail", "app.email.no_rate_limiter.app_error", nil, fmt.Sprintf("for key=%s", key), http.StatusInternalServerError)
}
// rate limit based on combination of date and action as key
rateLimited, result, err := a.Srv().EmailService.GetPerDayEmailRateLimiter().RateLimit(key, 1)
if err != nil {
return model.NewAppError("app.SendAdminUpgradeRequestEmail", "app.email.setup_rate_limiter.app_error", nil, fmt.Sprintf("for key=%s, error=%v", key, err), http.StatusInternalServerError)
}
if rateLimited {
return model.NewAppError("app.SendAdminUpgradeRequestEmail",
"app.email.rate_limit_exceeded.app_error", map[string]interface{}{"RetryAfter": result.RetryAfter.String(), "ResetAfter": result.ResetAfter.String()},
fmt.Sprintf("key=%s, retry_after_secs=%f, reset_after_secs=%f",
key, result.RetryAfter.Seconds(), result.ResetAfter.Seconds()),
http.StatusRequestEntityTooLarge)
}
sysAdmins, e := a.getSysAdminsEmailRecipients()
if e != nil {
return e
}
// we want to at least have one email sent out to an admin
countNotOks := 0
for admin := range sysAdmins {
ok, err := a.Srv().EmailService.SendUpgradeEmail(username, sysAdmins[admin].Email, sysAdmins[admin].Locale, *a.Config().ServiceSettings.SiteURL, action)
if !ok || err != nil {
a.Log().Error("Error sending upgrade request email", mlog.Err(err))
countNotOks++
}
}
// if not even one admin got an email, we consider that this operation errored
if countNotOks == len(sysAdmins) {
return model.NewAppError("app.SendAdminUpgradeRequestEmail", "app.user.send_emails.app_error", nil, "", http.StatusInternalServerError)
}
return nil
}
func (a *App) GetSubscriptionStats() (*model.SubscriptionStats, *model.AppError) {
if a.Srv().License() == nil || !*a.Srv().License().Features.Cloud {
return nil, model.NewAppError("app.GetSubscriptionStats", "api.cloud.license_error", nil, "", http.StatusInternalServerError)
}
subscription, appErr := a.Cloud().GetSubscription("")
if appErr != nil {
return nil, model.NewAppError("app.GetSubscriptionStats", "api.cloud.request_error", nil, appErr.Error(), http.StatusInternalServerError)
}
count, err := a.Srv().Store.User().Count(model.UserCountOptions{})
if err != nil {
return nil, model.NewAppError("app.GetSubscriptionStats", "app.user.get_total_users_count.app_error", nil, err.Error(), http.StatusInternalServerError)
}
cloudUserLimit := *a.Config().ExperimentalSettings.CloudUserLimit
s := cloudUserLimit - count
return &model.SubscriptionStats{
RemainingSeats: int(s),
IsPaidTier: subscription.IsPaidTier,
}, nil
}
func (a *App) CheckCloudAccountAtLimit() (bool, *model.AppError) {
if a.Srv().License() == nil || (a.Srv().License() != nil && !*a.Srv().License().Features.Cloud) {
// Not cloud instance, so no at limit checks
return false, nil
}
stats, err := a.GetSubscriptionStats()
if err != nil {
return false, err
}
if stats.IsPaidTier == "true" {
return false, nil
}
if stats.RemainingSeats < 1 {
return true, nil
}
return false, nil
}
func (a *App) CheckAndSendUserLimitWarningEmails(c *request.Context) *model.AppError {
if a.Srv().License() == nil || (a.Srv().License() != nil && !*a.Srv().License().Features.Cloud) {
// Not cloud instance, do nothing
return nil
}
subscription, err := a.Cloud().GetSubscription(c.Session().UserId)
if err != nil {
return model.NewAppError(
"app.CheckAndSendUserLimitWarningEmails",
"api.cloud.get_subscription.error",
nil,
err.Error(),
http.StatusInternalServerError)
}
if subscription != nil && subscription.IsPaidTier == "true" {
// Paid subscription, do nothing
return nil
}
cloudUserLimit := *a.Config().ExperimentalSettings.CloudUserLimit
systemUserCount, _ := a.Srv().Store.User().Count(model.UserCountOptions{})
remainingUsers := cloudUserLimit - systemUserCount
if remainingUsers > 0 {
return nil
}
sysAdmins, appErr := a.getSysAdminsEmailRecipients()
if appErr != nil {
return model.NewAppError(
"app.CheckAndSendUserLimitWarningEmails",
"api.cloud.get_admins_emails.error",
nil,
appErr.Error(),
http.StatusInternalServerError)
}
// -1 means they are 1 user over the limit - we only want to send the email for the 11th user
if remainingUsers == -1 {
// Over limit by 1 user
for admin := range sysAdmins {
_, appErr := a.Srv().EmailService.SendOverUserLimitWarningEmail(sysAdmins[admin].Email, sysAdmins[admin].Locale, *a.Config().ServiceSettings.SiteURL)
if appErr != nil {
a.Log().Error(
"Error sending user limit warning email to admin",
mlog.String("username", sysAdmins[admin].Username),
mlog.Err(err),
)
}
}
} else if remainingUsers == 0 {
// At limit
for admin := range sysAdmins {
_, err := a.Srv().EmailService.SendAtUserLimitWarningEmail(sysAdmins[admin].Email, sysAdmins[admin].Locale, *a.Config().ServiceSettings.SiteURL)
if err != nil {
a.Log().Error(
"Error sending user limit warning email to admin",
mlog.String("username", sysAdmins[admin].Username),
mlog.Err(err),
)
}
}
}
return nil
}
func (a *App) SendPaymentFailedEmail(failedPayment *model.FailedPayment) *model.AppError {
sysAdmins, err := a.getSysAdminsEmailRecipients()
if err != nil {

Просмотреть файл

@@ -741,33 +741,6 @@ func (es *Service) CreateVerifyEmailToken(userID string, newEmail string) (*mode
return token, nil
}
func (es *Service) SendAtUserLimitWarningEmail(email string, locale string, siteURL string) (bool, error) {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.at_limit_subject")
data := es.NewEmailTemplateData(locale)
data.Props["SiteURL"] = siteURL
data.Props["Title"] = T("api.templates.at_limit_title")
data.Props["Info1"] = T("api.templates.at_limit_info1")
data.Props["Info2"] = T("api.templates.at_limit_info2")
data.Props["Button"] = T("api.templates.upgrade_mattermost_cloud")
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
data.Props["Footer"] = T("api.templates.copyright")
body, err := es.templatesContainer.RenderToString("reached_user_limit_body", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendLicenseInactivityEmail(email, name, locale, siteURL string) error {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.server_inactivity_subject")
@@ -829,229 +802,6 @@ func (es *Service) SendLicenseUpForRenewalEmail(email, name, locale, siteURL, re
return nil
}
// SendUpgradeEmail formats an email template and sends an email to an admin specified in the email arg
func (es *Service) SendUpgradeEmail(user, email, locale, siteURL, action string) (bool, error) {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.upgrade_request_subject")
data := es.NewEmailTemplateData(locale)
data.Props["Info5"] = T("api.templates.at_limit_info5")
data.Props["BillingPath"] = "admin_console/billing/subscription"
data.Props["SiteURL"] = siteURL
data.Props["Button"] = T("api.templates.upgrade_mattermost_cloud")
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
data.Props["Footer"] = T("api.templates.copyright")
if action == model.InviteLimitation {
data.Props["Title"] = T("api.templates.upgrade_request_title", map[string]interface{}{"UserName": user})
data.Props["Info4"] = T("api.templates.upgrade_request_info4")
} else {
data.Props["Title"] = T("api.templates.upgrade_request_title2")
data.Props["Info4"] = T("api.templates.upgrade_request_info4_2")
}
body, err := es.templatesContainer.RenderToString("cloud_upgrade_request_email", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendOverUserLimitWarningEmail(email string, locale string, siteURL string) (bool, error) {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.over_limit_subject")
data := es.NewEmailTemplateData(locale)
data.Props["SiteURL"] = siteURL
data.Props["Title"] = T("api.templates.over_limit_title")
data.Props["Info1"] = T("api.templates.over_limit_info1")
data.Props["Info2"] = T("api.templates.over_limit_info2")
data.Props["Button"] = T("api.templates.upgrade_mattermost_cloud")
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
data.Props["Footer"] = T("api.templates.copyright")
body, err := es.templatesContainer.RenderToString("reached_user_limit_body", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendOverUserLimitThirtyDayWarningEmail(email string, locale string, siteURL string) (bool, error) {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.over_limit_30_days_subject")
data := es.NewEmailTemplateData(locale)
data.Props["SiteURL"] = siteURL
data.Props["Title"] = T("api.templates.over_limit_30_days_title")
data.Props["Info1"] = T("api.templates.over_limit_30_days_info1")
data.Props["Info2"] = T("api.templates.over_limit_30_days_info2")
data.Props["Info2Item1"] = T("api.templates.over_limit_30_days_info2_item1")
data.Props["Info2Item2"] = T("api.templates.over_limit_30_days_info2_item2")
data.Props["Info2Item3"] = T("api.templates.over_limit_30_days_info2_item3")
data.Props["Button"] = T("api.templates.over_limit_fix_now")
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
data.Props["Footer"] = T("api.templates.copyright")
body, err := es.templatesContainer.RenderToString("over_user_limit_30_days_body", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendOverUserLimitNinetyDayWarningEmail(email string, locale string, siteURL string, overLimitDate string) (bool, error) {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.over_limit_90_days_subject")
data := es.NewEmailTemplateData(locale)
data.Props["SiteURL"] = siteURL
data.Props["Title"] = T("api.templates.over_limit_90_days_title")
data.Props["Info1"] = T("api.templates.over_limit_90_days_info1", map[string]interface{}{"OverLimitDate": overLimitDate})
data.Props["Info2"] = T("api.templates.over_limit_90_days_info2")
data.Props["Info3"] = T("api.templates.over_limit_90_days_info3")
data.Props["Info4"] = T("api.templates.over_limit_90_days_info4")
data.Props["Button"] = T("api.templates.over_limit_fix_now")
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
data.Props["Footer"] = T("api.templates.copyright")
body, err := es.templatesContainer.RenderToString("over_user_limit_90_days_body", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendOverUserLimitWorkspaceSuspendedWarningEmail(email string, locale string, siteURL string) (bool, error) {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.over_limit_suspended_subject")
data := es.NewEmailTemplateData(locale)
data.Props["SiteURL"] = siteURL
data.Props["Title"] = T("api.templates.over_limit_suspended_title")
data.Props["Info1"] = T("api.templates.over_limit_suspended_info1")
data.Props["Info2"] = T("api.templates.over_limit_suspended_info2")
data.Props["Button"] = T("api.templates.over_limit_suspended_contact_support")
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
data.Props["Footer"] = T("api.templates.copyright")
body, err := es.templatesContainer.RenderToString("over_user_limit_workspace_suspended_body", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendOverUserFourteenDayWarningEmail(email string, locale string, siteURL string, overLimitDate string) (bool, error) {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.over_limit_14_days_subject")
data := es.NewEmailTemplateData(locale)
data.Props["SiteURL"] = siteURL
data.Props["Title"] = T("api.templates.over_limit_14_days_title")
data.Props["Info1"] = T("api.templates.over_limit_14_days_info1", map[string]interface{}{"OverLimitDate": overLimitDate})
data.Props["Button"] = T("api.templates.over_limit_fix_now")
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
data.Props["Footer"] = T("api.templates.copyright")
body, err := es.templatesContainer.RenderToString("over_user_limit_7_days_body", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendOverUserSevenDayWarningEmail(email string, locale string, siteURL string) (bool, error) {
T := i18n.GetUserTranslations(locale)
subject := T("api.templates.over_limit_7_days_subject")
data := es.NewEmailTemplateData(locale)
data.Props["SiteURL"] = siteURL
data.Props["Title"] = T("api.templates.over_limit_7_days_title")
data.Props["Info1"] = T("api.templates.over_limit_7_days_info1")
data.Props["Button"] = T("api.templates.over_limit_fix_now")
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
data.Props["Footer"] = T("api.templates.copyright")
body, err := es.templatesContainer.RenderToString("over_user_limit_7_days_body", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendSuspensionEmailToSupport(email string, installationID string, customerID string, subscriptionID string, siteURL string, userCount int64) (bool, error) {
// Localization not needed
subject := fmt.Sprintf("Cloud Installation %s Scheduled Suspension", installationID)
data := es.NewEmailTemplateData("en")
data.Props["CustomerID"] = customerID
data.Props["SiteURL"] = siteURL
data.Props["SubscriptionID"] = subscriptionID
data.Props["InstallationID"] = installationID
data.Props["SuspensionDate"] = time.Now().AddDate(0, 0, 61).Format("2006-01-02")
data.Props["UserCount"] = userCount
body, err := es.templatesContainer.RenderToString("over_user_limit_support_body", data)
if err != nil {
return false, err
}
if err := es.sendMail(email, subject, body); err != nil {
return false, err
}
return true, nil
}
func (es *Service) SendPaymentFailedEmail(email string, locale string, failedPayment *model.FailedPayment, siteURL string) (bool, error) {
T := i18n.GetUserTranslations(locale)

Просмотреть файл

@@ -111,27 +111,6 @@ func (_m *ServiceInterface) NewEmailTemplateData(locale string) templates.Data {
return r0
}
// SendAtUserLimitWarningEmail provides a mock function with given fields: _a0, locale, siteURL
func (_m *ServiceInterface) SendAtUserLimitWarningEmail(_a0 string, locale string, siteURL string) (bool, error) {
ret := _m.Called(_a0, locale, siteURL)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string) bool); ok {
r0 = rf(_a0, locale, siteURL)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(_a0, locale, siteURL)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendChangeUsernameEmail provides a mock function with given fields: newUsername, _a1, locale, siteURL
func (_m *ServiceInterface) SendChangeUsernameEmail(newUsername string, _a1 string, locale string, siteURL string) error {
ret := _m.Called(newUsername, _a1, locale, siteURL)
@@ -342,132 +321,6 @@ func (_m *ServiceInterface) SendNotificationMail(to string, subject string, html
return r0
}
// SendOverUserFourteenDayWarningEmail provides a mock function with given fields: _a0, locale, siteURL, overLimitDate
func (_m *ServiceInterface) SendOverUserFourteenDayWarningEmail(_a0 string, locale string, siteURL string, overLimitDate string) (bool, error) {
ret := _m.Called(_a0, locale, siteURL, overLimitDate)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string, string) bool); ok {
r0 = rf(_a0, locale, siteURL, overLimitDate)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string, string) error); ok {
r1 = rf(_a0, locale, siteURL, overLimitDate)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendOverUserLimitNinetyDayWarningEmail provides a mock function with given fields: _a0, locale, siteURL, overLimitDate
func (_m *ServiceInterface) SendOverUserLimitNinetyDayWarningEmail(_a0 string, locale string, siteURL string, overLimitDate string) (bool, error) {
ret := _m.Called(_a0, locale, siteURL, overLimitDate)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string, string) bool); ok {
r0 = rf(_a0, locale, siteURL, overLimitDate)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string, string) error); ok {
r1 = rf(_a0, locale, siteURL, overLimitDate)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendOverUserLimitThirtyDayWarningEmail provides a mock function with given fields: _a0, locale, siteURL
func (_m *ServiceInterface) SendOverUserLimitThirtyDayWarningEmail(_a0 string, locale string, siteURL string) (bool, error) {
ret := _m.Called(_a0, locale, siteURL)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string) bool); ok {
r0 = rf(_a0, locale, siteURL)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(_a0, locale, siteURL)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendOverUserLimitWarningEmail provides a mock function with given fields: _a0, locale, siteURL
func (_m *ServiceInterface) SendOverUserLimitWarningEmail(_a0 string, locale string, siteURL string) (bool, error) {
ret := _m.Called(_a0, locale, siteURL)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string) bool); ok {
r0 = rf(_a0, locale, siteURL)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(_a0, locale, siteURL)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendOverUserLimitWorkspaceSuspendedWarningEmail provides a mock function with given fields: _a0, locale, siteURL
func (_m *ServiceInterface) SendOverUserLimitWorkspaceSuspendedWarningEmail(_a0 string, locale string, siteURL string) (bool, error) {
ret := _m.Called(_a0, locale, siteURL)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string) bool); ok {
r0 = rf(_a0, locale, siteURL)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(_a0, locale, siteURL)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendOverUserSevenDayWarningEmail provides a mock function with given fields: _a0, locale, siteURL
func (_m *ServiceInterface) SendOverUserSevenDayWarningEmail(_a0 string, locale string, siteURL string) (bool, error) {
ret := _m.Called(_a0, locale, siteURL)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string) bool); ok {
r0 = rf(_a0, locale, siteURL)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(_a0, locale, siteURL)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendPasswordChangeEmail provides a mock function with given fields: _a0, method, locale, siteURL
func (_m *ServiceInterface) SendPasswordChangeEmail(_a0 string, method string, locale string, siteURL string) error {
ret := _m.Called(_a0, method, locale, siteURL)
@@ -552,48 +405,6 @@ func (_m *ServiceInterface) SendSignInChangeEmail(_a0 string, method string, loc
return r0
}
// SendSuspensionEmailToSupport provides a mock function with given fields: _a0, installationID, customerID, subscriptionID, siteURL, userCount
func (_m *ServiceInterface) SendSuspensionEmailToSupport(_a0 string, installationID string, customerID string, subscriptionID string, siteURL string, userCount int64) (bool, error) {
ret := _m.Called(_a0, installationID, customerID, subscriptionID, siteURL, userCount)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string, string, string, int64) bool); ok {
r0 = rf(_a0, installationID, customerID, subscriptionID, siteURL, userCount)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string, string, string, int64) error); ok {
r1 = rf(_a0, installationID, customerID, subscriptionID, siteURL, userCount)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendUpgradeEmail provides a mock function with given fields: user, _a1, locale, siteURL, action
func (_m *ServiceInterface) SendUpgradeEmail(user string, _a1 string, locale string, siteURL string, action string) (bool, error) {
ret := _m.Called(user, _a1, locale, siteURL, action)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, string, string, string) bool); ok {
r0 = rf(user, _a1, locale, siteURL, action)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, string, string, string) error); ok {
r1 = rf(user, _a1, locale, siteURL, action)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SendUserAccessTokenAddedEmail provides a mock function with given fields: _a0, locale, siteURL
func (_m *ServiceInterface) SendUserAccessTokenAddedEmail(_a0 string, locale string, siteURL string) error {
ret := _m.Called(_a0, locale, siteURL)

Просмотреть файл

@@ -141,16 +141,7 @@ type ServiceInterface interface {
SendDeactivateAccountEmail(email string, locale, siteURL string) error
SendNotificationMail(to, subject, htmlBody string) error
SendMailWithEmbeddedFiles(to, subject, htmlBody string, embeddedFiles map[string]io.Reader) error
SendAtUserLimitWarningEmail(email string, locale string, siteURL string) (bool, error)
SendLicenseUpForRenewalEmail(email, name, locale, siteURL, renewalLink string, daysToExpiration int) error
SendUpgradeEmail(user, email, locale, siteURL, action string) (bool, error)
SendOverUserLimitWarningEmail(email string, locale string, siteURL string) (bool, error)
SendOverUserLimitThirtyDayWarningEmail(email string, locale string, siteURL string) (bool, error)
SendOverUserLimitNinetyDayWarningEmail(email string, locale string, siteURL string, overLimitDate string) (bool, error)
SendOverUserLimitWorkspaceSuspendedWarningEmail(email string, locale string, siteURL string) (bool, error)
SendOverUserFourteenDayWarningEmail(email string, locale string, siteURL string, overLimitDate string) (bool, error)
SendOverUserSevenDayWarningEmail(email string, locale string, siteURL string) (bool, error)
SendSuspensionEmailToSupport(email string, installationID string, customerID string, subscriptionID string, siteURL string, userCount int64) (bool, error)
SendPaymentFailedEmail(email string, locale string, failedPayment *model.FailedPayment, siteURL string) (bool, error)
SendNoCardPaymentFailedEmail(email string, locale string, siteURL string) error
SendRemoveExpiredLicenseEmail(renewalLink, email string, locale, siteURL string) error

Просмотреть файл

@@ -39,75 +39,3 @@ func TestSendInviteEmailRateLimits(t *testing.T) {
assert.Equal(t, "app.email.rate_limit_exceeded.app_error", err.Id)
assert.Equal(t, http.StatusRequestEntityTooLarge, err.StatusCode)
}
func TestSendAdminUpgradeRequestEmail(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
mockSubscription := &model.Subscription{
ID: "MySubscriptionID",
CustomerID: "MyCustomer",
ProductID: "SomeProductId",
AddOns: []string{},
StartAt: 1000000000,
EndAt: 2000000000,
CreateAt: 1000000000,
Seats: 100,
DNS: "some.dns.server",
IsPaidTier: "false",
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ExperimentalSettings.CloudUserLimit = 10
})
err := th.App.SendAdminUpgradeRequestEmail(th.BasicUser.Username, mockSubscription, model.InviteLimitation)
require.Nil(t, err)
// other attempts by the same user or other users to send emails are blocked by rate limiter
err = th.App.SendAdminUpgradeRequestEmail(th.BasicUser.Username, mockSubscription, model.InviteLimitation)
require.NotNil(t, err)
assert.Equal(t, err.Id, "app.email.rate_limit_exceeded.app_error")
err = th.App.SendAdminUpgradeRequestEmail(th.BasicUser2.Username, mockSubscription, model.InviteLimitation)
require.NotNil(t, err)
assert.Equal(t, err.Id, "app.email.rate_limit_exceeded.app_error")
}
func TestSendAdminUpgradeRequestEmailOnJoin(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
mockSubscription := &model.Subscription{
ID: "MySubscriptionID",
CustomerID: "MyCustomer",
ProductID: "SomeProductId",
AddOns: []string{},
StartAt: 1000000000,
EndAt: 2000000000,
CreateAt: 1000000000,
Seats: 100,
DNS: "some.dns.server",
IsPaidTier: "false",
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ExperimentalSettings.CloudUserLimit = 10
})
err := th.App.SendAdminUpgradeRequestEmail(th.BasicUser.Username, mockSubscription, model.JoinLimitation)
require.Nil(t, err)
// other attempts by the same user or other users to send emails are blocked by rate limiter
err = th.App.SendAdminUpgradeRequestEmail(th.BasicUser.Username, mockSubscription, model.JoinLimitation)
require.NotNil(t, err)
assert.Equal(t, err.Id, "app.email.rate_limit_exceeded.app_error")
err = th.App.SendAdminUpgradeRequestEmail(th.BasicUser2.Username, mockSubscription, model.JoinLimitation)
require.NotNil(t, err)
assert.Equal(t, err.Id, "app.email.rate_limit_exceeded.app_error")
}

Просмотреть файл

@@ -69,12 +69,6 @@ func RegisterJobsLdapSyncInterface(f func(*App) ejobs.LdapSyncInterface) {
jobsLdapSyncInterface = f
}
var jobsCloudInterface func(*Server) ejobs.CloudJobInterface
func RegisterJobsCloudInterface(f func(*Server) ejobs.CloudJobInterface) {
jobsCloudInterface = f
}
var ldapInterface func(*App) einterfaces.LdapInterface
func RegisterLdapInterface(f func(*App) einterfaces.LdapInterface) {

Просмотреть файл

@@ -1144,28 +1144,6 @@ func (a *OpenTracingAppLayer) Channels() *app.Channels {
return resultVar0
}
func (a *OpenTracingAppLayer) CheckAndSendUserLimitWarningEmails(c *request.Context) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CheckAndSendUserLimitWarningEmails")
a.ctx = newCtx
a.app.Srv().Store.SetContext(newCtx)
defer func() {
a.app.Srv().Store.SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0 := a.app.CheckAndSendUserLimitWarningEmails(c)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
ext.Error.Set(span, true)
}
return resultVar0
}
func (a *OpenTracingAppLayer) CheckCanInviteToSharedChannel(channelId string) error {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CheckCanInviteToSharedChannel")
@@ -1188,28 +1166,6 @@ func (a *OpenTracingAppLayer) CheckCanInviteToSharedChannel(channelId string) er
return resultVar0
}
func (a *OpenTracingAppLayer) CheckCloudAccountAtLimit() (bool, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CheckCloudAccountAtLimit")
a.ctx = newCtx
a.app.Srv().Store.SetContext(newCtx)
defer func() {
a.app.Srv().Store.SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.CheckCloudAccountAtLimit()
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
ext.Error.Set(span, true)
}
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) CheckForClientSideCert(r *http.Request) (string, string, string) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CheckForClientSideCert")
@@ -5816,28 +5772,6 @@ func (a *OpenTracingAppLayer) GetEnvironmentConfig(filter func(reflect.StructFie
return resultVar0
}
func (a *OpenTracingAppLayer) GetErrorListForEmailsOverLimit(emailList []string, cloudUserLimit int64) ([]string, []*model.EmailInviteWithError, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetErrorListForEmailsOverLimit")
a.ctx = newCtx
a.app.Srv().Store.SetContext(newCtx)
defer func() {
a.app.Srv().Store.SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0, resultVar1, resultVar2 := a.app.GetErrorListForEmailsOverLimit(emailList, cloudUserLimit)
if resultVar2 != nil {
span.LogFields(spanlog.Error(resultVar2))
ext.Error.Set(span, true)
}
return resultVar0, resultVar1, resultVar2
}
func (a *OpenTracingAppLayer) GetFile(fileID string) ([]byte, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetFile")
@@ -9007,28 +8941,6 @@ func (a *OpenTracingAppLayer) GetStatusesByIds(userIDs []string) (map[string]int
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetSubscriptionStats() (*model.SubscriptionStats, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetSubscriptionStats")
a.ctx = newCtx
a.app.Srv().Store.SetContext(newCtx)
defer func() {
a.app.Srv().Store.SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.GetSubscriptionStats()
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
ext.Error.Set(span, true)
}
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetSuggestions(c *request.Context, commandArgs *model.CommandArgs, commands []*model.Command, roleID string) []model.AutocompleteSuggestion {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetSuggestions")
@@ -14461,28 +14373,6 @@ func (a *OpenTracingAppLayer) SendAckToPushProxy(ack *model.PushNotificationAck)
return resultVar0
}
func (a *OpenTracingAppLayer) SendAdminUpgradeRequestEmail(username string, subscription *model.Subscription, action string) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SendAdminUpgradeRequestEmail")
a.ctx = newCtx
a.app.Srv().Store.SetContext(newCtx)
defer func() {
a.app.Srv().Store.SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0 := a.app.SendAdminUpgradeRequestEmail(username, subscription, action)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
ext.Error.Set(span, true)
}
return resultVar0
}
func (a *OpenTracingAppLayer) SendAutoResponse(c *request.Context, channel *model.Channel, receiver *model.User, post *model.Post) (bool, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SendAutoResponse")

Просмотреть файл

@@ -1915,11 +1915,6 @@ func (s *Server) initJobs() {
s.Jobs.RegisterJobType(model.JobTypeLdapSync, builder.MakeWorker(), builder.MakeScheduler())
}
if jobsCloudInterface != nil {
builder := jobsCloudInterface(s)
s.Jobs.RegisterJobType(model.JobTypeCloud, builder.MakeWorker(), builder.MakeScheduler())
}
s.Jobs.RegisterJobType(
model.JobTypeBlevePostIndexing,
indexer.MakeWorker(s.Jobs, s.SearchEngine.BleveEngine.(*bleveengine.BleveEngine)),

Просмотреть файл

@@ -1248,47 +1248,6 @@ func (a *App) prepareInviteNewUsersToTeam(teamID, senderId string) (*model.User,
return user, team, nil
}
func genEmailInviteWithErrorList(emailList []string) []*model.EmailInviteWithError {
invitesNotSent := make([]*model.EmailInviteWithError, len(emailList))
for i := range emailList {
invite := &model.EmailInviteWithError{
Email: emailList[i],
Error: model.NewAppError("inviteUsersToTeam", "api.team.invite_members.limit_reached.app_error", map[string]interface{}{"Addresses": emailList[i]}, "", http.StatusBadRequest),
}
invitesNotSent[i] = invite
}
return invitesNotSent
}
func (a *App) GetErrorListForEmailsOverLimit(emailList []string, cloudUserLimit int64) ([]string, []*model.EmailInviteWithError, *model.AppError) {
var invitesNotSent []*model.EmailInviteWithError
if cloudUserLimit <= 0 {
return emailList, invitesNotSent, nil
}
systemUserCount, _ := a.Srv().Store.User().Count(model.UserCountOptions{})
remainingUsers := cloudUserLimit - systemUserCount
if remainingUsers <= 0 {
// No remaining users so all fail
invitesNotSent = genEmailInviteWithErrorList(emailList)
emailList = nil
} else if remainingUsers < int64(len(emailList)) {
// Trim the email list to only invite as many users as are remaining in subscription
// Set graceful errors for the remaining email addresses
emailsAboveLimit := emailList[remainingUsers:]
invitesNotSent = genEmailInviteWithErrorList(emailsAboveLimit)
// If 1 user remaining we have to prevent 0:0 reslicing
if remainingUsers == 1 {
email := emailList[0]
emailList = nil
emailList = append(emailList, email)
} else {
emailList = emailList[:(remainingUsers - 1)]
}
}
return emailList, invitesNotSent, nil
}
func (a *App) InviteNewUsersToTeamGracefully(emailList []string, teamID, senderId string, reminderInterval string) ([]*model.EmailInviteWithError, *model.AppError) {
if !*a.Config().ServiceSettings.EnableEmailInvitations {
return nil, model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.disabled.app_error", nil, "", http.StatusNotImplemented)