From 4132a02319a9cf07cbd13c989de9b891d89f8fb3 Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Wed, 26 Jul 2017 08:51:25 +0100 Subject: PLT-7183: User/Channel NotifyProps Bulk Import. (#7019) --- app/import.go | 132 +++++++++++++++++++++++++++++++++++++++ app/import_test.go | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++-- i18n/en.json | 36 +++++++++++ model/user.go | 43 ++++++++++--- model/utils.go | 16 ++++- 5 files changed, 390 insertions(+), 14 deletions(-) diff --git a/app/import.go b/app/import.go index 230032427..fb7d43cdf 100644 --- a/app/import.go +++ b/app/import.go @@ -71,6 +71,23 @@ type UserImportData struct { MessageDisplay *string `json:"message_display"` ChannelDisplayMode *string `json:"channel_display_mode"` TutorialStep *string `json:"tutorial_step"` + + NotifyProps *UserNotifyPropsImportData `json:"notify_props"` +} + +type UserNotifyPropsImportData struct { + Desktop *string `json:"desktop"` + DesktopDuration *string `json:"desktop_duration"` + DesktopSound *string `json:"desktop_sound"` + + Email *string `json:"email"` + + Mobile *string `json:"mobile"` + MobilePushStatus *string `json:"mobile_push_status"` + + ChannelTrigger *string `json:"channel"` + CommentsTrigger *string `json:"comments"` + MentionKeys *string `json:"mention_keys"` } type UserTeamImportData struct { @@ -88,6 +105,7 @@ type UserChannelImportData struct { type UserChannelNotifyPropsImportData struct { Desktop *string `json:"desktop"` + Mobile *string `json:"mobile"` MarkUnread *string `json:"mark_unread"` } @@ -444,6 +462,7 @@ func ImportUser(data *UserImportData, dryRun bool) *model.AppError { // We want to avoid database writes if nothing has changed. hasUserChanged := false + hasNotifyPropsChanged := false hasUserRolesChanged := false hasUserAuthDataChanged := false hasUserEmailVerifiedChanged := false @@ -453,6 +472,7 @@ func ImportUser(data *UserImportData, dryRun bool) *model.AppError { user = result.Data.(*model.User) } else { user = &model.User{} + user.MakeNonNil() hasUserChanged = true } @@ -557,6 +577,71 @@ func ImportUser(data *UserImportData, dryRun bool) *model.AppError { } user.Roles = roles + if data.NotifyProps != nil { + if data.NotifyProps.Desktop != nil { + if value, ok := user.NotifyProps[model.DESKTOP_NOTIFY_PROP]; !ok || value != *data.NotifyProps.Desktop { + user.AddNotifyProp(model.DESKTOP_NOTIFY_PROP, *data.NotifyProps.Desktop) + hasNotifyPropsChanged = true + } + } + + if data.NotifyProps.DesktopDuration != nil { + if value, ok := user.NotifyProps[model.DESKTOP_DURATION_NOTIFY_PROP]; !ok || value != *data.NotifyProps.DesktopDuration { + user.AddNotifyProp(model.DESKTOP_DURATION_NOTIFY_PROP, *data.NotifyProps.DesktopDuration) + hasNotifyPropsChanged = true + } + } + + if data.NotifyProps.DesktopSound != nil { + if value, ok := user.NotifyProps[model.DESKTOP_SOUND_NOTIFY_PROP]; !ok || value != *data.NotifyProps.DesktopSound { + user.AddNotifyProp(model.DESKTOP_SOUND_NOTIFY_PROP, *data.NotifyProps.DesktopSound) + hasNotifyPropsChanged = true + } + } + + if data.NotifyProps.Email != nil { + if value, ok := user.NotifyProps[model.EMAIL_NOTIFY_PROP]; !ok || value != *data.NotifyProps.Email { + user.AddNotifyProp(model.EMAIL_NOTIFY_PROP, *data.NotifyProps.Email) + hasNotifyPropsChanged = true + } + } + + if data.NotifyProps.Mobile != nil { + if value, ok := user.NotifyProps[model.PUSH_NOTIFY_PROP]; !ok || value != *data.NotifyProps.Mobile { + user.AddNotifyProp(model.PUSH_NOTIFY_PROP, *data.NotifyProps.Mobile) + hasNotifyPropsChanged = true + } + } + + if data.NotifyProps.MobilePushStatus != nil { + if value, ok := user.NotifyProps[model.PUSH_STATUS_NOTIFY_PROP]; !ok || value != *data.NotifyProps.MobilePushStatus { + user.AddNotifyProp(model.PUSH_STATUS_NOTIFY_PROP, *data.NotifyProps.MobilePushStatus) + hasNotifyPropsChanged = true + } + } + + if data.NotifyProps.ChannelTrigger != nil { + if value, ok := user.NotifyProps[model.CHANNEL_MENTIONS_NOTIFY_PROP]; !ok || value != *data.NotifyProps.ChannelTrigger { + user.AddNotifyProp(model.CHANNEL_MENTIONS_NOTIFY_PROP, *data.NotifyProps.ChannelTrigger) + hasNotifyPropsChanged = true + } + } + + if data.NotifyProps.CommentsTrigger != nil { + if value, ok := user.NotifyProps[model.COMMENTS_NOTIFY_PROP]; !ok || value != *data.NotifyProps.CommentsTrigger { + user.AddNotifyProp(model.COMMENTS_NOTIFY_PROP, *data.NotifyProps.CommentsTrigger) + hasNotifyPropsChanged = true + } + } + + if data.NotifyProps.MentionKeys != nil { + if value, ok := user.NotifyProps[model.MENTION_KEYS_NOTIFY_PROP]; !ok || value != *data.NotifyProps.MentionKeys { + user.AddNotifyProp(model.MENTION_KEYS_NOTIFY_PROP, *data.NotifyProps.MentionKeys) + hasNotifyPropsChanged = true + } + } + } + if user.Id == "" { if _, err := createUser(user); err != nil { return err @@ -572,6 +657,11 @@ func ImportUser(data *UserImportData, dryRun bool) *model.AppError { return err } } + if hasNotifyPropsChanged { + if _, err := UpdateUserNotifyProps(user.Id, user.NotifyProps); err != nil { + return err + } + } if len(password) > 0 { if err := UpdatePassword(user, password); err != nil { return err @@ -747,6 +837,10 @@ func ImportUserChannels(user *model.User, team *model.Team, teamMember *model.Te notifyProps[model.DESKTOP_NOTIFY_PROP] = *cdata.NotifyProps.Desktop } + if cdata.NotifyProps.Mobile != nil { + notifyProps[model.PUSH_NOTIFY_PROP] = *cdata.NotifyProps.Mobile + } + if cdata.NotifyProps.MarkUnread != nil { notifyProps[model.MARK_UNREAD_NOTIFY_PROP] = *cdata.NotifyProps.MarkUnread } @@ -829,6 +923,40 @@ func validateUserImportData(data *UserImportData) *model.AppError { return model.NewAppError("BulkImport", "app.import.validate_user_import_data.roles_invalid.error", nil, "", http.StatusBadRequest) } + if data.NotifyProps != nil { + if data.NotifyProps.Desktop != nil && !model.IsValidUserNotifyLevel(*data.NotifyProps.Desktop) { + return model.NewAppError("BulkImport", "app.import.validate_user_import_data.notify_props_desktop_invalid.error", nil, "", http.StatusBadRequest) + } + + if data.NotifyProps.DesktopDuration != nil && !model.IsValidNumberString(*data.NotifyProps.DesktopDuration) { + return model.NewAppError("BulkImport", "app.import.validate_user_import_data.notify_props_desktop_duration_invalid.error", nil, "", http.StatusBadRequest) + } + + if data.NotifyProps.DesktopSound != nil && !model.IsValidTrueOrFalseString(*data.NotifyProps.DesktopSound) { + return model.NewAppError("BulkImport", "app.import.validate_user_import_data.notify_props_desktop_sound_invalid.error", nil, "", http.StatusBadRequest) + } + + if data.NotifyProps.Email != nil && !model.IsValidTrueOrFalseString(*data.NotifyProps.Email) { + return model.NewAppError("BulkImport", "app.import.validate_user_import_data.notify_props_email_invalid.error", nil, "", http.StatusBadRequest) + } + + if data.NotifyProps.Mobile != nil && !model.IsValidUserNotifyLevel(*data.NotifyProps.Mobile) { + return model.NewAppError("BulkImport", "app.import.validate_user_import_data.notify_props_mobile_invalid.error", nil, "", http.StatusBadRequest) + } + + if data.NotifyProps.MobilePushStatus != nil && !model.IsValidPushStatusNotifyLevel(*data.NotifyProps.MobilePushStatus) { + return model.NewAppError("BulkImport", "app.import.validate_user_import_data.notify_props_mobile_push_status_invalid.error", nil, "", http.StatusBadRequest) + } + + if data.NotifyProps.ChannelTrigger != nil && !model.IsValidTrueOrFalseString(*data.NotifyProps.ChannelTrigger) { + return model.NewAppError("BulkImport", "app.import.validate_user_import_data.notify_props_channel_trigger_invalid.error", nil, "", http.StatusBadRequest) + } + + if data.NotifyProps.CommentsTrigger != nil && !model.IsValidCommentsNotifyLevel(*data.NotifyProps.CommentsTrigger) { + return model.NewAppError("BulkImport", "app.import.validate_user_import_data.notify_props_comments_trigger_invalid.error", nil, "", http.StatusBadRequest) + } + } + if data.Teams != nil { return validateUserTeamsImportData(data.Teams) } else { @@ -879,6 +1007,10 @@ func validateUserChannelsImportData(data *[]UserChannelImportData) *model.AppErr return model.NewAppError("BulkImport", "app.import.validate_user_channels_import_data.invalid_notify_props_desktop.error", nil, "", http.StatusBadRequest) } + if cdata.NotifyProps.Mobile != nil && !model.IsChannelNotifyLevelValid(*cdata.NotifyProps.Mobile) { + return model.NewAppError("BulkImport", "app.import.validate_user_channels_import_data.invalid_notify_props_mobile.error", nil, "", http.StatusBadRequest) + } + if cdata.NotifyProps.MarkUnread != nil && !model.IsChannelMarkUnreadLevelValid(*cdata.NotifyProps.MarkUnread) { return model.NewAppError("BulkImport", "app.import.validate_user_channels_import_data.invalid_notify_props_mark_unread.error", nil, "", http.StatusBadRequest) } diff --git a/app/import_test.go b/app/import_test.go index f480b9534..70a36f272 100644 --- a/app/import_test.go +++ b/app/import_test.go @@ -53,6 +53,30 @@ func checkPreference(t *testing.T, userId string, category string, name string, } } +func checkNotifyProp(t *testing.T, user *model.User, key string, value string) { + if actual, ok := user.NotifyProps[key]; !ok { + debug.PrintStack() + t.Fatalf("Notify prop %v not found. User: %v", key, user.Id) + } else if actual != value { + debug.PrintStack() + t.Fatalf("Notify Prop %v was %v but expected %v. User: %v", key, actual, value, user.Id) + } +} + +func checkError(t *testing.T, err *model.AppError) { + if err == nil { + debug.PrintStack() + t.Fatal("Should have returned an error.") + } +} + +func checkNoError(t *testing.T, err *model.AppError) { + if err != nil { + debug.PrintStack() + t.Fatalf("Unexpected Error: %v", err.Error()) + } +} + func TestImportValidateTeamImportData(t *testing.T) { // Test with minimum required valid properties. @@ -392,6 +416,44 @@ func TestImportValidateUserImportData(t *testing.T) { t.Fatal("Validation failed but should have been valid.") } data.Roles = ptrStr("system_user") + + // Try various valid/invalid notify props. + data.NotifyProps = &UserNotifyPropsImportData{} + + data.NotifyProps.Desktop = ptrStr("invalid") + checkError(t, validateUserImportData(&data)) + + data.NotifyProps.Desktop = ptrStr(model.USER_NOTIFY_ALL) + data.NotifyProps.DesktopDuration = ptrStr("invalid") + checkError(t, validateUserImportData(&data)) + + data.NotifyProps.DesktopDuration = ptrStr("5") + data.NotifyProps.DesktopSound = ptrStr("invalid") + checkError(t, validateUserImportData(&data)) + + data.NotifyProps.DesktopSound = ptrStr("true") + data.NotifyProps.Email = ptrStr("invalid") + checkError(t, validateUserImportData(&data)) + + data.NotifyProps.Email = ptrStr("true") + data.NotifyProps.Mobile = ptrStr("invalid") + checkError(t, validateUserImportData(&data)) + + data.NotifyProps.Mobile = ptrStr(model.USER_NOTIFY_ALL) + data.NotifyProps.MobilePushStatus = ptrStr("invalid") + checkError(t, validateUserImportData(&data)) + + data.NotifyProps.MobilePushStatus = ptrStr(model.STATUS_ONLINE) + data.NotifyProps.ChannelTrigger = ptrStr("invalid") + checkError(t, validateUserImportData(&data)) + + data.NotifyProps.ChannelTrigger = ptrStr("true") + data.NotifyProps.CommentsTrigger = ptrStr("invalid") + checkError(t, validateUserImportData(&data)) + + data.NotifyProps.CommentsTrigger = ptrStr(model.COMMENTS_NOTIFY_ROOT) + data.NotifyProps.MentionKeys = ptrStr("valid") + checkNoError(t, validateUserImportData(&data)) } func TestImportValidateUserTeamsImportData(t *testing.T) { @@ -481,14 +543,21 @@ func TestImportValidateUserChannelsImportData(t *testing.T) { t.Fatal("Should have failed with invalid desktop notify props.") } - // Invalid desktop notify props. + // Invalid mobile notify props. data[0].NotifyProps.Desktop = ptrStr("mention") + data[0].NotifyProps.Mobile = ptrStr("invalid") + if err := validateUserChannelsImportData(&data); err == nil { + t.Fatal("Should have failed with invalid mobile notify props.") + } + + // Invalid mark_unread notify props. + data[0].NotifyProps.Mobile = ptrStr("mention") data[0].NotifyProps.MarkUnread = ptrStr("invalid") if err := validateUserChannelsImportData(&data); err == nil { t.Fatal("Should have failed with invalid mark_unread notify props.") } - // Empty notify props. + // Valid notify props. data[0].NotifyProps.MarkUnread = ptrStr("mention") if err := validateUserChannelsImportData(&data); err != nil { t.Fatal("Should have succeeded with valid notify props.") @@ -1621,7 +1690,7 @@ func TestImportImportUser(t *testing.T) { // Check channel member properties. if channelMember, err := GetChannelMember(channel.Id, user.Id); err != nil { t.Fatalf("Failed to get channel member from database.") - } else if channelMember.Roles != "channel_user" || channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP] != "default" || channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != "all" { + } else if channelMember.Roles != "channel_user" || channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP] != "default" || channelMember.NotifyProps[model.PUSH_NOTIFY_PROP] != "default" || channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != "all" { t.Fatalf("Channel member properties not as expected") } @@ -1636,6 +1705,7 @@ func TestImportImportUser(t *testing.T) { Roles: ptrStr("channel_user channel_admin"), NotifyProps: &UserChannelNotifyPropsImportData{ Desktop: ptrStr(model.USER_NOTIFY_MENTION), + Mobile: ptrStr(model.USER_NOTIFY_MENTION), MarkUnread: ptrStr(model.USER_NOTIFY_MENTION), }, Favorite: ptrBool(true), @@ -1656,7 +1726,7 @@ func TestImportImportUser(t *testing.T) { if channelMember, err := GetChannelMember(channel.Id, user.Id); err != nil { t.Fatalf("Failed to get channel member Desktop from database.") - } else if channelMember.Roles != "channel_user channel_admin" && channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP] == model.USER_NOTIFY_MENTION && channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] == model.USER_NOTIFY_MENTION { + } else if channelMember.Roles != "channel_user channel_admin" || channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP] != model.USER_NOTIFY_MENTION || channelMember.NotifyProps[model.PUSH_NOTIFY_PROP] != model.USER_NOTIFY_MENTION || channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != model.USER_NOTIFY_MENTION { t.Fatalf("Channel member properties not as expected") } @@ -1726,6 +1796,105 @@ func TestImportImportUser(t *testing.T) { checkPreference(t, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "message_display", *data.MessageDisplay) checkPreference(t, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "channel_display_mode", *data.ChannelDisplayMode) checkPreference(t, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep) + + // Set Notify Props + data.NotifyProps = &UserNotifyPropsImportData{ + Desktop: ptrStr(model.USER_NOTIFY_ALL), + DesktopDuration: ptrStr("5"), + DesktopSound: ptrStr("true"), + Email: ptrStr("true"), + Mobile: ptrStr(model.USER_NOTIFY_ALL), + MobilePushStatus: ptrStr(model.STATUS_ONLINE), + ChannelTrigger: ptrStr("true"), + CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ROOT), + MentionKeys: ptrStr("valid,misc"), + } + if err := ImportUser(&data, false); err != nil { + t.Fatalf("Should have succeeded.") + } + + user, err = GetUserByUsername(username) + if err != nil { + t.Fatalf("Failed to get user from database.") + } + + checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_ALL) + checkNotifyProp(t, user, model.DESKTOP_DURATION_NOTIFY_PROP, "5") + checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "true") + checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "true") + checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_ALL) + checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_ONLINE) + checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "true") + checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ROOT) + checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "valid,misc") + + // Change Notify Props + data.NotifyProps = &UserNotifyPropsImportData{ + Desktop: ptrStr(model.USER_NOTIFY_MENTION), + DesktopDuration: ptrStr("3"), + DesktopSound: ptrStr("false"), + Email: ptrStr("false"), + Mobile: ptrStr(model.USER_NOTIFY_NONE), + MobilePushStatus: ptrStr(model.STATUS_AWAY), + ChannelTrigger: ptrStr("false"), + CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY), + MentionKeys: ptrStr("misc"), + } + if err := ImportUser(&data, false); err != nil { + t.Fatalf("Should have succeeded.") + } + + user, err = GetUserByUsername(username) + if err != nil { + t.Fatalf("Failed to get user from database.") + } + + checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION) + checkNotifyProp(t, user, model.DESKTOP_DURATION_NOTIFY_PROP, "3") + checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false") + checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false") + checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE) + checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY) + checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false") + checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY) + checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc") + + // Check Notify Props get set on *create* user. + username = model.NewId() + data = UserImportData{ + Username: &username, + Email: ptrStr(model.NewId() + "@example.com"), + } + data.NotifyProps = &UserNotifyPropsImportData{ + Desktop: ptrStr(model.USER_NOTIFY_MENTION), + DesktopDuration: ptrStr("3"), + DesktopSound: ptrStr("false"), + Email: ptrStr("false"), + Mobile: ptrStr(model.USER_NOTIFY_NONE), + MobilePushStatus: ptrStr(model.STATUS_AWAY), + ChannelTrigger: ptrStr("false"), + CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY), + MentionKeys: ptrStr("misc"), + } + + if err := ImportUser(&data, false); err != nil { + t.Fatalf("Should have succeeded.") + } + + user, err = GetUserByUsername(username) + if err != nil { + t.Fatalf("Failed to get user from database.") + } + + checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION) + checkNotifyProp(t, user, model.DESKTOP_DURATION_NOTIFY_PROP, "3") + checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false") + checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false") + checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE) + checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY) + checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false") + checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY) + checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc") } func AssertAllPostsCount(t *testing.T, initialCount int64, change int64, teamName string) { diff --git a/i18n/en.json b/i18n/en.json index bd90c7f49..627ea680b 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -3355,6 +3355,10 @@ "id": "app.import.validate_user_channels_import_data.invalid_notify_props_desktop.error", "translation": "Invalid Desktop NotifyProps for User's Channel Membership." }, + { + "id": "app.import.validate_user_channels_import_data.invalid_notify_props_mobile.error", + "translation": "Invalid Mobile NotifyProps for User's Channel Membership." + }, { "id": "app.import.validate_user_channels_import_data.invalid_notify_props_mark_unread.error", "translation": "Invalid MarkUnread NotifyProps for User's Channel Membership." @@ -3415,6 +3419,38 @@ "id": "app.import.validate_user_import_data.username_missing.error", "translation": "Missing require user property: username." }, + { + "id": "app.import.validate_user_import_data.notify_props_desktop_invalid.error", + "translation": "Invalid Desktop Notify Prop value for user." + }, + { + "id": "app.import.validate_user_import_data.notify_props_desktop_duration_invalid.error", + "translation": "Invalid Desktop Duration Notify Prop value for user." + }, + { + "id": "app.import.validate_user_import_data.notify_props_desktop_sound_invalid.error", + "translation": "Invalid Desktop Sound Notify Prop value for user." + }, + { + "id": "app.import.validate_user_import_data.notify_props_email_invalid.error", + "translation": "Invalid Email Notify Prop value for user." + }, + { + "id": "app.import.validate_user_import_data.notify_props_mobile_invalid.error", + "translation": "Invalid Mobile Notify Prop value for user." + }, + { + "id": "app.import.validate_user_import_data.notify_props_mobile_push_status_invalid.error", + "translation": "Invalid Mobile Push Status Notify Prop for user." + }, + { + "id": "app.import.validate_user_import_data.notify_props_channel_trigger_invalid.error", + "translation": "Invalid Channel Trigger Notify Prop for user." + }, + { + "id": "app.import.validate_user_import_data.notify_props_comment_trigger_invalid.error", + "translation": "Invalid Comment Trigger Notify Prop for user." + }, { "id": "app.import.validate_user_teams_import_data.invalid_roles.error", "translation": "Invalid roles for User's Team Membership." diff --git a/model/user.go b/model/user.go index 8e5c8fcc1..ab4b21e23 100644 --- a/model/user.go +++ b/model/user.go @@ -16,14 +16,23 @@ import ( ) const ( - ME = "me" - USER_NOTIFY_ALL = "all" - USER_NOTIFY_MENTION = "mention" - USER_NOTIFY_NONE = "none" - DESKTOP_NOTIFY_PROP = "desktop" - MARK_UNREAD_NOTIFY_PROP = "mark_unread" - PUSH_NOTIFY_PROP = "push" - EMAIL_NOTIFY_PROP = "email" + ME = "me" + USER_NOTIFY_ALL = "all" + USER_NOTIFY_MENTION = "mention" + USER_NOTIFY_NONE = "none" + DESKTOP_NOTIFY_PROP = "desktop" + DESKTOP_SOUND_NOTIFY_PROP = "desktop_sound" + DESKTOP_DURATION_NOTIFY_PROP = "desktop_duration" + MARK_UNREAD_NOTIFY_PROP = "mark_unread" + PUSH_NOTIFY_PROP = "push" + PUSH_STATUS_NOTIFY_PROP = "push_status" + EMAIL_NOTIFY_PROP = "email" + CHANNEL_MENTIONS_NOTIFY_PROP = "channel" + COMMENTS_NOTIFY_PROP = "comments" + MENTION_KEYS_NOTIFY_PROP = "mention_keys" + COMMENTS_NOTIFY_NEVER = "never" + COMMENTS_NOTIFY_ROOT = "root" + COMMENTS_NOTIFY_ANY = "any" DEFAULT_LOCALE = "en" USER_AUTH_SERVICE_EMAIL = "email" @@ -604,3 +613,21 @@ func CleanUsername(s string) string { return s } + +func IsValidUserNotifyLevel(notifyLevel string) bool { + return notifyLevel == CHANNEL_NOTIFY_ALL || + notifyLevel == CHANNEL_NOTIFY_MENTION || + notifyLevel == CHANNEL_NOTIFY_NONE +} + +func IsValidPushStatusNotifyLevel(notifyLevel string) bool { + return notifyLevel == STATUS_ONLINE || + notifyLevel == STATUS_AWAY || + notifyLevel == STATUS_OFFLINE +} + +func IsValidCommentsNotifyLevel(notifyLevel string) bool { + return notifyLevel == COMMENTS_NOTIFY_ANY || + notifyLevel == COMMENTS_NOTIFY_ROOT || + notifyLevel == COMMENTS_NOTIFY_NEVER +} diff --git a/model/utils.go b/model/utils.go index 7f612b572..090644ec6 100644 --- a/model/utils.go +++ b/model/utils.go @@ -11,14 +11,14 @@ import ( "fmt" "io" "io/ioutil" + "net" "net/mail" "net/url" "regexp" + "strconv" "strings" "time" - "net" - goi18n "github.com/nicksnyder/go-i18n/i18n" "github.com/pborman/uuid" ) @@ -480,3 +480,15 @@ func IsValidWebsocketUrl(rawUrl string) bool { return true } + +func IsValidTrueOrFalseString(value string) bool { + return value == "true" || value == "false" +} + +func IsValidNumberString(value string) bool { + if _, err := strconv.Atoi(value); err != nil { + return false + } + + return true +} -- cgit v1.2.3-1-g7c22