* MM-68547: Tighten authorization on group syncable link and patch endpoints
Adds an additional permission check on the group syncable link and patch
endpoints. Callers must hold the role-management permission for the
target team or channel (or the sysconsole groups-management permission).
Made-with: Cursor
* Linting
* MM-68547: Extend group syncable scheme_admin authorization checks
Gate any explicit scheme_admin value (in either direction) on link and
patch. Populate SchemeAdmin in the singular getGroupSyncable so that
patches that do not touch scheme_admin no longer overwrite the persisted
value. Restrict PermittedSyncableAdmins to active syncables. Start the
link upsert from the existing active row to preserve fields the caller
did not, or could not, set.
Made-with: Cursor
* MM-68547: Add store-layer regression coverage for SchemeAdmin handling
Extend testGetGroupSyncable to round-trip SchemeAdmin: true through
UpdateGroupSyncable and re-fetch, locking in that getGroupSyncable
populates the field from the persisted row.
Strengthen groupTestPermittedSyncableAdmins{Team,Channel} to assert
that DeleteGroupSyncable preserves SchemeAdmin in the persisted row
and that PermittedSyncableAdmins still excludes the row, making the
coupling between the two store changes explicit.
Made-with: Cursor
* MM-68547: Fix group details role-change dedup on remove
The roleChangeKey helper was reading team_id/channel_id from the items
in itemsToRemove, but onRemoveTeamOrChannel pushes those items with a
generic id field. The deletion of the staged role change in
handleRemovedTeamsAndChannels therefore never matched the key produced
by onChangeRoles, and a stale patchGroupSyncable was dispatched after
the unlink.
Accept either id or team_id/channel_id when computing the key. Also
extend the e2e assertion to verify the channel removal took effect
(delete_at != 0) alongside the existing scheme_admin check.
Made-with: Cursor
* MM-68547: Mirror delete_at assertion on the removed-team e2e test
The team variant of "does not update the role of a removed X" was left
asserting only on scheme_admin. Add the matching delete_at != 0 check
already present in the channel variant so both tests verify the same
user-visible contract.
Made-with: Cursor
* Skip SyncSyncableRoles if no scheme_admin
(cherry picked from commit 8c72083414)
Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>
* Remove unused property fields index
* Update server/channels/db/migrations/migrations.list
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Skip sqlstore DB setup during go test -list discovery (#36249)
sqlstore's TestMain calls sqlstore.InitTest (which opens postgres and
drops tables) before mainHelper.Main, so the -test.list bailout added
in #36222 never fired and shard-split discovery failed on the GitHub
host. Bail out at the top of TestMain instead, and restore HEAVY_MS
so sqlstore can still be treated as whole.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
(cherry picked from commit 6ce4db65dc)
* Revert test fix that is not needed on the v11.7 release branch
---------
Co-authored-by: David Krauser <david@krauser.org>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Fix silent test discovery failure in sharded CI (#36222)
* Raise shard-split HEAVY_MS above sqlstore timing (#36233)
Made-with: Cursor
(cherry picked from commit 795672f077)
---------
Co-authored-by: David Krauser <david@krauser.org>
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
* MM-68356 - ensure files are stripped when session is nil for fail-secure handling
* Add test for file stripping in permalink preview when session is nil
(cherry picked from commit 983ea5a49f)
Co-authored-by: Pablo Vélez <pablovv2012@gmail.com>
* MM-67592 - be changes for team admin abac channels (#35353)
* MM-67592 - be changes for team admin abac channels
* Revert team-scoped API routes, keep app layer business logic
* move from config to permission; Add cluster-aware LRU cache for policy team scope lookup
* remove unnecessary references to config value
* local/remote cache invalidation consistency for policy scope
* Replace policy scope cache with store-level team scope query
* rename functions and add comments to query
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM 67594 - policies CUD operations to team settings modal channels ABAC (#35590)
* MM-67592 - be changes for team admin abac channels
* Revert team-scoped API routes, keep app layer business logic
* move from config to permission; Add cluster-aware LRU cache for policy team scope lookup
* remove unnecessary references to config value
* local/remote cache invalidation consistency for policy scope
* Replace policy scope cache with store-level team scope query
* format files correctly
* fix mock expectations for store-query approach in tests
* rename functions and add comments to query
* revert error ids to original to prevent break tests
* adjust translations
* MM-67669 - add tab to team settings modal and basic listing
* adjust tests and fix linter
* use existing search api logic
* fix style and adjust flaky test to clean up and restore orinals
* address ai corabbit feedback and fix linter
* fix unit tests
* MM-67592 - be changes for team admin abac channels (#35353)
* MM-67592 - be changes for team admin abac channels
* fix linter
* fix ts linter for playwright
* Revert team-scoped API routes, keep app layer business logic
* move from config to permission; Add cluster-aware LRU cache for policy team scope lookup
* remove unnecessary references to config value
* local/remote cache invalidation consistency for policy scope
* Replace policy scope cache with store-level team scope query
* format files correctly
* fix mock expectations for store-query approach in tests
* rename functions and add comments to query
* revert error ids to original to prevent break tests
* adjust translations
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-67594 - support cud operations for team abac BE changes
* create the team settings policy edit section, reuse most components, add basic e2e
* move optional refresh policy list button to list component
* temp get team admins cud policies and sync job
* enhance validation and adjust e2e
* Fix testExpression permission; fix pagination of team policies; add isValidId validation
* adjust styles, handling renaming and add permission migrations
* update the permissions names, use the simple confirmation modal, define the delete modal
* fix policy deletion flow
* fix some linter issues and adjust helper tests
* remove delete from list and fix e2e
* code comments clean up
* remove CEL editor for now, clean styles, enhance e2e
* fix linter, adjust unit test
* fix linter and add missing translation
* fix policy deletion ownership and sanitize test expression
* fixed e2e tests
* rollback orphaned policy on failed channel assignment
* enforce channelless check before last_team_id fallback
* enforce channelless guard on assign fallback too
* add translations missing
* add teamId to audit payload when present
* fix refresh button pagination reset
* fix null safety in channel selector loadChannels
* use responsive width cap for team settings modal and adjust header size
* remove redundant raw term from channel search URL, add showRefreshButton prop to PolicyList component
* handle error when stamping last team ID on channelless policy
* replace Props-based ownership with in-memory LRU cache, disable save on zero channels
* make e2e tests more reliable in CI
* test skip if no license valid found
* add childCount guard to cache-hit paths and reduce TTL to 5s
* fix e2e, adjust translation
* address review feedback: flatten permission checks and separate error types
- Flatten nested permission branching in deleteAccessControlPolicy using
early returns to reduce indentation (review: isacikgoz)
- Validate teamID as input (400) before using it for permission checks (403)
in testExpression and validateExpressionAgainstRequester handlers
- Remove redundant hasSystemPermission check in searchAccessControlPolicies
since system_admin role already includes manage_team_access_rules
- Refactor ValidateTeamAdminPolicyOwnership to return (bool, *model.AppError)
separating "not owned" from "internal error" across all 8 call sites
- Update tests to assert on both return values
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* add persistent team scope to access control policies, replace in-memory cache
* fix translation
* fix case-insensitive policy search and sanitize search term input
* make policies tests have a unique name
* decouple scope/scopeID filter from TeamID in policy store
* Fix authZ bypass searchChannelsForAccessControlPolicy by forcing TeamIds to authorized team
* show unsaved changes on navigator back, and list all private channels on load
* filter already applied channels to a policy
* adjust the styles to dark mode; do not show added channels to the policy in the add channels modal
* fix linter
* MM-67967 add sync status footer to team settings (#35729)
* MM-67967 add sync status footer to team settings
* remove magic numbers and strings and polish the code
* fix linter
* fix linter: replace interface{} with any per gofmt rewrite rule
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refine getJobsByType team-scoped filtering and permissions
* fix sync footer stuck in syncing state on job creation error
* fix team-scoped job pagination in getJobsByType
* Fix authZ bypass searchChannelsForAccessControlPolicy by forcing TeamIds to authorized team
* implement ux feedback, change titles font, fix marging and scroll view jump
* MM-68135 - migrate add channels to policy modal to generic modal (#35907)
* MM-67920 unify e2e team settings tests (#35867)
* MM-67920 - extract duplicated policy editor helpers
* remove duplicate team icon test file
* rename Access Control to Membership Policies in e2e
* replace networkidle with explicit element waits
* fix attribute loading issue
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix playwright feedback issues and persist filters to the store layer in the no systemconsole path
* Improve policy scope validation and team admin security checks
* Renamed public channels to "AAA Public Channel %03d" and private ones to "ZZZ Private..." so the 55 public channels now fill the 50-result cap
* fix e2e tests and add new unit tests to improve coverage
* Improve e2e test stability: race condition handling and timeout adjustments
* Improve team-scoped ABAC policies: scope preservation, input validation, shared exclusion
* Add comprehensive ABAC test coverage: team admin ops and security validation to reduce flakyness
* Fix team policy editor back button: preserve navigation intent through Undo
* style: format import statements for better readability
* Enhance access control policy creation for team admins: enforce scope stamping from query parameters to prevent unauthorized team assignments
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add PermissionCreateAgent server-side permission definition
Define PermissionCreateAgent in the model layer with system scope,
add to SystemScopedPermissionsMinusSysconsole (feeds AllPermissions),
grant to system_user in MakeDefaultRoles(), and register a permissions
migration for existing installations (system_admin + system_user).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add exhaustive tests for PermissionCreateAgent permission
Model tests: verify create_agent is in AllPermissions, has system scope,
correct i18n fields, present in system_admin and system_user default roles,
and absent from system_guest.
Migration test: verify getAddCreateAgentPermissionMigration adds create_agent
to both system_admin and system_user, and is idempotent on re-run.
Also register the migration key in testlib mock store so server initialization
skips it during test setup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add webapp permission constants and i18n for create_agent
Add CREATE_AGENT constant to permissions.ts, display strings with
defineMessages in permissions.tsx, and i18n entries in en.json so the
permission appears in System Console Permission Schemes UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Clean up tests and minor fixups for create_agent permission
Consolidate role_test.go into table-driven tests, remove redundant comments
in permissions_migrations_test.go, add .planning/ to .gitignore, and
refresh webapp/package-lock.json.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Split create_agent into manage_own_agent and manage_others_agent
Replace PermissionCreateAgent with system-scoped own/others permissions,
update migration and defaults, and wire System Scheme UI for integrations.
Made-with: Cursor
* fixes
* Stabilize autotranslation E2E by pinning mock source language
Set LibreTranslate mock to English before the pre-enable post and Spanish
before the post-enable message so parallel tests cannot leave the mock in
a state where the new message is not translated.
Made-with: Cursor
* Revert package-lock, add more chnages
* Revert "Revert package-lock, add more chnages"
This reverts commit 7f6752c2e0.
* Drop unrelated autotranslation E2E tweak; restore package-lock
The Playwright autotranslation change was not caused by MM-65671. Revert
that test edit and restore webapp/package-lock.json after an accidental
revert of the prior package-lock update.
Made-with: Cursor
* Put package-lock back again
* fixes
* Fix migration tests for manage_own_agent on system_user role
Made-with: Cursor
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Add bulk set (replace) channel memberships API
PUT /api/v4/channels/{channel_id}/members accepts a complete desired
membership list and reconciles it against the current state, adding
missing users and removing extras while leaving existing members
untouched. Results stream back as NDJSON with configurable batch size
and delay to manage server load. Sysadmin only. Private channels
cannot be emptied entirely.
Rows created before the CreatedBy/UpdatedBy columns were added have NULL
in those fields, causing a scan error when reading them. Wraps those
columns with COALESCE(..., '') in the tableSelectQuery and in the Upsert
RETURNING clause.
Also removes the propertyValueColumns shared variable, inlining the
column lists directly in each INSERT statement to match the pattern used
in the property field store.
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
TestChannelStore sub-tests create channels, members, and team members
using fake TeamIds and UserIds (model.NewId() for non-existent rows).
These records are left in the database and cause integrity tests
(TestCheck*) running in the same binary to fail their full-table scans.
Register a t.Cleanup on TestChannelStore that purges the affected
tables entirely. A blanket purge is safe: the schema enforces no FK
constraints, and every test suite creates its own data independently.
* Add health flag to fast-fail when ES is offline
When Elasticsearch goes offline, the watcher takes up to 3 health
check cycles (~180 s) to detect the outage and stop the engine.
During that window every search query blocks for 30 s before
falling back to the database, and indexing goroutines pile up
unboundedly — causing server-wide slowness, posting failures,
and duplicate posts from client retries (MM-66612).
Introduce a `healthy` atomic flag on each ES/OpenSearch engine.
The watcher sets it to false on the *first* health-check failure
and back to true on success. `Broker.GetActiveEngines()` now
requires both `IsActive()` and `IsHealthy()`, so all search and
indexing operations skip the unhealthy engine immediately. The
existing 3-failure stop/restart cycle is unchanged and continues
to handle full recovery.
* Fix other tests
* Fix unrelated flaky test
* Use atomic.int32 everywhere
* Revert "Fix unrelated flaky test"
This reverts commit a289015637.
* Improve coverage for ActiveEngine/GetActiveEngines
* Document expectations on SearchEngineInterface
* Use mock.On("call").Unset
* Remove healthCalls to avoid a flaky test
* Be explicit on Unset
* Log any change in the health of the search engine
* Test the healthy<->unhealthy changes are logged
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-68235: Rename user-visible "Custom Profile Attributes" to "User Attributes"
Update all English i18n translation values and inline
defaultMessage strings to use the current product name
"User Attributes" instead of the old "Custom Profile
Attributes" / CPA naming.
Add naming-history comments to key CPA source files
(model, app, api4, admin component) explaining that
internal identifiers retain the old naming for backward
compatibility with REST APIs, WebSocket events, and the
Property System Architecture group name. This helps
future developers understand the mapping without needing
to track down the rename history.
* Fix missed lowercase "custom profile attribute" strings
* MM-67505 Add AnalyticsQueryTimeout setting and use when refreshing materialized views
* Fix last minute i18n change
* Disallow 0 values for AnalyticsQueryTimeout
* Fix E2E test config
* Fix post store tests crashing
* Update snapshot and revert accidental changes to it
* Add HealthCheck to search engine interface
The watcher (next commit) needs a way to probe whether
ES/OS is still reachable. Each backend does a cluster
health request with a 5 s timeout, snapshotting the
client under the read lock so the network call doesn't
block Stop()/Start().
* Add search engine background watcher
The old fire-and-forget ps.Go() calls for ES startup
had no retry, no health monitoring, and no backoff.
If Start() failed at boot the engine stayed down until
the next config change or server restart.
Replace with a single watcher goroutine that:
- retries Start() with exponential backoff (15 s–5 m)
- runs periodic health checks once active
- stops the engine after N consecutive failures
- reacts immediately to config/license changes
- shuts down cleanly via context cancellation
* Add tests for search engine watcher
Covers retry-then-health transition, exponential
backoff capping, disable/enable park-unpark via
notify, intermittent vs threshold health failures,
and edge cases (Start ok but not active, rapid
config changes, failure counter reset).
* Address review comments
* make i18n-extract
* Make Stop() a no-op if already stopped
Both Elasticsearch and OpenSearch Stop() methods returned an error
when the engine was already stopped. This forced every caller to
handle or ignore a non-error condition. Returning nil instead is
more idiomatic and simplifies all call sites.
* Simplify config listener branches
Merge the connectionChanged and startingES/stoppingES branches
into one. Since Stop() is now a no-op when already stopped, we
can always call Stop() then notify the watcher regardless of
which condition triggered the change.
* Restore license listener conditional order
Keep the original order (license-added first, license-removed
second) to reduce diff noise. The conditions are mutually
exclusive so the order has no semantic effect.
* Log consecutive failures in retry phase
Track and log consecutiveFailures when Start() fails or returns
nil but the engine is not active, so operators can see how many
attempts have been made alongside the backoff duration.
* Clarify health check timer reset placement
Add a comment explaining why the timer reset lives outside the
if/else: both success and below-threshold failure share the same
health interval, while the critical-failure path continues before
reaching this point.
* Remove nested select in disabled-engine path
Replace the nested select block with timer.Stop() + continue.
The main loop's select already handles ctx.Done() and notify,
so stopping the timer is enough to park until one of those fires.
* Add context.Context to Start()
Accept a context in SearchEngineInterface.Start() and propagate
it to all network calls (checkMaxVersion, fetchServerInfo, index
template creation). This lets the watcher's cancellable context
flow through to the HTTP client, so a stuck Start() call returns
promptly on shutdown instead of blocking until TCP timeout.
* Simplify startSearchEngineWatcher comment
Focus on the actual reason (long-lived, owns its lifecycle)
rather than the shutdown-blocking detail, which is less relevant
now that Start() accepts a cancellable context.
* Make the comment on the goroutine more accurate
* Fix log
* Revert the branches merge
This was causing a race condition in the TestElasticsearchAggregation
test.
* Own Start/Stop by the engine watcher
The config listener simply notifies now, so it's easier to follow the
logic of the calls.
* Refactor the engine watcher into its own type
Simplify the code by:
1. Moving the whole watcher into its own type, so that the
PlatformService contains an instance of it, instead of all the locks
and channels
2. Splitting the main loop into functions. John Carmack may not like
this, but it's way easier to read and follow.
* make i18n-extract
* Rename notify > reevaluate
* Park the watcher if there is no license
* Call reevaluate from within requestRestart
* Use RequestTimeoutSeconds instead of hardcoded 5s
* Use atomic.Int32 in the tests as well
* Add defensive code ta watcher exit
Stop the engine if it was still running when the watcher exits, having a
safety net for scenarios like race conditions between Start and a
cancelled context.
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* Reapply "Strip remote_id field from user patch API requests (#35910)" (#35996)
This reverts commit d1ca297721.
* Fix SetUserRemoteID to use test's own database in parallel mode
Replace testlib.SetUserRemoteID (which used mainHelper's shared
database) with a squirrel query against GetInternalMasterDB(), which
resolves to the correct per-test pooled database under parallel
execution.
* fix: add explicit permission grant in team members test
TestGetTeamMembersForUserRoleDataSanitization was relying on a permission
side-effect leaked from concurrent tests. Under fullyparallel, another test
temporarily adds PermissionReadOtherUsersTeams to system_user role, which
the team admin subtest accidentally benefits from. Under sequential execution
(binary parameters mode), no concurrent test leaks this permission, so the
team admin correctly gets 403.
Fix by explicitly granting ReadOtherUsersTeams in the subtest setup, matching
the pattern used in adjacent subtests.
Release Note
NONE
Co-authored-by: Claude <claude@anthropic.com>
* fix: remove explanatory comment per review feedback
---------
Co-authored-by: Claude <claude@anthropic.com>
* Remove system_secure_connection_manager role
The dedicated role for delegating secure connection management is no
longer needed. The manage_secure_connections permission remains and
continues to be granted to system admins via AllPermissions.
Removes the role definition, migration, permissions migration, UI
components, i18n strings, and all associated tests across server,
webapp, and e2e-tests.
* adds team member data sanitizing
* assert using require
* adds data sanitizing to team members for user endpoint
* team admin data visibility now tests with different user
* Strip remote_id from user patch API requests
* Ignore remote_id in user update API endpoints
Add SetUserRemoteID test helper in testlib to set remote_id via direct SQL,
bypassing the now-protected store Update method. Update existing tests in
app and api4 packages to use the new helper.
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* ci: enable fullyparallel mode for server tests
Replace os.Setenv, os.Chdir, and global state mutations with
parallel-safe alternatives (t.Setenv, t.Chdir, test hooks) across
37 files. Refactor GetLogRootPath and MM_INSTALL_TYPE to use
package-level test hooks instead of environment variables.
This enables gotestsum --fullparallel, allowing all test packages
to run with maximum parallelism within each shard.
Co-authored-by: Claude <claude@anthropic.com>
* ci: split fullyparallel from continue-on-error in workflow template
- Add new boolean input 'allow-failure' separate from 'fullyparallel'
- Change continue-on-error to use allow-failure instead of fullyparallel
- Update server-ci.yml to pass allow-failure: true for test coverage job
- Allows independent control of parallel execution and failure tolerance
Co-authored-by: Claude <claude@anthropic.com>
* fix: protect TestOverrideLogRootPath with sync.Mutex for parallel tests
- Replace global var TestOverrideLogRootPath with mutex-protected functions
- Add SetTestOverrideLogRootPath() and getTestOverrideLogRootPath() functions
- Update GetLogRootPath() to use thread-safe getter
- Update all test files to use SetTestOverrideLogRootPath() with t.Cleanup()
- Fixes race condition when running tests with t.Parallel()
Co-authored-by: Claude <claude@anthropic.com>
* fix: configure audit settings before server setup in tests
- Move ExperimentalAuditSettings from UpdateConfig() to config defaults
- Pass audit config via app.Config() option in SetupWithServerOptions()
- Fixes audit test setup ordering to configure BEFORE server initialization
- Resolves CodeRabbit's audit config timing issue in api4 tests
Co-authored-by: Claude <claude@anthropic.com>
* fix: implement SetTestOverrideLogRootPath mutex in logger.go
The previous commit updated test callers to use SetTestOverrideLogRootPath()
but didn't actually create the function in config/logger.go, causing build
failures across all CI shards. This commit:
- Replaces the exported var TestOverrideLogRootPath with mutex-protected
unexported state (testOverrideLogRootPath + testOverrideLogRootMu)
- Adds exported SetTestOverrideLogRootPath() setter
- Adds unexported getTestOverrideLogRootPath() getter
- Updates GetLogRootPath() to use the thread-safe getter
- Fixes log_test.go callers that were missed in the previous commit
Co-authored-by: Claude <claude@anthropic.com>
* fix(test): use SetupConfig for access_control feature flag registration
InitAccessControlPolicy() checks FeatureFlags.AttributeBasedAccessControl
at route registration time during server startup. Setting the flag via
UpdateConfig after Setup() is too late — routes are never registered
and API calls return 404.
Use SetupConfig() to pass the feature flag in the initial config before
server startup, ensuring routes are properly registered.
Co-authored-by: Claude <claude@anthropic.com>
* fix(test): restore BurnOnRead flag state in TestRevealPost subtest
The 'feature not enabled' subtest disables BurnOnRead without restoring
it via t.Cleanup. Subsequent subtests inherit the disabled state, which
can cause 501 errors when they expect the feature to be available.
Add t.Cleanup to restore FeatureFlags.BurnOnRead = true after the
subtest completes.
Co-authored-by: Claude <claude@anthropic.com>
* fix(test): restore EnableSharedChannelsMemberSync flag via t.Cleanup
The test disables EnableSharedChannelsMemberSync without restoring it.
If the subtest exits early (e.g., require failure), later sibling
subtests inherit a disabled flag and become flaky.
Add t.Cleanup to restore the flag after the subtest completes.
Co-authored-by: Claude <claude@anthropic.com>
* Fix test parallelism: use instance-scoped overrides and init-time audit config
Replace package-level test globals (TestOverrideInstallType,
SetTestOverrideLogRootPath) with fields on PlatformService so each test
gets its own instance without process-wide mutation. Fix three audit
tests (TestUserLoginAudit, TestLogoutAuditAuthStatus,
TestUpdatePasswordAudit) that configured the audit logger after server
init — the audit logger only reads config at startup, so pass audit
settings via app.Config() at init time instead.
Also revert the Go 1.24.13 downgrade and bump mattermost-govet to
v2.0.2 for Go 1.25.8 compatibility.
* Fix audit unit tests
* Fix MMCLOUDURL unit tests
* Fixed unit tests using MM_NOTIFY_ADMIN_COOL_OFF_DAYS
* Make app migrations idempotent for parallel test safety
Change System().Save() to System().SaveOrUpdate() in all migration
completion markers. When two parallel tests share a database pool entry,
both may race through the check-then-insert migration pattern. Save()
causes a duplicate key fatal crash; SaveOrUpdate() makes the second
write a harmless no-op.
* test: address review feedback on fullyparallel PR
- Use SetLogRootPathOverride() setter instead of direct field access
in platform/support_packet_test.go and platform/log_test.go (pvev)
- Restore TestGetLogRootPath in config/logger_test.go to keep
MM_LOG_PATH env var coverage; test uses t.Setenv so it runs
serially which is fine (pvev)
- Fix misleading comment in config_test.go: code uses t.Setenv,
not os.Setenv (jgheithcock)
Co-authored-by: Claude <claude@anthropic.com>
* fix: add missing os import in post_test.go
The os import was dropped during a merge conflict resolution while
burn-on-read shared channel tests from master still use os.Setenv.
Co-authored-by: Claude <claude@anthropic.com>
---------
Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: wiggin77 <wiggin77@warpmail.net>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Replace hardcoded test passwords with model.NewTestPassword()
Add model.NewTestPassword() utility that generates 14+ character
passwords meeting complexity requirements for FIPS compliance. Replace
all short hardcoded test passwords across the test suite with calls to
this function.
* Enforce FIPS compliance for passwords and HMAC keys
FIPS OpenSSL requires HMAC keys to be at least 14 bytes. PBKDF2 uses
the password as the HMAC key internally, so short passwords cause
PKCS5_PBKDF2_HMAC to fail.
- Add FIPSEnabled and PasswordFIPSMinimumLength build-tag constants
- Raise the password minimum length floor to 14 when compiled with
requirefips, applied in SetDefaults only when unset and validated
independently in IsValid
- Return ErrMismatchedHashAndPassword for too-short passwords in
PBKDF2 CompareHashAndPassword rather than a cryptic OpenSSL error
- Validate atmos/camo HMAC key length under FIPS and lengthen test
keys accordingly
- Adjust password validation tests to use PasswordFIPSMinimumLength
so they work under both FIPS and non-FIPS builds
* CI: shard FIPS test suite and extract merge template
Run FIPS tests on PRs that touch go.mod or have 'fips' in the branch
name. Shard FIPS tests across 4 runners matching the normal Postgres
suite. Extract the test result merge logic into a reusable workflow
template to deduplicate the normal and FIPS merge jobs.
* more
* Fix email test helper to respect FIPS minimum password length
* Fix test helpers to respect FIPS minimum password length
* Remove unnecessary "disable strict password requirements" blocks from test helpers
* Fix CodeRabbit review comments on PR #35905
- Add server-test-merge-template.yml to server-ci.yml pull_request.paths
so changes to the reusable merge workflow trigger Server CI validation
- Skip merge-postgres-fips-test-results job when test-postgres-normal-fips
was skipped, preventing failures due to missing artifacts
- Set guest.Password on returned guest in CreateGuestAndClient helper
to keep contract consistent with CreateUserWithClient
- Use shared LowercaseLetters/UppercaseLetters/NUMBERS/PasswordFIPSMinimumLength
constants in NewTestPassword() to avoid drift if FIPS floor changes
https://claude.ai/code/session_01HmE9QkZM3cAoXn2J7XrK2f
* Rename FIPS test artifact to match server-ci-report pattern
The server-ci-report job searches for artifacts matching "*-test-logs",
so rename from postgres-server-test-logs-fips to
postgres-server-fips-test-logs to be included in the report.
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Rename shared_channel_manager and secure_connection_manager roles to use system_ prefix
The new roles added in PR #35354 broke the naming convention that all
system-level roles stored in Users.Roles are prefixed with "system_".
Client-side code (role.includes('system')) and server-side code (explicit
switch cases in applyMultiRoleFilters) relied on this convention, causing
users assigned to these roles to not appear in the System Console.
Also adds both roles to the applyMultiRoleFilters switch statement in
user_store.go, which was missing them entirely.
Log only a 5-character prefix of the password reset token in audit
entries instead of the full 64-character bearer credential (CWE-532).
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-68179: Run sendLoop workers on all HA nodes
In HA clusters, sendLoop worker goroutines only ran on the leader node.
When an API request to send a channel invite landed on a non-leader node,
SendMsg enqueued the task to a local in-memory channel but no goroutine
consumed it, silently losing the message. Fix by starting sendLoop workers
in Start() on all nodes, independent of the leader-only ping lifecycle.
- Separate sendLoop lifecycle (Start/Shutdown) from ping lifecycle
(pingStart/pingStop on leader change)
- Rename resume/pause to pingStart/pingStop for clarity
- Change Active() to mean "service started" via atomic.Bool
- Remove SetActive (no longer needed; tests use Start())
* address review comment
* Added idempotency guard to Start()
* Start() and Shutdown(): CompareAndSwap instead of Load/Store — eliminates races where concurrent calls could both proceed. Only the winner of the CAS executes; the loser returns nil
immediately.
Ping test: replaced time.Sleep with assert.Never/assert.Eventually — no more brittle fixed sleeps. Uses assert.Never to verify no pings fire on non-leader, and assert.Eventually to
verify pings stop after losing leadership (snapshot-then-compare pattern).
* make unit tests parallel capable
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-68158: Fix shared channel remote display and add WebSocket notification
Fix getSharedChannelRemotes API handler passing ChannelId instead of
RemoteId to GetRemoteCluster, which always failed the lookup. Add
RemoteId to SharedChannelRemoteStatus model and store query.
Add shared_channel_remote_updated WebSocket event published from the
onInvite callback so the UI refreshes its cached remote names when the
async invite completes, instead of showing the generic "Shared with
trusted organizations" fallback.
* Improved unit tests per review comments
* Move password hashers from server/v8 to server/public to fix layering violation
* Revert "Move password hashers from server/v8 to server/public to fix layering violation"
This reverts commit 8cad5b8dc9.
* invert dependency between hashers and model
* make modules-tidy
---------
Co-authored-by: Jesse Hallam <jesse@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>