diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/admin.go | 2 | ||||
-rw-r--r-- | app/apptestlib.go | 2 | ||||
-rw-r--r-- | app/authentication.go | 4 | ||||
-rw-r--r-- | app/command.go | 16 | ||||
-rw-r--r-- | app/compliance.go | 6 | ||||
-rw-r--r-- | app/diagnostics.go | 105 | ||||
-rw-r--r-- | app/elasticsearch.go | 2 | ||||
-rw-r--r-- | app/email_batching.go | 2 | ||||
-rw-r--r-- | app/job.go | 2 | ||||
-rw-r--r-- | app/ldap.go | 4 | ||||
-rw-r--r-- | app/license_test.go | 2 | ||||
-rw-r--r-- | app/notification.go | 14 | ||||
-rw-r--r-- | app/oauth.go | 4 | ||||
-rw-r--r-- | app/post.go | 8 | ||||
-rw-r--r-- | app/slackimport_test.go | 126 | ||||
-rw-r--r-- | app/team.go | 4 | ||||
-rw-r--r-- | app/team_test.go | 20 | ||||
-rw-r--r-- | app/user.go | 2 | ||||
-rw-r--r-- | app/web_conn.go | 2 | ||||
-rw-r--r-- | app/webhook.go | 53 | ||||
-rw-r--r-- | app/webrtc.go | 17 | ||||
-rw-r--r-- | app/webtrc.go | 28 |
22 files changed, 217 insertions, 208 deletions
diff --git a/app/admin.go b/app/admin.go index 6fbe150c4..50ed769b6 100644 --- a/app/admin.go +++ b/app/admin.go @@ -13,10 +13,10 @@ import ( l4g "github.com/alecthomas/log4go" "github.com/mattermost/platform/einterfaces" + "github.com/mattermost/platform/jobs" "github.com/mattermost/platform/model" "github.com/mattermost/platform/store" "github.com/mattermost/platform/utils" - "github.com/mattermost/platform/jobs" ) func GetLogs(page, perPage int) ([]string, *model.AppError) { diff --git a/app/apptestlib.go b/app/apptestlib.go index 0c7086c64..3966bdeea 100644 --- a/app/apptestlib.go +++ b/app/apptestlib.go @@ -28,7 +28,7 @@ func SetupEnterprise() *TestHelper { utils.Cfg.TeamSettings.MaxUsersPerTeam = 50 *utils.Cfg.RateLimitSettings.Enable = false utils.DisableDebugLogForTest() - utils.License.Features.SetDefaults() + utils.License().Features.SetDefaults() NewServer() InitStores() StartServer() diff --git a/app/authentication.go b/app/authentication.go index 5e1b4461f..b09234d5f 100644 --- a/app/authentication.go +++ b/app/authentication.go @@ -102,7 +102,7 @@ func CheckUserAdditionalAuthenticationCriteria(user *model.User, mfaToken string } func CheckUserMfa(user *model.User, token string) *model.AppError { - if !user.MfaActive || !utils.IsLicensed || !*utils.License.Features.MFA || !*utils.Cfg.ServiceSettings.EnableMultifactorAuthentication { + if !user.MfaActive || !utils.IsLicensed() || !*utils.License().Features.MFA || !*utils.Cfg.ServiceSettings.EnableMultifactorAuthentication { return nil } @@ -143,7 +143,7 @@ func checkUserNotDisabled(user *model.User) *model.AppError { } func authenticateUser(user *model.User, password, mfaToken string) (*model.User, *model.AppError) { - ldapAvailable := *utils.Cfg.LdapSettings.Enable && einterfaces.GetLdapInterface() != nil && utils.IsLicensed && *utils.License.Features.LDAP + ldapAvailable := *utils.Cfg.LdapSettings.Enable && einterfaces.GetLdapInterface() != nil && utils.IsLicensed() && *utils.License().Features.LDAP if user.AuthService == model.USER_AUTH_SERVICE_LDAP { if !ldapAvailable { diff --git a/app/command.go b/app/command.go index bfb97ae0c..83500cc1f 100644 --- a/app/command.go +++ b/app/command.go @@ -45,10 +45,9 @@ func CreateCommandPost(post *model.Post, teamId string, response *model.CommandR parseSlackAttachment(post, response.Attachments) } - switch response.ResponseType { - case model.COMMAND_RESPONSE_TYPE_IN_CHANNEL: + if response.ResponseType == model.COMMAND_RESPONSE_TYPE_IN_CHANNEL { return CreatePost(post, teamId, true) - case model.COMMAND_RESPONSE_TYPE_EPHEMERAL: + } else if response.ResponseType == "" || response.ResponseType == model.COMMAND_RESPONSE_TYPE_EPHEMERAL { if response.Text == "" { return post, nil } @@ -196,7 +195,12 @@ func ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse, *model.App p.Set("command", "/"+trigger) p.Set("text", message) - p.Set("response_url", "not supported yet") + + if hook, err := CreateCommandWebhook(cmd.Id, args); err != nil { + return nil, model.NewAppError("command", "api.command.execute_command.failed.app_error", map[string]interface{}{"Trigger": trigger}, err.Error(), http.StatusInternalServerError) + } else { + p.Set("response_url", args.SiteURL+"/hooks/commands/"+hook.Id) + } method := "POST" if cmd.Method == model.COMMAND_METHOD_GET { @@ -209,11 +213,11 @@ func ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse, *model.App req.Header.Set("Content-Type", "application/x-www-form-urlencoded") } - if resp, err := utils.HttpClient().Do(req); err != nil { + if resp, err := utils.HttpClient(false).Do(req); err != nil { return nil, model.NewAppError("command", "api.command.execute_command.failed.app_error", map[string]interface{}{"Trigger": trigger}, err.Error(), http.StatusInternalServerError) } else { if resp.StatusCode == http.StatusOK { - response := model.CommandResponseFromJson(resp.Body) + response := model.CommandResponseFromHTTPBody(resp.Header.Get("Content-Type"), resp.Body) if response == nil { return nil, model.NewAppError("command", "api.command.execute_command.failed_empty.app_error", map[string]interface{}{"Trigger": trigger}, "", http.StatusInternalServerError) } else { diff --git a/app/compliance.go b/app/compliance.go index cb1eece70..5b4f9de67 100644 --- a/app/compliance.go +++ b/app/compliance.go @@ -12,7 +12,7 @@ import ( ) func GetComplianceReports(page, perPage int) (model.Compliances, *model.AppError) { - if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed || !*utils.License.Features.Compliance { + if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed() || !*utils.License().Features.Compliance { return nil, model.NewLocAppError("GetComplianceReports", "ent.compliance.licence_disable.app_error", nil, "") } @@ -24,7 +24,7 @@ func GetComplianceReports(page, perPage int) (model.Compliances, *model.AppError } func SaveComplianceReport(job *model.Compliance) (*model.Compliance, *model.AppError) { - if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed || !*utils.License.Features.Compliance || einterfaces.GetComplianceInterface() == nil { + if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed() || !*utils.License().Features.Compliance || einterfaces.GetComplianceInterface() == nil { return nil, model.NewLocAppError("saveComplianceReport", "ent.compliance.licence_disable.app_error", nil, "") } @@ -41,7 +41,7 @@ func SaveComplianceReport(job *model.Compliance) (*model.Compliance, *model.AppE } func GetComplianceReport(reportId string) (*model.Compliance, *model.AppError) { - if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed || !*utils.License.Features.Compliance || einterfaces.GetComplianceInterface() == nil { + if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed() || !*utils.License().Features.Compliance || einterfaces.GetComplianceInterface() == nil { return nil, model.NewLocAppError("downloadComplianceReport", "ent.compliance.licence_disable.app_error", nil, "") } diff --git a/app/diagnostics.go b/app/diagnostics.go index 983ce8077..1df5b1feb 100644 --- a/app/diagnostics.go +++ b/app/diagnostics.go @@ -49,7 +49,7 @@ const ( var client *analytics.Client func SendDailyDiagnostics() { - if *utils.Cfg.LogSettings.EnableDiagnostics { + if *utils.Cfg.LogSettings.EnableDiagnostics && utils.IsLeader() { initDiagnostics("") trackActivity() trackConfig() @@ -174,49 +174,50 @@ func trackActivity() { func trackConfig() { SendDiagnostic(TRACK_CONFIG_SERVICE, map[string]interface{}{ - "web_server_mode": *utils.Cfg.ServiceSettings.WebserverMode, - "enable_security_fix_alert": *utils.Cfg.ServiceSettings.EnableSecurityFixAlert, - "enable_insecure_outgoing_connections": *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections, - "enable_incoming_webhooks": utils.Cfg.ServiceSettings.EnableIncomingWebhooks, - "enable_outgoing_webhooks": utils.Cfg.ServiceSettings.EnableOutgoingWebhooks, - "enable_commands": *utils.Cfg.ServiceSettings.EnableCommands, - "enable_only_admin_integrations": *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations, - "enable_post_username_override": utils.Cfg.ServiceSettings.EnablePostUsernameOverride, - "enable_post_icon_override": utils.Cfg.ServiceSettings.EnablePostIconOverride, - "enable_apiv3": *utils.Cfg.ServiceSettings.EnableAPIv3, - "enable_user_access_tokens": *utils.Cfg.ServiceSettings.EnableUserAccessTokens, - "enable_custom_emoji": *utils.Cfg.ServiceSettings.EnableCustomEmoji, - "enable_emoji_picker": *utils.Cfg.ServiceSettings.EnableEmojiPicker, - "restrict_custom_emoji_creation": *utils.Cfg.ServiceSettings.RestrictCustomEmojiCreation, - "enable_testing": utils.Cfg.ServiceSettings.EnableTesting, - "enable_developer": *utils.Cfg.ServiceSettings.EnableDeveloper, - "enable_multifactor_authentication": *utils.Cfg.ServiceSettings.EnableMultifactorAuthentication, - "enforce_multifactor_authentication": *utils.Cfg.ServiceSettings.EnforceMultifactorAuthentication, - "enable_oauth_service_provider": utils.Cfg.ServiceSettings.EnableOAuthServiceProvider, - "connection_security": *utils.Cfg.ServiceSettings.ConnectionSecurity, - "uses_letsencrypt": *utils.Cfg.ServiceSettings.UseLetsEncrypt, - "forward_80_to_443": *utils.Cfg.ServiceSettings.Forward80To443, - "maximum_login_attempts": utils.Cfg.ServiceSettings.MaximumLoginAttempts, - "session_length_web_in_days": *utils.Cfg.ServiceSettings.SessionLengthWebInDays, - "session_length_mobile_in_days": *utils.Cfg.ServiceSettings.SessionLengthMobileInDays, - "session_length_sso_in_days": *utils.Cfg.ServiceSettings.SessionLengthSSOInDays, - "session_cache_in_minutes": *utils.Cfg.ServiceSettings.SessionCacheInMinutes, - "isdefault_site_url": isDefault(*utils.Cfg.ServiceSettings.SiteURL, model.SERVICE_SETTINGS_DEFAULT_SITE_URL), - "isdefault_tls_cert_file": isDefault(*utils.Cfg.ServiceSettings.TLSCertFile, model.SERVICE_SETTINGS_DEFAULT_TLS_CERT_FILE), - "isdefault_tls_key_file": isDefault(*utils.Cfg.ServiceSettings.TLSKeyFile, model.SERVICE_SETTINGS_DEFAULT_TLS_KEY_FILE), - "isdefault_read_timeout": isDefault(*utils.Cfg.ServiceSettings.ReadTimeout, model.SERVICE_SETTINGS_DEFAULT_READ_TIMEOUT), - "isdefault_write_timeout": isDefault(*utils.Cfg.ServiceSettings.WriteTimeout, model.SERVICE_SETTINGS_DEFAULT_WRITE_TIMEOUT), - "isdefault_google_developer_key": isDefault(utils.Cfg.ServiceSettings.GoogleDeveloperKey, ""), - "isdefault_allow_cors_from": isDefault(*utils.Cfg.ServiceSettings.AllowCorsFrom, model.SERVICE_SETTINGS_DEFAULT_ALLOW_CORS_FROM), - "restrict_post_delete": *utils.Cfg.ServiceSettings.RestrictPostDelete, - "allow_edit_post": *utils.Cfg.ServiceSettings.AllowEditPost, - "post_edit_time_limit": *utils.Cfg.ServiceSettings.PostEditTimeLimit, - "enable_user_typing_messages": *utils.Cfg.ServiceSettings.EnableUserTypingMessages, - "enable_channel_viewed_messages": *utils.Cfg.ServiceSettings.EnableChannelViewedMessages, - "time_between_user_typing_updates_milliseconds": *utils.Cfg.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds, - "cluster_log_timeout_milliseconds": *utils.Cfg.ServiceSettings.ClusterLogTimeoutMilliseconds, - "enable_post_search": *utils.Cfg.ServiceSettings.EnablePostSearch, - "enable_user_statuses": *utils.Cfg.ServiceSettings.EnableUserStatuses, + "web_server_mode": *utils.Cfg.ServiceSettings.WebserverMode, + "enable_security_fix_alert": *utils.Cfg.ServiceSettings.EnableSecurityFixAlert, + "enable_insecure_outgoing_connections": *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections, + "enable_incoming_webhooks": utils.Cfg.ServiceSettings.EnableIncomingWebhooks, + "enable_outgoing_webhooks": utils.Cfg.ServiceSettings.EnableOutgoingWebhooks, + "enable_commands": *utils.Cfg.ServiceSettings.EnableCommands, + "enable_only_admin_integrations": *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations, + "enable_post_username_override": utils.Cfg.ServiceSettings.EnablePostUsernameOverride, + "enable_post_icon_override": utils.Cfg.ServiceSettings.EnablePostIconOverride, + "enable_apiv3": *utils.Cfg.ServiceSettings.EnableAPIv3, + "enable_user_access_tokens": *utils.Cfg.ServiceSettings.EnableUserAccessTokens, + "enable_custom_emoji": *utils.Cfg.ServiceSettings.EnableCustomEmoji, + "enable_emoji_picker": *utils.Cfg.ServiceSettings.EnableEmojiPicker, + "restrict_custom_emoji_creation": *utils.Cfg.ServiceSettings.RestrictCustomEmojiCreation, + "enable_testing": utils.Cfg.ServiceSettings.EnableTesting, + "enable_developer": *utils.Cfg.ServiceSettings.EnableDeveloper, + "enable_multifactor_authentication": *utils.Cfg.ServiceSettings.EnableMultifactorAuthentication, + "enforce_multifactor_authentication": *utils.Cfg.ServiceSettings.EnforceMultifactorAuthentication, + "enable_oauth_service_provider": utils.Cfg.ServiceSettings.EnableOAuthServiceProvider, + "connection_security": *utils.Cfg.ServiceSettings.ConnectionSecurity, + "uses_letsencrypt": *utils.Cfg.ServiceSettings.UseLetsEncrypt, + "forward_80_to_443": *utils.Cfg.ServiceSettings.Forward80To443, + "maximum_login_attempts": utils.Cfg.ServiceSettings.MaximumLoginAttempts, + "session_length_web_in_days": *utils.Cfg.ServiceSettings.SessionLengthWebInDays, + "session_length_mobile_in_days": *utils.Cfg.ServiceSettings.SessionLengthMobileInDays, + "session_length_sso_in_days": *utils.Cfg.ServiceSettings.SessionLengthSSOInDays, + "session_cache_in_minutes": *utils.Cfg.ServiceSettings.SessionCacheInMinutes, + "isdefault_site_url": isDefault(*utils.Cfg.ServiceSettings.SiteURL, model.SERVICE_SETTINGS_DEFAULT_SITE_URL), + "isdefault_tls_cert_file": isDefault(*utils.Cfg.ServiceSettings.TLSCertFile, model.SERVICE_SETTINGS_DEFAULT_TLS_CERT_FILE), + "isdefault_tls_key_file": isDefault(*utils.Cfg.ServiceSettings.TLSKeyFile, model.SERVICE_SETTINGS_DEFAULT_TLS_KEY_FILE), + "isdefault_read_timeout": isDefault(*utils.Cfg.ServiceSettings.ReadTimeout, model.SERVICE_SETTINGS_DEFAULT_READ_TIMEOUT), + "isdefault_write_timeout": isDefault(*utils.Cfg.ServiceSettings.WriteTimeout, model.SERVICE_SETTINGS_DEFAULT_WRITE_TIMEOUT), + "isdefault_google_developer_key": isDefault(utils.Cfg.ServiceSettings.GoogleDeveloperKey, ""), + "isdefault_allow_cors_from": isDefault(*utils.Cfg.ServiceSettings.AllowCorsFrom, model.SERVICE_SETTINGS_DEFAULT_ALLOW_CORS_FROM), + "isdefault_allowed_untrusted_internal_connections": isDefault(*utils.Cfg.ServiceSettings.AllowedUntrustedInternalConnections, ""), + "restrict_post_delete": *utils.Cfg.ServiceSettings.RestrictPostDelete, + "allow_edit_post": *utils.Cfg.ServiceSettings.AllowEditPost, + "post_edit_time_limit": *utils.Cfg.ServiceSettings.PostEditTimeLimit, + "enable_user_typing_messages": *utils.Cfg.ServiceSettings.EnableUserTypingMessages, + "enable_channel_viewed_messages": *utils.Cfg.ServiceSettings.EnableChannelViewedMessages, + "time_between_user_typing_updates_milliseconds": *utils.Cfg.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds, + "cluster_log_timeout_milliseconds": *utils.Cfg.ServiceSettings.ClusterLogTimeoutMilliseconds, + "enable_post_search": *utils.Cfg.ServiceSettings.EnablePostSearch, + "enable_user_statuses": *utils.Cfg.ServiceSettings.EnableUserStatuses, }) SendDiagnostic(TRACK_CONFIG_TEAM, map[string]interface{}{ @@ -422,17 +423,17 @@ func trackConfig() { } func trackLicense() { - if utils.IsLicensed { + if utils.IsLicensed() { data := map[string]interface{}{ - "customer_id": utils.License.Customer.Id, - "license_id": utils.License.Id, - "issued": utils.License.IssuedAt, - "start": utils.License.StartsAt, - "expire": utils.License.ExpiresAt, - "users": *utils.License.Features.Users, + "customer_id": utils.License().Customer.Id, + "license_id": utils.License().Id, + "issued": utils.License().IssuedAt, + "start": utils.License().StartsAt, + "expire": utils.License().ExpiresAt, + "users": *utils.License().Features.Users, } - features := utils.License.Features.ToMap() + features := utils.License().Features.ToMap() for featureName, featureValue := range features { data["feature_"+featureName] = featureValue } diff --git a/app/elasticsearch.go b/app/elasticsearch.go index 740042ba5..6f3a4e38b 100644 --- a/app/elasticsearch.go +++ b/app/elasticsearch.go @@ -6,8 +6,8 @@ package app import ( "net/http" - "github.com/mattermost/platform/model" "github.com/mattermost/platform/einterfaces" + "github.com/mattermost/platform/model" "github.com/mattermost/platform/utils" ) diff --git a/app/email_batching.go b/app/email_batching.go index a578daf04..b37963a94 100644 --- a/app/email_batching.go +++ b/app/email_batching.go @@ -196,7 +196,7 @@ func sendBatchedEmailNotification(userId string, notifications []*batchedNotific } emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL - if utils.IsLicensed && *utils.License.Features.EmailNotificationContents { + if utils.IsLicensed() && *utils.License().Features.EmailNotificationContents { emailNotificationContentsType = *utils.Cfg.EmailSettings.EmailNotificationContentsType } diff --git a/app/job.go b/app/job.go index 36c0b1992..005324999 100644 --- a/app/job.go +++ b/app/job.go @@ -4,8 +4,8 @@ package app import ( - "github.com/mattermost/platform/model" "github.com/mattermost/platform/jobs" + "github.com/mattermost/platform/model" ) func GetJob(id string) (*model.Job, *model.AppError) { diff --git a/app/ldap.go b/app/ldap.go index 1b823dc47..17c24db8f 100644 --- a/app/ldap.go +++ b/app/ldap.go @@ -14,7 +14,7 @@ import ( func SyncLdap() { go func() { - if utils.IsLicensed && *utils.License.Features.LDAP && *utils.Cfg.LdapSettings.Enable { + if utils.IsLicensed() && *utils.License().Features.LDAP && *utils.Cfg.LdapSettings.Enable { if ldapI := einterfaces.GetLdapInterface(); ldapI != nil { ldapI.SyncNow() } else { @@ -25,7 +25,7 @@ func SyncLdap() { } func TestLdap() *model.AppError { - if ldapI := einterfaces.GetLdapInterface(); ldapI != nil && utils.IsLicensed && *utils.License.Features.LDAP && *utils.Cfg.LdapSettings.Enable { + if ldapI := einterfaces.GetLdapInterface(); ldapI != nil && utils.IsLicensed() && *utils.License().Features.LDAP && *utils.Cfg.LdapSettings.Enable { if err := ldapI.RunTest(); err != nil { err.StatusCode = 500 return err diff --git a/app/license_test.go b/app/license_test.go index a7761b204..07805992a 100644 --- a/app/license_test.go +++ b/app/license_test.go @@ -13,7 +13,7 @@ func TestLoadLicense(t *testing.T) { Setup() LoadLicense() - if utils.IsLicensed { + if utils.IsLicensed() { t.Fatal("shouldn't have a valid license") } } diff --git a/app/notification.go b/app/notification.go index 2b8c0c8c4..21271c716 100644 --- a/app/notification.go +++ b/app/notification.go @@ -236,7 +236,7 @@ func SendNotifications(post *model.Post, team *model.Team, channel *model.Channe sendPushNotifications := false if *utils.Cfg.EmailSettings.SendPushNotifications { pushServer := *utils.Cfg.EmailSettings.PushNotificationServer - if pushServer == model.MHPNS && (!utils.IsLicensed || !*utils.License.Features.MHPNS) { + if pushServer == model.MHPNS && (!utils.IsLicensed() || !*utils.License().Features.MHPNS) { l4g.Warn(utils.T("api.post.send_notifications_and_forget.push_notification.mhpnsWarn")) sendPushNotifications = false } else { @@ -359,7 +359,7 @@ func sendNotificationEmail(post *model.Post, user *model.User, channel *model.Ch } emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL - if utils.IsLicensed && *utils.License.Features.EmailNotificationContents { + if utils.IsLicensed() && *utils.License().Features.EmailNotificationContents { emailNotificationContentsType = *utils.Cfg.EmailSettings.EmailNotificationContentsType } @@ -682,7 +682,7 @@ func sendToPushProxy(msg model.PushNotification, session *model.Session) { request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+model.API_URL_SUFFIX_V1+"/send_push", strings.NewReader(msg.ToJson())) - if resp, err := utils.HttpClient().Do(request); err != nil { + if resp, err := utils.HttpClient(true).Do(request); err != nil { l4g.Error("Device push reported as error for UserId=%v SessionId=%v message=%v", session.UserId, session.Id, err.Error()) } else { pushResponse := model.PushResponseFromJson(resp.Body) @@ -828,12 +828,14 @@ func GetExplicitMentions(message string, keywords map[string][]string) (map[stri // Case-sensitive check for first name if ids, match := keywords[splitWord]; match { addMentionedUsers(ids) - } else if _, ok := systemMentions[word]; !ok && strings.HasPrefix(word, "@") { - username := word[1:len(splitWord)] + } else if _, ok := systemMentions[splitWord]; !ok && strings.HasPrefix(splitWord, "@") { + username := splitWord[1:] potentialOthersMentioned = append(potentialOthersMentioned, username) } } - } else if _, ok := systemMentions[word]; !ok && strings.HasPrefix(word, "@") { + } + + if _, ok := systemMentions[word]; !ok && strings.HasPrefix(word, "@") { username := word[1:] potentialOthersMentioned = append(potentialOthersMentioned, username) } diff --git a/app/oauth.go b/app/oauth.go index d3633b7eb..f8ddc6076 100644 --- a/app/oauth.go +++ b/app/oauth.go @@ -673,7 +673,7 @@ func AuthorizeOAuthUser(w http.ResponseWriter, r *http.Request, service, code, s var ar *model.AccessResponse var bodyBytes []byte - if resp, err := utils.HttpClient().Do(req); err != nil { + if resp, err := utils.HttpClient(true).Do(req); err != nil { return nil, "", stateProps, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.token_failed.app_error", nil, err.Error()) } else { bodyBytes, _ = ioutil.ReadAll(resp.Body) @@ -702,7 +702,7 @@ func AuthorizeOAuthUser(w http.ResponseWriter, r *http.Request, service, code, s req.Header.Set("Accept", "application/json") req.Header.Set("Authorization", "Bearer "+ar.AccessToken) - if resp, err := utils.HttpClient().Do(req); err != nil { + if resp, err := utils.HttpClient(true).Do(req); err != nil { return nil, "", stateProps, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.service.app_error", map[string]interface{}{"Service": service}, err.Error()) } else { diff --git a/app/post.go b/app/post.go index 055f98373..068266120 100644 --- a/app/post.go +++ b/app/post.go @@ -233,7 +233,7 @@ func UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model.AppError } else { oldPost = result.Data.(*model.PostList).Posts[post.Id] - if utils.IsLicensed { + if utils.IsLicensed() { if *utils.Cfg.ServiceSettings.AllowEditPost == model.ALLOW_EDIT_POST_NEVER && post.Message != oldPost.Message { err := model.NewAppError("UpdatePost", "api.post.update_post.permissions_denied.app_error", nil, "", http.StatusForbidden) return nil, err @@ -255,7 +255,7 @@ func UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model.AppError return nil, err } - if utils.IsLicensed { + if utils.IsLicensed() { if *utils.Cfg.ServiceSettings.AllowEditPost == model.ALLOW_EDIT_POST_TIME_LIMIT && model.GetMillis() > oldPost.CreateAt+int64(*utils.Cfg.ServiceSettings.PostEditTimeLimit*1000) && post.Message != oldPost.Message { err := model.NewAppError("UpdatePost", "api.post.update_post.permissions_time_limit.app_error", map[string]interface{}{"timeLimit": *utils.Cfg.ServiceSettings.PostEditTimeLimit}, "", http.StatusBadRequest) return nil, err @@ -503,7 +503,7 @@ func SearchPostsInTeam(terms string, userId string, teamId string, isOrSearch bo paramsList := model.ParseSearchParams(terms) esInterface := einterfaces.GetElasticsearchInterface() - if esInterface != nil && *utils.Cfg.ElasticsearchSettings.EnableSearching && utils.IsLicensed && *utils.License.Features.Elasticsearch { + if esInterface != nil && *utils.Cfg.ElasticsearchSettings.EnableSearching && utils.IsLicensed() && *utils.License().Features.Elasticsearch { finalParamsList := []*model.SearchParams{} for _, params := range paramsList { @@ -619,7 +619,7 @@ func GetFileInfosForPost(postId string, readFromMaster bool) ([]*model.FileInfo, func GetOpenGraphMetadata(url string) *opengraph.OpenGraph { og := opengraph.NewOpenGraph() - res, err := utils.HttpClient().Get(url) + res, err := utils.HttpClient(false).Get(url) if err != nil { l4g.Error("GetOpenGraphMetadata request failed for url=%v with err=%v", url, err.Error()) return og diff --git a/app/slackimport_test.go b/app/slackimport_test.go index 38f5e2e9b..4090cc432 100644 --- a/app/slackimport_test.go +++ b/app/slackimport_test.go @@ -4,28 +4,25 @@ package app import ( - "github.com/mattermost/platform/model" "os" "strings" "testing" -) -func TestSlackConvertTimeStamp(t *testing.T) { + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" - testTimeStamp := "1469785419.000033" - - result := SlackConvertTimeStamp(testTimeStamp) + "github.com/mattermost/platform/model" +) - if result != 1469785419000 { - t.Fatalf("Unexpected timestamp value %v returned.", result) - } +func TestSlackConvertTimeStamp(t *testing.T) { + assert.EqualValues(t, SlackConvertTimeStamp("1469785419.000033"), 1469785419000) } func TestSlackConvertChannelName(t *testing.T) { - var testData = []struct { + for _, tc := range []struct { nameInput string - idInput string - output string + idInput string + output string }{ {"test-channel", "C0G08DLQH", "test-channel"}, {"_test_channel_", "C0G04DLQH", "test_channel"}, @@ -33,12 +30,8 @@ func TestSlackConvertChannelName(t *testing.T) { {"-t", "C0G06DLQH", "slack-channel-t"}, {"a", "C0G05DLQH", "slack-channel-a"}, {"случайный", "C0G05DLQD", "c0g05dlqd"}, - } - - for _, td := range testData { - if td.output != SlackConvertChannelName(td.nameInput, td.idInput) { - t.Fatalf("Did not convert channel name correctly: %v", td.nameInput) - } + } { + assert.Equal(t, SlackConvertChannelName(tc.nameInput, tc.idInput), tc.output, "nameInput = %v", tc.nameInput) } } @@ -82,15 +75,7 @@ func TestSlackConvertUserMentions(t *testing.T) { }, } - convertedPosts := SlackConvertUserMentions(users, posts) - - for channelName, channelPosts := range convertedPosts { - for postIdx, post := range channelPosts { - if post.Text != expectedPosts[channelName][postIdx].Text { - t.Fatalf("Converted post text not as expected: %v", post.Text) - } - } - } + assert.Equal(t, expectedPosts, SlackConvertUserMentions(users, posts)) } func TestSlackConvertChannelMentions(t *testing.T) { @@ -117,69 +102,43 @@ func TestSlackConvertChannelMentions(t *testing.T) { Text: "Go to ~one.", }, { + User: "U00000A0A", Text: "Try ~two for this.", }, }, } - convertedPosts := SlackConvertChannelMentions(channels, posts) - - for channelName, channelPosts := range convertedPosts { - for postIdx, post := range channelPosts { - if post.Text != expectedPosts[channelName][postIdx].Text { - t.Fatalf("Converted post text not as expected: %v", post.Text) - } - } - } - + assert.Equal(t, expectedPosts, SlackConvertChannelMentions(channels, posts)) } func TestSlackParseChannels(t *testing.T) { file, err := os.Open("../tests/slack-import-test-channels.json") - if err != nil { - t.Fatalf("Failed to open data file: %v", err) - } + require.NoError(t, err) + defer file.Close() channels, err := SlackParseChannels(file) - if err != nil { - t.Fatalf("Error occurred parsing channels: %v", err) - } - - if len(channels) != 6 { - t.Fatalf("Unexpected number of channels: %v", len(channels)) - } + require.NoError(t, err) + assert.Equal(t, 6, len(channels)) } func TestSlackParseUsers(t *testing.T) { file, err := os.Open("../tests/slack-import-test-users.json") - if err != nil { - t.Fatalf("Failed to open data file: %v", err) - } + require.NoError(t, err) + defer file.Close() users, err := SlackParseUsers(file) - if err != nil { - t.Fatalf("Error occurred parsing users: %v", err) - } - - if len(users) != 11 { - t.Fatalf("Unexpected number of users: %v", len(users)) - } + require.NoError(t, err) + assert.Equal(t, 11, len(users)) } func TestSlackParsePosts(t *testing.T) { file, err := os.Open("../tests/slack-import-test-posts.json") - if err != nil { - t.Fatalf("Failed to open data file: %v", err) - } + require.NoError(t, err) + defer file.Close() posts, err := SlackParsePosts(file) - if err != nil { - t.Fatalf("Error occurred parsing posts: %v", err) - } - - if len(posts) != 8 { - t.Fatalf("Unexpected number of posts: %v", len(posts)) - } + require.NoError(t, err) + assert.Equal(t, 8, len(posts)) } func TestSlackSanitiseChannelProperties(t *testing.T) { @@ -191,9 +150,7 @@ func TestSlackSanitiseChannelProperties(t *testing.T) { } c1s := SlackSanitiseChannelProperties(c1) - if c1.DisplayName != c1s.DisplayName || c1.Name != c1s.Name || c1.Purpose != c1s.Purpose || c1.Header != c1s.Header { - t.Fatal("Unexpected alterations to the channel properties.") - } + assert.Equal(t, c1, c1s) c2 := model.Channel{ DisplayName: strings.Repeat("abcdefghij", 7), @@ -203,21 +160,12 @@ func TestSlackSanitiseChannelProperties(t *testing.T) { } c2s := SlackSanitiseChannelProperties(c2) - if c2s.DisplayName != strings.Repeat("abcdefghij", 6)+"abcd" { - t.Fatalf("Unexpected alterations to the channel properties: %v", c2s.DisplayName) - } - - if c2s.Name != strings.Repeat("abcdefghij", 6)+"abcd" { - t.Fatalf("Unexpected alterations to the channel properties: %v", c2s.Name) - } - - if c2s.Purpose != strings.Repeat("0123456789", 25) { - t.Fatalf("Unexpected alterations to the channel properties: %v", c2s.Purpose) - } - - if c2s.Header != strings.Repeat("0123456789", 102)+"0123" { - t.Fatalf("Unexpected alterations to the channel properties: %v", c2s.Header) - } + assert.Equal(t, model.Channel{ + DisplayName: strings.Repeat("abcdefghij", 6) + "abcd", + Name: strings.Repeat("abcdefghij", 6) + "abcd", + Purpose: strings.Repeat("0123456789", 25), + Header: strings.Repeat("0123456789", 102) + "0123", + }, c2s) } func TestSlackConvertPostsMarkup(t *testing.T) { @@ -321,11 +269,5 @@ in this~.`, }, } - actualOutput := SlackConvertPostsMarkup(input) - - for i := range actualOutput["test"] { - if actualOutput["test"][i].Text != expectedOutput["test"][i].Text { - t.Errorf("Unexpected message after markup translation: %v", actualOutput["test"][i].Text) - } - } + assert.Equal(t, expectedOutput, SlackConvertPostsMarkup(input)) } diff --git a/app/team.go b/app/team.go index e4a71d7d5..b479ed134 100644 --- a/app/team.go +++ b/app/team.go @@ -735,7 +735,9 @@ func PermanentDeleteTeam(team *model.Team) *model.AppError { } if result := <-Srv.Store.Channel().GetTeamChannels(team.Id); result.Err != nil { - return result.Err + if result.Err.Id != "store.sql_channel.get_channels.not_found.app_error" { + return result.Err + } } else { channels := result.Data.(*model.ChannelList) for _, c := range *channels { diff --git a/app/team_test.go b/app/team_test.go index a410d6652..4e0ea82f5 100644 --- a/app/team_test.go +++ b/app/team_test.go @@ -152,4 +152,24 @@ func TestPermanentDeleteTeam(t *testing.T) { if command, err = GetCommand(command.Id); command != nil || err == nil { t.Fatal("command wasn't deleted") } + + // Test deleting a team with no channels. + team = th.CreateTeam() + defer func() { + PermanentDeleteTeam(team) + }() + + if channels, err := GetPublicChannelsForTeam(team.Id, 0, 1000); err != nil { + t.Fatal(err) + } else { + for _, channel := range *channels { + if err2 := PermanentDeleteChannel(channel); err2 != nil { + t.Fatal(err) + } + } + } + + if err := PermanentDeleteTeam(team); err != nil { + t.Fatal(err) + } } diff --git a/app/user.go b/app/user.go index 426a11bcb..813421a5c 100644 --- a/app/user.go +++ b/app/user.go @@ -376,7 +376,7 @@ func GetUserByAuth(authData *string, authService string) (*model.User, *model.Ap } func GetUserForLogin(loginId string, onlyLdap bool) (*model.User, *model.AppError) { - ldapAvailable := *utils.Cfg.LdapSettings.Enable && einterfaces.GetLdapInterface() != nil && utils.IsLicensed && *utils.License.Features.LDAP + ldapAvailable := *utils.Cfg.LdapSettings.Enable && einterfaces.GetLdapInterface() != nil && utils.IsLicensed() && *utils.License().Features.LDAP if result := <-Srv.Store.User().GetForLogin( loginId, diff --git a/app/web_conn.go b/app/web_conn.go index 43047a881..24b7166c0 100644 --- a/app/web_conn.go +++ b/app/web_conn.go @@ -217,7 +217,7 @@ func (webCon *WebConn) IsAuthenticated() bool { func (webCon *WebConn) SendHello() { msg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_HELLO, "", "", webCon.UserId, nil) - msg.Add("server_version", fmt.Sprintf("%v.%v.%v.%v", model.CurrentVersion, model.BuildNumber, utils.ClientCfgHash, utils.IsLicensed)) + msg.Add("server_version", fmt.Sprintf("%v.%v.%v.%v", model.CurrentVersion, model.BuildNumber, utils.ClientCfgHash, utils.IsLicensed())) webCon.Send <- msg } diff --git a/app/webhook.go b/app/webhook.go index 29f642ea8..f84086d94 100644 --- a/app/webhook.go +++ b/app/webhook.go @@ -102,7 +102,7 @@ func TriggerWebhook(payload *model.OutgoingWebhookPayload, hook *model.OutgoingW req, _ := http.NewRequest("POST", url, body) req.Header.Set("Content-Type", contentType) req.Header.Set("Accept", "application/json") - if resp, err := utils.HttpClient().Do(req); err != nil { + if resp, err := utils.HttpClient(false).Do(req); err != nil { l4g.Error(utils.T("api.post.handle_webhook_events_and_forget.event_post.error"), err.Error()) } else { defer CloseBody(resp) @@ -533,3 +533,54 @@ func HandleIncomingWebhook(hookId string, req *model.IncomingWebhookRequest) *mo return nil } + +func CreateCommandWebhook(commandId string, args *model.CommandArgs) (*model.CommandWebhook, *model.AppError) { + hook := &model.CommandWebhook{ + CommandId: commandId, + UserId: args.UserId, + ChannelId: args.ChannelId, + RootId: args.RootId, + ParentId: args.ParentId, + } + + if result := <-Srv.Store.CommandWebhook().Save(hook); result.Err != nil { + return nil, result.Err + } else { + return result.Data.(*model.CommandWebhook), nil + } +} + +func HandleCommandWebhook(hookId string, response *model.CommandResponse) *model.AppError { + if response == nil { + return model.NewAppError("HandleCommandWebhook", "web.command_webhook.parse.app_error", nil, "", http.StatusBadRequest) + } + + var hook *model.CommandWebhook + if result := <-Srv.Store.CommandWebhook().Get(hookId); result.Err != nil { + return model.NewAppError("HandleCommandWebhook", "web.command_webhook.invalid.app_error", nil, "err="+result.Err.Message, result.Err.StatusCode) + } else { + hook = result.Data.(*model.CommandWebhook) + } + + var cmd *model.Command + if result := <-Srv.Store.Command().Get(hook.CommandId); result.Err != nil { + return model.NewAppError("HandleCommandWebhook", "web.command_webhook.command.app_error", nil, "err="+result.Err.Message, http.StatusBadRequest) + } else { + cmd = result.Data.(*model.Command) + } + + args := &model.CommandArgs{ + UserId: hook.UserId, + ChannelId: hook.ChannelId, + TeamId: cmd.TeamId, + RootId: hook.RootId, + ParentId: hook.ParentId, + } + + if result := <-Srv.Store.CommandWebhook().TryUse(hook.Id, 5); result.Err != nil { + return model.NewAppError("HandleCommandWebhook", "web.command_webhook.invalid.app_error", nil, "err="+result.Err.Message, result.Err.StatusCode) + } + + _, err := HandleCommandResponse(cmd, args, response, false) + return err +} diff --git a/app/webrtc.go b/app/webrtc.go index 4d44234a8..f8361bbb2 100644 --- a/app/webrtc.go +++ b/app/webrtc.go @@ -59,7 +59,7 @@ func GetWebrtcToken(sessionId string) (string, *model.AppError) { rq, _ := http.NewRequest("POST", *utils.Cfg.WebrtcSettings.GatewayAdminUrl, strings.NewReader(model.MapToJson(data))) rq.Header.Set("Content-Type", "application/json") - if rp, err := utils.HttpClient().Do(rq); err != nil { + if rp, err := utils.HttpClient(true).Do(rq); err != nil { return "", model.NewAppError("WebRTC.Token", "model.client.connecting.app_error", nil, err.Error(), http.StatusInternalServerError) } else if rp.StatusCode >= 300 { defer CloseBody(rp) @@ -80,3 +80,18 @@ func GenerateTurnPassword(username string, secret string) string { h.Write([]byte(username)) return base64.StdEncoding.EncodeToString(h.Sum(nil)) } + +func RevokeWebrtcToken(sessionId string) { + token := base64.StdEncoding.EncodeToString([]byte(sessionId)) + data := make(map[string]string) + data["janus"] = "remove_token" + data["token"] = token + data["transaction"] = model.NewId() + data["admin_secret"] = *utils.Cfg.WebrtcSettings.GatewayAdminSecret + + rq, _ := http.NewRequest("POST", *utils.Cfg.WebrtcSettings.GatewayAdminUrl, strings.NewReader(model.MapToJson(data))) + rq.Header.Set("Content-Type", "application/json") + + // we do not care about the response + utils.HttpClient(true).Do(rq) +} diff --git a/app/webtrc.go b/app/webtrc.go deleted file mode 100644 index 76e173651..000000000 --- a/app/webtrc.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package app - -import ( - "encoding/base64" - "net/http" - "strings" - - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/utils" -) - -func RevokeWebrtcToken(sessionId string) { - token := base64.StdEncoding.EncodeToString([]byte(sessionId)) - data := make(map[string]string) - data["janus"] = "remove_token" - data["token"] = token - data["transaction"] = model.NewId() - data["admin_secret"] = *utils.Cfg.WebrtcSettings.GatewayAdminSecret - - rq, _ := http.NewRequest("POST", *utils.Cfg.WebrtcSettings.GatewayAdminUrl, strings.NewReader(model.MapToJson(data))) - rq.Header.Set("Content-Type", "application/json") - - // we do not care about the response - utils.HttpClient().Do(rq) -} |