* Deprecate admin advisor

* Webapp portion

* More webapp deprecation

* More cleanup

* Linting

* emoved metric ack dialog from annoucenemet bar

* Cleanued up uninsed i18n strings

* Updated test

* fixed types

* Updating server test

* Updated i18n

* Updated cypress test:

* Updated cypress test:

---------

Co-authored-by: harshil Sharma <harshilsharma63@gmail.com>
Этот коммит содержится в:
Maria A Nunez
2024-02-25 22:35:00 -05:00
коммит произвёл GitHub
родитель dc8fc773dc
Коммит e9b9d4ff60
42 изменённых файлов: 45 добавлений и 2285 удалений

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

@@ -66,9 +66,6 @@ func (api *API) InitSystem() {
api.BaseRoutes.APIRoot.Handle("/upgrade_to_enterprise", api.APISessionRequired(upgradeToEnterprise)).Methods("POST")
api.BaseRoutes.APIRoot.Handle("/upgrade_to_enterprise/status", api.APISessionRequired(upgradeToEnterpriseStatus)).Methods("GET")
api.BaseRoutes.APIRoot.Handle("/restart", api.APISessionRequired(restart)).Methods("POST")
api.BaseRoutes.APIRoot.Handle("/warn_metrics/status", api.APISessionRequired(getWarnMetricsStatus)).Methods("GET")
api.BaseRoutes.APIRoot.Handle("/warn_metrics/ack/{warn_metric_id:[A-Za-z0-9-_]+}", api.APIHandler(sendWarnMetricAckEmail)).Methods("POST")
api.BaseRoutes.APIRoot.Handle("/warn_metrics/trial-license-ack/{warn_metric_id:[A-Za-z0-9-_]+}", api.APIHandler(requestTrialLicenseAndAckWarnMetric)).Methods("POST")
api.BaseRoutes.System.Handle("/notices/{team_id:[A-Za-z0-9]+}", api.APISessionRequired(getProductNotices)).Methods("GET")
api.BaseRoutes.System.Handle("/notices/view", api.APISessionRequired(updateViewedProductNotices)).Methods("PUT")
api.BaseRoutes.System.Handle("/support_packet", api.APISessionRequired(generateSupportPacket)).Methods("GET")
@@ -846,100 +843,6 @@ func restart(c *Context, w http.ResponseWriter, r *http.Request) {
}()
}
func getWarnMetricsStatus(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.App.SessionHasPermissionToAny(*c.AppContext.Session(), model.SysconsoleReadPermissions) {
c.SetPermissionError(model.SysconsoleReadPermissions...)
return
}
license := c.App.Channels().License()
if license != nil {
c.Logger.Debug("License is present, skip.")
return
}
status, appErr := c.App.GetWarnMetricsStatus(c.AppContext)
if appErr != nil {
c.Err = appErr
return
}
js, err := json.Marshal(status)
if err != nil {
c.Err = model.NewAppError("getWarnMetricsStatus", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
w.Write(js)
}
func sendWarnMetricAckEmail(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec := c.MakeAuditRecord("sendWarnMetricAckEmail", audit.Fail)
defer c.LogAuditRec(auditRec)
c.LogAudit("attempt")
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) {
c.SetPermissionError(model.PermissionManageSystem)
return
}
license := c.App.Channels().License()
if license != nil {
c.Logger.Debug("License is present, skip.")
return
}
user, appErr := c.App.GetUser(c.AppContext.Session().UserId)
if appErr != nil {
c.Err = appErr
return
}
var ack model.SendWarnMetricAck
if jsonErr := json.NewDecoder(r.Body).Decode(&ack); jsonErr != nil {
c.SetInvalidParamWithErr("ack", jsonErr)
return
}
appErr = c.App.NotifyAndSetWarnMetricAck(c.AppContext, c.Params.WarnMetricId, user, ack.ForceAck, false)
if appErr != nil {
c.Err = appErr
}
auditRec.Success()
ReturnStatusOK(w)
}
func requestTrialLicenseAndAckWarnMetric(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec := c.MakeAuditRecord("requestTrialLicenseAndAckWarnMetric", audit.Fail)
defer c.LogAuditRec(auditRec)
c.LogAudit("attempt")
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) {
c.SetPermissionError(model.PermissionManageSystem)
return
}
if model.BuildEnterpriseReady != "true" {
c.Logger.Debug("Not Enterprise Edition, skip.")
return
}
license := c.App.Channels().License()
if license != nil {
c.Logger.Debug("License is present, skip.")
return
}
if err := c.App.RequestLicenseAndAckWarnMetric(c.AppContext, c.Params.WarnMetricId, false); err != nil {
c.Err = err
return
}
auditRec.Success()
ReturnStatusOK(w)
}
func getProductNotices(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireTeamId()
if c.Err != nil {

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

@@ -1,273 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package app
import (
"net/http"
"strings"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/public/shared/i18n"
"github.com/mattermost/mattermost/server/public/shared/mlog"
"github.com/mattermost/mattermost/server/public/shared/request"
"github.com/mattermost/mattermost/server/v8/platform/shared/mail"
)
func (a *App) GetWarnMetricsStatus(rctx request.CTX) (map[string]*model.WarnMetricStatus, *model.AppError) {
systemDataList, nErr := a.Srv().Store().System().Get()
if nErr != nil {
return nil, model.NewAppError("GetWarnMetricsStatus", "app.system.get.app_error", nil, "", http.StatusInternalServerError).Wrap(nErr)
}
isE0Edition := model.BuildEnterpriseReady == "true" // license == nil was already validated upstream
result := map[string]*model.WarnMetricStatus{}
for key, value := range systemDataList {
if strings.HasPrefix(key, model.WarnMetricStatusStorePrefix) {
if warnMetric, ok := model.WarnMetricsTable[key]; ok {
if !warnMetric.IsBotOnly && (value == model.WarnMetricStatusRunonce || value == model.WarnMetricStatusLimitReached) {
result[key], _ = a.getWarnMetricStatusAndDisplayTextsForId(rctx, key, nil, isE0Edition)
}
}
}
}
return result, nil
}
func (a *App) getWarnMetricStatusAndDisplayTextsForId(rctx request.CTX, warnMetricId string, T i18n.TranslateFunc, isE0Edition bool) (*model.WarnMetricStatus, *model.WarnMetricDisplayTexts) {
var warnMetricStatus *model.WarnMetricStatus
var warnMetricDisplayTexts = &model.WarnMetricDisplayTexts{}
if warnMetric, ok := model.WarnMetricsTable[warnMetricId]; ok {
warnMetricStatus = &model.WarnMetricStatus{
Id: warnMetric.Id,
Limit: warnMetric.Limit,
Acked: false,
}
if T == nil {
rctx.Logger().Debug("No translation function")
return warnMetricStatus, nil
}
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.bot_response.notification_success.message")
switch warnMetricId {
case model.SystemWarnMetricNumberOfTeams5:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.number_of_teams_5.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_teams_5.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.number_of_teams_5.start_trial_notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.number_of_teams_5.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_teams_5.notification_body")
}
case model.SystemWarnMetricMfa:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.mfa.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.mfa.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.mfa.start_trial_notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.mfa.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.mfa.notification_body")
}
case model.SystemWarnMetricEmailDomain:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.email_domain.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.email_domain.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.email_domain.start_trial_notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.email_domain.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.email_domain.notification_body")
}
case model.SystemWarnMetricNumberOfChannels50:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.number_of_channels_50.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_channels_50.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.number_of_channels_50.start_trial.notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.number_of_channels_50.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_channels_50.notification_body")
}
case model.SystemWarnMetricNumberOfActiveUsers100:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.number_of_active_users_100.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_active_users_100.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.number_of_active_users_100.start_trial.notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.number_of_active_users_100.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_active_users_100.notification_body")
}
case model.SystemWarnMetricNumberOfActiveUsers200:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.number_of_active_users_200.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_active_users_200.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.number_of_active_users_200.start_trial.notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.number_of_active_users_200.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_active_users_200.notification_body")
}
case model.SystemWarnMetricNumberOfActiveUsers300:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.number_of_active_users_300.start_trial.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_active_users_300.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.number_of_active_users_300.start_trial.notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.number_of_active_users_300.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_active_users_300.notification_body")
}
case model.SystemWarnMetricNumberOfActiveUsers500:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.number_of_active_users_500.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_active_users_500.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.number_of_active_users_500.start_trial.notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.number_of_active_users_500.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_active_users_500.notification_body")
}
case model.SystemWarnMetricNumberOfPosts2m:
warnMetricDisplayTexts.BotTitle = T("api.server.warn_metric.number_of_posts_2M.notification_title")
if isE0Edition {
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_posts_2M.start_trial.notification_body")
warnMetricDisplayTexts.BotSuccessMessage = T("api.server.warn_metric.number_of_posts_2M.start_trial.notification_success.message")
} else {
warnMetricDisplayTexts.EmailBody = T("api.server.warn_metric.number_of_posts_2M.contact_us.email_body")
warnMetricDisplayTexts.BotMessageBody = T("api.server.warn_metric.number_of_posts_2M.notification_body")
}
default:
rctx.Logger().Debug("Invalid metric id", mlog.String("id", warnMetricId))
return nil, nil
}
return warnMetricStatus, warnMetricDisplayTexts
}
return nil, nil
}
func (a *App) NotifyAndSetWarnMetricAck(rctx request.CTX, warnMetricId string, sender *model.User, forceAck bool, isBot bool) *model.AppError {
if warnMetric, ok := model.WarnMetricsTable[warnMetricId]; ok {
data, nErr := a.Srv().Store().System().GetByName(warnMetric.Id)
if nErr == nil && data != nil && data.Value == model.WarnMetricStatusAck {
rctx.Logger().Debug("This metric warning has already been acknowledged", mlog.String("id", warnMetric.Id))
return nil
}
if !forceAck {
if *a.Config().EmailSettings.SMTPServer == "" {
return model.NewAppError("NotifyAndSetWarnMetricAck", "api.email.send_warn_metric_ack.missing_server.app_error", nil, i18n.T("api.context.invalid_param.app_error", map[string]any{"Name": "SMTPServer"}), http.StatusInternalServerError)
}
T := i18n.GetUserTranslations(sender.Locale)
data := a.Srv().EmailService.NewEmailTemplateData(sender.Locale)
data.Props["ContactNameHeader"] = T("api.templates.warn_metric_ack.body.contact_name_header")
data.Props["ContactNameValue"] = sender.GetFullName()
data.Props["ContactEmailHeader"] = T("api.templates.warn_metric_ack.body.contact_email_header")
data.Props["ContactEmailValue"] = sender.Email
//same definition as the active users count metric displayed in the SystemConsole Analytics section
registeredUsersCount, cerr := a.Srv().Store().User().Count(model.UserCountOptions{})
if cerr != nil {
rctx.Logger().Warn("Error retrieving the number of registered users", mlog.Err(cerr))
} else {
data.Props["RegisteredUsersHeader"] = T("api.templates.warn_metric_ack.body.registered_users_header")
data.Props["RegisteredUsersValue"] = registeredUsersCount
}
data.Props["SiteURLHeader"] = T("api.templates.warn_metric_ack.body.site_url_header")
data.Props["SiteURL"] = a.GetSiteURL()
data.Props["TelemetryIdHeader"] = T("api.templates.warn_metric_ack.body.diagnostic_id_header")
data.Props["TelemetryIdValue"] = a.TelemetryId()
data.Props["Footer"] = T("api.templates.warn_metric_ack.footer")
warnMetricStatus, warnMetricDisplayTexts := a.getWarnMetricStatusAndDisplayTextsForId(rctx, warnMetricId, T, false)
if warnMetricStatus == nil {
return model.NewAppError("NotifyAndSetWarnMetricAck", "api.email.send_warn_metric_ack.invalid_warn_metric.app_error", nil, "", http.StatusInternalServerError)
}
subject := T("api.templates.warn_metric_ack.subject")
data.Props["Title"] = warnMetricDisplayTexts.EmailBody
mailConfig := a.Srv().MailServiceConfig()
body, err := a.Srv().TemplatesContainer().RenderToString("warn_metric_ack", data)
if err != nil {
return model.NewAppError("NotifyAndSetWarnMetricAck", "api.email.send_warn_metric_ack.failure.app_error", map[string]any{"Error": err.Error()}, "", http.StatusInternalServerError)
}
if err := mail.SendMailUsingConfig(model.MmSupportAdvisorAddress, subject, body, mailConfig, false, "", "", "", sender.Email, "NotifyAndSetWarnMetricAck"); err != nil {
return model.NewAppError("NotifyAndSetWarnMetricAck", "api.email.send_warn_metric_ack.failure.app_error", map[string]any{"Error": err.Error()}, "", http.StatusInternalServerError)
}
}
if err := a.setWarnMetricsStatusAndNotify(rctx, warnMetric.Id); err != nil {
return err
}
}
return nil
}
func (a *App) setWarnMetricsStatusAndNotify(rctx request.CTX, warnMetricId string) *model.AppError {
// Ack all metric warnings on the server
if err := a.setWarnMetricsStatus(rctx, model.WarnMetricStatusAck); err != nil {
return err
}
// Inform client that this metric warning has been acked
message := model.NewWebSocketEvent(model.WebsocketWarnMetricStatusRemoved, "", "", "", nil, "")
message.Add("warnMetricId", warnMetricId)
a.Publish(message)
return nil
}
func (a *App) setWarnMetricsStatus(rctx request.CTX, status string) *model.AppError {
rctx.Logger().Debug("Set monitoring status for all warn metrics", mlog.String("status", status))
for _, warnMetric := range model.WarnMetricsTable {
if err := a.setWarnMetricsStatusForId(rctx, warnMetric.Id, status); err != nil {
return err
}
}
return nil
}
func (a *App) setWarnMetricsStatusForId(rctx request.CTX, warnMetricId string, status string) *model.AppError {
rctx.Logger().Debug("Store status for warn metric", mlog.String("warnMetricId", warnMetricId), mlog.String("status", status))
if err := a.Srv().Store().System().SaveOrUpdateWithWarnMetricHandling(&model.System{
Name: warnMetricId,
Value: status,
}); err != nil {
return model.NewAppError("setWarnMetricsStatusForId", "app.system.warn_metric.store.app_error", map[string]any{"WarnMetricName": warnMetricId}, "", http.StatusInternalServerError).Wrap(err)
}
return nil
}
func (a *App) RequestLicenseAndAckWarnMetric(c request.CTX, warnMetricId string, isBot bool) *model.AppError {
if *a.Config().ExperimentalSettings.RestrictSystemAdmin {
return model.NewAppError("RequestLicenseAndAckWarnMetric", "api.restricted_system_admin", nil, "", http.StatusForbidden)
}
currentUser, appErr := a.GetUser(c.Session().UserId)
if appErr != nil {
return appErr
}
registeredUsersCount, err := a.Srv().Store().User().Count(model.UserCountOptions{})
if err != nil {
return model.NewAppError("RequestLicenseAndAckWarnMetric", "api.license.request_trial_license.fail_get_user_count.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
if err := a.Channels().RequestTrialLicense(c.Session().UserId, int(registeredUsersCount), true, true); err != nil {
// turn off warn metric warning even in case of StartTrial failure
if nerr := a.setWarnMetricsStatusAndNotify(c, warnMetricId); nerr != nil {
return nerr
}
return err
}
if appErr = a.NotifyAndSetWarnMetricAck(c, warnMetricId, currentUser, true, isBot); appErr != nil {
return appErr
}
return nil
}

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

@@ -883,8 +883,6 @@ type AppIface interface {
GetUsersWithoutTeamPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError)
GetVerifyEmailToken(token string) (*model.Token, *model.AppError)
GetViewUsersRestrictions(c request.CTX, userID string) (*model.ViewUsersRestrictions, *model.AppError)
GetWarnMetricsBot(rctx request.CTX) (*model.Bot, *model.AppError)
GetWarnMetricsStatus(rctx request.CTX) (map[string]*model.WarnMetricStatus, *model.AppError)
HTTPService() httpservice.HTTPService
HandleCommandResponse(c request.CTX, command *model.Command, args *model.CommandArgs, response *model.CommandResponse, builtIn bool) (*model.CommandResponse, *model.AppError)
HandleCommandResponsePost(c request.CTX, command *model.Command, args *model.CommandArgs, response *model.CommandResponse, builtIn bool) (*model.Post, *model.AppError)
@@ -953,7 +951,6 @@ type AppIface interface {
NewPluginAPI(c request.CTX, manifest *model.Manifest) plugin.API
Notification() einterfaces.NotificationInterface
NotificationsLog() *mlog.Logger
NotifyAndSetWarnMetricAck(rctx request.CTX, warnMetricId string, sender *model.User, forceAck bool, isBot bool) *model.AppError
NotifySelfHostedSignupProgress(progress string, userId string)
NotifySharedChannelUserUpdate(user *model.User)
OpenInteractiveDialog(request model.OpenDialogRequest) *model.AppError
@@ -1016,7 +1013,6 @@ type AppIface interface {
RemoveUserFromChannel(c request.CTX, userIDToRemove string, removerUserId string, channel *model.Channel) *model.AppError
RemoveUserFromTeam(c request.CTX, teamID string, userID string, requestorId string) *model.AppError
RemoveUsersFromChannelNotMemberOfTeam(c request.CTX, remover *model.User, channel *model.Channel, team *model.Team) *model.AppError
RequestLicenseAndAckWarnMetric(c request.CTX, warnMetricId string, isBot bool) *model.AppError
ResetPasswordFromToken(c request.CTX, userSuppliedTokenString, newPassword string) *model.AppError
ResetPermissionsSystem() *model.AppError
ResetSamlAuthDataToEmail(includeDeleted bool, dryRun bool, userIDs []string) (numAffected int, appErr *model.AppError)

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

@@ -160,35 +160,6 @@ func (a *App) CreateBot(c request.CTX, bot *model.Bot) (*model.Bot, *model.AppEr
return savedBot, nil
}
func (a *App) GetWarnMetricsBot(rctx request.CTX) (*model.Bot, *model.AppError) {
perPage := 1
userOptions := &model.UserGetOptions{
Page: 0,
PerPage: perPage,
Role: model.SystemAdminRoleId,
Inactive: false,
}
sysAdminList, err := a.GetUsersFromProfiles(userOptions)
if err != nil {
return nil, err
}
if len(sysAdminList) == 0 {
return nil, model.NewAppError("GetWarnMetricsBot", "app.bot.get_warn_metrics_bot.empty_admin_list.app_error", nil, "", http.StatusInternalServerError)
}
T := i18n.GetUserTranslations(sysAdminList[0].Locale)
warnMetricsBot := &model.Bot{
Username: model.BotWarnMetricBotUsername,
DisplayName: T("app.system.warn_metric.bot_displayname"),
Description: "",
OwnerId: sysAdminList[0].Id,
}
return a.getOrCreateBot(rctx, warnMetricsBot)
}
func (a *App) GetSystemBot(rctx request.CTX) (*model.Bot, *model.AppError) {
perPage := 1
userOptions := &model.UserGetOptions{

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

@@ -27,14 +27,12 @@ import (
"net/http"
"net/url"
"path"
"path/filepath"
"strings"
"time"
"github.com/gorilla/mux"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/public/shared/i18n"
"github.com/mattermost/mattermost/server/public/shared/mlog"
"github.com/mattermost/mattermost/server/public/shared/request"
"github.com/mattermost/mattermost/server/v8/channels/store"
@@ -230,14 +228,6 @@ func (a *App) DoPostActionWithCookie(c request.CTX, postID, actionId, userID, se
return "", appErr
}
if strings.HasPrefix(upstreamURL, "/warn_metrics/") {
appErr = a.doLocalWarnMetricsRequest(c, upstreamURL, upstreamRequest)
if appErr != nil {
return "", appErr
}
return "", nil
}
requestJSON, err := json.Marshal(upstreamRequest)
if err != nil {
return "", model.NewAppError("DoPostActionWithCookie", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
@@ -446,92 +436,6 @@ func (ch *Channels) doPluginRequest(c request.CTX, method, rawURL string, values
return resp, nil
}
func (a *App) doLocalWarnMetricsRequest(c request.CTX, rawURL string, upstreamRequest *model.PostActionIntegrationRequest) *model.AppError {
_, err := url.Parse(rawURL)
if err != nil {
return model.NewAppError("doLocalWarnMetricsRequest", "api.post.do_action.action_integration.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
warnMetricId := filepath.Base(rawURL)
if warnMetricId == "" {
return model.NewAppError("doLocalWarnMetricsRequest", "api.post.do_action.action_integration.app_error", nil, "", http.StatusBadRequest)
}
license := a.Srv().License()
if license != nil {
c.Logger().Debug("License is present, skip this call")
return nil
}
user, appErr := a.GetUser(c.Session().UserId)
if appErr != nil {
return appErr
}
botPost := &model.Post{
UserId: upstreamRequest.Context["bot_user_id"].(string),
ChannelId: upstreamRequest.ChannelId,
HasReactions: true,
}
isE0Edition := (model.BuildEnterpriseReady == "true") // license == nil was already validated upstream
_, warnMetricDisplayTexts := a.getWarnMetricStatusAndDisplayTextsForId(c, warnMetricId, i18n.T, isE0Edition)
botPost.Message = ":white_check_mark: " + warnMetricDisplayTexts.BotSuccessMessage
if isE0Edition {
if appErr = a.RequestLicenseAndAckWarnMetric(c, warnMetricId, true); appErr != nil {
botPost.Message = ":warning: " + i18n.T("api.server.warn_metric.bot_response.start_trial_failure.message")
}
} else {
forceAck := upstreamRequest.Context["force_ack"].(bool)
if appErr = a.NotifyAndSetWarnMetricAck(c, warnMetricId, user, forceAck, true); appErr != nil {
if forceAck {
return appErr
}
mailtoLinkText := a.buildWarnMetricMailtoLink(c, warnMetricId, user)
botPost.Message = ":warning: " + i18n.T("api.server.warn_metric.bot_response.notification_failure.message")
actions := []*model.PostAction{}
actions = append(actions,
&model.PostAction{
Id: "emailUs",
Name: i18n.T("api.server.warn_metric.email_us"),
Type: model.PostActionTypeButton,
Options: []*model.PostActionOptions{
{
Text: "WarnMetricMailtoUrl",
Value: mailtoLinkText,
},
{
Text: "TrackEventId",
Value: warnMetricId,
},
},
Integration: &model.PostActionIntegration{
Context: model.StringInterface{
"bot_user_id": botPost.UserId,
"force_ack": true,
},
URL: fmt.Sprintf("/warn_metrics/ack/%s", model.SystemWarnMetricNumberOfActiveUsers500),
},
},
)
attachments := []*model.SlackAttachment{{
AuthorName: "",
Title: "",
Actions: actions,
Text: i18n.T("api.server.warn_metric.bot_response.notification_failure.body"),
}}
model.ParseSlackAttachment(botPost, attachments)
}
}
if _, err := a.CreatePostAsUser(c, botPost, c.Session().Id, true); err != nil {
return err
}
return nil
}
type MailToLinkContent struct {
MetricId string `json:"metric_id"`
MailRecipient string `json:"mail_recipient"`
@@ -545,43 +449,6 @@ func (mlc *MailToLinkContent) ToJSON() string {
return string(b)
}
func (a *App) buildWarnMetricMailtoLink(rctx request.CTX, warnMetricId string, user *model.User) string {
T := i18n.GetUserTranslations(user.Locale)
_, warnMetricDisplayTexts := a.getWarnMetricStatusAndDisplayTextsForId(rctx, warnMetricId, T, false)
mailBody := warnMetricDisplayTexts.EmailBody
mailBody += T("api.server.warn_metric.bot_response.mailto_contact_header", map[string]any{"Contact": user.GetFullName()})
mailBody += "\r\n"
mailBody += T("api.server.warn_metric.bot_response.mailto_email_header", map[string]any{"Email": user.Email})
mailBody += "\r\n"
registeredUsersCount, err := a.Srv().Store().User().Count(model.UserCountOptions{})
if err != nil {
rctx.Logger().Warn("Error retrieving the number of registered users", mlog.Err(err))
} else {
mailBody += i18n.T("api.server.warn_metric.bot_response.mailto_registered_users_header", map[string]any{"NoRegisteredUsers": registeredUsersCount})
mailBody += "\r\n"
}
mailBody += T("api.server.warn_metric.bot_response.mailto_site_url_header", map[string]any{"SiteUrl": a.GetSiteURL()})
mailBody += "\r\n"
mailBody += T("api.server.warn_metric.bot_response.mailto_diagnostic_id_header", map[string]any{"DiagnosticId": a.TelemetryId()})
mailBody += "\r\n"
mailBody += T("api.server.warn_metric.bot_response.mailto_footer")
mailToLinkContent := &MailToLinkContent{
MetricId: warnMetricId,
MailRecipient: model.MmSupportAdvisorAddress,
MailCC: user.Email,
MailSubject: T("api.server.warn_metric.bot_response.mailto_subject"),
MailBody: mailBody,
}
return mailToLinkContent.ToJSON()
}
func (a *App) DoLocalRequest(c request.CTX, rawURL string, body []byte) (*http.Response, *model.AppError) {
return a.doPluginRequest(c, "POST", rawURL, nil, body)
}

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

@@ -11391,50 +11391,6 @@ func (a *OpenTracingAppLayer) GetViewUsersRestrictions(c request.CTX, userID str
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetWarnMetricsBot(rctx request.CTX) (*model.Bot, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetWarnMetricsBot")
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.GetWarnMetricsBot(rctx)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
ext.Error.Set(span, true)
}
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetWarnMetricsStatus(rctx request.CTX) (map[string]*model.WarnMetricStatus, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetWarnMetricsStatus")
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.GetWarnMetricsStatus(rctx)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
ext.Error.Set(span, true)
}
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) HandleCommandResponse(c request.CTX, command *model.Command, args *model.CommandArgs, response *model.CommandResponse, builtIn bool) (*model.CommandResponse, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.HandleCommandResponse")
@@ -12872,28 +12828,6 @@ func (a *OpenTracingAppLayer) NewPluginAPI(c request.CTX, manifest *model.Manife
return resultVar0
}
func (a *OpenTracingAppLayer) NotifyAndSetWarnMetricAck(rctx request.CTX, warnMetricId string, sender *model.User, forceAck bool, isBot bool) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.NotifyAndSetWarnMetricAck")
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.NotifyAndSetWarnMetricAck(rctx, warnMetricId, sender, forceAck, isBot)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
ext.Error.Set(span, true)
}
return resultVar0
}
func (a *OpenTracingAppLayer) NotifySelfHostedSignupProgress(progress string, userId string) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.NotifySelfHostedSignupProgress")
@@ -14486,28 +14420,6 @@ func (a *OpenTracingAppLayer) RenameTeam(team *model.Team, newTeamName string, n
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) RequestLicenseAndAckWarnMetric(c request.CTX, warnMetricId string, isBot bool) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RequestLicenseAndAckWarnMetric")
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.RequestLicenseAndAckWarnMetric(c, warnMetricId, isBot)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
ext.Error.Set(span, true)
}
return resultVar0
}
func (a *OpenTracingAppLayer) ResetPasswordFromToken(c request.CTX, userSuppliedTokenString string, newPassword string) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.ResetPasswordFromToken")

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

@@ -9448,24 +9448,6 @@ func (s *OpenTracingLayerSystemStore) SaveOrUpdate(system *model.System) error {
return err
}
func (s *OpenTracingLayerSystemStore) SaveOrUpdateWithWarnMetricHandling(system *model.System) error {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SystemStore.SaveOrUpdateWithWarnMetricHandling")
s.Root.Store.SetContext(newCtx)
defer func() {
s.Root.Store.SetContext(origCtx)
}()
defer span.Finish()
err := s.SystemStore.SaveOrUpdateWithWarnMetricHandling(system)
if err != nil {
span.LogFields(spanlog.Error(err))
ext.Error.Set(span, true)
}
return err
}
func (s *OpenTracingLayerSystemStore) Update(system *model.System) error {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SystemStore.Update")

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

@@ -10799,27 +10799,6 @@ func (s *RetryLayerSystemStore) SaveOrUpdate(system *model.System) error {
}
func (s *RetryLayerSystemStore) SaveOrUpdateWithWarnMetricHandling(system *model.System) error {
tries := 0
for {
err := s.SystemStore.SaveOrUpdateWithWarnMetricHandling(system)
if err == nil {
return nil
}
if !isRepeatableError(err) {
return err
}
tries++
if tries >= 3 {
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
return err
}
timepkg.Sleep(100 * timepkg.Millisecond)
}
}
func (s *RetryLayerSystemStore) Update(system *model.System) error {
tries := 0

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

@@ -6,16 +6,12 @@ package sqlstore
import (
"database/sql"
"fmt"
"strconv"
"strings"
"time"
sq "github.com/mattermost/squirrel"
"github.com/pkg/errors"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/v8/channels/store"
"github.com/mattermost/mattermost/server/v8/channels/utils"
)
type SqlSystemStore struct {
@@ -59,24 +55,6 @@ func (s SqlSystemStore) SaveOrUpdate(system *model.System) error {
return nil
}
func (s SqlSystemStore) SaveOrUpdateWithWarnMetricHandling(system *model.System) error {
if err := s.SaveOrUpdate(system); err != nil {
return err
}
if strings.HasPrefix(system.Name, model.WarnMetricStatusStorePrefix) &&
(system.Value == model.WarnMetricStatusRunonce || system.Value == model.WarnMetricStatusLimitReached) {
if err := s.SaveOrUpdate(&model.System{
Name: model.SystemWarnMetricLastRunTimestampKey,
Value: strconv.FormatInt(utils.MillisFromTime(time.Now()), 10),
}); err != nil {
return errors.Wrapf(err, "failed to save system property with name=%s", model.SystemWarnMetricLastRunTimestampKey)
}
}
return nil
}
func (s SqlSystemStore) Update(system *model.System) error {
query := "UPDATE Systems SET Value=:Value WHERE Name=:Name"
if _, err := s.GetMasterX().NamedExec(query, system); err != nil {

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

@@ -586,7 +586,6 @@ type SystemStore interface {
GetByName(name string) (*model.System, error)
PermanentDeleteByName(name string) (*model.System, error)
InsertIfExists(system *model.System) (*model.System, error)
SaveOrUpdateWithWarnMetricHandling(system *model.System) error
}
type WebhookStore interface {

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

@@ -146,20 +146,6 @@ func (_m *SystemStore) SaveOrUpdate(system *model.System) error {
return r0
}
// SaveOrUpdateWithWarnMetricHandling provides a mock function with given fields: system
func (_m *SystemStore) SaveOrUpdateWithWarnMetricHandling(system *model.System) error {
ret := _m.Called(system)
var r0 error
if rf, ok := ret.Get(0).(func(*model.System) error); ok {
r0 = rf(system)
} else {
r0 = ret.Error(0)
}
return r0
}
// Update provides a mock function with given fields: system
func (_m *SystemStore) Update(system *model.System) error {
ret := _m.Called(system)

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

@@ -22,7 +22,6 @@ func TestSystemStore(t *testing.T, rctx request.CTX, ss store.Store) {
t.Run("InsertIfExists", func(t *testing.T) {
testInsertIfExists(t, rctx, ss)
})
t.Run("SaveOrUpdateWithWarnMetricHandling", func(t *testing.T) { testSystemStoreSaveOrUpdateWithWarnMetricHandling(t, rctx, ss) })
t.Run("GetByNameNoEntries", func(t *testing.T) { testSystemStoreGetByNameNoEntries(t, rctx, ss) })
}
@@ -73,33 +72,6 @@ func testSystemStoreSaveOrUpdate(t *testing.T, rctx request.CTX, ss store.Store)
assert.Equal(t, system.Value, res.Value)
}
func testSystemStoreSaveOrUpdateWithWarnMetricHandling(t *testing.T, rctx request.CTX, ss store.Store) {
system := &model.System{Name: model.NewId(), Value: "value"}
err := ss.System().SaveOrUpdateWithWarnMetricHandling(system)
require.NoError(t, err)
_, err = ss.System().GetByName(model.SystemWarnMetricLastRunTimestampKey)
assert.Error(t, err)
system.Name = "warn_metric_number_of_active_users_100"
system.Value = model.WarnMetricStatusRunonce
err = ss.System().SaveOrUpdateWithWarnMetricHandling(system)
require.NoError(t, err)
val1, nerr := ss.System().GetByName(model.SystemWarnMetricLastRunTimestampKey)
assert.NoError(t, nerr)
system.Name = "warn_metric_number_of_active_users_100"
system.Value = model.WarnMetricStatusAck
err = ss.System().SaveOrUpdateWithWarnMetricHandling(system)
require.NoError(t, err)
val2, nerr := ss.System().GetByName(model.SystemWarnMetricLastRunTimestampKey)
assert.NoError(t, nerr)
assert.Equal(t, val1, val2)
}
func testSystemStoreGetByNameNoEntries(t *testing.T, rctx request.CTX, ss store.Store) {
res, nErr := ss.System().GetByName(model.SystemFirstAdminVisitMarketplace)
_, ok := nErr.(*store.ErrNotFound)

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

@@ -8505,22 +8505,6 @@ func (s *TimerLayerSystemStore) SaveOrUpdate(system *model.System) error {
return err
}
func (s *TimerLayerSystemStore) SaveOrUpdateWithWarnMetricHandling(system *model.System) error {
start := time.Now()
err := s.SystemStore.SaveOrUpdateWithWarnMetricHandling(system)
elapsed := float64(time.Since(start)) / float64(time.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SystemStore.SaveOrUpdateWithWarnMetricHandling", success, elapsed)
}
return err
}
func (s *TimerLayerSystemStore) Update(system *model.System) error {
start := time.Now()

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

@@ -87,7 +87,6 @@ type Params struct {
FilterArchived bool
FilterParentTeamPermitted bool
CategoryId string
WarnMetricId string
ExportName string
ExcludePolicyConstrained bool
GroupSource model.GroupSource
@@ -227,7 +226,6 @@ func ParamsFromRequest(r *http.Request) *Params {
params.GroupIDs = query.Get("group_ids")
params.IncludeTotalCount, _ = strconv.ParseBool(query.Get("include_total_count"))
params.IncludeDeleted, _ = strconv.ParseBool(query.Get("include_deleted"))
params.WarnMetricId = props["warn_metric_id"]
params.ExportName = props["export_name"]
params.ExcludePolicyConstrained, _ = strconv.ParseBool(query.Get("exclude_policy_constrained"))