[MM-56616] Changes for the DM for batch reporting (#26019)

* [MM-56616] Changes for the DM for batch reporting

* Use requesting user's locale

* Fix lint

* Remove unnecessary test

* Move back to file attachment

* Add default API case

* Fix i18n

* Hardcode the CSV string
Этот коммит содержится в:
Devin Binnie
2024-01-29 09:52:33 -05:00
коммит произвёл GitHub
родитель d3be94f2b9
Коммит 435da9bea7
10 изменённых файлов: 106 добавлений и 166 удалений

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

@@ -1025,7 +1025,6 @@ type AppIface interface {
RestoreTeam(teamID string) *model.AppError
RestrictUsersGetByPermissions(c request.CTX, userID string, options *model.UserGetOptions) (*model.UserGetOptions, *model.AppError)
RestrictUsersSearchByPermissions(c request.CTX, userID string, options *model.UserSearchOptions) (*model.UserSearchOptions, *model.AppError)
RetrieveBatchReport(reportID string, format string) (filestore.ReadCloseSeeker, string, *model.AppError)
ReturnSessionToPool(session *model.Session)
RevokeAccessToken(c request.CTX, token string) *model.AppError
RevokeAllSessions(c request.CTX, userID string) *model.AppError
@@ -1082,7 +1081,7 @@ type AppIface interface {
SendPasswordReset(email string, siteURL string) (bool, *model.AppError)
SendPaymentFailedEmail(failedPayment *model.FailedPayment) *model.AppError
SendPersistentNotifications() error
SendReportToUser(rctx request.CTX, userID string, jobId string, format string) *model.AppError
SendReportToUser(rctx request.CTX, job *model.Job, format string) *model.AppError
SendTestPushNotification(deviceID string) string
SendUpgradeConfirmationEmail(isYearly bool) *model.AppError
ServeInterPluginRequest(w http.ResponseWriter, r *http.Request, sourcePluginId, destinationPluginId string)
@@ -1127,7 +1126,7 @@ type AppIface interface {
SlackImport(c request.CTX, fileData multipart.File, fileSize int64, teamID string) (*model.AppError, *bytes.Buffer)
SoftDeleteTeam(teamID string) *model.AppError
Srv() *Server
StartUsersBatchExport(rctx request.CTX, startAt int64, endAt int64) *model.AppError
StartUsersBatchExport(rctx request.CTX, dateRange string, startAt int64, endAt int64) *model.AppError
SubmitInteractiveDialog(c request.CTX, request model.SubmitDialogRequest) (*model.SubmitDialogResponse, *model.AppError)
SwitchEmailToLdap(c request.CTX, email, password, code, ldapLoginId, ldapPassword string) (string, *model.AppError)
SwitchEmailToOAuth(c request.CTX, w http.ResponseWriter, r *http.Request, email, password, code, service string) (string, *model.AppError)

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

@@ -14662,28 +14662,6 @@ func (a *OpenTracingAppLayer) RestrictUsersSearchByPermissions(c request.CTX, us
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) RetrieveBatchReport(reportID string, format string) (filestore.ReadCloseSeeker, string, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RetrieveBatchReport")
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.RetrieveBatchReport(reportID, format)
if resultVar2 != nil {
span.LogFields(spanlog.Error(resultVar2))
ext.Error.Set(span, true)
}
return resultVar0, resultVar1, resultVar2
}
func (a *OpenTracingAppLayer) ReturnSessionToPool(session *model.Session) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.ReturnSessionToPool")
@@ -15960,7 +15938,7 @@ func (a *OpenTracingAppLayer) SendPersistentNotifications() error {
return resultVar0
}
func (a *OpenTracingAppLayer) SendReportToUser(rctx request.CTX, userID string, jobId string, format string) *model.AppError {
func (a *OpenTracingAppLayer) SendReportToUser(rctx request.CTX, job *model.Job, format string) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SendReportToUser")
@@ -15972,7 +15950,7 @@ func (a *OpenTracingAppLayer) SendReportToUser(rctx request.CTX, userID string,
}()
defer span.Finish()
resultVar0 := a.app.SendReportToUser(rctx, userID, jobId, format)
resultVar0 := a.app.SendReportToUser(rctx, job, format)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
@@ -16923,7 +16901,7 @@ func (a *OpenTracingAppLayer) SoftDeleteTeam(teamID string) *model.AppError {
return resultVar0
}
func (a *OpenTracingAppLayer) StartUsersBatchExport(rctx request.CTX, startAt int64, endAt int64) *model.AppError {
func (a *OpenTracingAppLayer) StartUsersBatchExport(rctx request.CTX, dateRange string, startAt int64, endAt int64) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.StartUsersBatchExport")
@@ -16935,7 +16913,7 @@ func (a *OpenTracingAppLayer) StartUsersBatchExport(rctx request.CTX, startAt in
}()
defer span.Finish()
resultVar0 := a.app.StartUsersBatchExport(rctx, startAt, endAt)
resultVar0 := a.app.StartUsersBatchExport(rctx, dateRange, startAt, endAt)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))

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

@@ -14,7 +14,6 @@ import (
"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/filestore"
)
func (a *App) SaveReportChunk(format string, prefix string, count int, reportData []model.ReportableObject) *model.AppError {
@@ -84,26 +83,55 @@ func (a *App) compileCSVChunks(prefix string, numberOfChunks int, headers []stri
return nil
}
func (a *App) SendReportToUser(rctx request.CTX, userID string, jobId string, format string) *model.AppError {
func (a *App) SendReportToUser(rctx request.CTX, job *model.Job, format string) *model.AppError {
requestingUserId := job.Data["requesting_user_id"]
if requestingUserId == "" {
return model.NewAppError("SendReportToUser", "app.report.send_report_to_user.missing_user_id", nil, "", http.StatusInternalServerError)
}
dateRange := job.Data["date_range"]
if dateRange == "" {
return model.NewAppError("SendReportToUser", "app.report.send_report_to_user.missing_date_range", nil, "", http.StatusInternalServerError)
}
systemBot, err := a.GetSystemBot()
if err != nil {
return err
}
channel, err := a.GetOrCreateDirectChannel(request.EmptyContext(a.Log()), userID, systemBot.UserId)
path := makeCompiledFilePath(job.Id, format)
size, err := a.FileSize(path)
if err != nil {
return err
}
fileInfo, fileErr := a.Srv().Store().FileInfo().Save(rctx, &model.FileInfo{
Name: makeCompiledFilename(job.Id, format),
Extension: format,
Size: size,
Path: path,
CreatorId: systemBot.UserId,
})
if fileErr != nil {
return model.NewAppError("SendReportToUser", "app.report.send_report_to_user.failed_to_save", nil, "", http.StatusInternalServerError).Wrap(fileErr)
}
channel, err := a.GetOrCreateDirectChannel(request.EmptyContext(a.Log()), requestingUserId, systemBot.UserId)
if err != nil {
return err
}
user, err := a.GetUser(requestingUserId)
if err != nil {
return err
}
T := i18n.GetUserTranslations(user.Locale)
post := &model.Post{
ChannelId: channel.Id,
Message: i18n.T("app.report.send_report_to_user.export_finished", map[string]string{"Link": a.GetSiteURL() + "/api/v4/reports/export/" + jobId + "?format=" + format}),
Type: model.PostTypeAdminReport,
UserId: systemBot.UserId,
Props: model.StringInterface{
"reportId": jobId,
"format": format,
},
Message: T("app.report.send_report_to_user.export_finished", map[string]string{
"DateRange": getTranslatedDateRange(dateRange),
}),
Type: model.PostTypeDefault,
UserId: systemBot.UserId,
FileIds: []string{fileInfo.Id},
}
_, err = a.CreatePost(rctx, post, channel, false, true)
@@ -168,13 +196,14 @@ func (a *App) GetUserCountForReport(filter *model.UserReportOptions) (*int64, *m
return &count, nil
}
func (a *App) StartUsersBatchExport(rctx request.CTX, startAt int64, endAt int64) *model.AppError {
func (a *App) StartUsersBatchExport(rctx request.CTX, dateRange string, startAt int64, endAt int64) *model.AppError {
if license := a.Srv().License(); license == nil || (license.SkuShortName != model.LicenseShortSkuProfessional && license.SkuShortName != model.LicenseShortSkuEnterprise) {
return model.NewAppError("StartUsersBatchExport", "app.report.start_users_batch_export.license_error", nil, "", http.StatusBadRequest)
}
options := map[string]string{
"requesting_user_id": rctx.Session().UserId,
"date_range": dateRange,
"start_at": strconv.FormatInt(startAt, 10),
"end_at": strconv.FormatInt(endAt, 10),
}
@@ -186,7 +215,7 @@ func (a *App) StartUsersBatchExport(rctx request.CTX, startAt int64, endAt int64
return err
}
for _, job := range pendingJobs {
if job.Data["start_at"] == options["start_at"] && job.Data["end_at"] == options["end_at"] && job.Data["requesting_user_id"] == rctx.Session().UserId {
if job.Data["date_range"] == options["date_range"] && job.Data["requesting_user_id"] == rctx.Session().UserId {
return model.NewAppError("StartUsersBatchExport", "app.report.start_users_batch_export.job_exists", nil, "", http.StatusBadRequest)
}
}
@@ -196,7 +225,7 @@ func (a *App) StartUsersBatchExport(rctx request.CTX, startAt int64, endAt int64
return err
}
for _, job := range inProgressJobs {
if job.Data["start_at"] == options["start_at"] && job.Data["end_at"] == options["end_at"] && job.Data["requesting_user_id"] == rctx.Session().UserId {
if job.Data["date_range"] == options["date_range"] && job.Data["requesting_user_id"] == rctx.Session().UserId {
return model.NewAppError("StartUsersBatchExport", "app.report.start_users_batch_export.job_exists", nil, "", http.StatusBadRequest)
}
}
@@ -219,9 +248,15 @@ func (a *App) StartUsersBatchExport(rctx request.CTX, startAt int64, endAt int64
return
}
user, err := a.GetUser(rctx.Session().UserId)
if err != nil {
rctx.Logger().Error("Failed to get the user", mlog.Err(err))
return
}
T := i18n.GetUserTranslations(user.Locale)
post := &model.Post{
ChannelId: channel.Id,
Message: i18n.T("app.report.start_users_batch_export.started_export"),
Message: T("app.report.start_users_batch_export.started_export", map[string]string{"DateRange": getTranslatedDateRange(dateRange)}),
Type: model.PostTypeDefault,
UserId: systemBot.UserId,
}
@@ -234,16 +269,15 @@ func (a *App) StartUsersBatchExport(rctx request.CTX, startAt int64, endAt int64
return nil
}
func (a *App) RetrieveBatchReport(reportID string, format string) (filestore.ReadCloseSeeker, string, *model.AppError) {
if license := a.Srv().License(); license == nil || (license.SkuShortName != model.LicenseShortSkuProfessional && license.SkuShortName != model.LicenseShortSkuEnterprise) {
return nil, "", model.NewAppError("RetrieveBatchReport", "app.report.retrieve_batch_report.license_error", nil, "", http.StatusBadRequest)
func getTranslatedDateRange(dateRange string) string {
switch dateRange {
case model.ReportDurationLast30Days:
return i18n.T("app.report.date_range.last_30_days")
case model.ReportDurationPreviousMonth:
return i18n.T("app.report.date_range.previous_month")
case model.ReportDurationLast6Months:
return i18n.T("app.report.date_range.last_6_months")
default:
return i18n.T("app.report.date_range.all_time")
}
filePath := makeCompiledFilePath(reportID, format)
reader, err := a.FileReader(filePath)
if err != nil {
return nil, "", err
}
return reader, makeCompiledFilename(reportID, format), nil
}