Merge branch 'master' into MM-50966-in-product-expansion-backend

Этот коммит содержится в:
Conor Macpherson
2023-04-17 15:39:37 -04:00
родитель de3ada24dc 3f022e728f
Коммит a47c3cf859
229 изменённых файлов: 5793 добавлений и 4904 удалений

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

@@ -190,6 +190,8 @@ func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) {
s["CanReceiveNotifications"] = c.App.SendTestPushNotification(deviceID)
}
s["ActiveSearchBackend"] = c.App.ActiveSearchBackend()
if s[model.STATUS] != model.StatusOk {
w.WriteHeader(http.StatusInternalServerError)
}
@@ -295,7 +297,7 @@ func databaseRecycle(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
c.App.RecycleDatabaseConnection()
c.App.RecycleDatabaseConnection(c.AppContext)
auditRec.Success()
ReturnStatusOK(w)
@@ -348,7 +350,7 @@ func queryLogs(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
logs, logerr := c.App.QueryLogs(c.Params.Page, c.Params.LogsPerPage, logFilter)
logs, logerr := c.App.QueryLogs(c.AppContext, c.Params.Page, c.Params.LogsPerPage, logFilter)
if logerr != nil {
c.Err = logerr
return
@@ -387,7 +389,7 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
lines, appErr := c.App.GetLogs(c.Params.Page, c.Params.LogsPerPage)
lines, appErr := c.App.GetLogs(c.AppContext, c.Params.Page, c.Params.LogsPerPage)
if appErr != nil {
c.Err = appErr
return

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

@@ -117,6 +117,11 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if team.SchemeId != nil && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteUserManagementPermissions) {
c.SetPermissionError(model.PermissionSysconsoleWriteUserManagementPermissions)
return
}
rteam, err := c.App.CreateTeamWithUser(c.AppContext, &team, c.AppContext.Session().UserId)
if err != nil {
c.Err = err

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

@@ -95,6 +95,39 @@ func TestCreateTeam(t *testing.T) {
CheckForbiddenStatus(t, resp)
})
t.Run("should verify user permissions during team creation", func(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicense("custom_permissions_schemes"))
th.App.SetPhase2PermissionsMigrationStatus(true)
sc := th.SystemAdminClient
scheme, _, err := sc.CreateScheme(&model.Scheme{
DisplayName: "dn_" + model.NewId(),
Name: model.NewId(),
Scope: model.SchemeScopeTeam,
})
require.NoError(t, err)
team, _, err := sc.CreateTeam(&model.Team{
DisplayName: "dn_" + model.NewId(),
Name: GenerateTestTeamName(),
Email: th.GenerateTestEmail(),
Type: model.TeamOpen,
SchemeId: &scheme.Id,
})
require.NoError(t, err)
require.Equal(t, scheme.Id, *team.SchemeId)
_, r, err := th.Client.CreateTeam(&model.Team{
DisplayName: "dn_" + model.NewId(),
Name: GenerateTestTeamName(),
Email: th.GenerateTestEmail(),
Type: model.TeamOpen,
SchemeId: &scheme.Id,
})
require.Error(t, err)
CheckForbiddenStatus(t, r)
})
t.Run("should take under consideration the server language when creating a new team", func(t *testing.T) {
c := th.SystemAdminClient
cfg, _, err := c.GetConfig()

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

@@ -11,17 +11,17 @@ import (
"time"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/server/channels/app/request"
"github.com/mattermost/mattermost-server/v6/server/platform/services/cache"
"github.com/mattermost/mattermost-server/v6/server/platform/shared/i18n"
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mail"
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
)
var latestVersionCache = cache.NewLRU(cache.LRUOptions{
Size: 1,
})
func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) {
func (s *Server) GetLogs(c request.CTX, page, perPage int) ([]string, *model.AppError) {
var lines []string
license := s.License()
@@ -33,7 +33,7 @@ func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) {
lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
} else {
mlog.Error("Could not get cluster info")
c.Logger().Error("Could not get cluster info")
}
}
@@ -56,7 +56,7 @@ func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) {
return lines, nil
}
func (s *Server) QueryLogs(page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
func (s *Server) QueryLogs(c request.CTX, page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
logData := make(map[string][]string)
serverName := "default"
@@ -66,7 +66,7 @@ func (s *Server) QueryLogs(page, perPage int, logFilter *model.LogFilter) (map[s
if info := s.platform.Cluster().GetMyClusterInfo(); info != nil {
serverName = info.Hostname
} else {
mlog.Error("Could not get cluster info")
c.Logger().Error("Could not get cluster info")
}
}
@@ -111,12 +111,12 @@ func AddLocalLogs(logData map[string][]string, s *Server, page, perPage int, ser
return nil
}
func (a *App) QueryLogs(page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
return a.Srv().QueryLogs(page, perPage, logFilter)
func (a *App) QueryLogs(c request.CTX, page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
return a.Srv().QueryLogs(c, page, perPage, logFilter)
}
func (a *App) GetLogs(page, perPage int) ([]string, *model.AppError) {
return a.Srv().GetLogs(page, perPage)
func (a *App) GetLogs(c request.CTX, page, perPage int) ([]string, *model.AppError) {
return a.Srv().GetLogs(c, page, perPage)
}
func (s *Server) GetLogsSkipSend(page, perPage int, logFilter *model.LogFilter) ([]string, *model.AppError) {
@@ -146,15 +146,15 @@ func (s *Server) InvalidateAllCachesSkipSend() {
}
func (a *App) RecycleDatabaseConnection() {
mlog.Info("Attempting to recycle database connections.")
func (a *App) RecycleDatabaseConnection(c request.CTX) {
c.Logger().Info("Attempting to recycle database connections.")
// This works by setting 10 seconds as the max conn lifetime for all DB connections.
// This allows in gradually closing connections as they expire. In future, we can think
// of exposing this as a param from the REST api.
a.Srv().Store().RecycleDBConnections(10 * time.Second)
mlog.Info("Finished recycling database connections.")
c.Logger().Info("Finished recycling database connections.")
}
func (a *App) TestSiteURL(siteURL string) *model.AppError {

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

@@ -264,8 +264,6 @@ type AppIface interface {
// MoveChannel method is prone to data races if someone joins to channel during the move process. However this
// function is only exposed to sysadmins and the possibility of this edge case is relatively small.
MoveChannel(c request.CTX, team *model.Team, channel *model.Channel, user *model.User) *model.AppError
// NewWebConn returns a new WebConn instance.
NewWebConn(cfg *platform.WebConnConfig) *platform.WebConn
// NotifySessionsExpired is called periodically from the job server to notify any mobile sessions that have expired.
NotifySessionsExpired() error
// OverrideIconURLIfEmoji changes the post icon override URL prop, if it has an emoji icon,
@@ -402,6 +400,7 @@ type AppIface interface {
VerifyPlugin(plugin, signature io.ReadSeeker) *model.AppError
AccountMigration() einterfaces.AccountMigrationInterface
ActivateMfa(userID, token string) *model.AppError
ActiveSearchBackend() string
AddChannelsToRetentionPolicy(policyID string, channelIDs []string) *model.AppError
AddConfigListener(listener func(*model.Config, *model.Config)) string
AddDirectChannels(c request.CTX, teamID string, user *model.User) *model.AppError
@@ -682,7 +681,7 @@ type AppIface interface {
GetJobsPage(page int, perPage int) ([]*model.Job, *model.AppError)
GetLatestTermsOfService() (*model.TermsOfService, *model.AppError)
GetLatestVersion(latestVersionUrl string) (*model.GithubReleaseInfo, *model.AppError)
GetLogs(page, perPage int) ([]string, *model.AppError)
GetLogs(c request.CTX, page, perPage int) ([]string, *model.AppError)
GetLogsSkipSend(page, perPage int, logFilter *model.LogFilter) ([]string, *model.AppError)
GetMemberCountsByGroup(ctx context.Context, channelID string, includeTimezones bool) ([]*model.ChannelMemberCountByGroup, *model.AppError)
GetMessageForNotification(post *model.Post, translateFunc i18n.TranslateFunc) string
@@ -961,9 +960,9 @@ type AppIface interface {
PublishUserTyping(userID, channelID, parentId string) *model.AppError
PurgeBleveIndexes() *model.AppError
PurgeElasticsearchIndexes() *model.AppError
QueryLogs(page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError)
QueryLogs(c request.CTX, page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError)
ReadFile(path string) ([]byte, *model.AppError)
RecycleDatabaseConnection()
RecycleDatabaseConnection(c request.CTX)
RegenCommandToken(cmd *model.Command) (*model.Command, *model.AppError)
RegenOutgoingWebhookToken(hook *model.OutgoingWebhook) (*model.OutgoingWebhook, *model.AppError)
RegenerateOAuthAppSecret(app *model.OAuthApp) (*model.OAuthApp, *model.AppError)

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

@@ -89,6 +89,23 @@ func (a *OpenTracingAppLayer) ActivateMfa(userID string, token string) *model.Ap
return resultVar0
}
func (a *OpenTracingAppLayer) ActiveSearchBackend() string {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.ActiveSearchBackend")
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.ActiveSearchBackend()
return resultVar0
}
func (a *OpenTracingAppLayer) AddChannelMember(c request.CTX, userID string, channel *model.Channel, opts app.ChannelMemberOpts) (*model.ChannelMember, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.AddChannelMember")
@@ -7111,7 +7128,7 @@ func (a *OpenTracingAppLayer) GetLdapGroup(ldapGroupID string) (*model.Group, *m
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetLogs(page int, perPage int) ([]string, *model.AppError) {
func (a *OpenTracingAppLayer) GetLogs(c request.CTX, page int, perPage int) ([]string, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetLogs")
@@ -7123,7 +7140,7 @@ func (a *OpenTracingAppLayer) GetLogs(page int, perPage int) ([]string, *model.A
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.GetLogs(page, perPage)
resultVar0, resultVar1 := a.app.GetLogs(c, page, perPage)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
@@ -12761,23 +12778,6 @@ func (a *OpenTracingAppLayer) NewPluginAPI(c *request.Context, manifest *model.M
return resultVar0
}
func (a *OpenTracingAppLayer) NewWebConn(cfg *platform.WebConnConfig) *platform.WebConn {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.NewWebConn")
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.NewWebConn(cfg)
return resultVar0
}
func (a *OpenTracingAppLayer) NotifyAndSetWarnMetricAck(warnMetricId string, sender *model.User, forceAck bool, isBot bool) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.NotifyAndSetWarnMetricAck")
@@ -13624,7 +13624,7 @@ func (a *OpenTracingAppLayer) PurgeElasticsearchIndexes() *model.AppError {
return resultVar0
}
func (a *OpenTracingAppLayer) QueryLogs(page int, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
func (a *OpenTracingAppLayer) QueryLogs(c request.CTX, page int, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.QueryLogs")
@@ -13636,7 +13636,7 @@ func (a *OpenTracingAppLayer) QueryLogs(page int, perPage int, logFilter *model.
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.QueryLogs(page, perPage, logFilter)
resultVar0, resultVar1 := a.app.QueryLogs(c, page, perPage, logFilter)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
@@ -13668,7 +13668,7 @@ func (a *OpenTracingAppLayer) ReadFile(path string) ([]byte, *model.AppError) {
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) RecycleDatabaseConnection() {
func (a *OpenTracingAppLayer) RecycleDatabaseConnection(c request.CTX) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RecycleDatabaseConnection")
@@ -13680,7 +13680,7 @@ func (a *OpenTracingAppLayer) RecycleDatabaseConnection() {
}()
defer span.Finish()
a.app.RecycleDatabaseConnection()
a.app.RecycleDatabaseConnection(c)
}
func (a *OpenTracingAppLayer) RegenCommandToken(cmd *model.Command) (*model.Command, *model.AppError) {

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

@@ -352,7 +352,7 @@ func (ch *Channels) syncPlugins() *model.AppError {
}
mlog.Info("Syncing plugin from file store", mlog.String("bundle", plugin.path))
if _, err := ch.installPluginLocally(reader, signature, installPluginLocallyAlways); err != nil {
if _, err := ch.installPluginLocally(reader, signature, installPluginLocallyAlways); err != nil && err.Id != "app.plugin.blocked.app_error" && err.Id != "app.plugin.skip_installation.app_error" {
mlog.Error("Failed to sync plugin from file store", mlog.String("bundle", plugin.path), mlog.Err(err))
}
}(plugin)
@@ -952,6 +952,11 @@ func (ch *Channels) processPrepackagedPlugins(pluginsDir string) []*plugin.Prepa
defer wg.Done()
p, err := ch.processPrepackagedPlugin(psPath)
if err != nil {
var appErr *model.AppError
// A log line already appears if the plugin is on the blocklist
if errors.As(err, &appErr) && (appErr.Id == "app.plugin.blocked.app_error" || appErr.Id == "app.plugin.skip_installation.app_error") {
return
}
mlog.Error("Failed to install prepackaged plugin", mlog.String("path", psPath.path), mlog.Err(err))
return
}

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

@@ -92,7 +92,10 @@ func (ch *Channels) installPluginFromData(data model.PluginEventData) {
manifest, appErr := ch.installPluginLocally(reader, signature, installPluginLocallyAlways)
if appErr != nil {
mlog.Error("Failed to sync plugin from file store", mlog.String("bundle", plugin.path), mlog.Err(appErr))
// A log line already appears if the plugin is on the blocklist or skipped
if appErr.Id != "app.plugin.blocked.app_error" && appErr.Id != "app.plugin.skip_installation.app_error" {
mlog.Error("Failed to sync plugin from file store", mlog.String("bundle", plugin.path), mlog.Err(appErr))
}
return
}
@@ -330,8 +333,8 @@ func (ch *Channels) installExtractedPlugin(manifest *model.Manifest, fromPluginD
// Check plugin id is not blocked
if plugin.PluginIDIsBlocked(manifest.Id) {
mlog.Debug("Skipping installation of plugin since plugin is on blocklist", mlog.String("plugin_id", manifest.Id))
return nil, nil
mlog.Debug("Skipping installation of plugin since plugin is on blocklist. Some plugins are blocked because they are built into this version of Mattermost.", mlog.String("plugin_id", manifest.Id))
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.blocked.app_error", map[string]any{"Id": manifest.Id}, "", http.StatusInternalServerError)
}
// Check for plugins installed with the same ID.
@@ -365,7 +368,7 @@ func (ch *Channels) installExtractedPlugin(manifest *model.Manifest, fromPluginD
if version.LTE(existingVersion) {
mlog.Debug("Skipping local installation of plugin since existing version is newer", mlog.String("plugin_id", manifest.Id))
return nil, nil
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.skip_installation.app_error", map[string]any{"Id": manifest.Id}, "", http.StatusInternalServerError)
}
}

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

@@ -172,10 +172,9 @@ func TestInstallPluginLocally(t *testing.T) {
defer th.TearDown()
cleanExistingBundles(t, th)
manifest, appErr := installPlugin(t, th, "playbooks", "0.0.1", installPluginLocallyAlways)
require.Nil(t, appErr)
require.Nil(t, manifest)
_, appErr := installPlugin(t, th, "playbooks", "0.0.1", installPluginLocallyAlways)
require.NotNil(t, appErr)
require.Equal(t, "app.plugin.blocked.app_error", appErr.Id)
assertBundleInfoManifests(t, th, []*model.Manifest{})
})
@@ -222,9 +221,9 @@ func TestInstallPluginLocally(t *testing.T) {
require.Nil(t, appErr)
require.NotNil(t, existingManifest)
manifest, appErr := installPlugin(t, th, "valid", "0.0.1", installPluginLocallyOnlyIfNewOrUpgrade)
require.Nil(t, appErr)
require.Nil(t, manifest)
_, appErr = installPlugin(t, th, "valid", "0.0.1", installPluginLocallyOnlyIfNewOrUpgrade)
require.NotNil(t, appErr)
require.Equal(t, "app.plugin.skip_installation.app_error", appErr.Id)
assertBundleInfoManifests(t, th, []*model.Manifest{existingManifest})
})
@@ -238,9 +237,9 @@ func TestInstallPluginLocally(t *testing.T) {
require.Nil(t, appErr)
require.NotNil(t, existingManifest)
manifest, appErr := installPlugin(t, th, "valid", "0.0.2", installPluginLocallyOnlyIfNewOrUpgrade)
require.Nil(t, appErr)
require.Nil(t, manifest)
_, appErr = installPlugin(t, th, "valid", "0.0.2", installPluginLocallyOnlyIfNewOrUpgrade)
require.NotNil(t, appErr)
require.Equal(t, "app.plugin.skip_installation.app_error", appErr.Id)
assertBundleInfoManifests(t, th, []*model.Manifest{existingManifest})
})

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

@@ -60,3 +60,7 @@ func (a *App) PurgeBleveIndexes() *model.AppError {
}
return nil
}
func (a *App) ActiveSearchBackend() string {
return a.ch.srv.platform.SearchEngine.ActiveEngine()
}

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

@@ -260,8 +260,17 @@ func NewServer(options ...Option) (*Server, error) {
product.CommandKey: app,
}
// Step 4: Initialize products.
// Depends on s.httpService.
// It is important to initialize the hub only after the global logger is set
// to avoid race conditions while logging from inside the hub.
// Step 4: Start platform
s.platform.Start()
// NOTE: There should be no call to App.Srv().Channels() before step 5 is done
// otherwise it will throw a panic.
// Step 5: Initialize products.
// Depends on s.httpService, and depends on the hub to be initialized.
// Otherwise we run into race conditions.
err = s.initializeProducts(product.GetProducts(), serviceMap)
if err != nil {
return nil, errors.Wrap(err, "failed to initialize products")
@@ -275,11 +284,6 @@ func NewServer(options ...Option) (*Server, error) {
}
app.ch = channelsWrapper.app.ch
// It is important to initialize the hub only after the global logger is set
// to avoid race conditions while logging from inside the hub.
// Step 5: Start hub in platform which the hub depends on s.Channels() (step 4)
s.platform.Start()
// -------------------------------------------------------------------------
// Everything below this is not order sensitive and safe to be moved around.
// If you are adding a new field that is non-channels specific, please add

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

@@ -13,8 +13,3 @@ import (
func (a *App) PopulateWebConnConfig(s *model.Session, cfg *platform.WebConnConfig, seqVal string) (*platform.WebConnConfig, error) {
return a.Srv().Platform().PopulateWebConnConfig(s, cfg, seqVal)
}
// NewWebConn returns a new WebConn instance.
func (a *App) NewWebConn(cfg *platform.WebConnConfig) *platform.WebConn {
return a.Srv().Platform().NewWebConn(cfg, a, a.ch)
}

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

@@ -10,7 +10,7 @@ import (
"regexp"
"strings"
pbclient "github.com/mattermost/mattermost-plugin-playbooks/client"
pbclient "github.com/mattermost/mattermost-server/v6/server/playbooks/client"
fb_model "github.com/mattermost/mattermost-server/v6/server/boards/model"

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

@@ -17,7 +17,7 @@ import (
"github.com/mattermost/mattermost-server/v6/server/channels/app/request"
"github.com/mattermost/mattermost-server/v6/server/channels/app/worktemplates"
pbclient "github.com/mattermost/mattermost-plugin-playbooks/client"
pbclient "github.com/mattermost/mattermost-server/v6/server/playbooks/client"
)
func TestGetWorkTemplateCategories(t *testing.T) {

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

@@ -6,7 +6,7 @@ import (
"errors"
"net/http"
pbclient "github.com/mattermost/mattermost-plugin-playbooks/client"
pbclient "github.com/mattermost/mattermost-server/v6/server/playbooks/client"
"github.com/mattermost/mattermost-server/v6/model"
)

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

@@ -10,7 +10,7 @@ import (
"github.com/mattermost/mattermost-server/v6/model"
pbclient "github.com/mattermost/mattermost-plugin-playbooks/client"
pbclient "github.com/mattermost/mattermost-server/v6/server/playbooks/client"
)
func TestCanBeExecuted(t *testing.T) {