4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-09-02 17:27:07 +00:00

Update vendor (mattermost)

This commit is contained in:
Wim
2017-03-25 21:04:10 +01:00
parent 07fd825349
commit eacb1c1771
108 changed files with 26050 additions and 211 deletions

View File

@@ -27,7 +27,10 @@ var PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS *Permission
var PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS *Permission
var PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE *Permission
var PERMISSION_MANAGE_ROLES *Permission
var PERMISSION_MANAGE_TEAM_ROLES *Permission
var PERMISSION_MANAGE_CHANNEL_ROLES *Permission
var PERMISSION_CREATE_DIRECT_CHANNEL *Permission
var PERMISSION_CREATE_GROUP_CHANNEL *Permission
var PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES *Permission
var PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES *Permission
var PERMISSION_LIST_TEAM_CHANNELS *Permission
@@ -46,9 +49,13 @@ var PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH *Permission
var PERMISSION_CREATE_POST *Permission
var PERMISSION_EDIT_POST *Permission
var PERMISSION_EDIT_OTHERS_POSTS *Permission
var PERMISSION_DELETE_POST *Permission
var PERMISSION_DELETE_OTHERS_POSTS *Permission
var PERMISSION_REMOVE_USER_FROM_TEAM *Permission
var PERMISSION_CREATE_TEAM *Permission
var PERMISSION_MANAGE_TEAM *Permission
var PERMISSION_IMPORT_TEAM *Permission
var PERMISSION_VIEW_TEAM *Permission
// General permission that encompases all system admin functions
// in the future this could be broken up to allow access to some
@@ -123,6 +130,16 @@ func InitalizePermissions() {
"authentication.permissions.manage_roles.name",
"authentication.permissions.manage_roles.description",
}
PERMISSION_MANAGE_TEAM_ROLES = &Permission{
"manage_team_roles",
"authentication.permissions.manage_team_roles.name",
"authentication.permissions.manage_team_roles.description",
}
PERMISSION_MANAGE_CHANNEL_ROLES = &Permission{
"manage_channel_roles",
"authentication.permissions.manage_channel_roles.name",
"authentication.permissions.manage_channel_roles.description",
}
PERMISSION_MANAGE_SYSTEM = &Permission{
"manage_system",
"authentication.permissions.manage_system.name",
@@ -133,6 +150,11 @@ func InitalizePermissions() {
"authentication.permissions.create_direct_channel.name",
"authentication.permissions.create_direct_channel.description",
}
PERMISSION_CREATE_GROUP_CHANNEL = &Permission{
"create_group_channel",
"authentication.permissions.create_group_channel.name",
"authentication.permissions.create_group_channel.description",
}
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES = &Permission{
"manage__publicchannel_properties",
"authentication.permissions.manage_public_channel_properties.name",
@@ -223,11 +245,26 @@ func InitalizePermissions() {
"authentication.permissions.edit_others_posts.name",
"authentication.permissions.edit_others_posts.description",
}
PERMISSION_DELETE_POST = &Permission{
"delete_post",
"authentication.permissions.delete_post.name",
"authentication.permissions.delete_post.description",
}
PERMISSION_DELETE_OTHERS_POSTS = &Permission{
"delete_others_posts",
"authentication.permissions.delete_others_posts.name",
"authentication.permissions.delete_others_posts.description",
}
PERMISSION_REMOVE_USER_FROM_TEAM = &Permission{
"remove_user_from_team",
"authentication.permissions.remove_user_from_team.name",
"authentication.permissions.remove_user_from_team.description",
}
PERMISSION_CREATE_TEAM = &Permission{
"create_team",
"authentication.permissions.create_team.name",
"authentication.permissions.create_team.description",
}
PERMISSION_MANAGE_TEAM = &Permission{
"manage_team",
"authentication.permissions.manage_team.name",
@@ -238,6 +275,11 @@ func InitalizePermissions() {
"authentication.permissions.import_team.name",
"authentication.permissions.import_team.description",
}
PERMISSION_VIEW_TEAM = &Permission{
"view_team",
"authentication.permissions.view_team.name",
"authentication.permissions.view_team.description",
}
}
func InitalizeRoles() {
@@ -264,7 +306,9 @@ func InitalizeRoles() {
"channel_admin",
"authentication.roles.channel_admin.name",
"authentication.roles.channel_admin.description",
[]string{},
[]string{
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
},
}
BuiltInRoles[ROLE_CHANNEL_ADMIN.Id] = ROLE_CHANNEL_ADMIN
ROLE_CHANNEL_GUEST = &Role{
@@ -282,6 +326,7 @@ func InitalizeRoles() {
[]string{
PERMISSION_LIST_TEAM_CHANNELS.Id,
PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
PERMISSION_VIEW_TEAM.Id,
},
}
BuiltInRoles[ROLE_TEAM_USER.Id] = ROLE_TEAM_USER
@@ -295,7 +340,8 @@ func InitalizeRoles() {
PERMISSION_REMOVE_USER_FROM_TEAM.Id,
PERMISSION_MANAGE_TEAM.Id,
PERMISSION_IMPORT_TEAM.Id,
PERMISSION_MANAGE_ROLES.Id,
PERMISSION_MANAGE_TEAM_ROLES.Id,
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
PERMISSION_MANAGE_SLASH_COMMANDS.Id,
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
@@ -310,6 +356,7 @@ func InitalizeRoles() {
"authentication.roles.global_user.description",
[]string{
PERMISSION_CREATE_DIRECT_CHANNEL.Id,
PERMISSION_CREATE_GROUP_CHANNEL.Id,
PERMISSION_PERMANENT_DELETE_USER.Id,
PERMISSION_MANAGE_OAUTH.Id,
},
@@ -329,6 +376,7 @@ func InitalizeRoles() {
[]string{
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
PERMISSION_MANAGE_SYSTEM.Id,
PERMISSION_MANAGE_ROLES.Id,
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
@@ -340,6 +388,9 @@ func InitalizeRoles() {
PERMISSION_EDIT_OTHER_USERS.Id,
PERMISSION_MANAGE_OAUTH.Id,
PERMISSION_INVITE_USER.Id,
PERMISSION_DELETE_POST.Id,
PERMISSION_DELETE_OTHERS_POSTS.Id,
PERMISSION_CREATE_TEAM.Id,
},
ROLE_TEAM_USER.Permissions...,
),

View File

@@ -4,8 +4,12 @@
package model
import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"io"
"sort"
"strings"
"unicode/utf8"
)
@@ -13,11 +17,16 @@ const (
CHANNEL_OPEN = "O"
CHANNEL_PRIVATE = "P"
CHANNEL_DIRECT = "D"
CHANNEL_GROUP = "G"
CHANNEL_GROUP_MAX_USERS = 8
CHANNEL_GROUP_MIN_USERS = 3
DEFAULT_CHANNEL = "town-square"
CHANNEL_DISPLAY_NAME_MAX_RUNES = 64
CHANNEL_NAME_MIN_LENGTH = 2
CHANNEL_NAME_MAX_LENGTH = 64
CHANNEL_HEADER_MAX_RUNES = 1024
CHANNEL_PURPOSE_MAX_RUNES = 250
CHANNEL_CACHE_SIZE = 25000
)
type Channel struct {
@@ -83,15 +92,11 @@ func (o *Channel) IsValid() *AppError {
return NewLocAppError("Channel.IsValid", "model.channel.is_valid.display_name.app_error", nil, "id="+o.Id)
}
if len(o.Name) > CHANNEL_NAME_MAX_LENGTH {
return NewLocAppError("Channel.IsValid", "model.channel.is_valid.name.app_error", nil, "id="+o.Id)
}
if !IsValidChannelIdentifier(o.Name) {
return NewLocAppError("Channel.IsValid", "model.channel.is_valid.2_or_more.app_error", nil, "id="+o.Id)
}
if !(o.Type == CHANNEL_OPEN || o.Type == CHANNEL_PRIVATE || o.Type == CHANNEL_DIRECT) {
if !(o.Type == CHANNEL_OPEN || o.Type == CHANNEL_PRIVATE || o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP) {
return NewLocAppError("Channel.IsValid", "model.channel.is_valid.type.app_error", nil, "id="+o.Id)
}
@@ -128,6 +133,10 @@ func (o *Channel) ExtraUpdated() {
o.ExtraUpdateAt = GetMillis()
}
func (o *Channel) IsGroupOrDirect() bool {
return o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP
}
func GetDMNameFromIds(userId1, userId2 string) string {
if userId1 > userId2 {
return userId2 + "__" + userId1
@@ -135,3 +144,31 @@ func GetDMNameFromIds(userId1, userId2 string) string {
return userId1 + "__" + userId2
}
}
func GetGroupDisplayNameFromUsers(users []*User, truncate bool) string {
usernames := make([]string, len(users))
for index, user := range users {
usernames[index] = user.Username
}
sort.Strings(usernames)
name := strings.Join(usernames, ", ")
if truncate && len(name) > CHANNEL_NAME_MAX_LENGTH {
name = name[:CHANNEL_NAME_MAX_LENGTH]
}
return name
}
func GetGroupNameFromUserIds(userIds []string) string {
sort.Strings(userIds)
h := sha1.New()
for _, id := range userIds {
io.WriteString(h, id)
}
return hex.EncodeToString(h.Sum(nil))
}

View File

@@ -88,18 +88,32 @@ func (o *ChannelMember) IsValid() *AppError {
return NewLocAppError("ChannelMember.IsValid", "model.channel_member.is_valid.user_id.app_error", nil, "")
}
notifyLevel := o.NotifyProps["desktop"]
notifyLevel := o.NotifyProps[DESKTOP_NOTIFY_PROP]
if len(notifyLevel) > 20 || !IsChannelNotifyLevelValid(notifyLevel) {
return NewLocAppError("ChannelMember.IsValid", "model.channel_member.is_valid.notify_level.app_error",
nil, "notify_level="+notifyLevel)
}
markUnreadLevel := o.NotifyProps["mark_unread"]
markUnreadLevel := o.NotifyProps[MARK_UNREAD_NOTIFY_PROP]
if len(markUnreadLevel) > 20 || !IsChannelMarkUnreadLevelValid(markUnreadLevel) {
return NewLocAppError("ChannelMember.IsValid", "model.channel_member.is_valid.unread_level.app_error",
nil, "mark_unread_level="+markUnreadLevel)
}
if pushLevel, ok := o.NotifyProps[PUSH_NOTIFY_PROP]; ok {
if len(pushLevel) > 20 || !IsChannelNotifyLevelValid(pushLevel) {
return NewLocAppError("ChannelMember.IsValid", "model.channel_member.is_valid.push_level.app_error",
nil, "push_notification_level="+pushLevel)
}
}
if sendEmail, ok := o.NotifyProps[EMAIL_NOTIFY_PROP]; ok {
if len(sendEmail) > 20 || !IsSendEmailValid(sendEmail) {
return NewLocAppError("ChannelMember.IsValid", "model.channel_member.is_valid.email_value.app_error",
nil, "push_notification_level="+sendEmail)
}
}
return nil
}
@@ -126,9 +140,15 @@ func IsChannelMarkUnreadLevelValid(markUnreadLevel string) bool {
return markUnreadLevel == CHANNEL_MARK_UNREAD_ALL || markUnreadLevel == CHANNEL_MARK_UNREAD_MENTION
}
func IsSendEmailValid(sendEmail string) bool {
return sendEmail == CHANNEL_NOTIFY_DEFAULT || sendEmail == "true" || sendEmail == "false"
}
func GetDefaultChannelNotifyProps() StringMap {
return StringMap{
"desktop": CHANNEL_NOTIFY_DEFAULT,
"mark_unread": CHANNEL_MARK_UNREAD_ALL,
DESKTOP_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
MARK_UNREAD_NOTIFY_PROP: CHANNEL_MARK_UNREAD_ALL,
PUSH_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
EMAIL_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
}
}

View File

@@ -35,12 +35,14 @@ const (
STATUS = "status"
STATUS_OK = "OK"
STATUS_FAIL = "FAIL"
STATUS_REMOVE = "REMOVE"
CLIENT_DIR = "webapp/dist"
API_URL_SUFFIX_V1 = "/api/v1"
API_URL_SUFFIX_V3 = "/api/v3"
API_URL_SUFFIX = API_URL_SUFFIX_V3
API_URL_SUFFIX_V4 = "/api/v4"
API_URL_SUFFIX = API_URL_SUFFIX_V4
)
type Result struct {
@@ -71,7 +73,7 @@ type Client struct {
// NewClient constructs a new client with convienence methods for talking to
// the server.
func NewClient(url string) *Client {
return &Client{url, url + API_URL_SUFFIX, &http.Client{}, "", "", "", "", "", ""}
return &Client{url, url + API_URL_SUFFIX_V3, &http.Client{}, "", "", "", "", "", ""}
}
func closeBody(r *http.Response) {
@@ -782,7 +784,7 @@ func (c *Client) GetSessions(id string) (*Result, *AppError) {
}
func (c *Client) EmailToOAuth(m map[string]string) (*Result, *AppError) {
if r, err := c.DoApiPost("/users/claim/email_to_sso", MapToJson(m)); err != nil {
if r, err := c.DoApiPost("/users/claim/email_to_oauth", MapToJson(m)); err != nil {
return nil, err
} else {
defer closeBody(r)
@@ -1119,6 +1121,16 @@ func (c *Client) CreateDirectChannel(userId string) (*Result, *AppError) {
}
}
func (c *Client) CreateGroupChannel(userIds []string) (*Result, *AppError) {
if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/create_group", ArrayToJson(userIds)); err != nil {
return nil, err
} else {
defer closeBody(r)
return &Result{r.Header.Get(HEADER_REQUEST_ID),
r.Header.Get(HEADER_ETAG_SERVER), ChannelFromJson(r.Body)}, nil
}
}
func (c *Client) UpdateChannel(channel *Channel) (*Result, *AppError) {
if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update", channel.ToJson()); err != nil {
return nil, err
@@ -1471,6 +1483,21 @@ func (c *Client) GetPostById(postId string, etag string) (*PostList, *ResponseMe
}
}
// GetPermalink returns a post list, based on the provided channel and post ID.
func (c *Client) GetPermalink(channelId string, postId string, etag string) (*PostList, *ResponseMetadata) {
if r, err := c.DoApiGet(c.GetTeamRoute()+fmt.Sprintf("/pltmp/%v", postId), "", etag); err != nil {
return nil, &ResponseMetadata{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return PostListFromJson(r.Body),
&ResponseMetadata{
StatusCode: r.StatusCode,
RequestId: r.Header.Get(HEADER_REQUEST_ID),
Etag: r.Header.Get(HEADER_ETAG_SERVER),
}
}
}
func (c *Client) DeletePost(channelId string, postId string) (*Result, *AppError) {
if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/delete", postId), ""); err != nil {
return nil, err
@@ -1991,6 +2018,16 @@ func (c *Client) CreateIncomingWebhook(hook *IncomingWebhook) (*Result, *AppErro
}
}
func (c *Client) UpdateIncomingWebhook(hook *IncomingWebhook) (*Result, *AppError) {
if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/incoming/update", hook.ToJson()); err != nil {
return nil, err
} else {
defer closeBody(r)
return &Result{r.Header.Get(HEADER_REQUEST_ID),
r.Header.Get(HEADER_ETAG_SERVER), IncomingWebhookFromJson(r.Body)}, nil
}
}
func (c *Client) PostToWebhook(id, payload string) (*Result, *AppError) {
if r, err := c.DoPost("/hooks/"+id, payload, "application/x-www-form-urlencoded"); err != nil {
return nil, err
@@ -2082,6 +2119,16 @@ func (c *Client) CreateOutgoingWebhook(hook *OutgoingWebhook) (*Result, *AppErro
}
}
func (c *Client) UpdateOutgoingWebhook(hook *OutgoingWebhook) (*Result, *AppError) {
if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/update", hook.ToJson()); err != nil {
return nil, err
} else {
defer closeBody(r)
return &Result{r.Header.Get(HEADER_REQUEST_ID),
r.Header.Get(HEADER_ETAG_SERVER), OutgoingWebhookFromJson(r.Body)}, nil
}
}
func (c *Client) DeleteOutgoingWebhook(id string) (*Result, *AppError) {
data := make(map[string]string)
data["id"] = id
@@ -2319,3 +2366,26 @@ func (c *Client) ListReactions(channelId string, postId string) ([]*Reaction, *A
return ReactionsFromJson(r.Body), nil
}
}
// Updates the user's roles in the channel by replacing them with the roles provided.
func (c *Client) UpdateChannelRoles(channelId string, userId string, roles string) (map[string]string, *ResponseMetadata) {
data := make(map[string]string)
data["new_roles"] = roles
data["user_id"] = userId
if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/update_member_roles", MapToJson(data)); err != nil {
metadata := ResponseMetadata{Error: err}
if r != nil {
metadata.StatusCode = r.StatusCode
}
return nil, &metadata
} else {
defer closeBody(r)
return MapFromJson(r.Body),
&ResponseMetadata{
StatusCode: r.StatusCode,
RequestId: r.Header.Get(HEADER_REQUEST_ID),
Etag: r.Header.Get(HEADER_ETAG_SERVER),
}
}
}

1006
vendor/github.com/mattermost/platform/model/client4.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,7 @@ package model
import (
"encoding/json"
"fmt"
"io"
)
@@ -14,12 +15,12 @@ const (
)
type CommandResponse struct {
ResponseType string `json:"response_type"`
Text string `json:"text"`
Username string `json:"username"`
IconURL string `json:"icon_url"`
GotoLocation string `json:"goto_location"`
Attachments interface{} `json:"attachments"`
ResponseType string `json:"response_type"`
Text string `json:"text"`
Username string `json:"username"`
IconURL string `json:"icon_url"`
GotoLocation string `json:"goto_location"`
Attachments []*SlackAttachment `json:"attachments"`
}
func (o *CommandResponse) ToJson() string {
@@ -34,10 +35,19 @@ func (o *CommandResponse) ToJson() string {
func CommandResponseFromJson(data io.Reader) *CommandResponse {
decoder := json.NewDecoder(data)
var o CommandResponse
err := decoder.Decode(&o)
if err == nil {
return &o
} else {
if err := decoder.Decode(&o); err != nil {
return nil
}
// Ensure attachment fields are stored as strings
for _, attachment := range o.Attachments {
for _, field := range attachment.Fields {
if field.Value != nil {
field.Value = fmt.Sprintf("%v", field.Value)
}
}
}
return &o
}

View File

@@ -49,49 +49,109 @@ const (
RESTRICT_EMOJI_CREATION_ADMIN = "admin"
RESTRICT_EMOJI_CREATION_SYSTEM_ADMIN = "system_admin"
PERMISSIONS_DELETE_POST_ALL = "all"
PERMISSIONS_DELETE_POST_TEAM_ADMIN = "team_admin"
PERMISSIONS_DELETE_POST_SYSTEM_ADMIN = "system_admin"
ALLOW_EDIT_POST_ALWAYS = "always"
ALLOW_EDIT_POST_NEVER = "never"
ALLOW_EDIT_POST_TIME_LIMIT = "time_limit"
EMAIL_BATCHING_BUFFER_SIZE = 256
EMAIL_BATCHING_INTERVAL = 30
SITENAME_MAX_LENGTH = 30
SERVICE_SETTINGS_DEFAULT_SITE_URL = ""
SERVICE_SETTINGS_DEFAULT_TLS_CERT_FILE = ""
SERVICE_SETTINGS_DEFAULT_TLS_KEY_FILE = ""
SERVICE_SETTINGS_DEFAULT_READ_TIMEOUT = 300
SERVICE_SETTINGS_DEFAULT_WRITE_TIMEOUT = 300
SERVICE_SETTINGS_DEFAULT_ALLOW_CORS_FROM = ""
TEAM_SETTINGS_DEFAULT_CUSTOM_BRAND_TEXT = ""
TEAM_SETTINGS_DEFAULT_CUSTOM_DESCRIPTION_TEXT = ""
TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT = 300
EMAIL_SETTINGS_DEFAULT_FEEDBACK_ORGANIZATION = ""
SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK = "https://about.mattermost.com/default-terms/"
SUPPORT_SETTINGS_DEFAULT_PRIVACY_POLICY_LINK = "https://about.mattermost.com/default-privacy-policy/"
SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK = "https://about.mattermost.com/default-about/"
SUPPORT_SETTINGS_DEFAULT_HELP_LINK = "https://about.mattermost.com/default-help/"
SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK = "https://about.mattermost.com/default-report-a-problem/"
SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL = "feedback@mattermost.com"
LDAP_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE = ""
LDAP_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE = ""
LDAP_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE = ""
LDAP_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE = ""
LDAP_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE = ""
LDAP_SETTINGS_DEFAULT_ID_ATTRIBUTE = ""
LDAP_SETTINGS_DEFAULT_POSITION_ATTRIBUTE = ""
LDAP_SETTINGS_DEFAULT_LOGIN_FIELD_NAME = ""
SAML_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_LOCALE_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_POSITION_ATTRIBUTE = ""
NATIVEAPP_SETTINGS_DEFAULT_APP_DOWNLOAD_LINK = "https://about.mattermost.com/downloads/"
NATIVEAPP_SETTINGS_DEFAULT_ANDROID_APP_DOWNLOAD_LINK = "https://about.mattermost.com/mattermost-android-app/"
NATIVEAPP_SETTINGS_DEFAULT_IOS_APP_DOWNLOAD_LINK = "https://about.mattermost.com/mattermost-ios-app/"
WEBRTC_SETTINGS_DEFAULT_STUN_URI = ""
WEBRTC_SETTINGS_DEFAULT_TURN_URI = ""
ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS = 2500
)
type ServiceSettings struct {
SiteURL *string
ListenAddress string
ConnectionSecurity *string
TLSCertFile *string
TLSKeyFile *string
UseLetsEncrypt *bool
LetsEncryptCertificateCacheFile *string
Forward80To443 *bool
ReadTimeout *int
WriteTimeout *int
MaximumLoginAttempts int
SegmentDeveloperKey string
GoogleDeveloperKey string
EnableOAuthServiceProvider bool
EnableIncomingWebhooks bool
EnableOutgoingWebhooks bool
EnableCommands *bool
EnableOnlyAdminIntegrations *bool
EnablePostUsernameOverride bool
EnablePostIconOverride bool
EnableTesting bool
EnableDeveloper *bool
EnableSecurityFixAlert *bool
EnableInsecureOutgoingConnections *bool
EnableMultifactorAuthentication *bool
EnforceMultifactorAuthentication *bool
AllowCorsFrom *string
SessionLengthWebInDays *int
SessionLengthMobileInDays *int
SessionLengthSSOInDays *int
SessionCacheInMinutes *int
WebsocketSecurePort *int
WebsocketPort *int
WebserverMode *string
EnableCustomEmoji *bool
RestrictCustomEmojiCreation *string
SiteURL *string
ListenAddress string
ConnectionSecurity *string
TLSCertFile *string
TLSKeyFile *string
UseLetsEncrypt *bool
LetsEncryptCertificateCacheFile *string
Forward80To443 *bool
ReadTimeout *int
WriteTimeout *int
MaximumLoginAttempts int
GoogleDeveloperKey string
EnableOAuthServiceProvider bool
EnableIncomingWebhooks bool
EnableOutgoingWebhooks bool
EnableCommands *bool
EnableOnlyAdminIntegrations *bool
EnablePostUsernameOverride bool
EnablePostIconOverride bool
EnableLinkPreviews *bool
EnableTesting bool
EnableDeveloper *bool
EnableSecurityFixAlert *bool
EnableInsecureOutgoingConnections *bool
EnableMultifactorAuthentication *bool
EnforceMultifactorAuthentication *bool
AllowCorsFrom *string
SessionLengthWebInDays *int
SessionLengthMobileInDays *int
SessionLengthSSOInDays *int
SessionCacheInMinutes *int
WebsocketSecurePort *int
WebsocketPort *int
WebserverMode *string
EnableCustomEmoji *bool
RestrictCustomEmojiCreation *string
RestrictPostDelete *string
AllowEditPost *string
PostEditTimeLimit *int
TimeBetweenUserTypingUpdatesMilliseconds *int64
EnableUserTypingMessages *bool
ClusterLogTimeoutMilliseconds *int
}
type ClusterSettings struct {
@@ -433,7 +493,12 @@ func (o *Config) SetDefaults() {
if o.ServiceSettings.SiteURL == nil {
o.ServiceSettings.SiteURL = new(string)
*o.ServiceSettings.SiteURL = ""
*o.ServiceSettings.SiteURL = SERVICE_SETTINGS_DEFAULT_SITE_URL
}
if o.ServiceSettings.EnableLinkPreviews == nil {
o.ServiceSettings.EnableLinkPreviews = new(bool)
*o.ServiceSettings.EnableLinkPreviews = false
}
if o.ServiceSettings.EnableDeveloper == nil {
@@ -493,12 +558,12 @@ func (o *Config) SetDefaults() {
if o.TeamSettings.CustomBrandText == nil {
o.TeamSettings.CustomBrandText = new(string)
*o.TeamSettings.CustomBrandText = ""
*o.TeamSettings.CustomBrandText = TEAM_SETTINGS_DEFAULT_CUSTOM_BRAND_TEXT
}
if o.TeamSettings.CustomDescriptionText == nil {
o.TeamSettings.CustomDescriptionText = new(string)
*o.TeamSettings.CustomDescriptionText = ""
*o.TeamSettings.CustomDescriptionText = TEAM_SETTINGS_DEFAULT_CUSTOM_DESCRIPTION_TEXT
}
if o.TeamSettings.EnableOpenServer == nil {
@@ -552,7 +617,7 @@ func (o *Config) SetDefaults() {
if o.TeamSettings.UserStatusAwayTimeout == nil {
o.TeamSettings.UserStatusAwayTimeout = new(int64)
*o.TeamSettings.UserStatusAwayTimeout = 300
*o.TeamSettings.UserStatusAwayTimeout = TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT
}
if o.TeamSettings.MaxChannelsPerTeam == nil {
@@ -597,7 +662,7 @@ func (o *Config) SetDefaults() {
if o.EmailSettings.FeedbackOrganization == nil {
o.EmailSettings.FeedbackOrganization = new(string)
*o.EmailSettings.FeedbackOrganization = ""
*o.EmailSettings.FeedbackOrganization = EMAIL_SETTINGS_DEFAULT_FEEDBACK_ORGANIZATION
}
if o.EmailSettings.EnableEmailBatching == nil {
@@ -621,7 +686,7 @@ func (o *Config) SetDefaults() {
if o.SupportSettings.TermsOfServiceLink == nil {
o.SupportSettings.TermsOfServiceLink = new(string)
*o.SupportSettings.TermsOfServiceLink = "https://about.mattermost.com/default-terms/"
*o.SupportSettings.TermsOfServiceLink = SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK
}
if !IsSafeLink(o.SupportSettings.PrivacyPolicyLink) {
@@ -630,7 +695,7 @@ func (o *Config) SetDefaults() {
if o.SupportSettings.PrivacyPolicyLink == nil {
o.SupportSettings.PrivacyPolicyLink = new(string)
*o.SupportSettings.PrivacyPolicyLink = ""
*o.SupportSettings.PrivacyPolicyLink = SUPPORT_SETTINGS_DEFAULT_PRIVACY_POLICY_LINK
}
if !IsSafeLink(o.SupportSettings.AboutLink) {
@@ -639,7 +704,7 @@ func (o *Config) SetDefaults() {
if o.SupportSettings.AboutLink == nil {
o.SupportSettings.AboutLink = new(string)
*o.SupportSettings.AboutLink = ""
*o.SupportSettings.AboutLink = SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK
}
if !IsSafeLink(o.SupportSettings.HelpLink) {
@@ -648,7 +713,7 @@ func (o *Config) SetDefaults() {
if o.SupportSettings.HelpLink == nil {
o.SupportSettings.HelpLink = new(string)
*o.SupportSettings.HelpLink = ""
*o.SupportSettings.HelpLink = SUPPORT_SETTINGS_DEFAULT_HELP_LINK
}
if !IsSafeLink(o.SupportSettings.ReportAProblemLink) {
@@ -657,12 +722,12 @@ func (o *Config) SetDefaults() {
if o.SupportSettings.ReportAProblemLink == nil {
o.SupportSettings.ReportAProblemLink = new(string)
*o.SupportSettings.ReportAProblemLink = ""
*o.SupportSettings.ReportAProblemLink = SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK
}
if o.SupportSettings.SupportEmail == nil {
o.SupportSettings.SupportEmail = new(string)
*o.SupportSettings.SupportEmail = "feedback@mattermost.com"
*o.SupportSettings.SupportEmail = SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL
}
if o.LdapSettings.Enable == nil {
@@ -707,37 +772,37 @@ func (o *Config) SetDefaults() {
if o.LdapSettings.FirstNameAttribute == nil {
o.LdapSettings.FirstNameAttribute = new(string)
*o.LdapSettings.FirstNameAttribute = ""
*o.LdapSettings.FirstNameAttribute = LDAP_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE
}
if o.LdapSettings.LastNameAttribute == nil {
o.LdapSettings.LastNameAttribute = new(string)
*o.LdapSettings.LastNameAttribute = ""
*o.LdapSettings.LastNameAttribute = LDAP_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE
}
if o.LdapSettings.EmailAttribute == nil {
o.LdapSettings.EmailAttribute = new(string)
*o.LdapSettings.EmailAttribute = ""
*o.LdapSettings.EmailAttribute = LDAP_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE
}
if o.LdapSettings.UsernameAttribute == nil {
o.LdapSettings.UsernameAttribute = new(string)
*o.LdapSettings.UsernameAttribute = ""
*o.LdapSettings.UsernameAttribute = LDAP_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE
}
if o.LdapSettings.NicknameAttribute == nil {
o.LdapSettings.NicknameAttribute = new(string)
*o.LdapSettings.NicknameAttribute = ""
*o.LdapSettings.NicknameAttribute = LDAP_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE
}
if o.LdapSettings.IdAttribute == nil {
o.LdapSettings.IdAttribute = new(string)
*o.LdapSettings.IdAttribute = ""
*o.LdapSettings.IdAttribute = LDAP_SETTINGS_DEFAULT_ID_ATTRIBUTE
}
if o.LdapSettings.PositionAttribute == nil {
o.LdapSettings.PositionAttribute = new(string)
*o.LdapSettings.PositionAttribute = ""
*o.LdapSettings.PositionAttribute = LDAP_SETTINGS_DEFAULT_POSITION_ATTRIBUTE
}
if o.LdapSettings.SyncIntervalMinutes == nil {
@@ -762,7 +827,7 @@ func (o *Config) SetDefaults() {
if o.LdapSettings.LoginFieldName == nil {
o.LdapSettings.LoginFieldName = new(string)
*o.LdapSettings.LoginFieldName = ""
*o.LdapSettings.LoginFieldName = LDAP_SETTINGS_DEFAULT_LOGIN_FIELD_NAME
}
if o.ServiceSettings.SessionLengthWebInDays == nil {
@@ -807,7 +872,7 @@ func (o *Config) SetDefaults() {
if o.ServiceSettings.AllowCorsFrom == nil {
o.ServiceSettings.AllowCorsFrom = new(string)
*o.ServiceSettings.AllowCorsFrom = ""
*o.ServiceSettings.AllowCorsFrom = SERVICE_SETTINGS_DEFAULT_ALLOW_CORS_FROM
}
if o.ServiceSettings.WebserverMode == nil {
@@ -827,6 +892,21 @@ func (o *Config) SetDefaults() {
*o.ServiceSettings.RestrictCustomEmojiCreation = RESTRICT_EMOJI_CREATION_ALL
}
if o.ServiceSettings.RestrictPostDelete == nil {
o.ServiceSettings.RestrictPostDelete = new(string)
*o.ServiceSettings.RestrictPostDelete = PERMISSIONS_DELETE_POST_ALL
}
if o.ServiceSettings.AllowEditPost == nil {
o.ServiceSettings.AllowEditPost = new(string)
*o.ServiceSettings.AllowEditPost = ALLOW_EDIT_POST_ALWAYS
}
if o.ServiceSettings.PostEditTimeLimit == nil {
o.ServiceSettings.PostEditTimeLimit = new(int)
*o.ServiceSettings.PostEditTimeLimit = 300
}
if o.ClusterSettings.InterNodeListenAddress == nil {
o.ClusterSettings.InterNodeListenAddress = new(string)
*o.ClusterSettings.InterNodeListenAddress = ":8075"
@@ -853,7 +933,7 @@ func (o *Config) SetDefaults() {
if o.AnalyticsSettings.MaxUsersForStatistics == nil {
o.AnalyticsSettings.MaxUsersForStatistics = new(int)
*o.AnalyticsSettings.MaxUsersForStatistics = 2500
*o.AnalyticsSettings.MaxUsersForStatistics = ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS
}
if o.ComplianceSettings.Enable == nil {
@@ -943,52 +1023,52 @@ func (o *Config) SetDefaults() {
if o.SamlSettings.FirstNameAttribute == nil {
o.SamlSettings.FirstNameAttribute = new(string)
*o.SamlSettings.FirstNameAttribute = ""
*o.SamlSettings.FirstNameAttribute = SAML_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE
}
if o.SamlSettings.LastNameAttribute == nil {
o.SamlSettings.LastNameAttribute = new(string)
*o.SamlSettings.LastNameAttribute = ""
*o.SamlSettings.LastNameAttribute = SAML_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE
}
if o.SamlSettings.EmailAttribute == nil {
o.SamlSettings.EmailAttribute = new(string)
*o.SamlSettings.EmailAttribute = ""
*o.SamlSettings.EmailAttribute = SAML_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE
}
if o.SamlSettings.UsernameAttribute == nil {
o.SamlSettings.UsernameAttribute = new(string)
*o.SamlSettings.UsernameAttribute = ""
*o.SamlSettings.UsernameAttribute = SAML_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE
}
if o.SamlSettings.NicknameAttribute == nil {
o.SamlSettings.NicknameAttribute = new(string)
*o.SamlSettings.NicknameAttribute = ""
*o.SamlSettings.NicknameAttribute = SAML_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE
}
if o.SamlSettings.PositionAttribute == nil {
o.SamlSettings.PositionAttribute = new(string)
*o.SamlSettings.PositionAttribute = ""
*o.SamlSettings.PositionAttribute = SAML_SETTINGS_DEFAULT_POSITION_ATTRIBUTE
}
if o.SamlSettings.LocaleAttribute == nil {
o.SamlSettings.LocaleAttribute = new(string)
*o.SamlSettings.LocaleAttribute = ""
*o.SamlSettings.LocaleAttribute = SAML_SETTINGS_DEFAULT_LOCALE_ATTRIBUTE
}
if o.NativeAppSettings.AppDownloadLink == nil {
o.NativeAppSettings.AppDownloadLink = new(string)
*o.NativeAppSettings.AppDownloadLink = "https://about.mattermost.com/downloads/"
*o.NativeAppSettings.AppDownloadLink = NATIVEAPP_SETTINGS_DEFAULT_APP_DOWNLOAD_LINK
}
if o.NativeAppSettings.AndroidAppDownloadLink == nil {
o.NativeAppSettings.AndroidAppDownloadLink = new(string)
*o.NativeAppSettings.AndroidAppDownloadLink = "https://about.mattermost.com/mattermost-android-app/"
*o.NativeAppSettings.AndroidAppDownloadLink = NATIVEAPP_SETTINGS_DEFAULT_ANDROID_APP_DOWNLOAD_LINK
}
if o.NativeAppSettings.IosAppDownloadLink == nil {
o.NativeAppSettings.IosAppDownloadLink = new(string)
*o.NativeAppSettings.IosAppDownloadLink = "https://about.mattermost.com/mattermost-ios-app/"
*o.NativeAppSettings.IosAppDownloadLink = NATIVEAPP_SETTINGS_DEFAULT_IOS_APP_DOWNLOAD_LINK
}
if o.RateLimitSettings.Enable == nil {
@@ -1008,12 +1088,12 @@ func (o *Config) SetDefaults() {
if o.ServiceSettings.TLSKeyFile == nil {
o.ServiceSettings.TLSKeyFile = new(string)
*o.ServiceSettings.TLSKeyFile = ""
*o.ServiceSettings.TLSKeyFile = SERVICE_SETTINGS_DEFAULT_TLS_KEY_FILE
}
if o.ServiceSettings.TLSCertFile == nil {
o.ServiceSettings.TLSCertFile = new(string)
*o.ServiceSettings.TLSCertFile = ""
*o.ServiceSettings.TLSCertFile = SERVICE_SETTINGS_DEFAULT_TLS_CERT_FILE
}
if o.ServiceSettings.UseLetsEncrypt == nil {
@@ -1028,12 +1108,12 @@ func (o *Config) SetDefaults() {
if o.ServiceSettings.ReadTimeout == nil {
o.ServiceSettings.ReadTimeout = new(int)
*o.ServiceSettings.ReadTimeout = 300
*o.ServiceSettings.ReadTimeout = SERVICE_SETTINGS_DEFAULT_READ_TIMEOUT
}
if o.ServiceSettings.WriteTimeout == nil {
o.ServiceSettings.WriteTimeout = new(int)
*o.ServiceSettings.WriteTimeout = 300
*o.ServiceSettings.WriteTimeout = SERVICE_SETTINGS_DEFAULT_WRITE_TIMEOUT
}
if o.ServiceSettings.Forward80To443 == nil {
@@ -1046,6 +1126,21 @@ func (o *Config) SetDefaults() {
*o.MetricsSettings.BlockProfileRate = 0
}
if o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds == nil {
o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds = new(int64)
*o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds = 5000
}
if o.ServiceSettings.EnableUserTypingMessages == nil {
o.ServiceSettings.EnableUserTypingMessages = new(bool)
*o.ServiceSettings.EnableUserTypingMessages = true
}
if o.ServiceSettings.ClusterLogTimeoutMilliseconds == nil {
o.ServiceSettings.ClusterLogTimeoutMilliseconds = new(int)
*o.ServiceSettings.ClusterLogTimeoutMilliseconds = 2000
}
o.defaultWebrtcSettings()
}
@@ -1277,6 +1372,10 @@ func (o *Config) IsValid() *AppError {
return NewLocAppError("Config.IsValid", "model.config.is_valid.write_timeout.app_error", nil, "")
}
if *o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds < 1000 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.time_between_user_typing.app_error", nil, "")
}
return nil
}
@@ -1339,12 +1438,12 @@ func (o *Config) defaultWebrtcSettings() {
if o.WebrtcSettings.StunURI == nil {
o.WebrtcSettings.StunURI = new(string)
*o.WebrtcSettings.StunURI = ""
*o.WebrtcSettings.StunURI = WEBRTC_SETTINGS_DEFAULT_STUN_URI
}
if o.WebrtcSettings.TurnURI == nil {
o.WebrtcSettings.TurnURI = new(string)
*o.WebrtcSettings.TurnURI = ""
*o.WebrtcSettings.TurnURI = WEBRTC_SETTINGS_DEFAULT_TURN_URI
}
if o.WebrtcSettings.TurnUsername == nil {

View File

@@ -8,6 +8,10 @@ import (
"io"
)
const (
MaxImageSize = 6048 * 4032 // 24 megapixels, roughly 36MB as a raw image
)
var (
IMAGE_EXTENSIONS = [5]string{".jpg", ".jpeg", ".gif", ".bmp", ".png"}
IMAGE_MIME_TYPES = map[string]string{".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".bmp": "image/bmp", ".png": "image/png", ".tiff": "image/tiff"}

View File

@@ -65,6 +65,15 @@ func gitLabUserFromJson(data io.Reader) *GitLabUser {
}
}
func (glu *GitLabUser) ToJson() string {
b, err := json.Marshal(glu)
if err != nil {
return ""
} else {
return string(b)
}
}
func (glu *GitLabUser) IsValid() bool {
if glu.Id == 0 {
return false

View File

@@ -29,13 +29,13 @@ type IncomingWebhook struct {
}
type IncomingWebhookRequest struct {
Text string `json:"text"`
Username string `json:"username"`
IconURL string `json:"icon_url"`
ChannelName string `json:"channel"`
Props StringInterface `json:"props"`
Attachments interface{} `json:"attachments"`
Type string `json:"type"`
Text string `json:"text"`
Username string `json:"username"`
IconURL string `json:"icon_url"`
ChannelName string `json:"channel"`
Props StringInterface `json:"props"`
Attachments []*SlackAttachment `json:"attachments"`
Type string `json:"type"`
}
func (o *IncomingWebhook) ToJson() string {
@@ -212,31 +212,15 @@ func expandAnnouncement(text string) string {
func expandAnnouncements(i *IncomingWebhookRequest) {
i.Text = expandAnnouncement(i.Text)
if i.Attachments != nil {
attachments := i.Attachments.([]interface{})
for _, attachment := range attachments {
a := attachment.(map[string]interface{})
for _, attachment := range i.Attachments {
attachment.Pretext = expandAnnouncement(attachment.Pretext)
attachment.Text = expandAnnouncement(attachment.Text)
attachment.Title = expandAnnouncement(attachment.Title)
if a["pretext"] != nil {
a["pretext"] = expandAnnouncement(a["pretext"].(string))
}
if a["text"] != nil {
a["text"] = expandAnnouncement(a["text"].(string))
}
if a["title"] != nil {
a["title"] = expandAnnouncement(a["title"].(string))
}
if a["fields"] != nil {
fields := a["fields"].([]interface{})
for _, field := range fields {
f := field.(map[string]interface{})
if f["value"] != nil {
f["value"] = expandAnnouncement(fmt.Sprintf("%v", f["value"]))
}
}
for _, field := range attachment.Fields {
if field.Value != nil {
// Ensure the value is set to a string if it is set
field.Value = expandAnnouncement(fmt.Sprintf("%v", field.Value))
}
}
}

View File

@@ -14,8 +14,8 @@ type ScheduledTask struct {
Name string `json:"name"`
Interval time.Duration `json:"interval"`
Recurring bool `json:"recurring"`
function TaskFunc `json:",omitempty"`
timer *time.Timer `json:",omitempty"`
function TaskFunc
timer *time.Timer
}
var tasks = make(map[string]*ScheduledTask)

View File

@@ -8,6 +8,11 @@ import (
"io"
)
const (
EXPIRED_LICENSE_ERROR = "api.license.add_license.expired.app_error"
INVALID_LICENSE_ERROR = "api.license.add_license.invalid.app_error"
)
type LicenseRecord struct {
Id string `json:"id"`
CreateAt int64 `json:"create_at"`

View File

@@ -14,10 +14,15 @@ const (
POST_DEFAULT = ""
POST_SLACK_ATTACHMENT = "slack_attachment"
POST_SYSTEM_GENERIC = "system_generic"
POST_JOIN_LEAVE = "system_join_leave"
POST_ADD_REMOVE = "system_add_remove"
POST_JOIN_LEAVE = "system_join_leave" // Deprecated, use POST_JOIN_CHANNEL or POST_LEAVE_CHANNEL instead
POST_JOIN_CHANNEL = "system_join_channel"
POST_LEAVE_CHANNEL = "system_leave_channel"
POST_ADD_REMOVE = "system_add_remove" // Deprecated, use POST_ADD_TO_CHANNEL or POST_REMOVE_FROM_CHANNEL instead
POST_ADD_TO_CHANNEL = "system_add_to_channel"
POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel"
POST_HEADER_CHANGE = "system_header_change"
POST_DISPLAYNAME_CHANGE = "system_displayname_change"
POST_PURPOSE_CHANGE = "system_purpose_change"
POST_CHANNEL_DELETED = "system_channel_deleted"
POST_EPHEMERAL = "system_ephemeral"
POST_FILEIDS_MAX_RUNES = 150
@@ -31,6 +36,7 @@ type Post struct {
Id string `json:"id"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
EditAt int64 `json:"edit_at"`
DeleteAt int64 `json:"delete_at"`
UserId string `json:"user_id"`
ChannelId string `json:"channel_id"`
@@ -119,7 +125,9 @@ func (o *Post) IsValid() *AppError {
// should be removed once more message types are supported
if !(o.Type == POST_DEFAULT || o.Type == POST_JOIN_LEAVE || o.Type == POST_ADD_REMOVE ||
o.Type == POST_SLACK_ATTACHMENT || o.Type == POST_HEADER_CHANGE ||
o.Type == POST_JOIN_CHANNEL || o.Type == POST_LEAVE_CHANNEL ||
o.Type == POST_REMOVE_FROM_CHANNEL || o.Type == POST_ADD_TO_CHANNEL ||
o.Type == POST_SLACK_ATTACHMENT || o.Type == POST_HEADER_CHANGE || o.Type == POST_PURPOSE_CHANGE ||
o.Type == POST_DISPLAYNAME_CHANGE || o.Type == POST_CHANNEL_DELETED) {
return NewLocAppError("Post.IsValid", "model.post.is_valid.type.app_error", nil, "id="+o.Type)
}

View File

@@ -13,6 +13,13 @@ type PostList struct {
Posts map[string]*Post `json:"posts"`
}
func NewPostList() *PostList {
return &PostList{
Order: make([]string, 0),
Posts: make(map[string]*Post),
}
}
func (o *PostList) ToJson() string {
b, err := json.Marshal(o)
if err != nil {
@@ -72,10 +79,18 @@ func (o *PostList) Etag() string {
if v.UpdateAt > t {
t = v.UpdateAt
id = v.Id
} else if v.UpdateAt == t && v.Id > id {
t = v.UpdateAt
id = v.Id
}
}
return Etag(id, t)
orderId := ""
if len(o.Order) > 0 {
orderId = o.Order[0]
}
return Etag(orderId, id, t)
}
func (o *PostList) IsChannelId(channelId string) bool {

View File

@@ -10,8 +10,10 @@ import (
)
const (
PUSH_NOTIFY_APPLE = "apple"
PUSH_NOTIFY_ANDROID = "android"
PUSH_NOTIFY_APPLE = "apple"
PUSH_NOTIFY_ANDROID = "android"
PUSH_NOTIFY_APPLE_REACT_NATIVE = "apple_rn"
PUSH_NOTIFY_ANDROID_REACT_NATIVE = "android_rn"
PUSH_TYPE_MESSAGE = "message"
PUSH_TYPE_CLEAR = "clear"
@@ -46,12 +48,12 @@ func (me *PushNotification) ToJson() string {
}
func (me *PushNotification) SetDeviceIdAndPlatform(deviceId string) {
if strings.HasPrefix(deviceId, PUSH_NOTIFY_APPLE+":") {
me.Platform = PUSH_NOTIFY_APPLE
me.DeviceId = strings.TrimPrefix(deviceId, PUSH_NOTIFY_APPLE+":")
} else if strings.HasPrefix(deviceId, PUSH_NOTIFY_ANDROID+":") {
me.Platform = PUSH_NOTIFY_ANDROID
me.DeviceId = strings.TrimPrefix(deviceId, PUSH_NOTIFY_ANDROID+":")
index := strings.Index(deviceId, ":")
if index > -1 {
me.Platform = deviceId[:index]
me.DeviceId = deviceId[index+1:]
}
}

View File

@@ -0,0 +1,57 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package model
import (
"encoding/json"
"io"
)
const (
PUSH_STATUS = "status"
PUSH_STATUS_OK = "OK"
PUSH_STATUS_FAIL = "FAIL"
PUSH_STATUS_REMOVE = "REMOVE"
PUSH_STATUS_ERROR_MSG = "error"
)
type PushResponse map[string]string
func NewOkPushResponse() PushResponse {
m := make(map[string]string)
m[PUSH_STATUS] = PUSH_STATUS_OK
return m
}
func NewRemovePushResponse() PushResponse {
m := make(map[string]string)
m[PUSH_STATUS] = PUSH_STATUS_REMOVE
return m
}
func NewErrorPushResponse(message string) PushResponse {
m := make(map[string]string)
m[PUSH_STATUS] = PUSH_STATUS_FAIL
m[PUSH_STATUS_ERROR_MSG] = message
return m
}
func (me *PushResponse) ToJson() string {
if b, err := json.Marshal(me); err != nil {
return ""
} else {
return string(b)
}
}
func PushResponseFromJson(data io.Reader) PushResponse {
decoder := json.NewDecoder(data)
var objmap PushResponse
if err := decoder.Decode(&objmap); err != nil {
return make(map[string]string)
} else {
return objmap
}
}

View File

@@ -11,7 +11,7 @@ import (
const (
SESSION_COOKIE_TOKEN = "MMAUTHTOKEN"
SESSION_CACHE_SIZE = 25000
SESSION_CACHE_SIZE = 35000
SESSION_PROP_PLATFORM = "platform"
SESSION_PROP_OS = "os"
SESSION_PROP_BROWSER = "browser"
@@ -111,8 +111,7 @@ func (me *Session) GetTeamByTeamId(teamId string) *TeamMember {
}
func (me *Session) IsMobileApp() bool {
return len(me.DeviceId) > 0 &&
(strings.HasPrefix(me.DeviceId, PUSH_NOTIFY_APPLE+":") || strings.HasPrefix(me.DeviceId, PUSH_NOTIFY_ANDROID+":"))
return len(me.DeviceId) > 0
}
func (me *Session) GetUserRoles() []string {

View File

@@ -0,0 +1,29 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package model
type SlackAttachment struct {
Id int64 `json:"id"`
Fallback string `json:"fallback"`
Color string `json:"color"`
Pretext string `json:"pretext"`
AuthorName string `json:"author_name"`
AuthorLink string `json:"author_link"`
AuthorIcon string `json:"author_icon"`
Title string `json:"title"`
TitleLink string `json:"title_link"`
Text string `json:"text"`
Fields []*SlackAttachmentField `json:"fields"`
ImageURL string `json:"image_url"`
ThumbURL string `json:"thumb_url"`
Footer string `json:"footer"`
FooterIcon string `json:"footer_icon"`
Timestamp interface{} `json:"ts"` // This is either a string or an int64
}
type SlackAttachmentField struct {
Title string `json:"title"`
Value interface{} `json:"value"`
Short bool `json:"short"`
}

View File

@@ -12,7 +12,7 @@ const (
STATUS_OFFLINE = "offline"
STATUS_AWAY = "away"
STATUS_ONLINE = "online"
STATUS_CACHE_SIZE = 25000
STATUS_CACHE_SIZE = SESSION_CACHE_SIZE
STATUS_CHANNEL_TIMEOUT = 20000 // 20 seconds
STATUS_MIN_UPDATE_TIME = 120000 // 2 minutes
)

View File

@@ -7,14 +7,22 @@ import (
"encoding/json"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"unicode/utf8"
)
const (
TEAM_OPEN = "O"
TEAM_INVITE = "I"
TEAM_OPEN = "O"
TEAM_INVITE = "I"
TEAM_ALLOWED_DOMAINS_MAX_LENGTH = 500
TEAM_COMPANY_NAME_MAX_LENGTH = 64
TEAM_DESCRIPTION_MAX_LENGTH = 255
TEAM_DISPLAY_NAME_MAX_RUNES = 64
TEAM_EMAIL_MAX_LENGTH = 128
TEAM_NAME_MAX_LENGTH = 64
TEAM_NAME_MIN_LENGTH = 2
)
type Team struct {
@@ -48,6 +56,14 @@ func InvitesFromJson(data io.Reader) *Invites {
}
}
func (o *Invites) ToEmailList() []string {
emailList := make([]string, len(o.Invites))
for _, invite := range o.Invites {
emailList = append(emailList, invite["email"])
}
return emailList
}
func (o *Invites) ToJson() string {
b, err := json.Marshal(o)
if err != nil {
@@ -97,6 +113,26 @@ func TeamMapFromJson(data io.Reader) map[string]*Team {
}
}
func TeamListToJson(t []*Team) string {
b, err := json.Marshal(t)
if err != nil {
return ""
} else {
return string(b)
}
}
func TeamListFromJson(data io.Reader) []*Team {
decoder := json.NewDecoder(data)
var teams []*Team
err := decoder.Decode(&teams)
if err == nil {
return teams
} else {
return nil
}
}
func (o *Team) Etag() string {
return Etag(o.Id, o.UpdateAt)
}
@@ -104,55 +140,55 @@ func (o *Team) Etag() string {
func (o *Team) IsValid() *AppError {
if len(o.Id) != 26 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.id.app_error", nil, "")
return NewAppError("Team.IsValid", "model.team.is_valid.id.app_error", nil, "", http.StatusBadRequest)
}
if o.CreateAt == 0 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.create_at.app_error", nil, "id="+o.Id)
return NewAppError("Team.IsValid", "model.team.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if o.UpdateAt == 0 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.update_at.app_error", nil, "id="+o.Id)
return NewAppError("Team.IsValid", "model.team.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if len(o.Email) > 128 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.email.app_error", nil, "id="+o.Id)
if len(o.Email) > TEAM_EMAIL_MAX_LENGTH {
return NewAppError("Team.IsValid", "model.team.is_valid.email.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if len(o.Email) > 0 && !IsValidEmail(o.Email) {
return NewLocAppError("Team.IsValid", "model.team.is_valid.email.app_error", nil, "id="+o.Id)
return NewAppError("Team.IsValid", "model.team.is_valid.email.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if utf8.RuneCountInString(o.DisplayName) == 0 || utf8.RuneCountInString(o.DisplayName) > 64 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.name.app_error", nil, "id="+o.Id)
if utf8.RuneCountInString(o.DisplayName) == 0 || utf8.RuneCountInString(o.DisplayName) > TEAM_DISPLAY_NAME_MAX_RUNES {
return NewAppError("Team.IsValid", "model.team.is_valid.name.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if len(o.Name) > 64 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.url.app_error", nil, "id="+o.Id)
if len(o.Name) > TEAM_NAME_MAX_LENGTH {
return NewAppError("Team.IsValid", "model.team.is_valid.url.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if len(o.Description) > 255 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.description.app_error", nil, "id="+o.Id)
if len(o.Description) > TEAM_DESCRIPTION_MAX_LENGTH {
return NewAppError("Team.IsValid", "model.team.is_valid.description.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if IsReservedTeamName(o.Name) {
return NewLocAppError("Team.IsValid", "model.team.is_valid.reserved.app_error", nil, "id="+o.Id)
return NewAppError("Team.IsValid", "model.team.is_valid.reserved.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if !IsValidTeamName(o.Name) {
return NewLocAppError("Team.IsValid", "model.team.is_valid.characters.app_error", nil, "id="+o.Id)
return NewAppError("Team.IsValid", "model.team.is_valid.characters.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if !(o.Type == TEAM_OPEN || o.Type == TEAM_INVITE) {
return NewLocAppError("Team.IsValid", "model.team.is_valid.type.app_error", nil, "id="+o.Id)
return NewAppError("Team.IsValid", "model.team.is_valid.type.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if len(o.CompanyName) > 64 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.company.app_error", nil, "id="+o.Id)
if len(o.CompanyName) > TEAM_COMPANY_NAME_MAX_LENGTH {
return NewAppError("Team.IsValid", "model.team.is_valid.company.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
if len(o.AllowedDomains) > 500 {
return NewLocAppError("Team.IsValid", "model.team.is_valid.domains.app_error", nil, "id="+o.Id)
if len(o.AllowedDomains) > TEAM_ALLOWED_DOMAINS_MAX_LENGTH {
return NewAppError("Team.IsValid", "model.team.is_valid.domains.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
return nil
@@ -193,7 +229,7 @@ func IsValidTeamName(s string) bool {
return false
}
if len(s) <= 1 {
if len(s) < TEAM_NAME_MIN_LENGTH {
return false
}

View File

@@ -7,20 +7,36 @@ import (
"encoding/json"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"unicode"
"unicode/utf8"
"golang.org/x/crypto/bcrypt"
)
const (
USER_NOTIFY_ALL = "all"
USER_NOTIFY_MENTION = "mention"
USER_NOTIFY_NONE = "none"
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"
DEFAULT_LOCALE = "en"
USER_AUTH_SERVICE_EMAIL = "email"
USER_AUTH_SERVICE_USERNAME = "username"
USER_EMAIL_MAX_LENGTH = 128
USER_NICKNAME_MAX_RUNES = 64
USER_POSITION_MAX_RUNES = 35
USER_FIRST_NAME_MAX_RUNES = 64
USER_LAST_NAME_MAX_RUNES = 64
USER_AUTH_DATA_MAX_LENGTH = 128
USER_NAME_MAX_LENGTH = 64
USER_NAME_MIN_LENGTH = 1
)
type User struct {
@@ -51,56 +67,68 @@ type User struct {
LastActivityAt int64 `db:"-" json:"last_activity_at,omitempty"`
}
type UserPatch struct {
Username *string `json:"username"`
Nickname *string `json:"nickname"`
FirstName *string `json:"first_name"`
LastName *string `json:"last_name"`
Position *string `json:"position"`
Email *string `json:"email"`
Props *StringMap `json:"props,omitempty"`
NotifyProps *StringMap `json:"notify_props,omitempty"`
Locale *string `json:"locale"`
}
// IsValid validates the user and returns an error if it isn't configured
// correctly.
func (u *User) IsValid() *AppError {
if len(u.Id) != 26 {
return NewLocAppError("User.IsValid", "model.user.is_valid.id.app_error", nil, "")
return NewAppError("User.IsValid", "model.user.is_valid.id.app_error", nil, "", http.StatusBadRequest)
}
if u.CreateAt == 0 {
return NewLocAppError("User.IsValid", "model.user.is_valid.create_at.app_error", nil, "user_id="+u.Id)
return NewAppError("User.IsValid", "model.user.is_valid.create_at.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if u.UpdateAt == 0 {
return NewLocAppError("User.IsValid", "model.user.is_valid.update_at.app_error", nil, "user_id="+u.Id)
return NewAppError("User.IsValid", "model.user.is_valid.update_at.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if !IsValidUsername(u.Username) {
return NewLocAppError("User.IsValid", "model.user.is_valid.username.app_error", nil, "user_id="+u.Id)
return NewAppError("User.IsValid", "model.user.is_valid.username.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if len(u.Email) > 128 || len(u.Email) == 0 {
return NewLocAppError("User.IsValid", "model.user.is_valid.email.app_error", nil, "user_id="+u.Id)
if len(u.Email) > USER_EMAIL_MAX_LENGTH || len(u.Email) == 0 {
return NewAppError("User.IsValid", "model.user.is_valid.email.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if utf8.RuneCountInString(u.Nickname) > 64 {
return NewLocAppError("User.IsValid", "model.user.is_valid.nickname.app_error", nil, "user_id="+u.Id)
if utf8.RuneCountInString(u.Nickname) > USER_NICKNAME_MAX_RUNES {
return NewAppError("User.IsValid", "model.user.is_valid.nickname.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if utf8.RuneCountInString(u.Position) > 35 {
return NewLocAppError("User.IsValid", "model.user.is_valid.position.app_error", nil, "user_id="+u.Id)
if utf8.RuneCountInString(u.Position) > USER_POSITION_MAX_RUNES {
return NewAppError("User.IsValid", "model.user.is_valid.position.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if utf8.RuneCountInString(u.FirstName) > 64 {
return NewLocAppError("User.IsValid", "model.user.is_valid.first_name.app_error", nil, "user_id="+u.Id)
if utf8.RuneCountInString(u.FirstName) > USER_FIRST_NAME_MAX_RUNES {
return NewAppError("User.IsValid", "model.user.is_valid.first_name.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if utf8.RuneCountInString(u.LastName) > 64 {
return NewLocAppError("User.IsValid", "model.user.is_valid.last_name.app_error", nil, "user_id="+u.Id)
if utf8.RuneCountInString(u.LastName) > USER_LAST_NAME_MAX_RUNES {
return NewAppError("User.IsValid", "model.user.is_valid.last_name.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if u.AuthData != nil && len(*u.AuthData) > 128 {
return NewLocAppError("User.IsValid", "model.user.is_valid.auth_data.app_error", nil, "user_id="+u.Id)
if u.AuthData != nil && len(*u.AuthData) > USER_AUTH_DATA_MAX_LENGTH {
return NewAppError("User.IsValid", "model.user.is_valid.auth_data.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if u.AuthData != nil && len(*u.AuthData) > 0 && len(u.AuthService) == 0 {
return NewLocAppError("User.IsValid", "model.user.is_valid.auth_data_type.app_error", nil, "user_id="+u.Id)
return NewAppError("User.IsValid", "model.user.is_valid.auth_data_type.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
if len(u.Password) > 0 && u.AuthData != nil && len(*u.AuthData) > 0 {
return NewLocAppError("User.IsValid", "model.user.is_valid.auth_data_pwd.app_error", nil, "user_id="+u.Id)
return NewAppError("User.IsValid", "model.user.is_valid.auth_data_pwd.app_error", nil, "user_id="+u.Id, http.StatusBadRequest)
}
return nil
@@ -115,7 +143,7 @@ func (u *User) PreSave() {
}
if u.Username == "" {
u.Username = NewId()
u.Username = "n" + NewId()
}
if u.AuthData != nil && *u.AuthData == "" {
@@ -205,6 +233,44 @@ func (user *User) UpdateMentionKeysFromUsername(oldUsername string) {
}
}
func (u *User) Patch(patch *UserPatch) {
if patch.Username != nil {
u.Username = *patch.Username
}
if patch.Nickname != nil {
u.Nickname = *patch.Nickname
}
if patch.FirstName != nil {
u.FirstName = *patch.FirstName
}
if patch.LastName != nil {
u.LastName = *patch.LastName
}
if patch.Position != nil {
u.Position = *patch.Position
}
if patch.Email != nil {
u.Email = *patch.Email
}
if patch.Props != nil {
u.Props = *patch.Props
}
if patch.NotifyProps != nil {
u.NotifyProps = *patch.NotifyProps
}
if patch.Locale != nil {
u.Locale = *patch.Locale
}
}
// ToJson convert a User to a json string
func (u *User) ToJson() string {
b, err := json.Marshal(u)
@@ -215,6 +281,15 @@ func (u *User) ToJson() string {
}
}
func (u *UserPatch) ToJson() string {
b, err := json.Marshal(u)
if err != nil {
return ""
} else {
return string(b)
}
}
// Generate a valid strong etag so the browser can cache the results
func (u *User) Etag(showFullName, showEmail bool) string {
return Etag(u.Id, u.UpdateAt, showFullName, showEmail)
@@ -376,6 +451,13 @@ func IsInRole(userRoles string, inRole string) bool {
return false
}
func (u *User) IsSSOUser() bool {
if u.AuthService != "" && u.AuthService != USER_AUTH_SERVICE_EMAIL {
return true
}
return false
}
func (u *User) IsOAuthUser() bool {
if u.AuthService == USER_AUTH_SERVICE_GITLAB {
return true
@@ -402,6 +484,17 @@ func UserFromJson(data io.Reader) *User {
}
}
func UserPatchFromJson(data io.Reader) *UserPatch {
decoder := json.NewDecoder(data)
var user UserPatch
err := decoder.Decode(&user)
if err == nil {
return &user
} else {
return nil
}
}
func UserMapToJson(u map[string]*User) string {
b, err := json.Marshal(u)
if err != nil {
@@ -472,7 +565,7 @@ var restrictedUsernames = []string{
}
func IsValidUsername(s string) bool {
if len(s) == 0 || len(s) > 64 {
if len(s) < USER_NAME_MIN_LENGTH || len(s) > USER_NAME_MAX_LENGTH {
return false
}
@@ -480,6 +573,10 @@ func IsValidUsername(s string) bool {
return false
}
if !unicode.IsLetter(rune(s[0])) {
return false
}
for _, restrictedUsername := range restrictedUsernames {
if s == restrictedUsername {
return false

View File

@@ -34,14 +34,14 @@ type StringArray []string
type EncryptStringMap map[string]string
type AppError struct {
Id string `json:"id"`
Message string `json:"message"` // Message to be display to the end user without debugging information
DetailedError string `json:"detailed_error"` // Internal error string to help the developer
RequestId string `json:"request_id,omitempty"` // The RequestId that's also set in the header
StatusCode int `json:"status_code,omitempty"` // The http status code
Where string `json:"-"` // The function where it happened in the form of Struct.Func
IsOAuth bool `json:"is_oauth,omitempty"` // Whether the error is OAuth specific
params map[string]interface{} `json:"-"`
Id string `json:"id"`
Message string `json:"message"` // Message to be display to the end user without debugging information
DetailedError string `json:"detailed_error"` // Internal error string to help the developer
RequestId string `json:"request_id,omitempty"` // The RequestId that's also set in the header
StatusCode int `json:"status_code,omitempty"` // The http status code
Where string `json:"-"` // The function where it happened in the form of Struct.Func
IsOAuth bool `json:"is_oauth,omitempty"` // Whether the error is OAuth specific
params map[string]interface{}
}
func (er *AppError) Error() string {
@@ -93,6 +93,18 @@ func AppErrorFromJson(data io.Reader) *AppError {
}
}
func NewAppError(where string, id string, params map[string]interface{}, details string, status int) *AppError {
ap := &AppError{}
ap.Id = id
ap.params = params
ap.Message = id
ap.Where = where
ap.DetailedError = details
ap.StatusCode = status
ap.IsOAuth = false
return ap
}
func NewLocAppError(where string, id string, params map[string]interface{}, details string) *AppError {
ap := &AppError{}
ap.Id = id
@@ -268,7 +280,7 @@ func IsValidChannelIdentifier(s string) bool {
return false
}
if len(s) < 2 {
if len(s) < CHANNEL_NAME_MIN_LENGTH {
return false
}
@@ -370,7 +382,7 @@ func ClearMentionTags(post string) string {
var UrlRegex = regexp.MustCompile(`^((?:[a-z]+:\/\/)?(?:(?:[a-z0-9\-]+\.)+(?:[a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal))(:[0-9]{1,5})?(?:\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(?:\?[a-z0-9+_~\-\.%=&amp;]*)?)?(?:#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(?:\s+|$)$`)
var PartialUrlRegex = regexp.MustCompile(`/([A-Za-z0-9]{26})/([A-Za-z0-9]{26})/((?:[A-Za-z0-9]{26})?.+(?:\.[A-Za-z0-9]{3,})?)`)
var SplitRunes = map[rune]bool{',': true, ' ': true, '.': true, '!': true, '?': true, ':': true, ';': true, '\n': true, '<': true, '>': true, '(': true, ')': true, '{': true, '}': true, '[': true, ']': true, '+': true, '/': true, '\\': true}
var SplitRunes = map[rune]bool{',': true, ' ': true, '.': true, '!': true, '?': true, ':': true, ';': true, '\n': true, '<': true, '>': true, '(': true, ')': true, '{': true, '}': true, '[': true, ']': true, '+': true, '/': true, '\\': true, '^': true, '#': true, '$': true, '&': true}
func IsValidHttpUrl(rawUrl string) bool {
if strings.Index(rawUrl, "http://") != 0 && strings.Index(rawUrl, "https://") != 0 {

View File

@@ -13,6 +13,7 @@ import (
// It should be maitained in chronological order with most current
// release at the front of the list.
var versions = []string{
"3.7.0",
"3.6.0",
"3.5.0",
"3.4.0",

View File

@@ -8,6 +8,10 @@ import (
"github.com/gorilla/websocket"
)
const (
SOCKET_MAX_MESSAGE_SIZE_KB = 8 * 1024 // 8KB
)
type WebSocketClient struct {
Url string // The location of the server like "ws://localhost:8065"
ApiUrl string // The api location of the server like "ws://localhost:8065/api/v3"
@@ -22,14 +26,14 @@ type WebSocketClient struct {
// NewWebSocketClient constructs a new WebSocket client with convienence
// methods for talking to the server.
func NewWebSocketClient(url, authToken string) (*WebSocketClient, *AppError) {
conn, _, err := websocket.DefaultDialer.Dial(url+API_URL_SUFFIX+"/users/websocket", nil)
conn, _, err := websocket.DefaultDialer.Dial(url+API_URL_SUFFIX_V3+"/users/websocket", nil)
if err != nil {
return nil, NewLocAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error())
}
client := &WebSocketClient{
url,
url + API_URL_SUFFIX,
url + API_URL_SUFFIX_V3,
conn,
authToken,
1,

View File

@@ -14,8 +14,9 @@ const (
WEBSOCKET_EVENT_POST_EDITED = "post_edited"
WEBSOCKET_EVENT_POST_DELETED = "post_deleted"
WEBSOCKET_EVENT_CHANNEL_DELETED = "channel_deleted"
WEBSOCKET_EVENT_CHANNEL_VIEWED = "channel_viewed"
WEBSOCKET_EVENT_CHANNEL_CREATED = "channel_created"
WEBSOCKET_EVENT_DIRECT_ADDED = "direct_added"
WEBSOCKET_EVENT_GROUP_ADDED = "group_added"
WEBSOCKET_EVENT_NEW_USER = "new_user"
WEBSOCKET_EVENT_LEAVE_TEAM = "leave_team"
WEBSOCKET_EVENT_UPDATE_TEAM = "update_team"