diff --git a/e2e-tests/cypress/tests/support/index.js b/e2e-tests/cypress/tests/support/index.js index 3a8c279606..8051dafda0 100644 --- a/e2e-tests/cypress/tests/support/index.js +++ b/e2e-tests/cypress/tests/support/index.js @@ -177,7 +177,8 @@ function printServerDetails() { - BuildHash = ${config.BuildHash} - BuildHashEnterprise = ${config.BuildHashEnterprise} - BuildEnterpriseReady = ${config.BuildEnterpriseReady} - - TelemetryId = ${config.TelemetryId}`); + - TelemetryId = ${config.TelemetryId} + - ServiceEnvironment = ${config.ServiceEnvironment}`); }); } diff --git a/e2e-tests/playwright/global_setup.ts b/e2e-tests/playwright/global_setup.ts index 53386e351f..7bd53a3aa7 100644 --- a/e2e-tests/playwright/global_setup.ts +++ b/e2e-tests/playwright/global_setup.ts @@ -97,7 +97,8 @@ async function printClientInfo(client: Client) { - BuildEnterpriseReady = ${config.BuildEnterpriseReady} - FeatureFlagAppsEnabled = ${config.FeatureFlagAppsEnabled} - FeatureFlagCallsEnabled = ${config.FeatureFlagCallsEnabled} - - TelemetryId = ${config.TelemetryId}`); + - TelemetryId = ${config.TelemetryId} + - ServiceEnvironment = ${config.ServiceEnvironment}`); } async function ensurePluginsLoaded(client: Client) { diff --git a/server/Makefile b/server/Makefile index a5a031c117..9e0de059cd 100644 --- a/server/Makefile +++ b/server/Makefile @@ -41,9 +41,6 @@ ifeq ($(DIFF), 1) GIT_TREESTATE = dirty endif -# Go tags -GOTAGS ?= $(GOTAGS:) - # Docker export COMPOSE_PROJECT_NAME=mattermost-server @@ -55,7 +52,6 @@ endif ifeq ($(BUILD_NUMBER),dev) export MM_FEATUREFLAGS_GRAPHQL = true - GOTAGS += "testlicensekey" endif # mmctl @@ -577,7 +573,7 @@ run-server: setup-go-work prepackaged-binaries validate-go-version start-docker @echo Running mattermost for development mkdir -p $(BUILD_WEBAPP_DIR)/channels/dist/files - $(GO) run $(GOFLAGS) -tags $(GOTAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) $(RUN_IN_BACKGROUND) + $(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) $(RUN_IN_BACKGROUND) debug-server: start-docker ## Compile and start server using delve. mkdir -p $(BUILD_WEBAPP_DIR)/channels/dist/files @@ -601,7 +597,7 @@ run-cli: start-docker ## Runs CLI. @echo Running mattermost for development @echo Example should be like 'make ARGS="-version" run-cli' - $(GO) run $(GOFLAGS) -tags $(GOTAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) ${ARGS} + $(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) ${ARGS} run-client: client ## Runs the webapp. @echo Running mattermost client for development @@ -661,7 +657,7 @@ restart-client: | stop-client run-client ## Restarts the webapp. run-job-server: ## Runs the background job server. @echo Running job server for development - $(GO) run $(GOFLAGS) -tags $(GOTAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) jobserver & + $(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) jobserver & config-ldap: ## Configures LDAP. @echo Setting up configuration for local LDAP diff --git a/server/boards/services/store/mockstore/mockstore.go b/server/boards/services/store/mockstore/mockstore.go index 0abf7b470e..bf38cd7291 100644 --- a/server/boards/services/store/mockstore/mockstore.go +++ b/server/boards/services/store/mockstore/mockstore.go @@ -12,8 +12,8 @@ import ( time "time" gomock "github.com/golang/mock/gomock" - model0 "github.com/mattermost/mattermost-server/server/public/model" - model "github.com/mattermost/mattermost-server/server/v8/boards/model" + model "github.com/mattermost/mattermost-server/server/public/model" + model0 "github.com/mattermost/mattermost-server/server/v8/boards/model" ) // MockStore is a mock of Store interface. @@ -83,10 +83,10 @@ func (mr *MockStoreMockRecorder) CleanUpSessions(arg0 interface{}) *gomock.Call } // CreateBoardsAndBlocks mocks base method. -func (m *MockStore) CreateBoardsAndBlocks(arg0 *model.BoardsAndBlocks, arg1 string) (*model.BoardsAndBlocks, error) { +func (m *MockStore) CreateBoardsAndBlocks(arg0 *model0.BoardsAndBlocks, arg1 string) (*model0.BoardsAndBlocks, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateBoardsAndBlocks", arg0, arg1) - ret0, _ := ret[0].(*model.BoardsAndBlocks) + ret0, _ := ret[0].(*model0.BoardsAndBlocks) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -98,11 +98,11 @@ func (mr *MockStoreMockRecorder) CreateBoardsAndBlocks(arg0, arg1 interface{}) * } // CreateBoardsAndBlocksWithAdmin mocks base method. -func (m *MockStore) CreateBoardsAndBlocksWithAdmin(arg0 *model.BoardsAndBlocks, arg1 string) (*model.BoardsAndBlocks, []*model.BoardMember, error) { +func (m *MockStore) CreateBoardsAndBlocksWithAdmin(arg0 *model0.BoardsAndBlocks, arg1 string) (*model0.BoardsAndBlocks, []*model0.BoardMember, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateBoardsAndBlocksWithAdmin", arg0, arg1) - ret0, _ := ret[0].(*model.BoardsAndBlocks) - ret1, _ := ret[1].([]*model.BoardMember) + ret0, _ := ret[0].(*model0.BoardsAndBlocks) + ret1, _ := ret[1].([]*model0.BoardMember) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } @@ -114,7 +114,7 @@ func (mr *MockStoreMockRecorder) CreateBoardsAndBlocksWithAdmin(arg0, arg1 inter } // CreateCategory mocks base method. -func (m *MockStore) CreateCategory(arg0 model.Category) error { +func (m *MockStore) CreateCategory(arg0 model0.Category) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateCategory", arg0) ret0, _ := ret[0].(error) @@ -128,7 +128,7 @@ func (mr *MockStoreMockRecorder) CreateCategory(arg0 interface{}) *gomock.Call { } // CreateSession mocks base method. -func (m *MockStore) CreateSession(arg0 *model.Session) error { +func (m *MockStore) CreateSession(arg0 *model0.Session) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSession", arg0) ret0, _ := ret[0].(error) @@ -142,10 +142,10 @@ func (mr *MockStoreMockRecorder) CreateSession(arg0 interface{}) *gomock.Call { } // CreateSubscription mocks base method. -func (m *MockStore) CreateSubscription(arg0 *model.Subscription) (*model.Subscription, error) { +func (m *MockStore) CreateSubscription(arg0 *model0.Subscription) (*model0.Subscription, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSubscription", arg0) - ret0, _ := ret[0].(*model.Subscription) + ret0, _ := ret[0].(*model0.Subscription) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -157,10 +157,10 @@ func (mr *MockStoreMockRecorder) CreateSubscription(arg0 interface{}) *gomock.Ca } // CreateUser mocks base method. -func (m *MockStore) CreateUser(arg0 *model.User) (*model.User, error) { +func (m *MockStore) CreateUser(arg0 *model0.User) (*model0.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateUser", arg0) - ret0, _ := ret[0].(*model.User) + ret0, _ := ret[0].(*model0.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -256,7 +256,7 @@ func (mr *MockStoreMockRecorder) DeleteBoardRecord(arg0, arg1 interface{}) *gomo } // DeleteBoardsAndBlocks mocks base method. -func (m *MockStore) DeleteBoardsAndBlocks(arg0 *model.DeleteBoardsAndBlocks, arg1 string) error { +func (m *MockStore) DeleteBoardsAndBlocks(arg0 *model0.DeleteBoardsAndBlocks, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DeleteBoardsAndBlocks", arg0, arg1) ret0, _ := ret[0].(error) @@ -354,10 +354,10 @@ func (mr *MockStoreMockRecorder) DropAllTables() *gomock.Call { } // DuplicateBlock mocks base method. -func (m *MockStore) DuplicateBlock(arg0, arg1, arg2 string, arg3 bool) ([]*model.Block, error) { +func (m *MockStore) DuplicateBlock(arg0, arg1, arg2 string, arg3 bool) ([]*model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DuplicateBlock", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].([]*model.Block) + ret0, _ := ret[0].([]*model0.Block) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -369,11 +369,11 @@ func (mr *MockStoreMockRecorder) DuplicateBlock(arg0, arg1, arg2, arg3 interface } // DuplicateBoard mocks base method. -func (m *MockStore) DuplicateBoard(arg0, arg1, arg2 string, arg3 bool) (*model.BoardsAndBlocks, []*model.BoardMember, error) { +func (m *MockStore) DuplicateBoard(arg0, arg1, arg2 string, arg3 bool) (*model0.BoardsAndBlocks, []*model0.BoardMember, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DuplicateBoard", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*model.BoardsAndBlocks) - ret1, _ := ret[1].([]*model.BoardMember) + ret0, _ := ret[0].(*model0.BoardsAndBlocks) + ret1, _ := ret[1].([]*model0.BoardMember) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } @@ -400,10 +400,10 @@ func (mr *MockStoreMockRecorder) GetActiveUserCount(arg0 interface{}) *gomock.Ca } // GetAllTeams mocks base method. -func (m *MockStore) GetAllTeams() ([]*model.Team, error) { +func (m *MockStore) GetAllTeams() ([]*model0.Team, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAllTeams") - ret0, _ := ret[0].([]*model.Team) + ret0, _ := ret[0].([]*model0.Team) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -415,10 +415,10 @@ func (mr *MockStoreMockRecorder) GetAllTeams() *gomock.Call { } // GetBlock mocks base method. -func (m *MockStore) GetBlock(arg0 string) (*model.Block, error) { +func (m *MockStore) GetBlock(arg0 string) (*model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBlock", arg0) - ret0, _ := ret[0].(*model.Block) + ret0, _ := ret[0].(*model0.Block) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -445,10 +445,10 @@ func (mr *MockStoreMockRecorder) GetBlockCountsByType() *gomock.Call { } // GetBlockHistory mocks base method. -func (m *MockStore) GetBlockHistory(arg0 string, arg1 model.QueryBlockHistoryOptions) ([]*model.Block, error) { +func (m *MockStore) GetBlockHistory(arg0 string, arg1 model0.QueryBlockHistoryOptions) ([]*model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBlockHistory", arg0, arg1) - ret0, _ := ret[0].([]*model.Block) + ret0, _ := ret[0].([]*model0.Block) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -460,10 +460,10 @@ func (mr *MockStoreMockRecorder) GetBlockHistory(arg0, arg1 interface{}) *gomock } // GetBlockHistoryDescendants mocks base method. -func (m *MockStore) GetBlockHistoryDescendants(arg0 string, arg1 model.QueryBlockHistoryOptions) ([]*model.Block, error) { +func (m *MockStore) GetBlockHistoryDescendants(arg0 string, arg1 model0.QueryBlockHistoryOptions) ([]*model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBlockHistoryDescendants", arg0, arg1) - ret0, _ := ret[0].([]*model.Block) + ret0, _ := ret[0].([]*model0.Block) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -475,10 +475,10 @@ func (mr *MockStoreMockRecorder) GetBlockHistoryDescendants(arg0, arg1 interface } // GetBlockHistoryNewestChildren mocks base method. -func (m *MockStore) GetBlockHistoryNewestChildren(arg0 string, arg1 model.QueryBlockHistoryChildOptions) ([]*model.Block, bool, error) { +func (m *MockStore) GetBlockHistoryNewestChildren(arg0 string, arg1 model0.QueryBlockHistoryChildOptions) ([]*model0.Block, bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBlockHistoryNewestChildren", arg0, arg1) - ret0, _ := ret[0].([]*model.Block) + ret0, _ := ret[0].([]*model0.Block) ret1, _ := ret[1].(bool) ret2, _ := ret[2].(error) return ret0, ret1, ret2 @@ -491,10 +491,10 @@ func (mr *MockStoreMockRecorder) GetBlockHistoryNewestChildren(arg0, arg1 interf } // GetBlocks mocks base method. -func (m *MockStore) GetBlocks(arg0 model.QueryBlocksOptions) ([]*model.Block, error) { +func (m *MockStore) GetBlocks(arg0 model0.QueryBlocksOptions) ([]*model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBlocks", arg0) - ret0, _ := ret[0].([]*model.Block) + ret0, _ := ret[0].([]*model0.Block) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -506,10 +506,10 @@ func (mr *MockStoreMockRecorder) GetBlocks(arg0 interface{}) *gomock.Call { } // GetBlocksByIDs mocks base method. -func (m *MockStore) GetBlocksByIDs(arg0 []string) ([]*model.Block, error) { +func (m *MockStore) GetBlocksByIDs(arg0 []string) ([]*model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBlocksByIDs", arg0) - ret0, _ := ret[0].([]*model.Block) + ret0, _ := ret[0].([]*model0.Block) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -521,10 +521,10 @@ func (mr *MockStoreMockRecorder) GetBlocksByIDs(arg0 interface{}) *gomock.Call { } // GetBlocksComplianceHistory mocks base method. -func (m *MockStore) GetBlocksComplianceHistory(arg0 model.QueryBlocksComplianceHistoryOptions) ([]*model.BlockHistory, bool, error) { +func (m *MockStore) GetBlocksComplianceHistory(arg0 model0.QueryBlocksComplianceHistoryOptions) ([]*model0.BlockHistory, bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBlocksComplianceHistory", arg0) - ret0, _ := ret[0].([]*model.BlockHistory) + ret0, _ := ret[0].([]*model0.BlockHistory) ret1, _ := ret[1].(bool) ret2, _ := ret[2].(error) return ret0, ret1, ret2 @@ -537,10 +537,10 @@ func (mr *MockStoreMockRecorder) GetBlocksComplianceHistory(arg0 interface{}) *g } // GetBoard mocks base method. -func (m *MockStore) GetBoard(arg0 string) (*model.Board, error) { +func (m *MockStore) GetBoard(arg0 string) (*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoard", arg0) - ret0, _ := ret[0].(*model.Board) + ret0, _ := ret[0].(*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -552,11 +552,11 @@ func (mr *MockStoreMockRecorder) GetBoard(arg0 interface{}) *gomock.Call { } // GetBoardAndCard mocks base method. -func (m *MockStore) GetBoardAndCard(arg0 *model.Block) (*model.Board, *model.Block, error) { +func (m *MockStore) GetBoardAndCard(arg0 *model0.Block) (*model0.Board, *model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoardAndCard", arg0) - ret0, _ := ret[0].(*model.Board) - ret1, _ := ret[1].(*model.Block) + ret0, _ := ret[0].(*model0.Board) + ret1, _ := ret[1].(*model0.Block) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } @@ -568,11 +568,11 @@ func (mr *MockStoreMockRecorder) GetBoardAndCard(arg0 interface{}) *gomock.Call } // GetBoardAndCardByID mocks base method. -func (m *MockStore) GetBoardAndCardByID(arg0 string) (*model.Board, *model.Block, error) { +func (m *MockStore) GetBoardAndCardByID(arg0 string) (*model0.Board, *model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoardAndCardByID", arg0) - ret0, _ := ret[0].(*model.Board) - ret1, _ := ret[1].(*model.Block) + ret0, _ := ret[0].(*model0.Board) + ret1, _ := ret[1].(*model0.Block) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } @@ -599,10 +599,10 @@ func (mr *MockStoreMockRecorder) GetBoardCount() *gomock.Call { } // GetBoardHistory mocks base method. -func (m *MockStore) GetBoardHistory(arg0 string, arg1 model.QueryBoardHistoryOptions) ([]*model.Board, error) { +func (m *MockStore) GetBoardHistory(arg0 string, arg1 model0.QueryBoardHistoryOptions) ([]*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoardHistory", arg0, arg1) - ret0, _ := ret[0].([]*model.Board) + ret0, _ := ret[0].([]*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -614,10 +614,10 @@ func (mr *MockStoreMockRecorder) GetBoardHistory(arg0, arg1 interface{}) *gomock } // GetBoardMemberHistory mocks base method. -func (m *MockStore) GetBoardMemberHistory(arg0, arg1 string, arg2 uint64) ([]*model.BoardMemberHistoryEntry, error) { +func (m *MockStore) GetBoardMemberHistory(arg0, arg1 string, arg2 uint64) ([]*model0.BoardMemberHistoryEntry, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoardMemberHistory", arg0, arg1, arg2) - ret0, _ := ret[0].([]*model.BoardMemberHistoryEntry) + ret0, _ := ret[0].([]*model0.BoardMemberHistoryEntry) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -629,10 +629,10 @@ func (mr *MockStoreMockRecorder) GetBoardMemberHistory(arg0, arg1, arg2 interfac } // GetBoardsComplianceHistory mocks base method. -func (m *MockStore) GetBoardsComplianceHistory(arg0 model.QueryBoardsComplianceHistoryOptions) ([]*model.BoardHistory, bool, error) { +func (m *MockStore) GetBoardsComplianceHistory(arg0 model0.QueryBoardsComplianceHistoryOptions) ([]*model0.BoardHistory, bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoardsComplianceHistory", arg0) - ret0, _ := ret[0].([]*model.BoardHistory) + ret0, _ := ret[0].([]*model0.BoardHistory) ret1, _ := ret[1].(bool) ret2, _ := ret[2].(error) return ret0, ret1, ret2 @@ -645,10 +645,10 @@ func (mr *MockStoreMockRecorder) GetBoardsComplianceHistory(arg0 interface{}) *g } // GetBoardsForCompliance mocks base method. -func (m *MockStore) GetBoardsForCompliance(arg0 model.QueryBoardsForComplianceOptions) ([]*model.Board, bool, error) { +func (m *MockStore) GetBoardsForCompliance(arg0 model0.QueryBoardsForComplianceOptions) ([]*model0.Board, bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoardsForCompliance", arg0) - ret0, _ := ret[0].([]*model.Board) + ret0, _ := ret[0].([]*model0.Board) ret1, _ := ret[1].(bool) ret2, _ := ret[2].(error) return ret0, ret1, ret2 @@ -661,10 +661,10 @@ func (mr *MockStoreMockRecorder) GetBoardsForCompliance(arg0 interface{}) *gomoc } // GetBoardsForUserAndTeam mocks base method. -func (m *MockStore) GetBoardsForUserAndTeam(arg0, arg1 string, arg2 bool) ([]*model.Board, error) { +func (m *MockStore) GetBoardsForUserAndTeam(arg0, arg1 string, arg2 bool) ([]*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoardsForUserAndTeam", arg0, arg1, arg2) - ret0, _ := ret[0].([]*model.Board) + ret0, _ := ret[0].([]*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -676,10 +676,10 @@ func (mr *MockStoreMockRecorder) GetBoardsForUserAndTeam(arg0, arg1, arg2 interf } // GetBoardsInTeamByIds mocks base method. -func (m *MockStore) GetBoardsInTeamByIds(arg0 []string, arg1 string) ([]*model.Board, error) { +func (m *MockStore) GetBoardsInTeamByIds(arg0 []string, arg1 string) ([]*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBoardsInTeamByIds", arg0, arg1) - ret0, _ := ret[0].([]*model.Board) + ret0, _ := ret[0].([]*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -706,10 +706,10 @@ func (mr *MockStoreMockRecorder) GetCardLimitTimestamp() *gomock.Call { } // GetCategory mocks base method. -func (m *MockStore) GetCategory(arg0 string) (*model.Category, error) { +func (m *MockStore) GetCategory(arg0 string) (*model0.Category, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCategory", arg0) - ret0, _ := ret[0].(*model.Category) + ret0, _ := ret[0].(*model0.Category) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -721,10 +721,10 @@ func (mr *MockStoreMockRecorder) GetCategory(arg0 interface{}) *gomock.Call { } // GetChannel mocks base method. -func (m *MockStore) GetChannel(arg0, arg1 string) (*model0.Channel, error) { +func (m *MockStore) GetChannel(arg0, arg1 string) (*model.Channel, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetChannel", arg0, arg1) - ret0, _ := ret[0].(*model0.Channel) + ret0, _ := ret[0].(*model.Channel) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -736,10 +736,10 @@ func (mr *MockStoreMockRecorder) GetChannel(arg0, arg1 interface{}) *gomock.Call } // GetCloudLimits mocks base method. -func (m *MockStore) GetCloudLimits() (*model0.ProductLimits, error) { +func (m *MockStore) GetCloudLimits() (*model.ProductLimits, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCloudLimits") - ret0, _ := ret[0].(*model0.ProductLimits) + ret0, _ := ret[0].(*model.ProductLimits) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -751,10 +751,10 @@ func (mr *MockStoreMockRecorder) GetCloudLimits() *gomock.Call { } // GetFileInfo mocks base method. -func (m *MockStore) GetFileInfo(arg0 string) (*model0.FileInfo, error) { +func (m *MockStore) GetFileInfo(arg0 string) (*model.FileInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetFileInfo", arg0) - ret0, _ := ret[0].(*model0.FileInfo) + ret0, _ := ret[0].(*model.FileInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -766,10 +766,10 @@ func (mr *MockStoreMockRecorder) GetFileInfo(arg0 interface{}) *gomock.Call { } // GetLicense mocks base method. -func (m *MockStore) GetLicense() *model0.License { +func (m *MockStore) GetLicense() *model.License { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLicense") - ret0, _ := ret[0].(*model0.License) + ret0, _ := ret[0].(*model.License) return ret0 } @@ -780,10 +780,10 @@ func (mr *MockStoreMockRecorder) GetLicense() *gomock.Call { } // GetMemberForBoard mocks base method. -func (m *MockStore) GetMemberForBoard(arg0, arg1 string) (*model.BoardMember, error) { +func (m *MockStore) GetMemberForBoard(arg0, arg1 string) (*model0.BoardMember, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetMemberForBoard", arg0, arg1) - ret0, _ := ret[0].(*model.BoardMember) + ret0, _ := ret[0].(*model0.BoardMember) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -795,10 +795,10 @@ func (mr *MockStoreMockRecorder) GetMemberForBoard(arg0, arg1 interface{}) *gomo } // GetMembersForBoard mocks base method. -func (m *MockStore) GetMembersForBoard(arg0 string) ([]*model.BoardMember, error) { +func (m *MockStore) GetMembersForBoard(arg0 string) ([]*model0.BoardMember, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetMembersForBoard", arg0) - ret0, _ := ret[0].([]*model.BoardMember) + ret0, _ := ret[0].([]*model0.BoardMember) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -810,10 +810,10 @@ func (mr *MockStoreMockRecorder) GetMembersForBoard(arg0 interface{}) *gomock.Ca } // GetMembersForUser mocks base method. -func (m *MockStore) GetMembersForUser(arg0 string) ([]*model.BoardMember, error) { +func (m *MockStore) GetMembersForUser(arg0 string) ([]*model0.BoardMember, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetMembersForUser", arg0) - ret0, _ := ret[0].([]*model.BoardMember) + ret0, _ := ret[0].([]*model0.BoardMember) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -825,10 +825,10 @@ func (mr *MockStoreMockRecorder) GetMembersForUser(arg0 interface{}) *gomock.Cal } // GetNextNotificationHint mocks base method. -func (m *MockStore) GetNextNotificationHint(arg0 bool) (*model.NotificationHint, error) { +func (m *MockStore) GetNextNotificationHint(arg0 bool) (*model0.NotificationHint, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetNextNotificationHint", arg0) - ret0, _ := ret[0].(*model.NotificationHint) + ret0, _ := ret[0].(*model0.NotificationHint) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -840,10 +840,10 @@ func (mr *MockStoreMockRecorder) GetNextNotificationHint(arg0 interface{}) *gomo } // GetNotificationHint mocks base method. -func (m *MockStore) GetNotificationHint(arg0 string) (*model.NotificationHint, error) { +func (m *MockStore) GetNotificationHint(arg0 string) (*model0.NotificationHint, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetNotificationHint", arg0) - ret0, _ := ret[0].(*model.NotificationHint) + ret0, _ := ret[0].(*model0.NotificationHint) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -870,10 +870,10 @@ func (mr *MockStoreMockRecorder) GetRegisteredUserCount() *gomock.Call { } // GetSession mocks base method. -func (m *MockStore) GetSession(arg0 string, arg1 int64) (*model.Session, error) { +func (m *MockStore) GetSession(arg0 string, arg1 int64) (*model0.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSession", arg0, arg1) - ret0, _ := ret[0].(*model.Session) + ret0, _ := ret[0].(*model0.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -885,10 +885,10 @@ func (mr *MockStoreMockRecorder) GetSession(arg0, arg1 interface{}) *gomock.Call } // GetSharing mocks base method. -func (m *MockStore) GetSharing(arg0 string) (*model.Sharing, error) { +func (m *MockStore) GetSharing(arg0 string) (*model0.Sharing, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSharing", arg0) - ret0, _ := ret[0].(*model.Sharing) + ret0, _ := ret[0].(*model0.Sharing) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -900,10 +900,10 @@ func (mr *MockStoreMockRecorder) GetSharing(arg0 interface{}) *gomock.Call { } // GetSubTree2 mocks base method. -func (m *MockStore) GetSubTree2(arg0, arg1 string, arg2 model.QuerySubtreeOptions) ([]*model.Block, error) { +func (m *MockStore) GetSubTree2(arg0, arg1 string, arg2 model0.QuerySubtreeOptions) ([]*model0.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSubTree2", arg0, arg1, arg2) - ret0, _ := ret[0].([]*model.Block) + ret0, _ := ret[0].([]*model0.Block) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -930,10 +930,10 @@ func (mr *MockStoreMockRecorder) GetSubscribersCountForBlock(arg0 interface{}) * } // GetSubscribersForBlock mocks base method. -func (m *MockStore) GetSubscribersForBlock(arg0 string) ([]*model.Subscriber, error) { +func (m *MockStore) GetSubscribersForBlock(arg0 string) ([]*model0.Subscriber, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSubscribersForBlock", arg0) - ret0, _ := ret[0].([]*model.Subscriber) + ret0, _ := ret[0].([]*model0.Subscriber) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -945,10 +945,10 @@ func (mr *MockStoreMockRecorder) GetSubscribersForBlock(arg0 interface{}) *gomoc } // GetSubscription mocks base method. -func (m *MockStore) GetSubscription(arg0, arg1 string) (*model.Subscription, error) { +func (m *MockStore) GetSubscription(arg0, arg1 string) (*model0.Subscription, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSubscription", arg0, arg1) - ret0, _ := ret[0].(*model.Subscription) + ret0, _ := ret[0].(*model0.Subscription) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -960,10 +960,10 @@ func (mr *MockStoreMockRecorder) GetSubscription(arg0, arg1 interface{}) *gomock } // GetSubscriptions mocks base method. -func (m *MockStore) GetSubscriptions(arg0 string) ([]*model.Subscription, error) { +func (m *MockStore) GetSubscriptions(arg0 string) ([]*model0.Subscription, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSubscriptions", arg0) - ret0, _ := ret[0].([]*model.Subscription) + ret0, _ := ret[0].([]*model0.Subscription) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1005,10 +1005,10 @@ func (mr *MockStoreMockRecorder) GetSystemSettings() *gomock.Call { } // GetTeam mocks base method. -func (m *MockStore) GetTeam(arg0 string) (*model.Team, error) { +func (m *MockStore) GetTeam(arg0 string) (*model0.Team, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetTeam", arg0) - ret0, _ := ret[0].(*model.Team) + ret0, _ := ret[0].(*model0.Team) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1020,10 +1020,10 @@ func (mr *MockStoreMockRecorder) GetTeam(arg0 interface{}) *gomock.Call { } // GetTeamBoardsInsights mocks base method. -func (m *MockStore) GetTeamBoardsInsights(arg0 string, arg1 int64, arg2, arg3 int, arg4 []string) (*model.BoardInsightsList, error) { +func (m *MockStore) GetTeamBoardsInsights(arg0 string, arg1 int64, arg2, arg3 int, arg4 []string) (*model0.BoardInsightsList, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetTeamBoardsInsights", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(*model.BoardInsightsList) + ret0, _ := ret[0].(*model0.BoardInsightsList) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1050,10 +1050,10 @@ func (mr *MockStoreMockRecorder) GetTeamCount() *gomock.Call { } // GetTeamsForUser mocks base method. -func (m *MockStore) GetTeamsForUser(arg0 string) ([]*model.Team, error) { +func (m *MockStore) GetTeamsForUser(arg0 string) ([]*model0.Team, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetTeamsForUser", arg0) - ret0, _ := ret[0].([]*model.Team) + ret0, _ := ret[0].([]*model0.Team) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1065,10 +1065,10 @@ func (mr *MockStoreMockRecorder) GetTeamsForUser(arg0 interface{}) *gomock.Call } // GetTemplateBoards mocks base method. -func (m *MockStore) GetTemplateBoards(arg0, arg1 string) ([]*model.Board, error) { +func (m *MockStore) GetTemplateBoards(arg0, arg1 string) ([]*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetTemplateBoards", arg0, arg1) - ret0, _ := ret[0].([]*model.Board) + ret0, _ := ret[0].([]*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1095,10 +1095,10 @@ func (mr *MockStoreMockRecorder) GetUsedCardsCount() *gomock.Call { } // GetUserBoardsInsights mocks base method. -func (m *MockStore) GetUserBoardsInsights(arg0, arg1 string, arg2 int64, arg3, arg4 int, arg5 []string) (*model.BoardInsightsList, error) { +func (m *MockStore) GetUserBoardsInsights(arg0, arg1 string, arg2 int64, arg3, arg4 int, arg5 []string) (*model0.BoardInsightsList, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUserBoardsInsights", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].(*model.BoardInsightsList) + ret0, _ := ret[0].(*model0.BoardInsightsList) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1110,10 +1110,10 @@ func (mr *MockStoreMockRecorder) GetUserBoardsInsights(arg0, arg1, arg2, arg3, a } // GetUserByEmail mocks base method. -func (m *MockStore) GetUserByEmail(arg0 string) (*model.User, error) { +func (m *MockStore) GetUserByEmail(arg0 string) (*model0.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUserByEmail", arg0) - ret0, _ := ret[0].(*model.User) + ret0, _ := ret[0].(*model0.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1125,10 +1125,10 @@ func (mr *MockStoreMockRecorder) GetUserByEmail(arg0 interface{}) *gomock.Call { } // GetUserByID mocks base method. -func (m *MockStore) GetUserByID(arg0 string) (*model.User, error) { +func (m *MockStore) GetUserByID(arg0 string) (*model0.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUserByID", arg0) - ret0, _ := ret[0].(*model.User) + ret0, _ := ret[0].(*model0.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1140,10 +1140,10 @@ func (mr *MockStoreMockRecorder) GetUserByID(arg0 interface{}) *gomock.Call { } // GetUserByUsername mocks base method. -func (m *MockStore) GetUserByUsername(arg0 string) (*model.User, error) { +func (m *MockStore) GetUserByUsername(arg0 string) (*model0.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUserByUsername", arg0) - ret0, _ := ret[0].(*model.User) + ret0, _ := ret[0].(*model0.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1155,10 +1155,10 @@ func (mr *MockStoreMockRecorder) GetUserByUsername(arg0 interface{}) *gomock.Cal } // GetUserCategories mocks base method. -func (m *MockStore) GetUserCategories(arg0, arg1 string) ([]model.Category, error) { +func (m *MockStore) GetUserCategories(arg0, arg1 string) ([]model0.Category, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUserCategories", arg0, arg1) - ret0, _ := ret[0].([]model.Category) + ret0, _ := ret[0].([]model0.Category) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1170,10 +1170,10 @@ func (mr *MockStoreMockRecorder) GetUserCategories(arg0, arg1 interface{}) *gomo } // GetUserCategoryBoards mocks base method. -func (m *MockStore) GetUserCategoryBoards(arg0, arg1 string) ([]model.CategoryBoards, error) { +func (m *MockStore) GetUserCategoryBoards(arg0, arg1 string) ([]model0.CategoryBoards, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUserCategoryBoards", arg0, arg1) - ret0, _ := ret[0].([]model.CategoryBoards) + ret0, _ := ret[0].([]model0.CategoryBoards) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1185,10 +1185,10 @@ func (mr *MockStoreMockRecorder) GetUserCategoryBoards(arg0, arg1 interface{}) * } // GetUserPreferences mocks base method. -func (m *MockStore) GetUserPreferences(arg0 string) (model0.Preferences, error) { +func (m *MockStore) GetUserPreferences(arg0 string) (model.Preferences, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUserPreferences", arg0) - ret0, _ := ret[0].(model0.Preferences) + ret0, _ := ret[0].(model.Preferences) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1215,10 +1215,10 @@ func (mr *MockStoreMockRecorder) GetUserTimezone(arg0 interface{}) *gomock.Call } // GetUsersByTeam mocks base method. -func (m *MockStore) GetUsersByTeam(arg0, arg1 string, arg2, arg3 bool) ([]*model.User, error) { +func (m *MockStore) GetUsersByTeam(arg0, arg1 string, arg2, arg3 bool) ([]*model0.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUsersByTeam", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].([]*model.User) + ret0, _ := ret[0].([]*model0.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1230,10 +1230,10 @@ func (mr *MockStoreMockRecorder) GetUsersByTeam(arg0, arg1, arg2, arg3 interface } // GetUsersList mocks base method. -func (m *MockStore) GetUsersList(arg0 []string, arg1, arg2 bool) ([]*model.User, error) { +func (m *MockStore) GetUsersList(arg0 []string, arg1, arg2 bool) ([]*model0.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUsersList", arg0, arg1, arg2) - ret0, _ := ret[0].([]*model.User) + ret0, _ := ret[0].([]*model0.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1245,7 +1245,7 @@ func (mr *MockStoreMockRecorder) GetUsersList(arg0, arg1, arg2 interface{}) *gom } // InsertBlock mocks base method. -func (m *MockStore) InsertBlock(arg0 *model.Block, arg1 string) error { +func (m *MockStore) InsertBlock(arg0 *model0.Block, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InsertBlock", arg0, arg1) ret0, _ := ret[0].(error) @@ -1259,7 +1259,7 @@ func (mr *MockStoreMockRecorder) InsertBlock(arg0, arg1 interface{}) *gomock.Cal } // InsertBlocks mocks base method. -func (m *MockStore) InsertBlocks(arg0 []*model.Block, arg1 string) error { +func (m *MockStore) InsertBlocks(arg0 []*model0.Block, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InsertBlocks", arg0, arg1) ret0, _ := ret[0].(error) @@ -1273,10 +1273,10 @@ func (mr *MockStoreMockRecorder) InsertBlocks(arg0, arg1 interface{}) *gomock.Ca } // InsertBoard mocks base method. -func (m *MockStore) InsertBoard(arg0 *model.Board, arg1 string) (*model.Board, error) { +func (m *MockStore) InsertBoard(arg0 *model0.Board, arg1 string) (*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InsertBoard", arg0, arg1) - ret0, _ := ret[0].(*model.Board) + ret0, _ := ret[0].(*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1288,11 +1288,11 @@ func (mr *MockStoreMockRecorder) InsertBoard(arg0, arg1 interface{}) *gomock.Cal } // InsertBoardWithAdmin mocks base method. -func (m *MockStore) InsertBoardWithAdmin(arg0 *model.Board, arg1 string) (*model.Board, *model.BoardMember, error) { +func (m *MockStore) InsertBoardWithAdmin(arg0 *model0.Board, arg1 string) (*model0.Board, *model0.BoardMember, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InsertBoardWithAdmin", arg0, arg1) - ret0, _ := ret[0].(*model.Board) - ret1, _ := ret[1].(*model.BoardMember) + ret0, _ := ret[0].(*model0.Board) + ret1, _ := ret[1].(*model0.BoardMember) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } @@ -1304,7 +1304,7 @@ func (mr *MockStoreMockRecorder) InsertBoardWithAdmin(arg0, arg1 interface{}) *g } // PatchBlock mocks base method. -func (m *MockStore) PatchBlock(arg0 string, arg1 *model.BlockPatch, arg2 string) error { +func (m *MockStore) PatchBlock(arg0 string, arg1 *model0.BlockPatch, arg2 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PatchBlock", arg0, arg1, arg2) ret0, _ := ret[0].(error) @@ -1318,7 +1318,7 @@ func (mr *MockStoreMockRecorder) PatchBlock(arg0, arg1, arg2 interface{}) *gomoc } // PatchBlocks mocks base method. -func (m *MockStore) PatchBlocks(arg0 *model.BlockPatchBatch, arg1 string) error { +func (m *MockStore) PatchBlocks(arg0 *model0.BlockPatchBatch, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PatchBlocks", arg0, arg1) ret0, _ := ret[0].(error) @@ -1332,10 +1332,10 @@ func (mr *MockStoreMockRecorder) PatchBlocks(arg0, arg1 interface{}) *gomock.Cal } // PatchBoard mocks base method. -func (m *MockStore) PatchBoard(arg0 string, arg1 *model.BoardPatch, arg2 string) (*model.Board, error) { +func (m *MockStore) PatchBoard(arg0 string, arg1 *model0.BoardPatch, arg2 string) (*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PatchBoard", arg0, arg1, arg2) - ret0, _ := ret[0].(*model.Board) + ret0, _ := ret[0].(*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1347,10 +1347,10 @@ func (mr *MockStoreMockRecorder) PatchBoard(arg0, arg1, arg2 interface{}) *gomoc } // PatchBoardsAndBlocks mocks base method. -func (m *MockStore) PatchBoardsAndBlocks(arg0 *model.PatchBoardsAndBlocks, arg1 string) (*model.BoardsAndBlocks, error) { +func (m *MockStore) PatchBoardsAndBlocks(arg0 *model0.PatchBoardsAndBlocks, arg1 string) (*model0.BoardsAndBlocks, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PatchBoardsAndBlocks", arg0, arg1) - ret0, _ := ret[0].(*model.BoardsAndBlocks) + ret0, _ := ret[0].(*model0.BoardsAndBlocks) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1362,10 +1362,10 @@ func (mr *MockStoreMockRecorder) PatchBoardsAndBlocks(arg0, arg1 interface{}) *g } // PatchUserPreferences mocks base method. -func (m *MockStore) PatchUserPreferences(arg0 string, arg1 model.UserPreferencesPatch) (model0.Preferences, error) { +func (m *MockStore) PatchUserPreferences(arg0 string, arg1 model0.UserPreferencesPatch) (model.Preferences, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PatchUserPreferences", arg0, arg1) - ret0, _ := ret[0].(model0.Preferences) + ret0, _ := ret[0].(model.Preferences) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1391,7 +1391,7 @@ func (mr *MockStoreMockRecorder) PostMessage(arg0, arg1, arg2 interface{}) *gomo } // RefreshSession mocks base method. -func (m *MockStore) RefreshSession(arg0 *model.Session) error { +func (m *MockStore) RefreshSession(arg0 *model0.Session) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RefreshSession", arg0) ret0, _ := ret[0].(error) @@ -1405,7 +1405,7 @@ func (mr *MockStoreMockRecorder) RefreshSession(arg0 interface{}) *gomock.Call { } // RemoveDefaultTemplates mocks base method. -func (m *MockStore) RemoveDefaultTemplates(arg0 []*model.Board) error { +func (m *MockStore) RemoveDefaultTemplates(arg0 []*model0.Board) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RemoveDefaultTemplates", arg0) ret0, _ := ret[0].(error) @@ -1464,7 +1464,7 @@ func (mr *MockStoreMockRecorder) RunDataRetention(arg0, arg1 interface{}) *gomoc } // SaveFileInfo mocks base method. -func (m *MockStore) SaveFileInfo(arg0 *model0.FileInfo) error { +func (m *MockStore) SaveFileInfo(arg0 *model.FileInfo) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SaveFileInfo", arg0) ret0, _ := ret[0].(error) @@ -1478,10 +1478,10 @@ func (mr *MockStoreMockRecorder) SaveFileInfo(arg0 interface{}) *gomock.Call { } // SaveMember mocks base method. -func (m *MockStore) SaveMember(arg0 *model.BoardMember) (*model.BoardMember, error) { +func (m *MockStore) SaveMember(arg0 *model0.BoardMember) (*model0.BoardMember, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SaveMember", arg0) - ret0, _ := ret[0].(*model.BoardMember) + ret0, _ := ret[0].(*model0.BoardMember) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1493,10 +1493,10 @@ func (mr *MockStoreMockRecorder) SaveMember(arg0 interface{}) *gomock.Call { } // SearchBoardsForUser mocks base method. -func (m *MockStore) SearchBoardsForUser(arg0 string, arg1 model.BoardSearchField, arg2 string, arg3 bool) ([]*model.Board, error) { +func (m *MockStore) SearchBoardsForUser(arg0 string, arg1 model0.BoardSearchField, arg2 string, arg3 bool) ([]*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SearchBoardsForUser", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].([]*model.Board) + ret0, _ := ret[0].([]*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1508,10 +1508,10 @@ func (mr *MockStoreMockRecorder) SearchBoardsForUser(arg0, arg1, arg2, arg3 inte } // SearchBoardsForUserInTeam mocks base method. -func (m *MockStore) SearchBoardsForUserInTeam(arg0, arg1, arg2 string) ([]*model.Board, error) { +func (m *MockStore) SearchBoardsForUserInTeam(arg0, arg1, arg2 string) ([]*model0.Board, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SearchBoardsForUserInTeam", arg0, arg1, arg2) - ret0, _ := ret[0].([]*model.Board) + ret0, _ := ret[0].([]*model0.Board) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1523,10 +1523,10 @@ func (mr *MockStoreMockRecorder) SearchBoardsForUserInTeam(arg0, arg1, arg2 inte } // SearchUserChannels mocks base method. -func (m *MockStore) SearchUserChannels(arg0, arg1, arg2 string) ([]*model0.Channel, error) { +func (m *MockStore) SearchUserChannels(arg0, arg1, arg2 string) ([]*model.Channel, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SearchUserChannels", arg0, arg1, arg2) - ret0, _ := ret[0].([]*model0.Channel) + ret0, _ := ret[0].([]*model.Channel) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1538,10 +1538,10 @@ func (mr *MockStoreMockRecorder) SearchUserChannels(arg0, arg1, arg2 interface{} } // SearchUsersByTeam mocks base method. -func (m *MockStore) SearchUsersByTeam(arg0, arg1, arg2 string, arg3, arg4, arg5 bool) ([]*model.User, error) { +func (m *MockStore) SearchUsersByTeam(arg0, arg1, arg2 string, arg3, arg4, arg5 bool) ([]*model0.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SearchUsersByTeam", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].([]*model.User) + ret0, _ := ret[0].([]*model0.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1652,7 +1652,7 @@ func (mr *MockStoreMockRecorder) UpdateCardLimitTimestamp(arg0 interface{}) *gom } // UpdateCategory mocks base method. -func (m *MockStore) UpdateCategory(arg0 model.Category) error { +func (m *MockStore) UpdateCategory(arg0 model0.Category) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateCategory", arg0) ret0, _ := ret[0].(error) @@ -1666,7 +1666,7 @@ func (mr *MockStoreMockRecorder) UpdateCategory(arg0 interface{}) *gomock.Call { } // UpdateSession mocks base method. -func (m *MockStore) UpdateSession(arg0 *model.Session) error { +func (m *MockStore) UpdateSession(arg0 *model0.Session) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateSession", arg0) ret0, _ := ret[0].(error) @@ -1694,10 +1694,10 @@ func (mr *MockStoreMockRecorder) UpdateSubscribersNotifiedAt(arg0, arg1 interfac } // UpdateUser mocks base method. -func (m *MockStore) UpdateUser(arg0 *model.User) (*model.User, error) { +func (m *MockStore) UpdateUser(arg0 *model0.User) (*model0.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateUser", arg0) - ret0, _ := ret[0].(*model.User) + ret0, _ := ret[0].(*model0.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1737,10 +1737,10 @@ func (mr *MockStoreMockRecorder) UpdateUserPasswordByID(arg0, arg1 interface{}) } // UpsertNotificationHint mocks base method. -func (m *MockStore) UpsertNotificationHint(arg0 *model.NotificationHint, arg1 time.Duration) (*model.NotificationHint, error) { +func (m *MockStore) UpsertNotificationHint(arg0 *model0.NotificationHint, arg1 time.Duration) (*model0.NotificationHint, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpsertNotificationHint", arg0, arg1) - ret0, _ := ret[0].(*model.NotificationHint) + ret0, _ := ret[0].(*model0.NotificationHint) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1752,7 +1752,7 @@ func (mr *MockStoreMockRecorder) UpsertNotificationHint(arg0, arg1 interface{}) } // UpsertSharing mocks base method. -func (m *MockStore) UpsertSharing(arg0 model.Sharing) error { +func (m *MockStore) UpsertSharing(arg0 model0.Sharing) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpsertSharing", arg0) ret0, _ := ret[0].(error) @@ -1766,7 +1766,7 @@ func (mr *MockStoreMockRecorder) UpsertSharing(arg0 interface{}) *gomock.Call { } // UpsertTeamSettings mocks base method. -func (m *MockStore) UpsertTeamSettings(arg0 model.Team) error { +func (m *MockStore) UpsertTeamSettings(arg0 model0.Team) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpsertTeamSettings", arg0) ret0, _ := ret[0].(error) @@ -1780,7 +1780,7 @@ func (mr *MockStoreMockRecorder) UpsertTeamSettings(arg0 interface{}) *gomock.Ca } // UpsertTeamSignupToken mocks base method. -func (m *MockStore) UpsertTeamSignupToken(arg0 model.Team) error { +func (m *MockStore) UpsertTeamSignupToken(arg0 model0.Team) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpsertTeamSignupToken", arg0) ret0, _ := ret[0].(error) diff --git a/server/boards/services/telemetry/telemetry.go b/server/boards/services/telemetry/telemetry.go index 8d14dec57a..97f13d5afd 100644 --- a/server/boards/services/telemetry/telemetry.go +++ b/server/boards/services/telemetry/telemetry.go @@ -5,20 +5,28 @@ package telemetry import ( "os" - "strings" "time" rudder "github.com/rudderlabs/analytics-go" "github.com/mattermost/mattermost-server/server/v8/boards/services/scheduler" + "github.com/mattermost/mattermost-server/server/public/model" "github.com/mattermost/mattermost-server/server/public/shared/mlog" "github.com/mattermost/mattermost-server/server/v8/channels/utils" ) const ( - rudderKey = "placeholder_boards_rudder_key" - rudderDataplaneURL = "placeholder_rudder_dataplane_url" + rudderDataplaneURL = "https://pdat.matterlytics.com" + rudderKeyProd = "1myWcDbTkIThnpPYyms7DKlmQWl" + rudderKeyTest = "1myWYwHRDFdLDTpznQ7qFlOPQaa" + + // These are placeholders to allow the existing release pipelines to run without failing to + // insert the values that are now hard-coded above. Remove this once we converge on the + // unified delivery pipeline in GitHub. + _ = "placeholder_rudder_dataplane_url" + _ = "placeholder_boards_rudder_key" + timeBetweenTelemetryChecks = 10 * time.Minute ) @@ -54,13 +62,21 @@ func (ts *Service) RegisterTracker(name string, f TrackerFunc) { } func (ts *Service) getRudderConfig() RudderConfig { - if !strings.Contains(rudderKey, "placeholder") && !strings.Contains(rudderDataplaneURL, "placeholder") { - return RudderConfig{rudderKey, rudderDataplaneURL} - } + // Support unit testing if os.Getenv("RUDDER_KEY") != "" && os.Getenv("RUDDER_DATAPLANE_URL") != "" { return RudderConfig{os.Getenv("RUDDER_KEY"), os.Getenv("RUDDER_DATAPLANE_URL")} } - return RudderConfig{} + + rudderKey := "" + switch model.GetServiceEnvironment() { + case model.ServiceEnvironmentProduction: + rudderKey = rudderKeyProd + case model.ServiceEnvironmentTest: + rudderKey = rudderKeyTest + case model.ServiceEnvironmentDev: + } + + return RudderConfig{rudderKey, rudderDataplaneURL} } func (ts *Service) sendDailyTelemetry(override bool) { diff --git a/server/build/release.mk b/server/build/release.mk index 60004e5d0d..41f1b4b14e 100644 --- a/server/build/release.mk +++ b/server/build/release.mk @@ -5,85 +5,85 @@ build-linux: build-linux-amd64 build-linux-arm64 build-linux-amd64: @echo Build Linux amd64 ifeq ($(BUILDER_GOOS_GOARCH),"linux_amd64") - env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... else mkdir -p $(GOBIN)/linux_amd64 - env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN)/linux_amd64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN)/linux_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... endif build-linux-arm64: @echo Build Linux arm64 ifeq ($(BUILDER_GOOS_GOARCH),"linux_arm64") - env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... else mkdir -p $(GOBIN)/linux_arm64 - env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN)/linux_arm64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN)/linux_arm64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... endif build-osx: @echo Build OSX amd64 ifeq ($(BUILDER_GOOS_GOARCH),"darwin_amd64") - env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... else mkdir -p $(GOBIN)/darwin_amd64 - env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN)/darwin_amd64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN)/darwin_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... endif @echo Build OSX arm64 ifeq ($(BUILDER_GOOS_GOARCH),"darwin_arm64") - env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... else mkdir -p $(GOBIN)/darwin_arm64 - env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN)/darwin_arm64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN)/darwin_arm64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... endif build-windows: @echo Build Windows amd64 ifeq ($(BUILDER_GOOS_GOARCH),"windows_amd64") - env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... else mkdir -p $(GOBIN)/windows_amd64 - env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN)/windows_amd64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./... + env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN)/windows_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./... endif build-cmd-linux: @echo Build CMD Linux amd64 ifeq ($(BUILDER_GOOS_GOARCH),"linux_amd64") - env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... else mkdir -p $(GOBIN)/linux_amd64 - env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN)/linux_amd64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN)/linux_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... endif @echo Build CMD Linux arm64 ifeq ($(BUILDER_GOOS_GOARCH),"linux_arm64") - env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... else mkdir -p $(GOBIN)/linux_arm64 - env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN)/linux_arm64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN)/linux_arm64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... endif build-cmd-osx: @echo Build CMD OSX amd64 ifeq ($(BUILDER_GOOS_GOARCH),"darwin_amd64") - env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... else mkdir -p $(GOBIN)/darwin_amd64 - env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN)/darwin_amd64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN)/darwin_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... endif @echo Build CMD OSX arm64 ifeq ($(BUILDER_GOOS_GOARCH),"darwin_arm64") - env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... else mkdir -p $(GOBIN)/darwin_arm64 - env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN)/darwin_arm64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN)/darwin_arm64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... endif build-cmd-windows: @echo Build CMD Windows amd64 ifeq ($(BUILDER_GOOS_GOARCH),"windows_amd64") - env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... else mkdir -p $(GOBIN)/windows_amd64 - env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN)/windows_amd64 $(GOFLAGS) -trimpath -tags '$(GOTAGS)' -ldflags '$(LDFLAGS)' ./cmd/... + env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN)/windows_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/... endif build: setup-go-work build-client build-linux build-windows build-osx diff --git a/server/channels/app/product_notices_test.go b/server/channels/app/product_notices_test.go index bf42d13a04..254d8a7e33 100644 --- a/server/channels/app/product_notices_test.go +++ b/server/channels/app/product_notices_test.go @@ -640,6 +640,9 @@ func TestNoticeValidation(t *testing.T) { model.BuildNumber = tt.args.serverVersion if model.BuildNumber == "" { model.BuildNumber = "5.26.1" + defer func() { + model.BuildNumber = "" + }() } if ok, err := noticeMatchesConditions( th.App.Config(), diff --git a/server/channels/app/server.go b/server/channels/app/server.go index 403141ace2..394aa7ee68 100644 --- a/server/channels/app/server.go +++ b/server/channels/app/server.go @@ -74,8 +74,12 @@ import ( "github.com/mattermost/mattermost-server/server/v8/platform/shared/templates" ) -// declaring this as var to allow overriding in tests -var SentryDSN = "placeholder_sentry_dsn" +var SentryDSN = "https://9d7c9cccf549479799f880bcf4f26323@o94110.ingest.sentry.io/5212327" + +// This is a placeholder to allow the existing release pipelines to run without failing to insert +// the key that's now hard-coded above. Remove this once we converge on the unified delivery +// pipeline in GitHub. +var _ = "placeholder_sentry_dsn" type Server struct { // RootRouter is the starting point for all HTTP requests to the server. @@ -294,9 +298,10 @@ func NewServer(options ...Option) (*Server, error) { // ------------------------------------------------------------------------- if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry { - if strings.Contains(SentryDSN, "placeholder") { - mlog.Warn("Sentry reporting is enabled, but SENTRY_DSN is not set. Disabling reporting.") - } else { + switch model.GetServiceEnvironment() { + case model.ServiceEnvironmentDev: + mlog.Warn("Sentry reporting is enabled, but service environment is dev. Disabling reporting.") + case model.ServiceEnvironmentProduction, model.ServiceEnvironmentTest: if err2 := sentry.Init(sentry.ClientOptions{ Dsn: SentryDSN, Release: model.BuildHash, @@ -424,6 +429,7 @@ func NewServer(options ...Option) (*Server, error) { mlog.String("build_date", model.BuildDate), mlog.String("build_hash", model.BuildHash), mlog.String("build_hash_enterprise", model.BuildHashEnterprise), + mlog.String("service_environment", model.GetServiceEnvironment()), ) if model.BuildEnterpriseReady == "true" { mlog.Info("Enterprise Build", mlog.Bool("enterprise_build", true)) @@ -907,11 +913,15 @@ func (s *Server) Start() error { var handler http.Handler = s.RootRouter - if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry && !strings.Contains(SentryDSN, "placeholder") { - sentryHandler := sentryhttp.New(sentryhttp.Options{ - Repanic: true, - }) - handler = sentryHandler.Handle(handler) + switch model.GetServiceEnvironment() { + case model.ServiceEnvironmentProduction, model.ServiceEnvironmentTest: + if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry { + sentryHandler := sentryhttp.New(sentryhttp.Options{ + Repanic: true, + }) + handler = sentryHandler.Handle(handler) + } + case model.ServiceEnvironmentDev: } if allowedOrigins := *s.platform.Config().ServiceSettings.AllowCorsFrom; allowedOrigins != "" { diff --git a/server/channels/app/server_test.go b/server/channels/app/server_test.go index 19ee870169..5e8fc99516 100644 --- a/server/channels/app/server_test.go +++ b/server/channels/app/server_test.go @@ -395,6 +395,22 @@ func TestSentry(t *testing.T) { }} testDir, _ := fileutils.FindDir("tests") + setSentryDSN := func(t *testing.T, dsn *sentry.Dsn) { + os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentTest) + + // Allow Playbooks to startup + oldBuildHash := model.BuildHash + model.BuildHash = "dev" + + oldSentryDSN := SentryDSN + SentryDSN = dsn.String() + t.Cleanup(func() { + os.Unsetenv("MM_SERVICEENVIRONMENT") + model.BuildHash = oldBuildHash + SentryDSN = oldSentryDSN + }) + } + t.Run("sentry is disabled, should not receive a report", func(t *testing.T) { data := make(chan bool, 1) @@ -408,7 +424,7 @@ func TestSentry(t *testing.T) { _, port, _ := net.SplitHostPort(server.Listener.Addr().String()) dsn, err := sentry.NewDsn(fmt.Sprintf("http://test:test@localhost:%s/123", port)) require.NoError(t, err) - SentryDSN = dsn.String() + setSentryDSN(t, dsn) s, err := newServerWithConfig(t, func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = "localhost:0" @@ -452,7 +468,7 @@ func TestSentry(t *testing.T) { _, port, _ := net.SplitHostPort(server.Listener.Addr().String()) dsn, err := sentry.NewDsn(fmt.Sprintf("http://test:test@localhost:%s/123", port)) require.NoError(t, err) - SentryDSN = dsn.String() + setSentryDSN(t, dsn) s, err := newServerWithConfig(t, func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = "localhost:0" diff --git a/server/channels/utils/fileutils/fileutils_test.go b/server/channels/utils/fileutils/fileutils_test.go index c223586443..b2b1851ea1 100644 --- a/server/channels/utils/fileutils/fileutils_test.go +++ b/server/channels/utils/fileutils/fileutils_test.go @@ -102,7 +102,7 @@ func TestFindFile(t *testing.T) { fmt.Sprintf("%s: quadruple-nested subdirectory of containing directory", fileName), &tmpDir5, fileName, - filePath, + filePathResolved, }, }...) } diff --git a/server/channels/utils/license.go b/server/channels/utils/license.go index aeefabc35f..b85d7d5c52 100644 --- a/server/channels/utils/license.go +++ b/server/channels/utils/license.go @@ -74,6 +74,13 @@ func (l *LicenseValidatorImpl) ValidateLicense(signed []byte) (bool, string) { plaintext := decoded[:len(decoded)-256] signature := decoded[len(decoded)-256:] + var publicKey []byte + switch model.GetServiceEnvironment() { + case model.ServiceEnvironmentProduction: + publicKey = productionPublicKey + case model.ServiceEnvironmentTest, model.ServiceEnvironmentDev: + publicKey = testPublicKey + } block, _ := pem.Decode(publicKey) public, err := x509.ParsePKIXPublicKey(block.Bytes) diff --git a/server/channels/utils/license_public_key.go b/server/channels/utils/license_public_key.go index 9f589c2779..55b8e6fdac 100644 --- a/server/channels/utils/license_public_key.go +++ b/server/channels/utils/license_public_key.go @@ -1,10 +1,12 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -//go:build !testlicensekey package utils import _ "embed" //go:embed license-public-key.txt -var publicKey []byte +var productionPublicKey []byte + +//go:embed license-public-key-test.txt +var testPublicKey []byte diff --git a/server/channels/utils/license_public_key_test_env.go b/server/channels/utils/license_public_key_test_env.go deleted file mode 100644 index 52644ae774..0000000000 --- a/server/channels/utils/license_public_key_test_env.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. -//go:build testlicensekey - -package utils - -import _ "embed" - -//go:embed license-public-key-test.txt -var publicKey []byte diff --git a/server/channels/utils/license_test.go b/server/channels/utils/license_test.go index 8c57685444..9e64fee8fe 100644 --- a/server/channels/utils/license_test.go +++ b/server/channels/utils/license_test.go @@ -9,10 +9,13 @@ import ( "os" "testing" + "github.com/mattermost/mattermost-server/server/public/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var validTestLicense = []byte("eyJpZCI6InpvZ3c2NW44Z2lmajVkbHJoYThtYnUxcGl3IiwiaXNzdWVkX2F0IjoxNjg0Nzg3MzcxODY5LCJzdGFydHNfYXQiOjE2ODQ3ODczNzE4NjksImV4cGlyZXNfYXQiOjIwMDA0MDY1MzgwMDAsInNrdV9uYW1lIjoiUHJvZmVzc2lvbmFsIiwic2t1X3Nob3J0X25hbWUiOiJwcm9mZXNzaW9uYWwiLCJjdXN0b21lciI6eyJpZCI6InA5dW4zNjlhNjdnaW1qNHlkNmk2aWIzOXdoIiwibmFtZSI6Ik1hdHRlcm1vc3QiLCJlbWFpbCI6ImpvcmFtQG1hdHRlcm1vc3QuY29tIiwiY29tcGFueSI6Ik1hdHRlcm1vc3QifSwiZmVhdHVyZXMiOnsidXNlcnMiOjIwMDAwMCwibGRhcCI6dHJ1ZSwibGRhcF9ncm91cHMiOmZhbHNlLCJtZmEiOnRydWUsImdvb2dsZV9vYXV0aCI6dHJ1ZSwib2ZmaWNlMzY1X29hdXRoIjp0cnVlLCJjb21wbGlhbmNlIjpmYWxzZSwiY2x1c3RlciI6dHJ1ZSwibWV0cmljcyI6dHJ1ZSwibWhwbnMiOnRydWUsInNhbWwiOnRydWUsImVsYXN0aWNfc2VhcmNoIjp0cnVlLCJhbm5vdW5jZW1lbnQiOnRydWUsInRoZW1lX21hbmFnZW1lbnQiOmZhbHNlLCJlbWFpbF9ub3RpZmljYXRpb25fY29udGVudHMiOmZhbHNlLCJkYXRhX3JldGVudGlvbiI6ZmFsc2UsIm1lc3NhZ2VfZXhwb3J0IjpmYWxzZSwiY3VzdG9tX3Blcm1pc3Npb25zX3NjaGVtZXMiOmZhbHNlLCJjdXN0b21fdGVybXNfb2Zfc2VydmljZSI6ZmFsc2UsImd1ZXN0X2FjY291bnRzIjp0cnVlLCJndWVzdF9hY2NvdW50c19wZXJtaXNzaW9ucyI6dHJ1ZSwiaWRfbG9hZGVkIjpmYWxzZSwibG9ja190ZWFtbWF0ZV9uYW1lX2Rpc3BsYXkiOmZhbHNlLCJjbG91ZCI6ZmFsc2UsInNoYXJlZF9jaGFubmVscyI6ZmFsc2UsInJlbW90ZV9jbHVzdGVyX3NlcnZpY2UiOmZhbHNlLCJvcGVuaWQiOnRydWUsImVudGVycHJpc2VfcGx1Z2lucyI6dHJ1ZSwiYWR2YW5jZWRfbG9nZ2luZyI6dHJ1ZSwiZnV0dXJlX2ZlYXR1cmVzIjpmYWxzZX0sImlzX3RyaWFsIjp0cnVlLCJpc19nb3Zfc2t1IjpmYWxzZX0bEOVk2GdE1kSWKJ3dENWnkj0htY6QyXTtNA5hqnQ71Uc6teqXc7htHAxrnT/hV42xu+G24OMrAIsQtX4NjFSX6jvehIMRL5II3RPXYhHKUd2wruQ5ITEh1htFb5DgOJW3tvBdMmXt09nXjLRS1UYJ7ZsX3mU0uQndt7qfMriGAkk71veYuUJgztB3MsV7lRWB+8ZTp6WJ7RH+uWnuDspiA8B85mLnyuoCDokYksF2uIb+CtPGBTUB6qSOgxBBJxu5qftQXISCDAWY4O8lCrN3p5HCA/zf/rSRRNtet06QFobbjUDI4B7ZEAescKBKoHpP6nZPhg4KmhnkUi/o04ox") + func TestValidateLicense(t *testing.T) { t.Run("should fail with junk data", func(t *testing.T) { b1 := []byte("junk") @@ -24,7 +27,7 @@ func TestValidateLicense(t *testing.T) { require.False(t, ok, "should have failed - bad license") }) - t.Run("should not panic on shorted than expected input", func(t *testing.T) { + t.Run("should not panic on shorter than expected input", func(t *testing.T) { var licenseData bytes.Buffer var inputData []byte @@ -62,6 +65,33 @@ func TestValidateLicense(t *testing.T) { require.False(t, ok) require.Empty(t, str) }) + + t.Run("should reject invalid license in test service environment", func(t *testing.T) { + os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentTest) + defer os.Unsetenv("MM_SERVICEENVIRONMENT") + + ok, str := LicenseValidator.ValidateLicense(nil) + require.False(t, ok) + require.Empty(t, str) + }) + + t.Run("should validate valid test license in test service environment", func(t *testing.T) { + os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentTest) + defer os.Unsetenv("MM_SERVICEENVIRONMENT") + + ok, str := LicenseValidator.ValidateLicense(validTestLicense) + require.True(t, ok) + require.NotEmpty(t, str) + }) + + t.Run("should reject valid test license in production service environment", func(t *testing.T) { + os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentProduction) + defer os.Unsetenv("MM_SERVICEENVIRONMENT") + + ok, str := LicenseValidator.ValidateLicense(validTestLicense) + require.False(t, ok) + require.Empty(t, str) + }) } func TestGetLicenseFileLocation(t *testing.T) { diff --git a/server/config/client.go b/server/config/client.go index b97e9a87bb..b4adc9201a 100644 --- a/server/config/client.go +++ b/server/config/client.go @@ -234,6 +234,7 @@ func GenerateLimitedClientConfig(c *model.Config, telemetryID string, license *m props["BuildHash"] = model.BuildHash props["BuildHashEnterprise"] = model.BuildHashEnterprise props["BuildEnterpriseReady"] = model.BuildEnterpriseReady + props["ServiceEnvironment"] = model.GetServiceEnvironment() props["EnableBotAccountCreation"] = strconv.FormatBool(*c.ServiceSettings.EnableBotAccountCreation) props["EnableFile"] = strconv.FormatBool(*c.LogSettings.EnableFile) diff --git a/server/platform/services/telemetry/telemetry.go b/server/platform/services/telemetry/telemetry.go index 24477b1a51..e7b478af68 100644 --- a/server/platform/services/telemetry/telemetry.go +++ b/server/platform/services/telemetry/telemetry.go @@ -31,8 +31,15 @@ const ( DBAccessAttempts = 3 DBAccessTimeoutSecs = 10 - RudderKey = "placeholder_rudder_key" - RudderDataplaneURL = "placeholder_rudder_dataplane_url" + rudderDataplaneURL = "https://pdat.matterlytics.com" + rudderKeyProd = "1aoejPqhgONMI720CsBSRWzzRQ9" + rudderKeyTest = "1aoeoCDeh7OCHcbW2kseWlwUFyq" + + // These are placeholders to allow the existing release pipelines to run without failing to + // insert the values that are now hard-coded above. Remove this once we converge on the + // unified delivery pipeline in GitHub. + _ = "placeholder_rudder_dataplane_url" + _ = "placeholder_rudder_key" EnvVarInstallType = "MM_INSTALL_TYPE" @@ -156,13 +163,21 @@ func (ts *TelemetryService) ensureTelemetryID() error { } func (ts *TelemetryService) getRudderConfig() RudderConfig { - if !strings.Contains(RudderKey, "placeholder") && !strings.Contains(RudderDataplaneURL, "placeholder") { - return RudderConfig{RudderKey, RudderDataplaneURL} - } else if os.Getenv("RudderKey") != "" && os.Getenv("RudderDataplaneURL") != "" { + // Support unit testing + if os.Getenv("RudderKey") != "" && os.Getenv("RudderDataplaneURL") != "" { return RudderConfig{os.Getenv("RudderKey"), os.Getenv("RudderDataplaneURL")} - } else { - return RudderConfig{} } + + rudderKey := "" + switch model.GetServiceEnvironment() { + case model.ServiceEnvironmentProduction: + rudderKey = rudderKeyProd + case model.ServiceEnvironmentTest: + rudderKey = rudderKeyTest + case model.ServiceEnvironmentDev: + } + + return RudderConfig{rudderKey, rudderDataplaneURL} } func (ts *TelemetryService) telemetryEnabled() bool { @@ -1333,7 +1348,7 @@ func (ts *TelemetryService) initRudder(endpoint string, rudderKey string) { config.Endpoint = endpoint config.Verbose = ts.verbose // For testing - if endpoint != RudderDataplaneURL { + if endpoint != rudderDataplaneURL { config.BatchSize = 1 } client, err := rudder.NewWithConfig(rudderKey, endpoint, config) diff --git a/server/platform/services/telemetry/telemetry_test.go b/server/platform/services/telemetry/telemetry_test.go index a17f10e996..53ca9396bd 100644 --- a/server/platform/services/telemetry/telemetry_test.go +++ b/server/platform/services/telemetry/telemetry_test.go @@ -13,7 +13,6 @@ import ( "net/http" "net/http/httptest" "os" - "strings" "testing" "time" @@ -124,7 +123,7 @@ func makeTelemetryServiceAndReceiver(t *testing.T, cloudLicense bool) (*Telemetr service.TelemetryID = testTelemetryID service.rudderClient = nil - service.initRudder(receiver.URL, RudderKey) + service.initRudder(receiver.URL, "") // initializing rudder send a client identify message select { @@ -340,6 +339,10 @@ func TestEnsureTelemetryID(t *testing.T) { }) t.Run("fail to save test ID", func(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } + storeMock := &storeMocks.Store{} systemStore := storeMocks.SystemStore{} @@ -579,9 +582,6 @@ func TestRudderTelemetry(t *testing.T) { }) t.Run("SendDailyTelemetryNoRudderKey", func(t *testing.T) { - if !strings.Contains(RudderKey, "placeholder") { - t.Skipf("Skipping telemetry on production builds") - } service.sendDailyTelemetry(false) select { @@ -593,9 +593,6 @@ func TestRudderTelemetry(t *testing.T) { }) t.Run("SendDailyTelemetryNonCloud", func(t *testing.T) { - if !strings.Contains(RudderKey, "placeholder") { - t.Skipf("Skipping telemetry on production builds") - } service.sendDailyTelemetry(true) var batches []testBatch @@ -618,9 +615,6 @@ func TestRudderTelemetry(t *testing.T) { }) t.Run("SendDailyTelemetryDisabled", func(t *testing.T) { - if !strings.Contains(RudderKey, "placeholder") { - t.Skipf("Skipping telemetry on production builds") - } *cfg.LogSettings.EnableDiagnostics = false defer func() { *cfg.LogSettings.EnableDiagnostics = true @@ -663,9 +657,6 @@ func TestRudderTelemetry(t *testing.T) { }) t.Run("RudderConfigUsesConfigForValues", func(t *testing.T) { - if !strings.Contains(RudderKey, "placeholder") { - t.Skipf("Skipping telemetry on production builds") - } os.Setenv("RudderKey", "abc123") os.Setenv("RudderDataplaneURL", "arudderstackplace") defer os.Unsetenv("RudderKey") @@ -679,9 +670,6 @@ func TestRudderTelemetry(t *testing.T) { } func TestRudderTelemetryCloud(t *testing.T) { - if !strings.Contains(RudderKey, "placeholder") { - t.Skipf("Skipping telemetry on production builds") - } if testing.Short() { t.SkipNow() } diff --git a/server/playbooks/product/playbooks_product.go b/server/playbooks/product/playbooks_product.go index 14018a4418..d645a1e634 100644 --- a/server/playbooks/product/playbooks_product.go +++ b/server/playbooks/product/playbooks_product.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" "os" - "strings" "time" "github.com/mattermost/mattermost-server/server/public/model" @@ -54,10 +53,16 @@ const ( const ServerKey product.ServiceKey = "server" -// These credentials for Rudder need to be replaced at build-time. const ( - rudderDataplaneURL = "placeholder_rudder_dataplane_url" - rudderWriteKey = "placeholder_playbooks_rudder_key" + rudderDataplaneURL = "https://pdat.matterlytics.com" + rudderKeyProd = "1ag0Mv7LPf5uJNhcnKomqg0ENFd" + rudderKeyTest = "1Zu3mOF6U6M9zeaJsfmmhYigWLt" + + // These are placeholders to allow the existing release pipelines to run without failing to + // insert the values that are now hard-coded above. Remove this once we converge on the + // unified delivery pipeline in GitHub. + _ = "placeholder_rudder_dataplane_url" + _ = "placeholder_playbooks_rudder_key" ) var errServiceTypeAssert = errors.New("type assertion failed") @@ -334,14 +339,23 @@ func (pp *playbooksProduct) Start() error { pp.handler = api.NewHandler(pp.config) - if strings.HasPrefix(rudderWriteKey, "placeholder_") { + rudderWriteKey := "" + switch model.GetServiceEnvironment() { + case model.ServiceEnvironmentProduction: + rudderWriteKey = rudderKeyProd + case model.ServiceEnvironmentTest: + rudderWriteKey = rudderKeyTest + case model.ServiceEnvironmentDev: + } + + if rudderWriteKey == "" { logrus.Warn("Rudder credentials are not set. Disabling analytics.") pp.telemetryClient = &telemetry.NoopTelemetry{} } else { logrus.Info("Rudder credentials are set. Enabling analytics.") diagnosticID := pp.serviceAdapter.GetDiagnosticID() serverVersion := pp.serviceAdapter.GetServerVersion() - pp.telemetryClient, err = telemetry.NewRudder(rudderDataplaneURL, rudderWriteKey, diagnosticID, model.BuildHash, serverVersion) + pp.telemetryClient, err = telemetry.NewRudder(rudderDataplaneURL, rudderWriteKey, diagnosticID, serverVersion) if err != nil { return errors.Wrapf(err, "failed init telemetry client") } diff --git a/server/playbooks/server/telemetry/rudder.go b/server/playbooks/server/telemetry/rudder.go index 294a23b2a7..b0909fdbca 100644 --- a/server/playbooks/server/telemetry/rudder.go +++ b/server/playbooks/server/telemetry/rudder.go @@ -99,15 +99,11 @@ const ( // dataPlaneURL with the writeKey, identified with the diagnosticID. The // version of the server is also sent with every event tracked. // If either diagnosticID or serverVersion are empty, an error is returned. -func NewRudder(dataPlaneURL, writeKey, diagnosticID, pluginVersion, serverVersion string) (*RudderTelemetry, error) { +func NewRudder(dataPlaneURL, writeKey, diagnosticID, serverVersion string) (*RudderTelemetry, error) { if diagnosticID == "" { return nil, errors.New("diagnosticID should not be empty") } - if pluginVersion == "" { - return nil, errors.New("pluginVersion should not be empty") - } - if serverVersion == "" { return nil, errors.New("serverVersion should not be empty") } @@ -117,6 +113,10 @@ func NewRudder(dataPlaneURL, writeKey, diagnosticID, pluginVersion, serverVersio return nil, err } + // Continue to emit the pluginVersion for backwards compatibility, but just set it to + // the server version given we're permanently part of the monorepo now. + pluginVersion := serverVersion + return &RudderTelemetry{ client: client, diagnosticID: diagnosticID, diff --git a/server/playbooks/server/telemetry/rudder_test.go b/server/playbooks/server/telemetry/rudder_test.go index 2f67254a60..326d9dc5e8 100644 --- a/server/playbooks/server/telemetry/rudder_test.go +++ b/server/playbooks/server/telemetry/rudder_test.go @@ -28,7 +28,7 @@ var ( ) func TestNewRudder(t *testing.T) { - r, err := NewRudder("dummy_key", "dummy_url", diagnosticID, pluginVersion, serverVersion) + r, err := NewRudder("dummy_key", "dummy_url", diagnosticID, serverVersion) require.Equal(t, r.diagnosticID, diagnosticID) require.Equal(t, r.serverVersion, serverVersion) require.NoError(t, err) diff --git a/server/public/model/config.go b/server/public/model/config.go index 25cfae32b3..06bc443d93 100644 --- a/server/public/model/config.go +++ b/server/public/model/config.go @@ -2860,14 +2860,18 @@ type CloudSettings struct { func (s *CloudSettings) SetDefaults() { if s.CWSURL == nil { - s.CWSURL = NewString(CloudSettingsDefaultCwsURL) - if !isProdLicensePublicKey { + switch GetServiceEnvironment() { + case ServiceEnvironmentProduction: + s.CWSURL = NewString(CloudSettingsDefaultCwsURL) + case ServiceEnvironmentTest, ServiceEnvironmentDev: s.CWSURL = NewString(CloudSettingsDefaultCwsURLTest) } } if s.CWSAPIURL == nil { - s.CWSAPIURL = NewString(CloudSettingsDefaultCwsAPIURL) - if !isProdLicensePublicKey { + switch GetServiceEnvironment() { + case ServiceEnvironmentProduction: + s.CWSAPIURL = NewString(CloudSettingsDefaultCwsAPIURL) + case ServiceEnvironmentTest, ServiceEnvironmentDev: s.CWSAPIURL = NewString(CloudSettingsDefaultCwsAPIURLTest) } } diff --git a/server/public/model/service_environment.go b/server/public/model/service_environment.go new file mode 100644 index 0000000000..e531e35a00 --- /dev/null +++ b/server/public/model/service_environment.go @@ -0,0 +1,45 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package model + +import ( + "os" + "strings" +) + +const ( + // ServiceEnvironmentProduction represents the production self-managed or cloud + // environments. This can be configured explicitly with MM_SERVICEENVIRONMENT explicitly + // set to "production", but is also the default for any production builds. + ServiceEnvironmentProduction = "production" + // ServiceEnvironmentTest represents testing environments in which MM_SERVICEENVIRONMENT + // is set explicitly to "test". + ServiceEnvironmentTest = "test" + // ServiceEnvironmentDev represents development environments. This can be configured + // explicitly with MM_SERVICEENVIRONMENT set to "dev", but is also the default for any + // non-production builds. + ServiceEnvironmentDev = "dev" +) + +// GetServiceEnvironment returns the currently configured external service environment, +// deciding which public key is used to validate enterprise licenses, which telemetry keys are +// active, and which Stripe keys are in use. +// +// To configure an environment other than default, set MM_SERVICEENVIRONMENT before +// starting the application. Production builds default to ServiceEnvironmentProduction, and +// non-production builds default to ServiceEnvironmentDev. +// +// Note that this configuration is explicitly not part of the model.Config data structure, as it +// should never be persisted to the config store nor accidentally configured in any other way than +// the MM_SERVICEENVIRONMENT variable. +func GetServiceEnvironment() string { + externalServiceEnvironment := strings.TrimSpace(strings.ToLower(os.Getenv("MM_SERVICEENVIRONMENT"))) + + switch externalServiceEnvironment { + case ServiceEnvironmentProduction, ServiceEnvironmentTest, ServiceEnvironmentDev: + return externalServiceEnvironment + } + + return getDefaultServiceEnvironment() +} diff --git a/server/public/model/license_key.go b/server/public/model/service_environment_dev_default.go similarity index 55% rename from server/public/model/license_key.go rename to server/public/model/service_environment_dev_default.go index a55fa1df07..8b665c36ad 100644 --- a/server/public/model/license_key.go +++ b/server/public/model/service_environment_dev_default.go @@ -1,7 +1,10 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -//go:build !testlicensekey + +//go:build !production package model -const isProdLicensePublicKey = true +func getDefaultServiceEnvironment() string { + return ServiceEnvironmentDev +} diff --git a/server/public/model/license_key_test_env.go b/server/public/model/service_environment_production_default.go similarity index 54% rename from server/public/model/license_key_test_env.go rename to server/public/model/service_environment_production_default.go index 189dcd40ee..4d027bf595 100644 --- a/server/public/model/license_key_test_env.go +++ b/server/public/model/service_environment_production_default.go @@ -1,7 +1,10 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -//go:build testlicensekey + +//go:build production package model -const isProdLicensePublicKey = false +func getDefaultServiceEnvironment() string { + return ServiceEnvironmentProduction +} diff --git a/server/public/model/service_environment_test.go b/server/public/model/service_environment_test.go new file mode 100644 index 0000000000..a327fbc34d --- /dev/null +++ b/server/public/model/service_environment_test.go @@ -0,0 +1,47 @@ +package model_test + +import ( + "os" + "testing" + + "github.com/mattermost/mattermost-server/server/public/model" + "github.com/stretchr/testify/require" +) + +// TestGetServiceEnvironment verifies the semantics of the MM_SERVICEENVIRONMENT environment +// variable when explicitly configured as well as when left undefined or empty. +// +// To guard against accidental use of production keys (especially telemetry), all development and +// testing defaults to the test service environment, making it impossible to test the production +// semantics at the unit test level. Validating the default, enterprise service environment is left +// to smoketests before releasing. +func TestGetServiceEnvironment(t *testing.T) { + t.Run("no env defaults to test (without production tag)", func(t *testing.T) { + require.Equal(t, model.ServiceEnvironmentTest, model.GetServiceEnvironment()) + }) + t.Run("empty string defaults to test (without production tag)", func(t *testing.T) { + os.Setenv("MM_SERVICEENVIRONMENT", "") + defer os.Unsetenv("MM_SERVICEENVIRONMENT") + require.Equal(t, model.ServiceEnvironmentTest, model.GetServiceEnvironment()) + }) + t.Run("production", func(t *testing.T) { + os.Setenv("MM_SERVICEENVIRONMENT", "production") + defer os.Unsetenv("MM_SERVICEENVIRONMENT") + require.Equal(t, model.ServiceEnvironmentProduction, model.GetServiceEnvironment()) + }) + t.Run("test", func(t *testing.T) { + os.Setenv("MM_SERVICEENVIRONMENT", "test") + defer os.Unsetenv("MM_SERVICEENVIRONMENT") + require.Equal(t, model.ServiceEnvironmentTest, model.GetServiceEnvironment()) + }) + t.Run("dev", func(t *testing.T) { + os.Setenv("MM_SERVICEENVIRONMENT", "dev") + defer os.Unsetenv("MM_SERVICEENVIRONMENT") + require.Equal(t, model.ServiceEnvironmentDev, model.GetServiceEnvironment()) + }) + t.Run("whitespace and case insensitive", func(t *testing.T) { + os.Setenv("MM_SERVICEENVIRONMENT", " Test ") + defer os.Unsetenv("MM_SERVICEENVIRONMENT") + require.Equal(t, model.ServiceEnvironmentTest, model.GetServiceEnvironment()) + }) +} diff --git a/webapp/boards/src/index.tsx b/webapp/boards/src/index.tsx index 6a1ba97a96..e699fc7b91 100644 --- a/webapp/boards/src/index.tsx +++ b/webapp/boards/src/index.tsx @@ -12,6 +12,8 @@ import {SuiteWindow} from 'src/types/index' import {PluginRegistry} from 'src/types/mattermost-webapp' +import {ServiceEnvironment} from '@mattermost/types/config' + import {RudderTelemetryHandler, rudderAnalytics} from 'src/rudder' import appBarIcon from 'static/app-bar-icon.png' @@ -83,8 +85,19 @@ function getSubpath(siteURL: string): string { return url.pathname.replace(/\/+$/, '') } -const TELEMETRY_RUDDER_KEY = 'placeholder_boards_rudder_key' -const TELEMETRY_RUDDER_DATAPLANE_URL = 'placeholder_rudder_dataplane_url' +const TELEMETRY_RUDDER_URL = 'https://pdat.matterlytics.com' +const TELEMETRY_RUDDER_KEY_PROD = '1myWcDbTkIThnpPYyms7DKlmQWl' +const TELEMETRY_RUDDER_KEY_TEST = '1myWYwHRDFdLDTpznQ7qFlOPQaa' + +// TO_BE_DEPRECATED_* are placeholders to allow the existing release pipelines to run without +// failing to insert the values that are now hard-coded above. Remove this once we converge +// on the unified delivery pipeline in GitHub. +// +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const TO_BE_DEPRECATED_TELEMETRY_RUDDER_URL = 'placeholder_rudder_dataplane_url' +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const TO_BE_DEPRECATAED_TELEMETRY_RUDDER_KEY = 'placeholder_boards_rudder_key' + const TELEMETRY_OPTIONS = { context: { ip: '0.0.0.0', @@ -512,12 +525,17 @@ export default class Plugin { const config = await octoClient.getClientConfig() if (config?.telemetry) { - let rudderKey = TELEMETRY_RUDDER_KEY - let rudderUrl = TELEMETRY_RUDDER_DATAPLANE_URL - - if (rudderKey.startsWith('placeholder') && rudderUrl.startsWith('placeholder')) { - rudderKey = process.env.RUDDER_KEY as string //eslint-disable-line no-process-env - rudderUrl = process.env.RUDDER_DATAPLANE_URL as string //eslint-disable-line no-process-env + const rudderUrl = TELEMETRY_RUDDER_URL + let rudderKey = '' + switch (mmStore.getState().entities.general.config.ServiceEnvironment) { + case ServiceEnvironment.PRODUCTION: + rudderKey = TELEMETRY_RUDDER_KEY_PROD + break + case ServiceEnvironment.TEST: + rudderKey = TELEMETRY_RUDDER_KEY_TEST + break + case ServiceEnvironment.DEV: + break } if (rudderKey !== '') { diff --git a/webapp/boards/webpack.config.js b/webapp/boards/webpack.config.js index f870adc80d..110c15b184 100644 --- a/webapp/boards/webpack.config.js +++ b/webapp/boards/webpack.config.js @@ -172,15 +172,6 @@ config.output = { chunkFilename: '[name].[contenthash].js', }; -/* eslint-disable no-process-env */ -const env = {}; -env.RUDDER_KEY = JSON.stringify(process.env.RUDDER_KEY || ''); -env.RUDDER_DATAPLANE_URL = JSON.stringify(process.env.RUDDER_DATAPLANE_URL || ''); - -config.plugins.push(new webpack.DefinePlugin({ - 'process.env': env, -})); - config.plugins.push(new MiniCssExtractPlugin({ filename: '[name].[contenthash].css', chunkFilename: '[name].[contenthash].css', diff --git a/webapp/channels/src/components/admin_console/billing/payment_info_edit.tsx b/webapp/channels/src/components/admin_console/billing/payment_info_edit.tsx index 8d2fff2e89..b594c635ce 100644 --- a/webapp/channels/src/components/admin_console/billing/payment_info_edit.tsx +++ b/webapp/channels/src/components/admin_console/billing/payment_info_edit.tsx @@ -25,7 +25,7 @@ import {CloudLinks} from 'utils/constants'; import BlockableLink from 'components/admin_console/blockable_link'; import FormattedMarkdownMessage from 'components/formatted_markdown_message'; import PaymentForm from 'components/payment_form/payment_form'; -import {STRIPE_CSS_SRC, STRIPE_PUBLIC_KEY} from 'components/payment_form/stripe'; +import {STRIPE_CSS_SRC, getStripePublicKey} from 'components/payment_form/stripe'; import SaveButton from 'components/save_button'; import AlertBanner from 'components/alert_banner'; import AdminHeader from 'components/widgets/admin_console/admin_header'; @@ -58,6 +58,8 @@ const PaymentInfoEdit: React.FC = () => { card: {} as any, }); + const stripePublicKey = useSelector((state: GlobalState) => getStripePublicKey(state)); + useEffect(() => { dispatch(getCloudCustomer()); }, []); @@ -83,7 +85,7 @@ const PaymentInfoEdit: React.FC = () => { }; if (!stripePromise) { - stripePromise = loadStripe(STRIPE_PUBLIC_KEY); + stripePromise = loadStripe(stripePublicKey); } return ( diff --git a/webapp/channels/src/components/common/hooks/useLoadStripe.ts b/webapp/channels/src/components/common/hooks/useLoadStripe.ts index c048ae171d..1cafaabd27 100644 --- a/webapp/channels/src/components/common/hooks/useLoadStripe.ts +++ b/webapp/channels/src/components/common/hooks/useLoadStripe.ts @@ -2,22 +2,26 @@ // See LICENSE.txt for license information. import {useEffect, useRef, useState} from 'react'; +import {useSelector} from 'react-redux'; import {Stripe} from '@stripe/stripe-js'; import {loadStripe} from '@stripe/stripe-js/pure'; // https://github.com/stripe/stripe-js#importing-loadstripe-without-side-effects -import {STRIPE_PUBLIC_KEY} from 'components/payment_form/stripe'; +import {GlobalState} from 'types/store'; + +import {getStripePublicKey} from 'components/payment_form/stripe'; // reloadHint export default function useLoadStripe(reloadHint?: number) { const stripeRef = useRef(null); const [, setDone] = useState(false); + const stripePublicKey = useSelector((state: GlobalState) => getStripePublicKey(state)); useEffect(() => { if (stripeRef.current) { return; } - loadStripe(STRIPE_PUBLIC_KEY).then((stripe: Stripe | null) => { + loadStripe(stripePublicKey).then((stripe: Stripe | null) => { stripeRef.current = stripe; // deliberately cause a rerender so that the input can render. diff --git a/webapp/channels/src/components/payment_form/stripe.ts b/webapp/channels/src/components/payment_form/stripe.ts index 1d6587c377..010484c965 100644 --- a/webapp/channels/src/components/payment_form/stripe.ts +++ b/webapp/channels/src/components/payment_form/stripe.ts @@ -10,6 +10,9 @@ import { SetupIntent, } from '@stripe/stripe-js'; +import {GlobalState} from 'types/store'; +import {ServiceEnvironment} from '@mattermost/types/config'; + type ConfirmCardSetupType = (clientSecret: string, data?: ConfirmCardSetupData | undefined, options?: ConfirmCardSetupOptions | undefined) => Promise<{ setupIntent?: SetupIntent | undefined; error?: StripeError | undefined }> | undefined; function prodConfirmCardSetup(confirmCardSetup: ConfirmCardSetupType): ConfirmCardSetupType { @@ -26,4 +29,15 @@ export const getConfirmCardSetup = (isCwsMockMode?: boolean) => (isCwsMockMode ? export const STRIPE_CSS_SRC = 'https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i&display=swap'; //eslint-disable-next-line no-process-env -export const STRIPE_PUBLIC_KEY = process.env.STRIPE_PUBLIC_KEY || 'pk_test_ttEpW6dCHksKyfAFzh6MvgBj'; + +export const getStripePublicKey = (state: GlobalState) => { + switch (state.entities.general.config.ServiceEnvironment) { + case ServiceEnvironment.PRODUCTION: + return 'pk_live_cDF5gYLPf5vQjJ7jp71p7GRK'; + case ServiceEnvironment.TEST: + case ServiceEnvironment.DEV: + return 'pk_test_ttEpW6dCHksKyfAFzh6MvgBj'; + } + + return ''; +}; diff --git a/webapp/channels/src/components/purchase_modal/index.ts b/webapp/channels/src/components/purchase_modal/index.ts index 3ca17957e6..a4bee92484 100644 --- a/webapp/channels/src/components/purchase_modal/index.ts +++ b/webapp/channels/src/components/purchase_modal/index.ts @@ -30,6 +30,8 @@ import withGetCloudSubscription from 'components/common/hocs/cloud/with_get_clou import {findOnlyYearlyProducts} from 'utils/products'; import {getCloudContactSalesLink, getCloudSupportLink} from 'utils/contact_support_sales'; +import {getStripePublicKey} from 'components/payment_form/stripe'; + const PurchaseModal = makeAsyncComponent('PurchaseModal', React.lazy(() => import('./purchase_modal'))); function mapStateToProps(state: GlobalState) { @@ -46,6 +48,7 @@ function mapStateToProps(state: GlobalState) { const companyName = customer?.name || ''; const contactSalesLink = getCloudContactSalesLink(firstName, lastName, companyName, customerEmail, 'mattermost', 'in-product-cloud'); const contactSupportLink = getCloudSupportLink(customerEmail, 'Cloud purchase', '', window.location.host); + const stripePublicKey = getStripePublicKey(state); return { show: isModalOpen(state, ModalIdentifiers.CLOUD_PURCHASE), @@ -64,6 +67,7 @@ function mapStateToProps(state: GlobalState) { theme: getTheme(state), isDelinquencyModal, usersCount: Number(getAdminAnalytics(state)!.TOTAL_USERS) || 1, + stripePublicKey, }; } type Actions = { diff --git a/webapp/channels/src/components/purchase_modal/purchase_modal.tsx b/webapp/channels/src/components/purchase_modal/purchase_modal.tsx index 932ac74fcd..fa4f084dde 100644 --- a/webapp/channels/src/components/purchase_modal/purchase_modal.tsx +++ b/webapp/channels/src/components/purchase_modal/purchase_modal.tsx @@ -36,7 +36,7 @@ import { import {goToMattermostContactSalesForm} from 'utils/contact_support_sales'; import PaymentDetails from 'components/admin_console/billing/payment_details'; -import {STRIPE_CSS_SRC, STRIPE_PUBLIC_KEY} from 'components/payment_form/stripe'; +import {STRIPE_CSS_SRC} from 'components/payment_form/stripe'; import RootPortal from 'components/root_portal'; import FullScreenModal from 'components/widgets/modals/full_screen_modal'; import OverlayTrigger from 'components/overlay_trigger'; @@ -130,6 +130,8 @@ type Props = { // callerCTA is information about the cta that opened this modal. This helps us provide a telemetry path // showing information about how the modal was opened all the way to more CTAs within the modal itself callerCTA?: string; + + stripePublicKey: string; actions: { openModal:

(modalData: ModalData

) => void; closeModal: () => void; @@ -964,7 +966,7 @@ class PurchaseModal extends React.PureComponent { ); } if (!stripePromise) { - stripePromise = loadStripe(STRIPE_PUBLIC_KEY); + stripePromise = loadStripe(this.props.stripePublicKey); } return ( diff --git a/webapp/channels/src/components/root/root.test.tsx b/webapp/channels/src/components/root/root.test.tsx index d5cb9c6587..eae461b83c 100644 --- a/webapp/channels/src/components/root/root.test.tsx +++ b/webapp/channels/src/components/root/root.test.tsx @@ -16,6 +16,9 @@ import * as GlobalActions from 'actions/global_actions'; import Constants, {StoragePrefixes, WindowSizes} from 'utils/constants'; import matchMedia from 'tests/helpers/match_media.mock'; import {ProductComponent} from 'types/store/plugins'; +import {ServiceEnvironment} from '@mattermost/types/config'; + +import store from 'stores/redux_store.jsx'; jest.mock('rudder-sdk-js', () => ({ identify: jest.fn(), @@ -201,12 +204,16 @@ describe('components/Root', () => { describe('onConfigLoaded', () => { afterEach(() => { Client4.telemetryHandler = undefined; - - Constants.TELEMETRY_RUDDER_KEY = 'placeholder_rudder_key'; - Constants.TELEMETRY_RUDDER_DATAPLANE_URL = 'placeholder_rudder_dataplane_url'; }); test('should not set a TelemetryHandler when onConfigLoaded is called if Rudder is not configured', () => { + store.dispatch({ + type: GeneralTypes.CLIENT_CONFIG_RECEIVED, + data: { + ServiceEnvironment: ServiceEnvironment.DEV, + }, + }); + const wrapper = shallow(); Client4.trackEvent('category', 'event'); @@ -217,8 +224,12 @@ describe('components/Root', () => { }); test('should set a TelemetryHandler when onConfigLoaded is called if Rudder is configured', () => { - Constants.TELEMETRY_RUDDER_KEY = 'testKey'; - Constants.TELEMETRY_RUDDER_DATAPLANE_URL = 'url'; + store.dispatch({ + type: GeneralTypes.CLIENT_CONFIG_RECEIVED, + data: { + ServiceEnvironment: ServiceEnvironment.TEST, + }, + }); const wrapper = shallow(); @@ -236,8 +247,12 @@ describe('components/Root', () => { // Simulate an error occurring and the callback not getting called }); - Constants.TELEMETRY_RUDDER_KEY = 'testKey'; - Constants.TELEMETRY_RUDDER_DATAPLANE_URL = 'url'; + store.dispatch({ + type: GeneralTypes.CLIENT_CONFIG_RECEIVED, + data: { + ServiceEnvironment: ServiceEnvironment.TEST, + }, + }); const wrapper = shallow(); diff --git a/webapp/channels/src/components/root/root.tsx b/webapp/channels/src/components/root/root.tsx index 36bd42eddf..878a2cf31f 100644 --- a/webapp/channels/src/components/root/root.tsx +++ b/webapp/channels/src/components/root/root.tsx @@ -93,6 +93,7 @@ import {applyLuxonDefaults} from './effects'; import RootProvider from './root_provider'; import RootRedirect from './root_redirect'; +import {ServiceEnvironment} from '@mattermost/types/config'; const CreateTeam = makeAsyncComponent('CreateTeam', LazyCreateTeam); const ErrorPage = makeAsyncComponent('ErrorPage', LazyErrorPage); @@ -229,17 +230,23 @@ export default class Root extends React.PureComponent { } onConfigLoaded = () => { + const config = getConfig(store.getState()); const telemetryId = this.props.telemetryId; - let rudderKey: string | null | undefined = Constants.TELEMETRY_RUDDER_KEY; - let rudderUrl: string | null | undefined = Constants.TELEMETRY_RUDDER_DATAPLANE_URL; - - if (rudderKey.startsWith('placeholder') && rudderUrl.startsWith('placeholder')) { - rudderKey = process.env.RUDDER_KEY; //eslint-disable-line no-process-env - rudderUrl = process.env.RUDDER_DATAPLANE_URL; //eslint-disable-line no-process-env + const rudderUrl = 'https://pdat.matterlytics.com'; + let rudderKey = ''; + switch (config.ServiceEnvironment) { + case ServiceEnvironment.PRODUCTION: + rudderKey = '1aoejPqhgONMI720CsBSRWzzRQ9'; + break; + case ServiceEnvironment.TEST: + rudderKey = '1aoeoCDeh7OCHcbW2kseWlwUFyq'; + break; + case ServiceEnvironment.DEV: + break; } - if (rudderKey != null && rudderKey !== '' && this.props.telemetryEnabled) { + if (rudderKey !== '' && this.props.telemetryEnabled) { const rudderCfg: {setCookieDomain?: string} = {}; const siteURL = getConfig(store.getState()).SiteURL; if (siteURL !== '') { diff --git a/webapp/channels/src/utils/constants.tsx b/webapp/channels/src/utils/constants.tsx index 4379d79b32..469f9b7634 100644 --- a/webapp/channels/src/utils/constants.tsx +++ b/webapp/channels/src/utils/constants.tsx @@ -1974,8 +1974,6 @@ export const Constants = { AUTOCOMPLETE_SPLIT_CHARACTERS: ['.', '-', '_'], ANIMATION_TIMEOUT: 1000, SEARCH_TIMEOUT_MILLISECONDS: 100, - TELEMETRY_RUDDER_KEY: 'placeholder_rudder_key', - TELEMETRY_RUDDER_DATAPLANE_URL: 'placeholder_rudder_dataplane_url', TEAMMATE_NAME_DISPLAY: { SHOW_USERNAME: 'username', SHOW_NICKNAME_FULLNAME: 'nickname_full_name', diff --git a/webapp/channels/webpack.config.js b/webapp/channels/webpack.config.js index a366d2b5f6..90eea50f32 100644 --- a/webapp/channels/webpack.config.js +++ b/webapp/channels/webpack.config.js @@ -410,20 +410,14 @@ if (DEV) { config.devtool = 'source-map'; } -const env = { - STRIPE_PUBLIC_KEY: JSON.stringify(process.env.STRIPE_PUBLIC_KEY || ''), -}; +const env = {}; if (DEV) { env.PUBLIC_PATH = JSON.stringify(publicPath); - env.RUDDER_KEY = JSON.stringify(process.env.RUDDER_KEY || ''); - env.RUDDER_DATAPLANE_URL = JSON.stringify(process.env.RUDDER_DATAPLANE_URL || ''); if (process.env.MM_LIVE_RELOAD) { config.plugins.push(new LiveReloadPlugin()); } } else { env.NODE_ENV = JSON.stringify('production'); - env.RUDDER_KEY = JSON.stringify(process.env.RUDDER_KEY || ''); - env.RUDDER_DATAPLANE_URL = JSON.stringify(process.env.RUDDER_DATAPLANE_URL || ''); } config.plugins.push(new webpack.DefinePlugin({ diff --git a/webapp/platform/types/src/config.ts b/webapp/platform/types/src/config.ts index 6a2f3ac48a..6b8e0d653d 100644 --- a/webapp/platform/types/src/config.ts +++ b/webapp/platform/types/src/config.ts @@ -203,6 +203,7 @@ export type ClientConfig = { PersistentNotificationIntervalMinutes: string; AllowPersistentNotificationsForGuests: string; DelayChannelAutocomplete: 'true' | 'false'; + ServiceEnvironment: string; }; export type License = { @@ -948,3 +949,9 @@ export enum CollapsedThreads { DEFAULT_OFF = 'default_off', ALWAYS_ON = 'always_on', } + +export enum ServiceEnvironment { + PRODUCTION = 'production', + TEST = 'test', + DEV = 'dev', +}