Дисклеймер: Данный туториал представлен исключительно в ознакомительных целях. Автор ни в коем случае не призывает заниматься этим в целях, которые выходят за рамки локальных экспериментов.

Mattermost в редакции Team edition имеет ряд ограничений, которые активируются только при применении Enterprise лицензии. Но покопавшись немного в коде, выяснилось что некоторые функции все-таки можно включить, внеся некоторые изменения и собрав из исходников.


Начать можно с официального гайда для разработчиков -https://developers.mattermost.com/contribute/developer-setup/

В моем случае всё билд окружение уже настроено, репозиторий склонирован и переключен на тег v10.12.0. Поэтому остановимся на пункте 9.

Перед локальным запуском, необходимо внести изменения в некоторые функции, которые позволят активировать закрытые фичи.

Таких мест всего 2:
- server/channels/app/platform/license.go
- webapp/channels/src/utils/license_utils.ts

Вносим изменения:

server/channels/app/platform/license.go changes
 func (ps *PlatformService) License() *model.License {
-	return ps.licenseValue.Load()
+	return model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
 }

Тут мы подменяем проверку настроящей лицензии, на тестовую лицензию из e2e тестов.

webapp/channels/src/utils/license_utils.ts changes
export const isEnterpriseLicense = (license?: ClientLicense) => {
    switch (license?.SkuShortName) {
    case LicenseSkus.Enterprise:
    case LicenseSkus.E20:
    case LicenseSkus.EnterpriseAdvanced:
        return true;
    }

-    return false;
+    return true;
};
-export const isNonEnterpriseLicense = (license?: ClientLicense) => !isEnterpriseLicense(license);
+export const isNonEnterpriseLicense = (license?: ClientLicense) => false;
 export function isMinimumProfessionalLicense(license: ClientLicense): boolean {
-    if (!license) {
-        return false;
-    }
-
-    return getLicenseTier(license.SkuShortName) >= getLicenseTier(LicenseSkus.Professional);
+    return true;
 }
 export function isMinimumEnterpriseLicense(license: ClientLicense): boolean {
-    if (!license) {
-        return false;
-    }
-
-    return getLicenseTier(license.SkuShortName) >= getLicenseTier(LicenseSkus.Enterprise);
+    return true;
 }
 export function isMinimumEnterpriseAdvancedLicense(license?: ClientLicense): boolean {
-    if (!license) {
-        return false;
-    }
-
-    return getLicenseTier(license.SkuShortName) >= getLicenseTier(LicenseSkus.EnterpriseAdvanced);
+    return true;
 }

Здесь мы просто во всех функциях проверки увроня лицензии убираем логику и возвращаем true.

