...
 
Commits (12)
......@@ -74,7 +74,9 @@ TE_PACKAGES=$(shell go list ./...)
TE_PACKAGES_COMMA=$(shell echo $(TE_PACKAGES) | tr ' ' ',')
# Plugins Packages
PLUGIN_PACKAGES=mattermost-plugin-zoom mattermost-plugin-jira
PLUGIN_PACKAGES=mattermost-plugin-zoom
# 12076003 means release version 1.0.1
PLUGIN_PACKAGES_LEGACY=mattermost-plugin-jira/releases/12076003
# Prepares the enterprise build if exists. The IGNORE stuff is a hack to get the Makefile to execute the commands outside a target
ifeq ($(BUILD_ENTERPRISE_READY),true)
......
......@@ -16,6 +16,8 @@ import (
)
func TestUploadFileAsMultipart(t *testing.T) {
t.Skip("Broken test skipped")
th := Setup().InitBasic()
defer th.TearDown()
Client := th.Client
......
......@@ -59,6 +59,11 @@ func openDialog(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if dialog.Dialog.Elements == nil || len(dialog.Dialog.Elements) == 0 {
c.SetInvalidParam("dialog.elements")
return
}
if err := c.App.OpenInteractiveDialog(dialog); err != nil {
c.Err = err
return
......
......@@ -8,7 +8,6 @@ import (
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/assert"
......@@ -25,11 +24,6 @@ func TestOpenDialog(t *testing.T) {
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1"
})
WebSocketClient, err := th.CreateWebSocketClient()
require.Nil(t, err)
WebSocketClient.Listen()
_, triggerId, err := model.GenerateTriggerId(th.BasicUser.Id, th.App.AsymmetricSigningKey())
require.Nil(t, err)
......@@ -57,21 +51,6 @@ func TestOpenDialog(t *testing.T) {
CheckNoError(t, resp)
assert.True(t, pass)
timeout := time.After(300 * time.Millisecond)
waiting := true
for waiting {
select {
case event := <-WebSocketClient.EventChannel:
if event.Event == model.WEBSOCKET_EVENT_OPEN_DIALOG {
waiting = false
}
case <-timeout:
waiting = false
t.Fatal("should have received open_dialog event")
}
}
// Should fail on bad trigger ID
request.TriggerId = "junk"
pass, resp = Client.OpenInteractiveDialog(request)
......@@ -84,6 +63,17 @@ func TestOpenDialog(t *testing.T) {
pass, resp = Client.OpenInteractiveDialog(request)
CheckBadRequestStatus(t, resp)
assert.False(t, pass)
// At least one element is required
request.URL = "http://localhost:8065"
request.Dialog.Elements = nil
pass, resp = Client.OpenInteractiveDialog(request)
CheckBadRequestStatus(t, resp)
assert.False(t, pass)
request.Dialog.Elements = []model.DialogElement{}
pass, resp = Client.OpenInteractiveDialog(request)
CheckBadRequestStatus(t, resp)
assert.False(t, pass)
}
func TestSubmitDialog(t *testing.T) {
......
......@@ -291,6 +291,10 @@ func (a *App) Desanitize(cfg *model.Config) {
cfg.GitLabSettings.Secret = actual.GitLabSettings.Secret
}
if cfg.PhabricatorSettings.Secret == model.FAKE_SETTING {
cfg.PhabricatorSettings.Secret = actual.PhabricatorSettings.Secret
}
if *cfg.SqlSettings.DataSource == model.FAKE_SETTING {
*cfg.SqlSettings.DataSource = *actual.SqlSettings.DataSource
}
......
......@@ -401,9 +401,10 @@ func (a *App) trackConfig() {
})
a.SendDiagnostic(TRACK_CONFIG_OAUTH, map[string]interface{}{
"enable_gitlab": cfg.GitLabSettings.Enable,
"enable_google": cfg.GoogleSettings.Enable,
"enable_office365": cfg.Office365Settings.Enable,
"enable_gitlab": cfg.GitLabSettings.Enable,
"enable_phabricator": cfg.PhabricatorSettings.Enable,
"enable_google": cfg.GoogleSettings.Enable,
"enable_office365": cfg.Office365Settings.Enable,
})
a.SendDiagnostic(TRACK_CONFIG_SUPPORT, map[string]interface{}{
......
......@@ -783,9 +783,8 @@ func (a *App) AuthorizeOAuthUser(w http.ResponseWriter, r *http.Request, service
return nil, "", stateProps, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.missing.app_error", nil, "response_body="+string(bodyBytes), http.StatusInternalServerError)
}
p = url.Values{}
p.Set("access_token", ar.AccessToken)
req, _ = http.NewRequest("GET", sso.UserApiEndpoint, strings.NewReader(""))
endpointUrl := sso.UserApiEndpoint+"?access_token="+ar.AccessToken
req, _ = http.NewRequest("GET", endpointUrl, strings.NewReader(""))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept", "application/json")
......
......@@ -5,15 +5,15 @@ build-linux:
@echo Build Linux amd64
env GOOS=linux GOARCH=amd64 $(GO) install -i $(GOFLAGS) $(GO_LINKER_FLAGS) ./...
build-osx:
build-osx:
@echo Build OSX amd64
env GOOS=darwin GOARCH=amd64 $(GO) install -i $(GOFLAGS) $(GO_LINKER_FLAGS) ./...
build-windows:
build-windows:
@echo Build Windows amd64
env GOOS=windows GOARCH=amd64 $(GO) install -i $(GOFLAGS) $(GO_LINKER_FLAGS) ./...
build: build-linux build-windows build-osx
build: build-linux
build-client:
@echo Building mattermost web app
......@@ -60,66 +60,78 @@ endif
cp NOTICE.txt $(DIST_PATH)
cp README.md $(DIST_PATH)
@# ----- PLATFORM SPECIFIC -----
@# Make osx package
@# Copy binary
ifeq ($(BUILDER_GOOS_GOARCH),"darwin_amd64")
cp $(GOPATH)/bin/mattermost $(DIST_PATH)/bin # from native bin dir, not cross-compiled
cp $(GOPATH)/bin/platform $(DIST_PATH)/bin # from native bin dir, not cross-compiled
@for plugin_package in $(PLUGIN_PACKAGES) ; do \
curl -s https://api.github.com/repos/mattermost/$$plugin_package/releases/latest | grep browser_download_url | grep darwin | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
done
else
cp $(GOPATH)/bin/darwin_amd64/mattermost $(DIST_PATH)/bin # from cross-compiled bin dir
cp $(GOPATH)/bin/darwin_amd64/platform $(DIST_PATH)/bin # from cross-compiled bin dir
@for plugin_package in $(PLUGIN_PACKAGES) ; do \
curl -s https://api.github.com/repos/mattermost/$$plugin_package/releases/latest | grep browser_download_url | grep darwin | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
done
endif
@# Package
tar -C dist -czf $(DIST_PATH)-$(BUILD_TYPE_NAME)-osx-amd64.tar.gz mattermost
@# Cleanup
rm -f $(DIST_PATH)/bin/mattermost
rm -f $(DIST_PATH)/bin/platform
rm -f $(DIST_PATH)/prepackaged_plugins/*
@# Make windows package
@# Copy binary
ifeq ($(BUILDER_GOOS_GOARCH),"windows_amd64")
cp $(GOPATH)/bin/mattermost.exe $(DIST_PATH)/bin # from native bin dir, not cross-compiled
cp $(GOPATH)/bin/platform.exe $(DIST_PATH)/bin # from native bin dir, not cross-compiled
@for plugin_package in $(PLUGIN_PACKAGES) ; do \
curl -s https://api.github.com/repos/mattermost/$$plugin_package/releases/latest | grep browser_download_url | grep windows | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
done
else
cp $(GOPATH)/bin/windows_amd64/mattermost.exe $(DIST_PATH)/bin # from cross-compiled bin dir
cp $(GOPATH)/bin/windows_amd64/platform.exe $(DIST_PATH)/bin # from cross-compiled bin dir
@# Download prepackaged plugins
@echo Downloading prepackaged plugins
@for plugin_package in $(PLUGIN_PACKAGES) ; do \
curl -s https://api.github.com/repos/mattermost/$$plugin_package/releases/latest | grep browser_download_url | grep windows | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
curl -s https://api.github.com/repos/mattermost/$$plugin_package/releases/latest | grep browser_download_url | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
done
endif
@# Package
cd $(DIST_ROOT) && zip -9 -r -q -l mattermost-$(BUILD_TYPE_NAME)-windows-amd64.zip mattermost && cd ..
@# Cleanup
rm -f $(DIST_PATH)/bin/mattermost.exe
rm -f $(DIST_PATH)/bin/platform.exe
rm -f $(DIST_PATH)/prepackaged_plugins/*
@# ----- PLATFORM SPECIFIC -----
# @# Make osx package
# @# Copy binary
#ifeq ($(BUILDER_GOOS_GOARCH),"darwin_amd64")
# cp $(GOPATH)/bin/mattermost $(DIST_PATH)/bin # from native bin dir, not cross-compiled
# cp $(GOPATH)/bin/platform $(DIST_PATH)/bin # from native bin dir, not cross-compiled
#
# @echo Downloading prepackaged plugins legacy
# @for plugin_package_legacy in $(PLUGIN_PACKAGES_LEGACY) ; do \
# curl -s https://api.github.com/repos/mattermost/$$plugin_package_legacy | grep browser_download_url | grep darwin | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
# done
#else
# cp $(GOPATH)/bin/darwin_amd64/mattermost $(DIST_PATH)/bin # from cross-compiled bin dir
# cp $(GOPATH)/bin/darwin_amd64/platform $(DIST_PATH)/bin # from cross-compiled bin dir
# @echo Downloading prepackaged plugins legacy
# @for plugin_package_legacy in $(PLUGIN_PACKAGES_LEGACY) ; do \
# curl -s https://api.github.com/repos/mattermost/$$plugin_package_legacy | grep browser_download_url | grep darwin | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
# done
#endif
# @# Package
# tar -C dist -czf $(DIST_PATH)-$(BUILD_TYPE_NAME)-osx-amd64.tar.gz mattermost
# @# Cleanup
# rm -f $(DIST_PATH)/bin/mattermost
# rm -f $(DIST_PATH)/bin/platform
# rm -f $(DIST_PATH)/prepackaged_plugins/*jira*
#
# @# Make windows package
# @# Copy binary
#ifeq ($(BUILDER_GOOS_GOARCH),"windows_amd64")
# cp $(GOPATH)/bin/mattermost.exe $(DIST_PATH)/bin # from native bin dir, not cross-compiled
# cp $(GOPATH)/bin/platform.exe $(DIST_PATH)/bin # from native bin dir, not cross-compiled
# @echo Downloading prepackaged plugins legacy
# @for plugin_package_legacy in $(PLUGIN_PACKAGES_LEGACY) ; do \
# curl -s https://api.github.com/repos/mattermost/$$plugin_package_legacy | grep browser_download_url | grep windows | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
# done
#else
# cp $(GOPATH)/bin/windows_amd64/mattermost.exe $(DIST_PATH)/bin # from cross-compiled bin dir
# cp $(GOPATH)/bin/windows_amd64/platform.exe $(DIST_PATH)/bin # from cross-compiled bin dir
# @echo Downloading prepackaged plugins legacy
# @for plugin_package_legacy in $(PLUGIN_PACKAGES_LEGACY) ; do \
# curl -s https://api.github.com/repos/mattermost/$$plugin_package_legacy | grep browser_download_url | grep windows | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
# done
#endif
# @# Package
# cd $(DIST_ROOT) && zip -9 -r -q -l mattermost-$(BUILD_TYPE_NAME)-windows-amd64.zip mattermost && cd ..
# @# Cleanup
# rm -f $(DIST_PATH)/bin/mattermost.exe
# rm -f $(DIST_PATH)/bin/platform.exe
# rm -f $(DIST_PATH)/prepackaged_plugins/*jira*
#
@# Make linux package
@# Copy binary
ifeq ($(BUILDER_GOOS_GOARCH),"linux_amd64")
cp $(GOPATH)/bin/mattermost $(DIST_PATH)/bin # from native bin dir, not cross-compiled
cp $(GOPATH)/bin/platform $(DIST_PATH)/bin # from native bin dir, not cross-compiled
@for plugin_package in $(PLUGIN_PACKAGES) ; do \
curl -s https://api.github.com/repos/mattermost/$$plugin_package/releases/latest | grep browser_download_url | grep linux | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
@echo Downloading prepackaged plugins legacy
@for plugin_package_legacy in $(PLUGIN_PACKAGES_LEGACY) ; do \
curl -s https://api.github.com/repos/mattermost/$$plugin_package_legacy | grep browser_download_url | grep linux | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
done
else
cp $(GOPATH)/bin/linux_amd64/mattermost $(DIST_PATH)/bin # from cross-compiled bin dir
cp $(GOPATH)/bin/linux_amd64/platform $(DIST_PATH)/bin # from cross-compiled bin dir
@for plugin_package in $(PLUGIN_PACKAGES) ; do \
curl -s https://api.github.com/repos/mattermost/$$plugin_package/releases/latest | grep browser_download_url | grep linux | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
@echo Downloading prepackaged plugins legacy
@for plugin_package_legacy in $(PLUGIN_PACKAGES_LEGACY) ; do \
curl -s https://api.github.com/repos/mattermost/$$plugin_package_legacy | grep browser_download_url | grep linux | cut -d '"' -f 4 | wget -qi - -P $(DIST_PATH)/prepackaged_plugins/ ;\
done
endif
@# Package
......
......@@ -10,6 +10,7 @@ import (
// Plugins
_ "github.com/mattermost/mattermost-server/model/gitlab"
_ "github.com/mattermost/mattermost-server/model/phabricator"
// Enterprise Imports
_ "github.com/mattermost/mattermost-server/imports"
......
......@@ -253,6 +253,15 @@
"TokenEndpoint": "",
"UserApiEndpoint": ""
},
"PhabricatorSettings": {
"Enable": false,
"Secret": "",
"Id": "",
"Scope": "",
"AuthEndpoint": "",
"TokenEndpoint": "",
"UserApiEndpoint": ""
},
"GoogleSettings": {
"Enable": false,
"Secret": "",
......
......@@ -1042,7 +1042,7 @@
},
{
"id": "api.emoji.upload.large_image.too_large.app_error",
"translation": "Unable to create emoji. Image must be smaller than {{.MaxWidth}} by {{.MaxHeight}}."
"translation": "이모지를 생성할 수 없습니다. 이미지는 가로{{ .MaxWidth }}, 세로{{ .MaxHeight }} 보다 작아야 합니다."
},
{
"id": "api.emoji.upload.open.app_error",
......@@ -1760,7 +1760,7 @@
},
{
"id": "api.team.update_restricted_domains.mismatch.app_error",
"translation": "Restricting team to {{ .Domain }} is not allowed by the system config. Please contact your system administrator."
"translation": "팀을 {{ .Domain }}로 제한하는 것은 시스템 설정에 의해 허가되어 있지 않습니다. 시스템 관리자에게 문의하세요."
},
{
"id": "api.team.update_team_scheme.license.error",
......@@ -1780,15 +1780,15 @@
},
{
"id": "api.templates.deactivate_body.warning",
"translation": "If this change was not initiated by you or you want to reactivate your account, contact your system administrator."
"translation": "만약 이 변경사항이 당신에 의해 적용되지 않았거나 계정을 다시 활성화 시키고 싶으시면 시스템 관리자에게 문의하세요."
},
{
"id": "api.templates.deactivate_subject",
"translation": "[{{ .SiteName }}] Your account at {{ .ServerURL }} has been deactivated"
"translation": "[{{ .SiteName }}], {{ .ServerURL }}에 가입된 당신의 계정이 비활성화 되었습니다."
},
{
"id": "api.templates.email_change_body.info",
"translation": "Your email address for {{.TeamDisplayName}} has been changed to {{.NewEmail}}."
"translation": "{{.TeamDisplayName}}에 속한 당신의 이메일 주소가 {{.NewEmail}}로 변경되었습니다."
},
{
"id": "api.templates.email_change_body.title",
......@@ -1796,7 +1796,7 @@
},
{
"id": "api.templates.email_change_subject",
"translation": "[{{ .SiteName }}] Your email address has changed"
"translation": "[{{ .SiteName }}], 당신의 이메일 주소가 변경되었습니다."
},
{
"id": "api.templates.email_change_verify_body.button",
......@@ -1812,7 +1812,7 @@
},
{
"id": "api.templates.email_change_verify_subject",
"translation": "[{{ .SiteName }}] Verify new email address"
"translation": "[{{ .SiteName }}], 새로운 이메일 주소를 확인하세요."
},
{
"id": "api.templates.email_footer",
......@@ -1820,15 +1820,15 @@
},
{
"id": "api.templates.email_info1",
"translation": "Any questions at all, mail us any time: "
"translation": "궁금한 점이 있으면 언제든지 메일로 연락하세요: "
},
{
"id": "api.templates.email_info2",
"translation": "Best wishes,"
"translation": "행복을 기원하며,"
},
{
"id": "api.templates.email_info3",
"translation": "The {{.SiteName}} Team"
"translation": "{{.SiteName}} 팀"
},
{
"id": "api.templates.email_organization",
......@@ -1836,7 +1836,7 @@
},
{
"id": "api.templates.email_warning",
"translation": "If you did not make this change, please contact the system administrator."
"translation": "만약 변경한 적이 없다면, 시스템 관리자에게 문의해 주세요."
},
{
"id": "api.templates.invite_body.button",
......@@ -1844,11 +1844,11 @@
},
{
"id": "api.templates.invite_body.extra_info",
"translation": "Mattermost lets you share messages and files from your PC or phone, with instant search and archiving. After you’ve joined <strong>{{.TeamDisplayName}}</strong>, you can sign-in to your new team and access these features anytime from the web address:<br/><br/><a href='{{.TeamURL}}'>{{.TeamURL}}</a>"
"translation": "Mattermost에서는 PC와 모바일간에 메시지와 파일들을 공유할 수 있으며, 검색과 보관 기능을 사용할 수 있습니다. [[{{.TeamDisplayName}}]] 에 참여한 후에는, 새로운 팀에 들어갈 수 있으며 이러한 기능들을 언제든지 사용할 수 있습니다. 웹 주소:"
},
{
"id": "api.templates.invite_body.info",
"translation": "The team {{.SenderStatus}} [[{{.SenderName}}]], has invited you to join [[{{.TeamDisplayName}}]]."
"translation": "팀 {{.SenderStatus}} [[{{.SenderName}}]] 가 당신을 [[{{.TeamDisplayName}}]] 에 초대했습니다."
},
{
"id": "api.templates.invite_body.title",
......@@ -1856,31 +1856,31 @@
},
{
"id": "api.templates.invite_subject",
"translation": "[{{ .SiteName }}] {{ .SenderName }} invited you to join {{ .TeamDisplayName }} Team"
"translation": "[{{ .SiteName }}] {{ .SenderName }} 가 당신을 {{ .TeamDisplayName }} 팀에 초대했습니다."
},
{
"id": "api.templates.mfa_activated_body.info",
"translation": "Multi-factor authentication has been added to your account on {{ .SiteURL }}."
"translation": "{{ .SiteURL }} 의 당신의 계정에 다중 요소 인증이 추가되었습니다."
},
{
"id": "api.templates.mfa_activated_body.title",
"translation": "Multi-factor authentication was added"
"translation": "다중 요소 인증이 추가되었습니다"
},
{
"id": "api.templates.mfa_change_subject",
"translation": "[{{ .SiteName }}] Your MFA has been updated"
"translation": "[{{ .SiteName }}], 당신의 MFA가 업데이트 되었습니다"
},
{
"id": "api.templates.mfa_deactivated_body.info",
"translation": "Multi-factor authentication has been removed from your account on {{ .SiteURL }}."
"translation": "{{ .SiteURL }}의 당신의 계정에서 다중 요소 인증이 제거되었습니다."
},
{
"id": "api.templates.mfa_deactivated_body.title",
"translation": "Multi-factor authentication was removed"
"translation": "다중 요소 인증이 제거되었습니다"
},
{
"id": "api.templates.password_change_body.info",
"translation": "Your password has been updated for {{.TeamDisplayName}} on {{ .TeamURL }} by {{.Method}}."
"translation": "{{.Method}} 에 의해 {{ .TeamURL }} 의 {{.TeamDisplayName}} 에 대한 당신의 비밀번호가 업데이트 되었습니다."
},
{
"id": "api.templates.password_change_body.title",
......@@ -1888,7 +1888,7 @@
},
{
"id": "api.templates.password_change_subject",
"translation": "[{{ .SiteName }}] Your password has been updated"
"translation": "[{{ .SiteName }}], 당신의 비밀번호가 업데이트 되었습니다"
},
{
"id": "api.templates.post_body.button",
......@@ -1900,11 +1900,11 @@
},
{
"id": "api.templates.reset_body.info1",
"translation": "To change your password, click \"Reset Password\" below."
"translation": "비밀번호를 변경하기 위해서는, 아래의 \"비밀번호 초기화\" 를 누르세요."
},
{
"id": "api.templates.reset_body.info2",
"translation": "If you did not mean to reset your password, please ignore this email and your password will remain the same. The password reset link expires in 24 hours."
"translation": "만약 비밀번호를 초기화 할 의사가 없다면, 이 이메일은 무시하세요. 당신의 비밀번호는 변경되지 않을 것입니다. 비밀번호 변경 링크는 24시간 안에 폐기됩니다."
},
{
"id": "api.templates.reset_body.title",
......@@ -1912,7 +1912,7 @@
},
{
"id": "api.templates.reset_subject",
"translation": "[{{ .SiteName }}] Reset your password"
"translation": "[{{ .SiteName }}] 비밀번호를 초기화했습니다."
},
{
"id": "api.templates.signin_change_email.body.info",
......@@ -1928,23 +1928,23 @@
},
{
"id": "api.templates.signin_change_email.subject",
"translation": "[{{ .SiteName }}] Your sign-in method has been updated"
"translation": "[{{ .SiteName }}] 당신의 로그인 방식이 변경되었습니다."
},
{
"id": "api.templates.user_access_token_body.info",
"translation": "A personal access token was added to your account on {{ .SiteURL }}. They can be used to access {{.SiteName}} with your account."
"translation": "{{ .SiteURL }} 에서 당신의 계정에 개인 엑세스 토큰이 발급되었습니다. 당신의 계정으로 {{.SiteName}} 에 접속할 때 사용하실 수 있습니다."
},
{
"id": "api.templates.user_access_token_body.title",
"translation": "Personal access token added to your account"
"translation": "개인 엑세스 토큰이 당신의 계정에 발급되었습니다"
},
{
"id": "api.templates.user_access_token_subject",
"translation": "[{{ .SiteName }}] Personal access token added to your account"
"translation": "[{{ .SiteName }}] 당신의 계정에 개인 엑세스 토큰이 발급되었습니다"
},
{
"id": "api.templates.username_change_body.info",
"translation": "Your username for {{.TeamDisplayName}} has been changed to {{.NewUsername}}."
"translation": "{{.TeamDisplayName}} 팀의 당신의 사용자명이 {{.NewUsername}} 로 변경되었습니다."
},
{
"id": "api.templates.username_change_body.title",
......@@ -1952,7 +1952,7 @@
},
{
"id": "api.templates.username_change_subject",
"translation": "[{{ .SiteName }}] Your username has changed"
"translation": "[{{ .SiteName }}] 당신의 사용자명이 변경되었습니다"
},
{
"id": "api.templates.verify_body.button",
......@@ -1996,7 +1996,7 @@
},
{
"id": "api.templates.welcome_subject",
"translation": "[{{ .SiteName }}] You joined {{ .ServerURL }}"
"translation": "[{{ .SiteName }}] {{ .ServerURL }} 에 참가했습니다."
},
{
"id": "api.user.activate_mfa.email_and_ldap_only.app_error",
......
......@@ -165,7 +165,7 @@
},
{
"id": "api.channel.join_channel.post_and_forget",
"translation": "%v присоединяется к каналу."
"translation": "%v - выполнен вход на канал"
},
{
"id": "api.channel.leave.default.app_error",
......@@ -1330,7 +1330,7 @@
},
{
"id": "api.post.check_for_out_of_channel_mentions.message.one",
"translation": "{{.Username}} были упомянуты, но они не получили уведомлений поскольку не состоят в этом канале."
"translation": "{{.Username}} упомянули, но уведомлений не будут получены поскольку пользователи не состоят в этом канале."
},
{
"id": "api.post.create_post.can_not_post_to_deleted.error",
......@@ -3160,7 +3160,7 @@
},
{
"id": "app.team.join_user_to_team.max_accounts.app_error",
"translation": "Эта команда достигла максимального количества разрешенных учетных записей. Свяжитесь с системным администратором для установки большего предела."
"translation": "Эта команда достигла максимального количества разрешенных учетных записей. Свяжитесь с системным администратором для увеличения лимита учётных записей."
},
{
"id": "app.user.complete_switch_with_oauth.blank_email.app_error",
......@@ -3312,7 +3312,7 @@
},
{
"id": "ent.elasticsearch.data_retention_delete_indexes.get_indexes.error",
"translation": "Не удалось создать индекс Elasticsearch"
"translation": "Не удалось получить индексы Elasticsearch"
},
{
"id": "ent.elasticsearch.delete_post.error",
......@@ -3324,7 +3324,7 @@
},
{
"id": "ent.elasticsearch.index_post.error",
"translation": "Не удалось удалить плагин"
"translation": "Не удалось проиндексировать запись"
},
{
"id": "ent.elasticsearch.indexer.do_job.get_oldest_post.error",
......@@ -3388,7 +3388,7 @@
},
{
"id": "ent.elasticsearch.test_config.license.error",
"translation": "Редакция не поддерживает Elasticsearch."
"translation": "Ваша версия сервера Mattermost не поддерживает Elasticsearch."
},
{
"id": "ent.elasticsearch.test_config.reenter_password",
......
......@@ -38,9 +38,10 @@ const (
PASSWORD_MAXIMUM_LENGTH = 64
PASSWORD_MINIMUM_LENGTH = 5
SERVICE_GITLAB = "gitlab"
SERVICE_GOOGLE = "google"
SERVICE_OFFICE365 = "office365"
SERVICE_GITLAB = "gitlab"
SERVICE_PHABRICATOR = "phabricator"
SERVICE_GOOGLE = "google"
SERVICE_OFFICE365 = "office365"
GENERIC_NO_CHANNEL_NOTIFICATION = "generic_no_channel"
GENERIC_NOTIFICATION = "generic"
......@@ -50,6 +51,7 @@ const (
DIRECT_MESSAGE_TEAM = "team"
SHOW_USERNAME = "username"
SHOW_NICKNAME_USERNAME = "nickname_username"
SHOW_NICKNAME_FULLNAME = "nickname_full_name"
SHOW_FULLNAME = "full_name"
......@@ -1940,6 +1942,7 @@ type Config struct {
AnnouncementSettings AnnouncementSettings
ThemeSettings ThemeSettings
GitLabSettings SSOSettings
PhabricatorSettings SSOSettings
GoogleSettings SSOSettings
Office365Settings SSOSettings
LdapSettings LdapSettings
......@@ -1977,6 +1980,8 @@ func (o *Config) GetSSOService(service string) *SSOSettings {
switch service {
case SERVICE_GITLAB:
return &o.GitLabSettings
case SERVICE_PHABRICATOR:
return &o.PhabricatorSettings
case SERVICE_GOOGLE:
return &o.GoogleSettings
case SERVICE_OFFICE365:
......@@ -2121,7 +2126,7 @@ func (ts *TeamSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.restrict_direct_message.app_error", nil, "", http.StatusBadRequest)
}
if !(*ts.TeammateNameDisplay == SHOW_FULLNAME || *ts.TeammateNameDisplay == SHOW_NICKNAME_FULLNAME || *ts.TeammateNameDisplay == SHOW_USERNAME) {
if !(*ts.TeammateNameDisplay == SHOW_FULLNAME || *ts.TeammateNameDisplay == SHOW_NICKNAME_FULLNAME || *ts.TeammateNameDisplay == SHOW_NICKNAME_USERNAME || *ts.TeammateNameDisplay == SHOW_USERNAME) {
return NewAppError("Config.IsValid", "model.config.is_valid.teammate_name_display.app_error", nil, "", http.StatusBadRequest)
}
......@@ -2541,6 +2546,10 @@ func (o *Config) Sanitize() {
o.GitLabSettings.Secret = FAKE_SETTING
}
if len(o.PhabricatorSettings.Secret) > 0 {
o.PhabricatorSettings.Secret = FAKE_SETTING
}
*o.SqlSettings.DataSource = FAKE_SETTING
o.SqlSettings.AtRestEncryptKey = FAKE_SETTING
......
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package model
const (
USER_AUTH_SERVICE_PHABRICATOR = "phabricator"
)
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package oauthphabricator
import (
"encoding/json"
"io"
"strings"
"github.com/mattermost/mattermost-server/einterfaces"
"github.com/mattermost/mattermost-server/model"
)
type PhabricatorProvider struct {
}
type PhabricatorUser struct {
Id string `json:"phid"`
Username string `json:"userName"`
Email string `json:"primaryEmail"`
Name string `json:"realName"`
}
type PhabricatorConduitResult struct {
User PhabricatorUser `json:"result"`
}
func init() {
provider := &PhabricatorProvider{}
einterfaces.RegisterOauthProvider(model.USER_AUTH_SERVICE_PHABRICATOR, provider)
}
func userFromPhabricatorUser(phu *PhabricatorUser) *model.User {
user := &model.User{}
user.Username = model.CleanUsername(phu.Username)
splitName := strings.Split(phu.Name, " ")
if len(splitName) == 2 {
user.FirstName = splitName[0]
user.LastName = splitName[1]
} else if len(splitName) >= 2 {
user.FirstName = splitName[0]
user.LastName = strings.Join(splitName[1:], " ")
} else {
user.FirstName = phu.Name
}
strings.TrimSpace(user.Email)
user.Email = phu.Email
userId := phu.getAuthData()
user.AuthData = &userId
user.AuthService = model.USER_AUTH_SERVICE_PHABRICATOR
return user
}
func phabricatorUserFromJson(data io.Reader) *PhabricatorUser {
decoder := json.NewDecoder(data)
var phc PhabricatorConduitResult
err := decoder.Decode(&phc)
if err == nil {
return &phc.User
} else {
return nil
}
}
func (phu *PhabricatorUser) ToJson() string {
b, err := json.Marshal(phu)
if err != nil {
return ""
} else {
return string(b)
}
}
func (phu *PhabricatorUser) IsValid() bool {
if len(phu.Id) == 0 {
return false
}
if len(phu.Email) == 0 {
return false
}
return true
}
func (phu *PhabricatorUser) getAuthData() string {
return strings.Replace(phu.Id, "PHID-USER-", "PHID--", 1)
}
func (m *PhabricatorProvider) GetIdentifier() string {
return model.USER_AUTH_SERVICE_PHABRICATOR
}
func (m *PhabricatorProvider) GetUserFromJson(data io.Reader) *model.User {
phu := phabricatorUserFromJson(data)
if phu.IsValid() {
return userFromPhabricatorUser(phu)
}
return &model.User{}
}
func (m *PhabricatorProvider) GetAuthDataFromJson(data io.Reader) string {
phu := phabricatorUserFromJson(data)
if phu.IsValid() {
return phu.getAuthData()
}
return ""
}
......@@ -33,6 +33,7 @@ func (o *SwitchRequest) EmailToOAuth() bool {
return o.CurrentService == USER_AUTH_SERVICE_EMAIL &&
(o.NewService == USER_AUTH_SERVICE_SAML ||
o.NewService == USER_AUTH_SERVICE_GITLAB ||
o.NewService == USER_AUTH_SERVICE_PHABRICATOR ||
o.NewService == SERVICE_GOOGLE ||
o.NewService == SERVICE_OFFICE365)
}
......@@ -40,6 +41,7 @@ func (o *SwitchRequest) EmailToOAuth() bool {
func (o *SwitchRequest) OAuthToEmail() bool {
return (o.CurrentService == USER_AUTH_SERVICE_SAML ||
o.CurrentService == USER_AUTH_SERVICE_GITLAB ||
o.CurrentService == USER_AUTH_SERVICE_PHABRICATOR ||
o.CurrentService == SERVICE_GOOGLE ||
o.CurrentService == SERVICE_OFFICE365) && o.NewService == USER_AUTH_SERVICE_EMAIL
}
......
......@@ -419,15 +419,16 @@ func (u *User) GetFullName() string {
func (u *User) GetDisplayName(nameFormat string) string {
displayName := u.Username
fullName := u.GetFullName()
if nameFormat == SHOW_NICKNAME_FULLNAME {
if nameFormat == SHOW_NICKNAME_FULLNAME || nameFormat == SHOW_NICKNAME_USERNAME {
if len(u.Nickname) > 0 {
displayName = u.Nickname
} else if fullName := u.GetFullName(); len(fullName) > 0 {
} else if nameFormat == SHOW_NICKNAME_FULLNAME && len(fullName) > 0 {
displayName = fullName
}
} else if nameFormat == SHOW_FULLNAME {
if fullName := u.GetFullName(); len(fullName) > 0 {
if len(fullName) > 0 {
displayName = fullName
}
}
......@@ -486,7 +487,7 @@ func (u *User) IsSSOUser() bool {
}
func (u *User) IsOAuthUser() bool {
return u.AuthService == USER_AUTH_SERVICE_GITLAB
return u.AuthService == USER_AUTH_SERVICE_GITLAB || u.AuthService == USER_AUTH_SERVICE_PHABRICATOR
}
func (u *User) IsLDAPUser() bool {
......
......@@ -581,8 +581,6 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
props["EnableUserTypingMessages"] = strconv.FormatBool(*c.ServiceSettings.EnableUserTypingMessages)
props["EnableChannelViewedMessages"] = strconv.FormatBool(*c.ServiceSettings.EnableChannelViewedMessages)
props["PluginsEnabled"] = strconv.FormatBool(*c.PluginSettings.Enable)
props["RunJobs"] = strconv.FormatBool(*c.JobSettings.RunJobs)
props["EnableEmailInvitations"] = strconv.FormatBool(*c.ServiceSettings.EnableEmailInvitations)
......@@ -725,6 +723,7 @@ func GenerateLimitedClientConfig(c *model.Config, diagnosticId string, license *
props["EmailLoginButtonTextColor"] = *c.EmailSettings.LoginButtonTextColor
props["EnableSignUpWithGitLab"] = strconv.FormatBool(c.GitLabSettings.Enable)
props["EnableSignUpWithPhabricator"] = strconv.FormatBool(c.PhabricatorSettings.Enable)
props["TermsOfServiceLink"] = *c.SupportSettings.TermsOfServiceLink
props["PrivacyPolicyLink"] = *c.SupportSettings.PrivacyPolicyLink
......@@ -746,6 +745,8 @@ func GenerateLimitedClientConfig(c *model.Config, diagnosticId string, license *
hasImageProxy := c.ServiceSettings.ImageProxyType != nil && *c.ServiceSettings.ImageProxyType != "" && c.ServiceSettings.ImageProxyURL != nil && *c.ServiceSettings.ImageProxyURL != ""
props["HasImageProxy"] = strconv.FormatBool(hasImageProxy)
props["PluginsEnabled"] = strconv.FormatBool(*c.PluginSettings.Enable)
// Set default values for all options that require a license.
props["EnableCustomBrand"] = "false"
props["CustomBrandText"] = ""
......
......@@ -69,9 +69,13 @@ func UpdateAssetsSubpath(subpath string) error {
script := fmt.Sprintf("window.publicPath='%s'", newPath)
scriptHash := sha256.Sum256([]byte(script))
reCSP := regexp.MustCompile(`<meta http-equiv=Content-Security-Policy content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval'([^"]*)">`)
reCSP := regexp.MustCompile(`<meta http-equiv="Content-Security-Policy" content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval'([^"]*)">`)
if results := reCSP.FindAllString(newRootHtml, -1); len(results) == 0 {
return fmt.Errorf("failed to find 'Content-Security-Policy' meta tag to rewrite")
}
newRootHtml = reCSP.ReplaceAllLiteralString(newRootHtml, fmt.Sprintf(
`<meta http-equiv=Content-Security-Policy content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval' 'sha256-%s'">`,
`<meta http-equiv="Content-Security-Policy" content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval' 'sha256-%s'">`,
base64.StdEncoding.EncodeToString(scriptHash[:]),
))
......
This diff is collapsed.