-
Notifications
You must be signed in to change notification settings - Fork 7.3k
/
cloud.go
177 lines (152 loc) · 5.69 KB
/
cloud.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package app
import (
"fmt"
"net/http"
"time"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/shared/mlog"
)
func (a *App) getSysAdminsEmailRecipients() ([]*model.User, *model.AppError) {
userOptions := &model.UserGetOptions{
Page: 0,
PerPage: 100,
Role: model.SYSTEM_ADMIN_ROLE_ID,
Inactive: false,
}
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.PerDayEmailRateLimiter == 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.PerDayEmailRateLimiter.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) CheckAndSendUserLimitWarningEmails() *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(a.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 {
_, appErr := a.Srv().EmailService.SendAtUserLimitWarningEmail(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),
)
}
}
}
return nil
}
func (a *App) SendPaymentFailedEmail(failedPayment *model.FailedPayment) *model.AppError {
sysAdmins, err := a.getSysAdminsEmailRecipients()
if err != nil {
return err
}
for _, admin := range sysAdmins {
_, err := a.Srv().EmailService.SendPaymentFailedEmail(admin.Email, admin.Locale, failedPayment, *a.Config().ServiceSettings.SiteURL)
if err != nil {
a.Log().Error("Error sending payment failed email", mlog.Err(err))
}
}
return nil
}
// SendNoCardPaymentFailedEmail
func (a *App) SendNoCardPaymentFailedEmail() *model.AppError {
sysAdmins, err := a.getSysAdminsEmailRecipients()
if err != nil {
return err
}
for _, admin := range sysAdmins {
err := a.Srv().EmailService.SendNoCardPaymentFailedEmail(admin.Email, admin.Locale, *a.Config().ServiceSettings.SiteURL)
if err != nil {
a.Log().Error("Error sending payment failed email", mlog.Err(err))
}
}
return nil
}