Merge branch 'master' into MM-50966-in-product-expansion-backend
Этот коммит содержится в:
@@ -157,11 +157,6 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
*cfg.PluginSettings.MarketplaceURL = *appCfg.PluginSettings.MarketplaceURL
|
||||
}
|
||||
|
||||
if cfg.PluginSettings.PluginStates[model.PluginIdFocalboard].Enable && cfg.FeatureFlags.BoardsProduct {
|
||||
c.Err = model.NewAppError("EnablePlugin", "app.plugin.product_mode.app_error", map[string]any{"Name": model.PluginIdFocalboard}, "", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// There are some settings that cannot be changed in a cloud env
|
||||
if c.App.Channels().License().IsCloud() {
|
||||
// Both of them cannot be nil since cfg.SetDefaults is called earlier for cfg,
|
||||
|
||||
@@ -11,8 +11,6 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -26,8 +24,6 @@ import (
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
)
|
||||
|
||||
const serverInactivityHours = 100
|
||||
|
||||
// Returns category if enabled is true (default false)
|
||||
// If "" is returned when enabled is false, the category headers aren't attached to the email
|
||||
func getSendGridCategory(category string, enabled bool) string {
|
||||
@@ -948,48 +944,6 @@ func (es *Service) CreateVerifyEmailToken(userID string, newEmail string) (*mode
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (es *Service) SendLicenseInactivityEmail(email, name, locale, siteURL string) error {
|
||||
T := i18n.GetUserTranslations(locale)
|
||||
subject := T("api.templates.server_inactivity_subject")
|
||||
data := es.NewEmailTemplateData(locale)
|
||||
data.Props["SiteURL"] = siteURL
|
||||
data.Props["Title"] = T("api.templates.server_inactivity_title")
|
||||
data.Props["SubTitle"] = T("api.templates.server_inactivity_subtitle", map[string]any{"Name": name})
|
||||
data.Props["InfoBullet"] = T("api.templates.server_inactivity_info_bullet")
|
||||
data.Props["InfoBullet1"] = T("api.templates.server_inactivity_info_bullet1")
|
||||
data.Props["InfoBullet2"] = T("api.templates.server_inactivity_info_bullet2")
|
||||
data.Props["Info"] = T("api.templates.server_inactivity_info")
|
||||
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
|
||||
data.Props["QuestionTitle"] = T("api.templates.questions_footer.title")
|
||||
data.Props["QuestionInfo"] = T("api.templates.questions_footer.info")
|
||||
data.Props["Button"] = T("api.templates.server_inactivity_button")
|
||||
data.Props["SupportEmail"] = "feedback@mattermost.com"
|
||||
data.Props["ButtonURL"] = siteURL
|
||||
data.Props["Channels"] = T("Channels")
|
||||
data.Props["Playbooks"] = T("Playbooks")
|
||||
data.Props["Boards"] = T("Boards")
|
||||
|
||||
inactivityDurationHoursEnv := os.Getenv("MM_INACTIVITY_DURATION")
|
||||
inactivityDurationHours, parseError := strconv.ParseFloat(inactivityDurationHoursEnv, 64)
|
||||
if parseError != nil {
|
||||
// default to 100 hours
|
||||
inactivityDurationHours = serverInactivityHours
|
||||
}
|
||||
|
||||
data.Props["FooterDisclaimer"] = T("api.templates.server_inactivity_footer_disclaimer", map[string]any{"Hours": inactivityDurationHours})
|
||||
|
||||
body, err := es.templatesContainer.RenderToString("inactivity_body", data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := es.sendMail(email, subject, body, "LicenseInactivityEmail"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *Service) SendLicenseUpForRenewalEmail(email, name, locale, siteURL, ctaTitle, ctaLink, ctaText string, daysToExpiration int) error {
|
||||
T := i18n.GetUserTranslations(locale)
|
||||
subject := T("api.templates.license_up_for_renewal_subject")
|
||||
|
||||
@@ -408,7 +408,6 @@ func TestMailServiceConfig(t *testing.T) {
|
||||
LoginButtonColor: new(string),
|
||||
LoginButtonBorderColor: new(string),
|
||||
LoginButtonTextColor: new(string),
|
||||
EnableInactivityEmail: new(bool),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -344,20 +344,6 @@ func (_m *ServiceInterface) SendInviteEmailsToTeamAndChannels(team *model.Team,
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SendLicenseInactivityEmail provides a mock function with given fields: _a0, name, locale, siteURL
|
||||
func (_m *ServiceInterface) SendLicenseInactivityEmail(_a0 string, name string, locale string, siteURL string) error {
|
||||
ret := _m.Called(_a0, name, locale, siteURL)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, string) error); ok {
|
||||
r0 = rf(_a0, name, locale, siteURL)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SendLicenseUpForRenewalEmail provides a mock function with given fields: _a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration
|
||||
func (_m *ServiceInterface) SendLicenseUpForRenewalEmail(_a0 string, name string, locale string, siteURL string, ctaTitle string, ctaLink string, ctaText string, daysToExpiration int) error {
|
||||
ret := _m.Called(_a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration)
|
||||
|
||||
@@ -163,7 +163,6 @@ type ServiceInterface interface {
|
||||
InitEmailBatching()
|
||||
SendChangeUsernameEmail(newUsername, email, locale, siteURL string) error
|
||||
CreateVerifyEmailToken(userID string, newEmail string) (*model.Token, error)
|
||||
SendLicenseInactivityEmail(email, name, locale, siteURL string) error
|
||||
Stop()
|
||||
}
|
||||
|
||||
|
||||
@@ -27,15 +27,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
sendQueueSize = 256
|
||||
sendSlowWarn = (sendQueueSize * 50) / 100
|
||||
sendFullWarn = (sendQueueSize * 95) / 100
|
||||
writeWaitTime = 30 * time.Second
|
||||
pongWaitTime = 100 * time.Second
|
||||
pingInterval = (pongWaitTime * 6) / 10
|
||||
authCheckInterval = 5 * time.Second
|
||||
webConnMemberCacheTime = 1000 * 60 * 30 // 30 minutes
|
||||
deadQueueSize = 128 // Approximated from /proc/sys/net/core/wmem_default / 2048 (avg msg size)
|
||||
sendQueueSize = 256
|
||||
sendSlowWarn = (sendQueueSize * 50) / 100
|
||||
sendFullWarn = (sendQueueSize * 95) / 100
|
||||
writeWaitTime = 30 * time.Second
|
||||
pongWaitTime = 100 * time.Second
|
||||
pingInterval = (pongWaitTime * 6) / 10
|
||||
authCheckInterval = 5 * time.Second
|
||||
webConnMemberCacheTime = 1000 * 60 * 30 // 30 minutes
|
||||
deadQueueSize = 128 // Approximated from /proc/sys/net/core/wmem_default / 2048 (avg msg size)
|
||||
websocketSuppressWarnThreshold = time.Minute
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -112,6 +113,13 @@ type WebConn struct {
|
||||
endWritePump chan struct{}
|
||||
pumpFinished chan struct{}
|
||||
pluginPosted chan pluginWSPostedHook
|
||||
|
||||
// These counters are to suppress spammy websocket.slow
|
||||
// and websocket.full logs which happen continuously, if they
|
||||
// do happen. To improve the situation, we log them only once
|
||||
// per minute.
|
||||
lastLogTimeSlow time.Time
|
||||
lastLogTimeFull time.Time
|
||||
}
|
||||
|
||||
// CheckConnResult indicates whether a connectionID was present in the hub or not.
|
||||
@@ -215,6 +223,8 @@ func (ps *PlatformService) NewWebConn(cfg *WebConnConfig, suite SuiteIFace, runn
|
||||
endWritePump: make(chan struct{}),
|
||||
pumpFinished: make(chan struct{}),
|
||||
pluginPosted: make(chan pluginWSPostedHook, 10),
|
||||
lastLogTimeSlow: time.Now(),
|
||||
lastLogTimeFull: time.Now(),
|
||||
}
|
||||
|
||||
wc.SetSession(&cfg.Session)
|
||||
@@ -460,7 +470,7 @@ func (wc *WebConn) writePump() {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(wc.send) >= sendFullWarn {
|
||||
if len(wc.send) >= sendFullWarn && time.Since(wc.lastLogTimeFull) > websocketSuppressWarnThreshold {
|
||||
logData := []mlog.Field{
|
||||
mlog.String("user_id", wc.UserId),
|
||||
mlog.String("type", msg.EventType()),
|
||||
@@ -471,6 +481,7 @@ func (wc *WebConn) writePump() {
|
||||
}
|
||||
|
||||
mlog.Warn("websocket.full", logData...)
|
||||
wc.lastLogTimeFull = time.Now()
|
||||
}
|
||||
|
||||
if evtOk {
|
||||
@@ -711,11 +722,15 @@ func (wc *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
|
||||
case model.WebsocketEventTyping,
|
||||
model.WebsocketEventStatusChange,
|
||||
model.WebsocketEventChannelViewed:
|
||||
mlog.Warn(
|
||||
"websocket.slow: dropping message",
|
||||
mlog.String("user_id", wc.UserId),
|
||||
mlog.String("type", msg.EventType()),
|
||||
)
|
||||
if time.Since(wc.lastLogTimeSlow) > websocketSuppressWarnThreshold {
|
||||
mlog.Warn(
|
||||
"websocket.slow: dropping message",
|
||||
mlog.String("user_id", wc.UserId),
|
||||
mlog.String("type", msg.EventType()),
|
||||
)
|
||||
// Reset timer to now.
|
||||
wc.lastLogTimeSlow = time.Now()
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,7 +484,6 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
s.Go(func() {
|
||||
appInstance := New(ServerConnector(s.Channels()))
|
||||
s.runLicenseExpirationCheckJob()
|
||||
s.runInactivityCheckJob()
|
||||
runDNDStatusExpireJob(appInstance)
|
||||
runPostReminderJob(appInstance)
|
||||
})
|
||||
@@ -1198,12 +1197,6 @@ func runConfigCleanupJob(s *Server) {
|
||||
}, time.Hour*24)
|
||||
}
|
||||
|
||||
func (s *Server) runInactivityCheckJob() {
|
||||
model.CreateRecurringTask("Server inactivity Check", func() {
|
||||
s.doInactivityCheck()
|
||||
}, time.Hour*24)
|
||||
}
|
||||
|
||||
func (s *Server) runLicenseExpirationCheckJob() {
|
||||
s.doLicenseExpirationCheck()
|
||||
model.CreateRecurringTask("License Expiration Check", func() {
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
)
|
||||
|
||||
const serverInactivityHours = 100
|
||||
const inactivityEmailSent = "INACTIVITY"
|
||||
|
||||
func (s *Server) doInactivityCheck() {
|
||||
|
||||
if *s.platform.Config().ServiceSettings.EnableDeveloper {
|
||||
mlog.Info("No activity check because developer mode is enabled")
|
||||
return
|
||||
}
|
||||
|
||||
if !*s.platform.Config().EmailSettings.EnableInactivityEmail {
|
||||
mlog.Info("No activity check because EnableInactivityEmail is false")
|
||||
return
|
||||
}
|
||||
|
||||
if !s.platform.Config().FeatureFlags.EnableInactivityCheckJob {
|
||||
mlog.Info("No activity check because EnableInactivityCheckJob feature flag is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
_, sysValErr := s.Store().System().GetByName(inactivityEmailSent)
|
||||
// if there is no error which may include *store.ErrNotFound, it means this check was already flagged as done
|
||||
if sysValErr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
inactivityDurationHoursEnv := os.Getenv("MM_INACTIVITY_DURATION")
|
||||
inactivityDurationHours, parseError := strconv.ParseFloat(inactivityDurationHoursEnv, 64)
|
||||
if parseError != nil {
|
||||
// default to 100 hours
|
||||
inactivityDurationHours = serverInactivityHours
|
||||
}
|
||||
|
||||
// The first time this job runs. We check if the user has not made any posts in last inactivityDurationHours
|
||||
// and remind them to use the workspace. If no posts have been made. We check the last time
|
||||
// they logged in (session) for the last inactivityDurationHours and send a reminder.
|
||||
lastPostAt, _ := s.Store().Post().GetLastPostRowCreateAt()
|
||||
if lastPostAt != 0 {
|
||||
posT := time.Unix(lastPostAt/1000, 0)
|
||||
timeForLastPost := time.Since(posT).Hours()
|
||||
if timeForLastPost > inactivityDurationHours {
|
||||
s.takeInactivityAction()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
lastSessionAt, _ := s.Store().Session().GetLastSessionRowCreateAt()
|
||||
if lastSessionAt != 0 {
|
||||
sesT := time.Unix(lastSessionAt/1000, 0)
|
||||
timeForLastSession := time.Since(sesT).Hours()
|
||||
if timeForLastSession > inactivityDurationHours {
|
||||
s.takeInactivityAction()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) takeInactivityAction() {
|
||||
siteURL := *s.platform.Config().ServiceSettings.SiteURL
|
||||
if siteURL == "" {
|
||||
mlog.Warn("No SiteURL configured")
|
||||
}
|
||||
|
||||
properties := map[string]any{
|
||||
"SiteURL": siteURL,
|
||||
}
|
||||
s.GetTelemetryService().SendTelemetry("inactive_server", properties)
|
||||
users, err := s.Store().User().GetSystemAdminProfiles()
|
||||
if err != nil {
|
||||
mlog.Error("Failed to get system admins for inactivity check from Mattermost.")
|
||||
return
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
|
||||
// See https://go.dev/doc/faq#closures_and_goroutines for why we make this assignment
|
||||
user := user
|
||||
|
||||
if user.Email == "" {
|
||||
mlog.Error("Invalid system admin email.", mlog.String("user_email", user.Email))
|
||||
continue
|
||||
}
|
||||
|
||||
name := user.FirstName
|
||||
if name == "" {
|
||||
name = user.Username
|
||||
}
|
||||
|
||||
mlog.Debug("Sending inactivity reminder email.", mlog.String("user_email", user.Email))
|
||||
s.Go(func() {
|
||||
if err := s.EmailService.SendLicenseInactivityEmail(user.Email, name, user.Locale, siteURL); err != nil {
|
||||
mlog.Error("Error while sending inactivity reminder email.", mlog.String("user_email", user.Email), mlog.Err(err))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Mark that we sent emails.
|
||||
sysVar := &model.System{Name: inactivityEmailSent, Value: "true"}
|
||||
if err := s.Store().System().SaveOrUpdate(sysVar); err != nil {
|
||||
mlog.Error("Unable to save INACTIVITY", mlog.Err(err))
|
||||
}
|
||||
|
||||
// do some telemetry about sending the email
|
||||
s.GetTelemetryService().SendTelemetry("inactive_server_emails_sent", properties)
|
||||
}
|
||||
@@ -6057,24 +6057,6 @@ func (s *OpenTracingLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerPostStore) GetLastPostRowCreateAt() (int64, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetLastPostRowCreateAt")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.PostStore.GetLastPostRowCreateAt()
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerPostStore) GetMaxPostSize() int {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetMaxPostSize")
|
||||
@@ -8171,24 +8153,6 @@ func (s *OpenTracingLayerSessionStore) Get(ctx context.Context, sessionIDOrToken
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SessionStore.GetLastSessionRowCreateAt")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.SessionStore.GetLastSessionRowCreateAt()
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SessionStore.GetSessions")
|
||||
|
||||
@@ -6856,27 +6856,6 @@ func (s *RetryLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID strin
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerPostStore) GetLastPostRowCreateAt() (int64, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.PostStore.GetLastPostRowCreateAt()
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
if !isRepeatableError(err) {
|
||||
return result, err
|
||||
}
|
||||
tries++
|
||||
if tries >= 3 {
|
||||
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
|
||||
return result, err
|
||||
}
|
||||
timepkg.Sleep(100 * timepkg.Millisecond)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerPostStore) GetMaxPostSize() int {
|
||||
|
||||
return s.PostStore.GetMaxPostSize()
|
||||
@@ -9304,27 +9283,6 @@ func (s *RetryLayerSessionStore) Get(ctx context.Context, sessionIDOrToken strin
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.SessionStore.GetLastSessionRowCreateAt()
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
if !isRepeatableError(err) {
|
||||
return result, err
|
||||
}
|
||||
tries++
|
||||
if tries >= 3 {
|
||||
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
|
||||
return result, err
|
||||
}
|
||||
timepkg.Sleep(100 * timepkg.Millisecond)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) {
|
||||
|
||||
tries := 0
|
||||
|
||||
@@ -2300,17 +2300,6 @@ func (s *SqlPostStore) AnalyticsPostCount(options *model.PostCountOptions) (int6
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) GetLastPostRowCreateAt() (int64, error) {
|
||||
query := `SELECT CREATEAT FROM Posts ORDER BY CREATEAT DESC LIMIT 1`
|
||||
var createAt int64
|
||||
err := s.GetReplicaX().Get(&createAt, query)
|
||||
if err != nil {
|
||||
return 0, errors.Wrapf(err, "failed to get last post createat")
|
||||
}
|
||||
|
||||
return createAt, nil
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) GetPostsCreatedAt(channelId string, time int64) ([]*model.Post, error) {
|
||||
query := `SELECT * FROM Posts WHERE CreateAt = ? AND ChannelId = ?`
|
||||
|
||||
|
||||
@@ -221,17 +221,6 @@ func (me SqlSessionStore) UpdateExpiresAt(sessionId string, time int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (me *SqlSessionStore) GetLastSessionRowCreateAt() (int64, error) {
|
||||
query := `SELECT CREATEAT FROM Sessions ORDER BY CREATEAT DESC LIMIT 1`
|
||||
var createAt int64
|
||||
err := me.GetReplicaX().Get(&createAt, query)
|
||||
if err != nil {
|
||||
return 0, errors.Wrapf(err, "failed to get last session createat")
|
||||
}
|
||||
|
||||
return createAt, nil
|
||||
}
|
||||
|
||||
func (me SqlSessionStore) UpdateLastActivityAt(sessionId string, time int64) error {
|
||||
_, err := me.GetMasterX().Exec("UPDATE Sessions SET LastActivityAt = ? WHERE Id = ?", time, sessionId)
|
||||
if err != nil {
|
||||
|
||||
@@ -381,7 +381,6 @@ type PostStore interface {
|
||||
AnalyticsPostCount(options *model.PostCountOptions) (int64, error)
|
||||
ClearCaches()
|
||||
InvalidateLastPostTimeCache(channelID string)
|
||||
GetLastPostRowCreateAt() (int64, error)
|
||||
GetPostsCreatedAt(channelID string, timestamp int64) ([]*model.Post, error)
|
||||
Overwrite(post *model.Post) (*model.Post, error)
|
||||
OverwriteMultiple(posts []*model.Post) ([]*model.Post, int, error)
|
||||
@@ -510,7 +509,6 @@ type SessionStore interface {
|
||||
Remove(sessionIDOrToken string) error
|
||||
RemoveAllSessions() error
|
||||
PermanentDeleteSessionsByUser(teamID string) error
|
||||
GetLastSessionRowCreateAt() (int64, error)
|
||||
UpdateExpiresAt(sessionID string, timestamp int64) error
|
||||
UpdateLastActivityAt(sessionID string, timestamp int64) error
|
||||
UpdateRoles(userID string, roles string) (string, error)
|
||||
|
||||
@@ -277,27 +277,6 @@ func (_m *PostStore) GetFlaggedPostsForTeam(userID string, teamID string, offset
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetLastPostRowCreateAt provides a mock function with given fields:
|
||||
func (_m *PostStore) GetLastPostRowCreateAt() (int64, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 int64
|
||||
if rf, ok := ret.Get(0).(func() int64); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetMaxPostSize provides a mock function with given fields:
|
||||
func (_m *PostStore) GetMaxPostSize() int {
|
||||
ret := _m.Called()
|
||||
|
||||
@@ -74,27 +74,6 @@ func (_m *SessionStore) Get(ctx context.Context, sessionIDOrToken string) (*mode
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetLastSessionRowCreateAt provides a mock function with given fields:
|
||||
func (_m *SessionStore) GetLastSessionRowCreateAt() (int64, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 int64
|
||||
if rf, ok := ret.Get(0).(func() int64); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetSessions provides a mock function with given fields: userID
|
||||
func (_m *SessionStore) GetSessions(userID string) ([]*model.Session, error) {
|
||||
ret := _m.Called(userID)
|
||||
|
||||
@@ -43,7 +43,6 @@ func TestPostStore(t *testing.T, ss store.Store, s SqlStore) {
|
||||
t.Run("GetFlaggedPosts", func(t *testing.T) { testPostStoreGetFlaggedPosts(t, ss) })
|
||||
t.Run("GetFlaggedPostsForChannel", func(t *testing.T) { testPostStoreGetFlaggedPostsForChannel(t, ss) })
|
||||
t.Run("GetPostsCreatedAt", func(t *testing.T) { testPostStoreGetPostsCreatedAt(t, ss) })
|
||||
t.Run("GetLastPostRowCreateAt", func(t *testing.T) { testPostStoreGetLastPostRowCreateAt(t, ss) })
|
||||
t.Run("Overwrite", func(t *testing.T) { testPostStoreOverwrite(t, ss) })
|
||||
t.Run("OverwriteMultiple", func(t *testing.T) { testPostStoreOverwriteMultiple(t, ss) })
|
||||
t.Run("GetPostsByIds", func(t *testing.T) { testPostStoreGetPostsByIds(t, ss) })
|
||||
@@ -3361,40 +3360,6 @@ func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) {
|
||||
require.Len(t, r.Order, 0, "should have 0 posts")
|
||||
}
|
||||
|
||||
func testPostStoreGetLastPostRowCreateAt(t *testing.T, ss store.Store) {
|
||||
teamId := model.NewId()
|
||||
channel1, err := ss.Channel().Save(&model.Channel{
|
||||
TeamId: teamId,
|
||||
DisplayName: "DisplayName1",
|
||||
Name: "channel" + model.NewId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
createTime1 := model.GetMillis() + 1
|
||||
o0 := &model.Post{}
|
||||
o0.ChannelId = channel1.Id
|
||||
o0.UserId = model.NewId()
|
||||
o0.Message = NewTestId()
|
||||
o0.CreateAt = createTime1
|
||||
o0, err = ss.Post().Save(o0)
|
||||
require.NoError(t, err)
|
||||
|
||||
createTime2 := model.GetMillis() + 2
|
||||
|
||||
o1 := &model.Post{}
|
||||
o1.ChannelId = o0.ChannelId
|
||||
o1.UserId = model.NewId()
|
||||
o1.Message = "Latest message"
|
||||
o1.CreateAt = createTime2
|
||||
_, err = ss.Post().Save(o1)
|
||||
require.NoError(t, err)
|
||||
|
||||
createAt, err := ss.Post().GetLastPostRowCreateAt()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, createAt, createTime2)
|
||||
}
|
||||
|
||||
func testPostStoreGetPostsCreatedAt(t *testing.T, ss store.Store) {
|
||||
teamId := model.NewId()
|
||||
channel1, err := ss.Channel().Save(&model.Channel{
|
||||
|
||||
@@ -33,7 +33,6 @@ func TestSessionStore(t *testing.T, ss store.Store) {
|
||||
t.Run("SessionUpdateDeviceId2", func(t *testing.T) { testSessionUpdateDeviceId2(t, ss) })
|
||||
t.Run("UpdateExpiresAt", func(t *testing.T) { testSessionStoreUpdateExpiresAt(t, ss) })
|
||||
t.Run("UpdateLastActivityAt", func(t *testing.T) { testSessionStoreUpdateLastActivityAt(t, ss) })
|
||||
t.Run("GetLastSessionRowCreateAt", func(t *testing.T) { testSessionStoreGetLastSessionRowCreateAt(t, ss) })
|
||||
t.Run("SessionCount", func(t *testing.T) { testSessionCount(t, ss) })
|
||||
t.Run("GetSessionsExpired", func(t *testing.T) { testGetSessionsExpired(t, ss) })
|
||||
t.Run("UpdateExpiredNotify", func(t *testing.T) { testUpdateExpiredNotify(t, ss) })
|
||||
@@ -47,23 +46,6 @@ func testSessionStoreSave(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func testSessionStoreGetLastSessionRowCreateAt(t *testing.T, ss store.Store) {
|
||||
s1 := &model.Session{}
|
||||
s1.UserId = model.NewId()
|
||||
_, err := ss.Session().Save(s1)
|
||||
require.NoError(t, err)
|
||||
|
||||
latestSessionUserid := model.NewId()
|
||||
s2 := &model.Session{}
|
||||
s2.UserId = latestSessionUserid
|
||||
latestSession, err := ss.Session().Save(s2)
|
||||
require.NoError(t, err)
|
||||
|
||||
createAt, err := ss.Session().GetLastSessionRowCreateAt()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, latestSession.CreateAt, createAt)
|
||||
}
|
||||
|
||||
func testSessionGet(t *testing.T, ss store.Store) {
|
||||
s1 := &model.Session{}
|
||||
s1.UserId = model.NewId()
|
||||
|
||||
@@ -5483,22 +5483,6 @@ func (s *TimerLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID strin
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerPostStore) GetLastPostRowCreateAt() (int64, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.PostStore.GetLastPostRowCreateAt()
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("PostStore.GetLastPostRowCreateAt", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerPostStore) GetMaxPostSize() int {
|
||||
start := time.Now()
|
||||
|
||||
@@ -7370,22 +7354,6 @@ func (s *TimerLayerSessionStore) Get(ctx context.Context, sessionIDOrToken strin
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.SessionStore.GetLastSessionRowCreateAt()
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("SessionStore.GetLastSessionRowCreateAt", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) {
|
||||
start := time.Now()
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user