Теперь можем запустить локально (продолжаем с пункта 9 официального гайда для разработчиков:

  1. Запуск

    cd <repo_path>/server
    make run-server
  2. Ждем когда все запустится

  3. Чекаем что все ОК

    curl http://localhost:8065/api/v4/system/ping
    # примерный ответ будет: {"AndroidLatestVersion":"","AndroidMinVersion":"","DesktopLatestVersion":"","DesktopMinVersion":"","IosLatestVersion":"","IosMinVersion":"","status":"OK"}
  4. В соседней вкладке терминала создадим пользователей

    cd <repo_path>/server
    bin/mmctl user create --local --email admin@example.com --username admin --password adminadmin --system-admin
    bin/mmctl user create --local --email admin2@example.com --username admin2 --password adminadmin --system-admin
  5. В соседней вкладке терминала запустим webapp

    cd <repo_path>/webapp
    make run
  6. Ждем запуска

  7. Заходим на локальный ММ по адресу http://localhost:8065

  8. После проверки, для остановки, выполняем в соседней вкладке терминала

cd <repo_path>/server
make stop-server
make stop-docker

Какие функции разлочились:

  1. Создание групп (User Groups)

    скрины
    Настройки -> User Groups
    Настройки -> User Groups
    Создаем группу и добавляем пользователей
    Создаем группу и добавляем пользователей
    Отправляем сообщение на группу
    Отправляем сообщение на группу
    Видим что пришло уведомление
    Видим что пришло уведомление
  2. Метрики мониторинга http://localhost:8067

    скрины
    Включаем метрики в настройках
    Включаем метрики в настройках
    http://localhost:8067
    http://localhost:8067/metrics
  3. Редактирование пользователей в админке

    скрины

Также можно собрать локальный тестовый докер образ:

  1. Сборка

    cd <repo_path>/server
    make build
    make package
  2. Копируем собраный пакет в контекст сборки докера и билдим

    cp ./dist/mattermost-team-linux-amd64.tar.gz ./build/
  3. Вносим изменения в Dockerfile

    +COPY mattermost-team-linux-amd64.tar.gz /mattermost-team-linux-amd64.tar.gz
    +
     # Set mattermost group/user and download Mattermost
     RUN mkdir -p /mattermost/data /mattermost/plugins /mattermost/client/plugins \
       && groupadd --gid ${PGID} mattermost \
       && useradd --uid ${PUID} --gid ${PGID} --comment "" --home-dir /mattermost mattermost \
    -  && curl -L $MM_PACKAGE | tar -xvz \
    +  && tar -xPvzf mattermost-team-linux-amd64.tar.gz \
       && chown -R mattermost:mattermost /mattermost /mattermost/data /mattermost/plugins /mattermost/client/plugins
  4. Билдим

    cd build
    docker build -t mattermost-test -f ./Dockerfile .
  5. Создадим директорию для временных файлов

    mkdir ~/mattermost_tmp
    cd ~/mattermost_tmp
    mkdir pgdata config data logs
  6. Запуск БД

    docker run -d \
            --name mm_postgres \
            -p 127.0.0.1:5432:5432 \
            -e POSTGRES_PASSWORD=postgres \
            -e PGDATA=/var/lib/postgresql/data/pgdata \
            -v ./pgdata:/var/lib/postgresql/data \
            postgres
  7. Создадим базу данных

    docker exec -it mm_postgres bash
    # подключится к postgres
    psql -h localhost -U postgres -w
    # создадим базу
    create database mattermost;
    # выходим
    quit;
    exit
  8. Берем базовый конфиг (нужно поправить пути и коннект к базе) или готовый из примера ниже (там все прописано) и копируем его в ~/mattermost_tmp/config/

    config.json
    {
        "ServiceSettings": {
            "SiteURL": "http://localhost:8065",
            "WebsocketURL": "",
            "LicenseFileLocation": "",
            "ListenAddress": ":8065",
            "ConnectionSecurity": "",
            "TLSCertFile": "",
            "TLSKeyFile": "",
            "TLSMinVer": "1.2",
            "TLSStrictTransport": false,
            "TLSStrictTransportMaxAge": 63072000,
            "TLSOverwriteCiphers": [],
            "UseLetsEncrypt": false,
            "LetsEncryptCertificateCacheFile": "./config/letsencrypt.cache",
            "Forward80To443": false,
            "TrustedProxyIPHeader": [],
            "ReadTimeout": 300,
            "WriteTimeout": 300,
            "IdleTimeout": 60,
            "MaximumLoginAttempts": 10,
            "GoroutineHealthThreshold": -1,
            "EnableOAuthServiceProvider": true,
            "EnableIncomingWebhooks": true,
            "EnableOutgoingWebhooks": true,
            "EnableOutgoingOAuthConnections": false,
            "EnableCommands": true,
            "OutgoingIntegrationRequestsTimeout": 30,
            "EnablePostUsernameOverride": true,
            "EnablePostIconOverride": true,
            "GoogleDeveloperKey": "",
            "EnableLinkPreviews": true,
            "EnablePermalinkPreviews": true,
            "RestrictLinkPreviews": "",
            "EnableTesting": false,
            "EnableDeveloper": false,
            "DeveloperFlags": "",
            "EnableClientPerformanceDebugging": false,
            "EnableSecurityFixAlert": true,
            "EnableInsecureOutgoingConnections": true,
            "AllowedUntrustedInternalConnections": "",
            "EnableMultifactorAuthentication": false,
            "EnforceMultifactorAuthentication": false,
            "EnableUserAccessTokens": true,
            "AllowCorsFrom": "",
            "CorsExposedHeaders": "",
            "CorsAllowCredentials": false,
            "CorsDebug": false,
            "AllowCookiesForSubdomains": false,
            "ExtendSessionLengthWithActivity": true,
            "TerminateSessionsOnPasswordChange": false,
            "SessionLengthWebInDays": 180,
            "SessionLengthWebInHours": 4320,
            "SessionLengthMobileInDays": 180,
            "SessionLengthMobileInHours": 4320,
            "SessionLengthSSOInDays": 30,
            "SessionLengthSSOInHours": 720,
            "SessionCacheInMinutes": 10,
            "SessionIdleTimeoutInMinutes": 43200,
            "WebsocketSecurePort": 443,
            "WebsocketPort": 80,
            "WebserverMode": "gzip",
            "EnableGifPicker": false,
            "GiphySdkKey": "",
            "EnableCustomEmoji": true,
            "EnableEmojiPicker": true,
            "PostEditTimeLimit": -1,
            "TimeBetweenUserTypingUpdatesMilliseconds": 5000,
            "EnableCrossTeamSearch": true,
            "EnablePostSearch": true,
            "EnableFileSearch": true,
            "MinimumHashtagLength": 3,
            "EnableUserTypingMessages": true,
            "EnableChannelViewedMessages": true,
            "EnableUserStatuses": true,
            "ExperimentalEnableAuthenticationTransfer": true,
            "ClusterLogTimeoutMilliseconds": 2000,
            "EnableTutorial": true,
            "EnableOnboardingFlow": true,
            "ExperimentalEnableDefaultChannelLeaveJoinMessages": true,
            "ExperimentalGroupUnreadChannels": "disabled",
            "EnableAPITeamDeletion": false,
            "EnableAPITriggerAdminNotifications": false,
            "EnableAPIUserDeletion": false,
            "EnableAPIPostDeletion": false,
            "EnableDesktopLandingPage": true,
            "ExperimentalEnableHardenedMode": false,
            "ExperimentalStrictCSRFEnforcement": false,
            "EnableEmailInvitations": true,
            "DisableBotsWhenOwnerIsDeactivated": true,
            "EnableBotAccountCreation": true,
            "EnableSVGs": true,
            "EnableLatex": true,
            "EnableInlineLatex": true,
            "PostPriority": true,
            "AllowPersistentNotifications": true,
            "AllowPersistentNotificationsForGuests": false,
            "PersistentNotificationIntervalMinutes": 5,
            "PersistentNotificationMaxCount": 6,
            "PersistentNotificationMaxRecipients": 5,
            "EnableAPIChannelDeletion": false,
            "EnableLocalMode": true,
            "LocalModeSocketLocation": "/var/tmp/mattermost_local.socket",
            "EnableAWSMetering": false,
            "SplitKey": "",
            "FeatureFlagSyncIntervalSeconds": 30,
            "DebugSplit": false,
            "ThreadAutoFollow": true,
            "CollapsedThreads": "always_on",
            "ManagedResourcePaths": "",
            "EnableCustomGroups": true,
            "AllowSyncedDrafts": true,
            "UniqueEmojiReactionLimitPerPost": 50,
            "RefreshPostStatsRunTime": "00:00",
            "MaximumPayloadSizeBytes": 100000,
            "MaximumURLLength": 2048,
            "ScheduledPosts": true,
            "EnableWebHubChannelIteration": false,
            "FrameAncestors": "",
            "DeleteAccountLink": ""
        },
        "TeamSettings": {
            "SiteName": "Mattermost",
            "MaxUsersPerTeam": 300,
            "EnableJoinLeaveMessageByDefault": true,
            "EnableUserCreation": true,
            "EnableOpenServer": false,
            "EnableUserDeactivation": false,
            "RestrictCreationToDomains": "",
            "EnableCustomUserStatuses": true,
            "EnableCustomBrand": true,
            "CustomBrandText": "",
            "CustomDescriptionText": "",
            "RestrictDirectMessage": "any",
            "EnableLastActiveTime": true,
            "UserStatusAwayTimeout": 300,
            "MaxChannelsPerTeam": 2000,
            "MaxNotificationsPerChannel": 1000,
            "EnableConfirmNotificationsToChannel": false,
            "TeammateNameDisplay": "username",
            "ExperimentalViewArchivedChannels": true,
            "ExperimentalEnableAutomaticReplies": true,
            "LockTeammateNameDisplay": false,
            "ExperimentalPrimaryTeam": "",
            "ExperimentalDefaultChannels": []
        },
        "ClientRequirements": {
            "AndroidLatestVersion": "",
            "AndroidMinVersion": "",
            "IosLatestVersion": "",
            "IosMinVersion": ""
        },
        "SqlSettings": {
            "DriverName": "postgres",
            "DataSource": "postgres://postgres:postgres@mm_postgres:5432/mattermost?sslmode=disable\u0026connect_timeout=10\u0026binary_parameters=yes",
            "DataSourceReplicas": [],
            "DataSourceSearchReplicas": [],
            "MaxIdleConns": 20,
            "ConnMaxLifetimeMilliseconds": 3600000,
            "ConnMaxIdleTimeMilliseconds": 300000,
            "MaxOpenConns": 300,
            "Trace": false,
            "AtRestEncryptKey": "o8qmtcmxr67rh8eomnugap49kqgesnp9",
            "QueryTimeout": 30,
            "DisableDatabaseSearch": false,
            "MigrationsStatementTimeoutSeconds": 100000,
            "ReplicaLagSettings": [],
            "ReplicaMonitorIntervalSeconds": 5
        },
        "LogSettings": {
            "EnableConsole": true,
            "ConsoleLevel": "INFO",
            "ConsoleJson": true,
            "EnableColor": true,
            "EnableFile": true,
            "FileLevel": "INFO",
            "FileJson": true,
            "FileLocation": "/mattermost/logs",
            "EnableWebhookDebugging": true,
            "EnableDiagnostics": false,
            "VerboseDiagnostics": false,
            "EnableSentry": true,
            "AdvancedLoggingJSON": {},
            "MaxFieldSize": 2048
        },
        "ExperimentalAuditSettings": {
            "FileEnabled": false,
            "FileName": "",
            "FileMaxSizeMB": 100,
            "FileMaxAgeDays": 0,
            "FileMaxBackups": 0,
            "FileCompress": false,
            "FileMaxQueueSize": 1000,
            "AdvancedLoggingJSON": {},
            "Certificate": ""
        },
        "NotificationLogSettings": {
            "EnableConsole": true,
            "ConsoleLevel": "DEBUG",
            "ConsoleJson": true,
            "EnableColor": true,
            "EnableFile": true,
            "FileLevel": "INFO",
            "FileJson": true,
            "FileLocation": "/mattermost/logs",
            "AdvancedLoggingJSON": {}
        },
        "PasswordSettings": {
            "MinimumLength": 8,
            "Lowercase": false,
            "Number": false,
            "Uppercase": false,
            "Symbol": false,
            "EnableForgotLink": false
        },
        "FileSettings": {
            "EnableFileAttachments": true,
            "EnableMobileUpload": true,
            "EnableMobileDownload": true,
            "MaxFileSize": 104857600,
            "MaxImageResolution": 33177600,
            "MaxImageDecoderConcurrency": -1,
            "DriverName": "local",
            "Directory": "./data/",
            "EnablePublicLink": false,
            "ExtractContent": true,
            "ArchiveRecursion": false,
            "PublicLinkSalt": "q8pf6phaiaata8g1s1qfqaa31hpn5q55",
            "InitialFont": "nunito-bold.ttf",
            "AmazonS3AccessKeyId": "",
            "AmazonS3SecretAccessKey": "",
            "AmazonS3Bucket": "",
            "AmazonS3PathPrefix": "",
            "AmazonS3Region": "",
            "AmazonS3Endpoint": "s3.amazonaws.com",
            "AmazonS3SSL": true,
            "AmazonS3SignV2": false,
            "AmazonS3SSE": false,
            "AmazonS3Trace": false,
            "AmazonS3RequestTimeoutMilliseconds": 30000,
            "AmazonS3UploadPartSizeBytes": 5242880,
            "AmazonS3StorageClass": "",
            "DedicatedExportStore": false,
            "ExportDriverName": "local",
            "ExportDirectory": "./data/",
            "ExportAmazonS3AccessKeyId": "",
            "ExportAmazonS3SecretAccessKey": "",
            "ExportAmazonS3Bucket": "",
            "ExportAmazonS3PathPrefix": "",
            "ExportAmazonS3Region": "",
            "ExportAmazonS3Endpoint": "s3.amazonaws.com",
            "ExportAmazonS3SSL": true,
            "ExportAmazonS3SignV2": false,
            "ExportAmazonS3SSE": false,
            "ExportAmazonS3Trace": false,
            "ExportAmazonS3RequestTimeoutMilliseconds": 30000,
            "ExportAmazonS3PresignExpiresSeconds": 21600,
            "ExportAmazonS3UploadPartSizeBytes": 104857600,
            "ExportAmazonS3StorageClass": ""
        },
        "EmailSettings": {
            "EnableSignUpWithEmail": true,
            "EnableSignInWithEmail": true,
            "EnableSignInWithUsername": true,
            "SendEmailNotifications": false,
            "UseChannelInEmailNotifications": false,
            "RequireEmailVerification": false,
            "FeedbackName": "",
            "FeedbackEmail": "",
            "ReplyToAddress": "",
            "FeedbackOrganization": "",
            "EnableSMTPAuth": false,
            "SMTPUsername": "",
            "SMTPPassword": "",
            "SMTPServer": "localhost",
            "SMTPPort": "10025",
            "SMTPServerTimeout": 10,
            "ConnectionSecurity": "",
            "SendPushNotifications": true,
            "PushNotificationServer": "https://push-test.mattermost.com",
            "PushNotificationContents": "full",
            "PushNotificationBuffer": 1000,
            "EnableEmailBatching": false,
            "EmailBatchingBufferSize": 256,
            "EmailBatchingInterval": 30,
            "EnablePreviewModeBanner": true,
            "SkipServerCertificateVerification": false,
            "EmailNotificationContentsType": "full",
            "LoginButtonColor": "#0000",
            "LoginButtonBorderColor": "#2389D7",
            "LoginButtonTextColor": "#2389D7"
        },
        "RateLimitSettings": {
            "Enable": false,
            "PerSec": 10,
            "MaxBurst": 100,
            "MemoryStoreSize": 10000,
            "VaryByRemoteAddr": true,
            "VaryByUser": false,
            "VaryByHeader": ""
        },
        "PrivacySettings": {
            "ShowEmailAddress": true,
            "ShowFullName": true
        },
        "SupportSettings": {
            "TermsOfServiceLink": "https://mattermost.com/pl/terms-of-use/",
            "PrivacyPolicyLink": "https://mattermost.com/pl/privacy-policy/",
            "AboutLink": "https://mattermost.com/pl/about-mattermost",
            "HelpLink": "https://mattermost.com/pl/help/",
            "ReportAProblemLink": "https://mattermost.com/pl/report-a-bug",
            "ReportAProblemType": "default",
            "ReportAProblemMail": "",
            "AllowDownloadLogs": true,
            "ForgotPasswordLink": "",
            "SupportEmail": "",
            "CustomTermsOfServiceEnabled": false,
            "CustomTermsOfServiceReAcceptancePeriod": 365,
            "EnableAskCommunityLink": true
        },
        "AnnouncementSettings": {
            "EnableBanner": false,
            "BannerText": "",
            "BannerColor": "#f2a93b",
            "BannerTextColor": "#333333",
            "AllowBannerDismissal": true,
            "AdminNoticesEnabled": true,
            "UserNoticesEnabled": true,
            "NoticesURL": "https://notices.mattermost.com/",
            "NoticesFetchFrequency": 3600,
            "NoticesSkipCache": false
        },
        "ThemeSettings": {
            "EnableThemeSelection": true,
            "DefaultTheme": "default",
            "AllowCustomThemes": true,
            "AllowedThemes": []
        },
        "GitLabSettings": {
            "Enable": false,
            "Secret": "",
            "Id": "",
            "Scope": "",
            "AuthEndpoint": "",
            "TokenEndpoint": "",
            "UserAPIEndpoint": "",
            "DiscoveryEndpoint": "",
            "ButtonText": "",
            "ButtonColor": ""
        },
        "GoogleSettings": {
            "Enable": false,
            "Secret": "",
            "Id": "",
            "Scope": "profile email",
            "AuthEndpoint": "https://accounts.google.com/o/oauth2/v2/auth",
            "TokenEndpoint": "https://www.googleapis.com/oauth2/v4/token",
            "UserAPIEndpoint": "https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses,nicknames,metadata",
            "DiscoveryEndpoint": "",
            "ButtonText": "",
            "ButtonColor": ""
        },
        "Office365Settings": {
            "Enable": false,
            "Secret": "",
            "Id": "",
            "Scope": "User.Read",
            "AuthEndpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
            "TokenEndpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/token",
            "UserAPIEndpoint": "https://graph.microsoft.com/v1.0/me",
            "DiscoveryEndpoint": "",
            "DirectoryId": ""
        },
        "OpenIdSettings": {
            "Enable": false,
            "Secret": "",
            "Id": "",
            "Scope": "profile openid email",
            "AuthEndpoint": "",
            "TokenEndpoint": "",
            "UserAPIEndpoint": "",
            "DiscoveryEndpoint": "",
            "ButtonText": "",
            "ButtonColor": "#145DBF"
        },
        "LdapSettings": {
            "Enable": false,
            "EnableSync": false,
            "LdapServer": "",
            "LdapPort": 389,
            "ConnectionSecurity": "",
            "BaseDN": "",
            "BindUsername": "",
            "BindPassword": "",
            "MaximumLoginAttempts": 10,
            "UserFilter": "",
            "GroupFilter": "",
            "GuestFilter": "",
            "EnableAdminFilter": false,
            "AdminFilter": "",
            "GroupDisplayNameAttribute": "",
            "GroupIdAttribute": "",
            "FirstNameAttribute": "",
            "LastNameAttribute": "",
            "EmailAttribute": "",
            "UsernameAttribute": "",
            "NicknameAttribute": "",
            "IdAttribute": "",
            "PositionAttribute": "",
            "LoginIdAttribute": "",
            "PictureAttribute": "",
            "SyncIntervalMinutes": 60,
            "ReAddRemovedMembers": false,
            "SkipCertificateVerification": false,
            "PublicCertificateFile": "",
            "PrivateKeyFile": "",
            "QueryTimeout": 60,
            "MaxPageSize": 0,
            "LoginFieldName": "",
            "LoginButtonColor": "#0000",
            "LoginButtonBorderColor": "#2389D7",
            "LoginButtonTextColor": "#2389D7"
        },
        "ComplianceSettings": {
            "Enable": false,
            "Directory": "./data/",
            "EnableDaily": false,
            "BatchSize": 30000
        },
        "LocalizationSettings": {
            "DefaultServerLocale": "en",
            "DefaultClientLocale": "en",
            "AvailableLocales": "",
            "EnableExperimentalLocales": false
        },
        "SamlSettings": {
            "Enable": false,
            "EnableSyncWithLdap": false,
            "EnableSyncWithLdapIncludeAuth": false,
            "IgnoreGuestsLdapSync": false,
            "Verify": true,
            "Encrypt": true,
            "SignRequest": false,
            "IdpURL": "",
            "IdpDescriptorURL": "",
            "IdpMetadataURL": "",
            "ServiceProviderIdentifier": "",
            "AssertionConsumerServiceURL": "",
            "SignatureAlgorithm": "RSAwithSHA1",
            "CanonicalAlgorithm": "Canonical1.0",
            "ScopingIDPProviderId": "",
            "ScopingIDPName": "",
            "IdpCertificateFile": "",
            "PublicCertificateFile": "",
            "PrivateKeyFile": "",
            "IdAttribute": "",
            "GuestAttribute": "",
            "EnableAdminAttribute": false,
            "AdminAttribute": "",
            "FirstNameAttribute": "",
            "LastNameAttribute": "",
            "EmailAttribute": "",
            "UsernameAttribute": "",
            "NicknameAttribute": "",
            "LocaleAttribute": "",
            "PositionAttribute": "",
            "LoginButtonText": "SAML",
            "LoginButtonColor": "#34a28b",
            "LoginButtonBorderColor": "#2389D7",
            "LoginButtonTextColor": "#ffffff"
        },
        "NativeAppSettings": {
            "AppCustomURLSchemes": [
                "mmauth://",
                "mmauthbeta://"
            ],
            "AppDownloadLink": "https://mattermost.com/pl/download-apps",
            "AndroidAppDownloadLink": "https://mattermost.com/pl/android-app/",
            "IosAppDownloadLink": "https://mattermost.com/pl/ios-app/",
            "MobileExternalBrowser": false,
            "MobileEnableBiometrics": false,
            "MobilePreventScreenCapture": false,
            "MobileJailbreakProtection": false,
            "MobileEnableSecureFilePreview": false,
            "MobileAllowPdfLinkNavigation": false
        },
        "CacheSettings": {
            "CacheType": "lru",
            "RedisAddress": "",
            "RedisPassword": "********************************",
            "RedisDB": -1,
            "RedisCachePrefix": "",
            "DisableClientCache": false
        },
        "ClusterSettings": {
            "Enable": false,
            "ClusterName": "",
            "OverrideHostname": "",
            "NetworkInterface": "",
            "BindAddress": "",
            "AdvertiseAddress": "",
            "UseIPAddress": true,
            "EnableGossipCompression": true,
            "EnableExperimentalGossipEncryption": false,
            "EnableGossipEncryption": false,
            "ReadOnlyConfig": true,
            "GossipPort": 8074
        },
        "MetricsSettings": {
            "Enable": true,
            "BlockProfileRate": 0,
            "ListenAddress": ":8067",
            "EnableClientMetrics": false,
            "EnableNotificationMetrics": true,
            "ClientSideUserIds": []
        },
        "ExperimentalSettings": {
            "ClientSideCertEnable": false,
            "ClientSideCertCheck": "secondary",
            "LinkMetadataTimeoutMilliseconds": 5000,
            "RestrictSystemAdmin": false,
            "EnableSharedChannels": false,
            "EnableRemoteClusterService": false,
            "DisableAppBar": false,
            "DisableRefetchingOnBrowserFocus": false,
            "DelayChannelAutocomplete": false,
            "DisableWakeUpReconnectHandler": false,
            "UsersStatusAndProfileFetchingPollIntervalMilliseconds": 3000,
            "YoutubeReferrerPolicy": false,
            "ExperimentalChannelCategorySorting": false
        },
        "AnalyticsSettings": {
            "MaxUsersForStatistics": 2500
        },
        "ElasticsearchSettings": {
            "ConnectionURL": "http://localhost:9200",
            "Backend": "elasticsearch",
            "Username": "elastic",
            "Password": "changeme",
            "EnableIndexing": false,
            "EnableSearching": false,
            "EnableAutocomplete": false,
            "Sniff": true,
            "PostIndexReplicas": 1,
            "PostIndexShards": 1,
            "ChannelIndexReplicas": 1,
            "ChannelIndexShards": 1,
            "UserIndexReplicas": 1,
            "UserIndexShards": 1,
            "AggregatePostsAfterDays": 365,
            "PostsAggregatorJobStartTime": "03:00",
            "IndexPrefix": "",
            "GlobalSearchPrefix": "",
            "LiveIndexingBatchSize": 1,
            "BatchSize": 10000,
            "RequestTimeoutSeconds": 30,
            "SkipTLSVerification": false,
            "CA": "",
            "ClientCert": "",
            "ClientKey": "",
            "Trace": "",
            "IgnoredPurgeIndexes": ""
        },
        "BleveSettings": {
            "IndexDir": "",
            "EnableIndexing": false,
            "EnableSearching": false,
            "EnableAutocomplete": false,
            "BatchSize": 10000
        },
        "DataRetentionSettings": {
            "EnableMessageDeletion": false,
            "EnableFileDeletion": false,
            "EnableBoardsDeletion": false,
            "MessageRetentionDays": 365,
            "MessageRetentionHours": 0,
            "FileRetentionDays": 365,
            "FileRetentionHours": 0,
            "BoardsRetentionDays": 365,
            "DeletionJobStartTime": "02:00",
            "BatchSize": 3000,
            "TimeBetweenBatchesMilliseconds": 100,
            "RetentionIdsBatchSize": 100,
            "PreservePinnedPosts": false
        },
        "MessageExportSettings": {
            "EnableExport": false,
            "ExportFormat": "actiance",
            "DailyRunTime": "01:00",
            "ExportFromTimestamp": 0,
            "BatchSize": 10000,
            "DownloadExportResults": false,
            "ChannelBatchSize": 100,
            "ChannelHistoryBatchSize": 10,
            "GlobalRelaySettings": {
                "CustomerType": "A9",
                "SMTPUsername": "",
                "SMTPPassword": "",
                "EmailAddress": "",
                "SMTPServerTimeout": 1800,
                "CustomSMTPServerName": "",
                "CustomSMTPPort": "25"
            }
        },
        "JobSettings": {
            "RunJobs": true,
            "RunScheduler": true,
            "CleanupJobsThresholdDays": -1,
            "CleanupConfigThresholdDays": -1
        },
        "PluginSettings": {
            "Enable": true,
            "EnableUploads": true,
            "AllowInsecureDownloadURL": true,
            "EnableHealthCheck": true,
            "Directory": "./plugins",
            "ClientDirectory": "./client/plugins",
            "Plugins": {
                "com.mattermost.calls": {
                    "iceserversconfigs": "[{\"urls\":[\"stun:stun.global.calls.mattermost.com:3478\"]}]"
                },
                "mattermost-ai": {
                    "allowedUpstreamHostnames": "",
                    "bots": null,
                    "defaultBotName": "",
                    "embeddingSearchConfig": {
                        "chunkingOptions": {
                            "chunkOverlap": 0,
                            "chunkSize": 0,
                            "chunkingStrategy": "",
                            "minChunkSize": 0
                        },
                        "dimensions": 0,
                        "embeddingProvider": {
                            "parameters": null,
                            "type": ""
                        },
                        "parameters": null,
                        "type": "",
                        "vectorStore": {
                            "parameters": null,
                            "type": ""
                        }
                    },
                    "enableLLMTrace": false,
                    "mcp": {
                        "enabled": false,
                        "idleTimeoutMinutes": 0,
                        "servers": null
                    },
                    "services": null,
                    "transcriptBackend": ""
                },
                "playbooks": {
                    "BotUserID": "j8nigb4znty68bcde5z75iztuc",
                    "EnableIncrementalUpdates": false,
                    "EnableTeamsTabApp": false,
                    "TeamsTabAppBotUserID": "",
                    "TeamsTabAppTenantIDs": ""
                }
            },
            "PluginStates": {
                "com.mattermost.calls": {
                    "Enable": true
                },
                "com.mattermost.nps": {
                    "Enable": true
                },
                "mattermost-ai": {
                    "Enable": true
                },
                "playbooks": {
                    "Enable": true
                }
            },
            "EnableMarketplace": true,
            "EnableRemoteMarketplace": true,
            "AutomaticPrepackagedPlugins": true,
            "RequirePluginSignature": false,
            "MarketplaceURL": "https://api.integrations.mattermost.com",
            "SignaturePublicKeyFiles": [],
            "ChimeraOAuthProxyURL": ""
        },
        "DisplaySettings": {
            "CustomURLSchemes": [],
            "MaxMarkdownNodes": 0
        },
        "GuestAccountsSettings": {
            "Enable": false,
            "HideTags": false,
            "AllowEmailAccounts": true,
            "EnforceMultifactorAuthentication": false,
            "RestrictCreationToDomains": ""
        },
        "ImageProxySettings": {
            "Enable": false,
            "ImageProxyType": "local",
            "RemoteImageProxyURL": "",
            "RemoteImageProxyOptions": ""
        },
        "CloudSettings": {
            "CWSURL": "https://customers.mattermost.com",
            "CWSAPIURL": "https://portal.internal.prod.cloud.mattermost.com",
            "CWSMock": false,
            "Disable": false
        },
        "ImportSettings": {
            "Directory": "./import",
            "RetentionDays": 30
        },
        "ExportSettings": {
            "Directory": "./export",
            "RetentionDays": 30
        },
        "WranglerSettings": {
            "PermittedWranglerRoles": [],
            "AllowedEmailDomain": [],
            "MoveThreadMaxCount": 100,
            "MoveThreadToAnotherTeamEnable": false,
            "MoveThreadFromPrivateChannelEnable": false,
            "MoveThreadFromDirectMessageChannelEnable": false,
            "MoveThreadFromGroupMessageChannelEnable": false
        },
        "ConnectedWorkspacesSettings": {
            "EnableSharedChannels": false,
            "EnableRemoteClusterService": false,
            "DisableSharedChannelsStatusSync": false,
            "SyncUsersOnConnectionOpen": false,
            "GlobalUserSyncBatchSize": 25,
            "MaxPostsPerSync": 50,
            "MemberSyncBatchSize": 20
        },
        "AccessControlSettings": {
            "EnableAttributeBasedAccessControl": false,
            "EnableChannelScopeAccessControl": false,
            "EnableUserManagedAttributes": false
        },
        "ContentFlaggingSettings": {
            "EnableContentFlagging": false,
            "ReviewerSettings": {
                "CommonReviewers": true,
                "CommonReviewerIds": [],
                "TeamReviewersSetting": {},
                "SystemAdminsAsReviewers": false,
                "TeamAdminsAsReviewers": true
            },
            "NotificationSettings": {
                "EventTargetMapping": {
                    "assigned": [
                        "reviewers"
                    ],
                    "dismissed": [
                        "reviewers",
                        "reporter"
                    ],
                    "flagged": [
                        "reviewers"
                    ],
                    "removed": [
                        "reviewers",
                        "author",
                        "reporter"
                    ]
                }
            },
            "AdditionalSettings": {
                "Reasons": [
                    "Inappropriate content",
                    "Sensitive data",
                    "Security concern",
                    "Harassment or abuse",
                    "Spam or phishing"
                ],
                "ReporterCommentRequired": true,
                "ReviewerCommentRequired": true,
                "HideFlaggedContent": true
            }
        }
    }
  9. Запуск сервера

    docker run -d \
            --name mattermost_server \
            -p 127.0.0.1:8065:8065 \
            -p 127.0.0.1:8067:8067 \
            -p 127.0.0.1:8443:8443 \
            --link mm_postgres:mm_postgres \
            -v ./data:/mattermost/data \
            -v ./logs:/mattermost/logs \
            -v ./config:/mattermost/config \
            mattermost-test:latest

По портам:
- 8065 сам сервер ММ
- 8067 метрики
- 8443 звонки

Что еще можно сделать?

В плагине mattermost-plugin-calls, начиная с версии 1.0.0, групповые звонки доступны только с Enterprise лицензией. Это тоже можно отредактировать.

Нужно поправить mattermost-plugin-calls/server/enterprise/license.go

server/enterprise/license.go changes
 func (e *LicenseChecker) HostControlsAllowed() bool {
-	return e.isAtLeastE10Licensed()
+	return true
 }
 
 func (e *LicenseChecker) GroupCallsAllowed() bool {
-	return e.isAtLeastE10Licensed() || os.Getenv("MM_CALLS_GROUP_CALLS_ALLOWED") == "true"
+	return true
 }

И собрать пакет

make dist

Собранный пакет будет лежать в директории dist. Далее просто его загружаем в админке ММ перезаписывая существующий и звонки в группах будут снова доступны.

Если кто-то пользуется плагином для календаря, есть форк в котором внесены изменения для корректной работы уведомлений о предстоящих событиях в различных таймзонах: https://github.com/DawgTeam/mattermost-yandex-calendar-plugin

Комментарии (0)