From 59e6abcc11ed3a3548ffb02d1e455485672d8308 Mon Sep 17 00:00:00 2001 From: Wim Date: Sun, 15 May 2016 23:02:30 +0200 Subject: Sync with mattermost 3.0 --- .../mattermost/platform/einterfaces/LICENSE.txt | 4 +- .../mattermost/platform/einterfaces/ldap.go | 4 +- .../mattermost/platform/model/LICENSE.txt | 4 +- .../github.com/mattermost/platform/model/client.go | 462 ++++++++++++++++----- .../mattermost/platform/model/command.go | 11 +- .../github.com/mattermost/platform/model/config.go | 212 ++++++++-- .../mattermost/platform/model/gitlab/gitlab.go | 13 +- .../mattermost/platform/model/incoming_webhook.go | 24 +- .../mattermost/platform/model/license.go | 18 + .../mattermost/platform/model/message.go | 2 + .../mattermost/platform/model/outgoing_webhook.go | 18 + .../github.com/mattermost/platform/model/post.go | 1 + .../mattermost/platform/model/push_notification.go | 7 +- .../mattermost/platform/model/search_params.go | 1 + .../mattermost/platform/model/session.go | 34 +- .../github.com/mattermost/platform/model/system.go | 9 +- .../github.com/mattermost/platform/model/team.go | 34 +- .../github.com/mattermost/platform/model/user.go | 103 +++-- .../github.com/mattermost/platform/model/utils.go | 65 ++- .../mattermost/platform/model/version.go | 14 +- 20 files changed, 808 insertions(+), 232 deletions(-) (limited to 'vendor/github.com/mattermost/platform') diff --git a/vendor/github.com/mattermost/platform/einterfaces/LICENSE.txt b/vendor/github.com/mattermost/platform/einterfaces/LICENSE.txt index b05ccb40..e5875711 100644 --- a/vendor/github.com/mattermost/platform/einterfaces/LICENSE.txt +++ b/vendor/github.com/mattermost/platform/einterfaces/LICENSE.txt @@ -11,8 +11,8 @@ You may be licensed to use source code to create compiled versions not produced 1. Under the Free Software Foundation’s GNU AGPL v.3.0, subject to the exceptions outlined in this policy; or 2. Under a commercial license available from Mattermost, Inc. by contacting commercial@mattermost.com -You are licensed to use the source code in Admin Tools and Configuration Files (api/templates/, config/, model/, -web/react/utils/, web/static/, web/templates/ and all subdirectories thereof) under the Apache License v2.0. +You are licensed to use the source code in Admin Tools and Configuration Files (templates/, config/, model/, +webapp/client, webapp/fonts, webapp/i18n, webapp/images and all subdirectories thereof) under the Apache License v2.0. We promise that we will not enforce the copyleft provisions in AGPL v3.0 against you if your application (a) does not link to the Mattermost Platform directly, but exclusively uses the Mattermost Admin Tools and Configuration Files, and diff --git a/vendor/github.com/mattermost/platform/einterfaces/ldap.go b/vendor/github.com/mattermost/platform/einterfaces/ldap.go index 1c593832..25d591ce 100644 --- a/vendor/github.com/mattermost/platform/einterfaces/ldap.go +++ b/vendor/github.com/mattermost/platform/einterfaces/ldap.go @@ -8,9 +8,11 @@ import ( ) type LdapInterface interface { - DoLogin(team *model.Team, id string, password string) (*model.User, *model.AppError) + DoLogin(id string, password string) (*model.User, *model.AppError) GetUser(id string) (*model.User, *model.AppError) CheckPassword(id string, password string) *model.AppError + SwitchToLdap(userId, ldapId, ldapPassword string) *model.AppError + ValidateFilter(filter string) *model.AppError } var theLdapInterface LdapInterface diff --git a/vendor/github.com/mattermost/platform/model/LICENSE.txt b/vendor/github.com/mattermost/platform/model/LICENSE.txt index b05ccb40..e5875711 100644 --- a/vendor/github.com/mattermost/platform/model/LICENSE.txt +++ b/vendor/github.com/mattermost/platform/model/LICENSE.txt @@ -11,8 +11,8 @@ You may be licensed to use source code to create compiled versions not produced 1. Under the Free Software Foundation’s GNU AGPL v.3.0, subject to the exceptions outlined in this policy; or 2. Under a commercial license available from Mattermost, Inc. by contacting commercial@mattermost.com -You are licensed to use the source code in Admin Tools and Configuration Files (api/templates/, config/, model/, -web/react/utils/, web/static/, web/templates/ and all subdirectories thereof) under the Apache License v2.0. +You are licensed to use the source code in Admin Tools and Configuration Files (templates/, config/, model/, +webapp/client, webapp/fonts, webapp/i18n, webapp/images and all subdirectories thereof) under the Apache License v2.0. We promise that we will not enforce the copyleft provisions in AGPL v3.0 against you if your application (a) does not link to the Mattermost Platform directly, but exclusively uses the Mattermost Admin Tools and Configuration Files, and diff --git a/vendor/github.com/mattermost/platform/model/client.go b/vendor/github.com/mattermost/platform/model/client.go index f397a9c2..152aaa70 100644 --- a/vendor/github.com/mattermost/platform/model/client.go +++ b/vendor/github.com/mattermost/platform/model/client.go @@ -16,21 +16,22 @@ import ( ) const ( - HEADER_REQUEST_ID = "X-Request-ID" - HEADER_VERSION_ID = "X-Version-ID" - HEADER_ETAG_SERVER = "ETag" - HEADER_ETAG_CLIENT = "If-None-Match" - HEADER_FORWARDED = "X-Forwarded-For" - HEADER_REAL_IP = "X-Real-IP" - HEADER_FORWARDED_PROTO = "X-Forwarded-Proto" - HEADER_TOKEN = "token" - HEADER_BEARER = "BEARER" - HEADER_AUTH = "Authorization" - HEADER_MM_SESSION_TOKEN_INDEX = "X-MM-TokenIndex" - SESSION_TOKEN_INDEX = "session_token_index" - HEADER_REQUESTED_WITH = "X-Requested-With" - HEADER_REQUESTED_WITH_XML = "XMLHttpRequest" - API_URL_SUFFIX = "/api/v1" + HEADER_REQUEST_ID = "X-Request-ID" + HEADER_VERSION_ID = "X-Version-ID" + HEADER_ETAG_SERVER = "ETag" + HEADER_ETAG_CLIENT = "If-None-Match" + HEADER_FORWARDED = "X-Forwarded-For" + HEADER_REAL_IP = "X-Real-IP" + HEADER_FORWARDED_PROTO = "X-Forwarded-Proto" + HEADER_TOKEN = "token" + HEADER_BEARER = "BEARER" + HEADER_AUTH = "Authorization" + HEADER_REQUESTED_WITH = "X-Requested-With" + HEADER_REQUESTED_WITH_XML = "XMLHttpRequest" + + API_URL_SUFFIX_V1 = "/api/v1" + API_URL_SUFFIX_V3 = "/api/v3" + API_URL_SUFFIX = API_URL_SUFFIX_V3 ) type Result struct { @@ -41,16 +42,56 @@ type Result struct { type Client struct { Url string // The location of the server like "http://localhost:8065" - ApiUrl string // The api location of the server like "http://localhost:8065/api/v1" + ApiUrl string // The api location of the server like "http://localhost:8065/api/v3" HttpClient *http.Client // The http client AuthToken string AuthType string + TeamId string } // 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, &http.Client{}, "", "", ""} +} + +func (c *Client) SetOAuthToken(token string) { + c.AuthToken = token + c.AuthType = HEADER_TOKEN +} + +func (c *Client) ClearOAuthToken() { + c.AuthToken = "" + c.AuthType = HEADER_BEARER +} + +func (c *Client) SetTeamId(teamId string) { + c.TeamId = teamId +} + +func (c *Client) GetTeamId() string { + if len(c.TeamId) == 0 { + println(`You are trying to use a route that requires a team_id, + but you have not called SetTeamId() in client.go`) + } + + return c.TeamId +} + +func (c *Client) ClearTeamId() { + c.TeamId = "" +} + +func (c *Client) GetTeamRoute() string { + return fmt.Sprintf("/teams/%v", c.GetTeamId()) +} + +func (c *Client) GetChannelRoute(channelId string) string { + return fmt.Sprintf("/teams/%v/channels/%v", c.GetTeamId(), channelId) +} + +func (c *Client) GetChannelNameRoute(channelName string) string { + return fmt.Sprintf("/teams/%v/channels/name/%v", c.GetTeamId(), channelName) } func (c *Client) DoPost(url, data, contentType string) (*http.Response, *AppError) { @@ -164,10 +205,19 @@ func (c *Client) GetAllTeams() (*Result, *AppError) { } } -func (c *Client) FindTeamByName(name string, allServers bool) (*Result, *AppError) { +func (c *Client) GetAllTeamListings() (*Result, *AppError) { + if r, err := c.DoApiGet("/teams/all_team_listings", "", ""); err != nil { + return nil, err + } else { + + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), TeamMapFromJson(r.Body)}, nil + } +} + +func (c *Client) FindTeamByName(name string) (*Result, *AppError) { m := make(map[string]string) m["name"] = name - m["all"] = fmt.Sprintf("%v", allServers) if r, err := c.DoApiPost("/teams/find_team_by_name", MapToJson(m)); err != nil { return nil, err } else { @@ -181,31 +231,32 @@ func (c *Client) FindTeamByName(name string, allServers bool) (*Result, *AppErro } } -func (c *Client) FindTeams(email string) (*Result, *AppError) { - m := make(map[string]string) - m["email"] = email - if r, err := c.DoApiPost("/teams/find_teams", MapToJson(m)); err != nil { +func (c *Client) AddUserToTeam(userId string) (*Result, *AppError) { + data := make(map[string]string) + data["user_id"] = userId + if r, err := c.DoApiPost(c.GetTeamRoute()+"/add_user_to_team", MapToJson(data)); err != nil { return nil, err } else { - return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), TeamMapFromJson(r.Body)}, nil + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil } } -func (c *Client) FindTeamsSendEmail(email string) (*Result, *AppError) { - m := make(map[string]string) - m["email"] = email - if r, err := c.DoApiPost("/teams/email_teams", MapToJson(m)); err != nil { +func (c *Client) AddUserToTeamFromInvite(hash, dataToHash, inviteId string) (*Result, *AppError) { + data := make(map[string]string) + data["hash"] = hash + data["data"] = dataToHash + data["invite_id"] = inviteId + if r, err := c.DoApiPost("/teams/add_user_to_team_from_invite", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), ArrayFromJson(r.Body)}, nil + r.Header.Get(HEADER_ETAG_SERVER), TeamFromJson(r.Body)}, nil } } func (c *Client) InviteMembers(invites *Invites) (*Result, *AppError) { - if r, err := c.DoApiPost("/teams/invite_members", invites.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/invite_members", invites.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -214,7 +265,7 @@ func (c *Client) InviteMembers(invites *Invites) (*Result, *AppError) { } func (c *Client) UpdateTeam(team *Team) (*Result, *AppError) { - if r, err := c.DoApiPost("/teams/update", team.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/update", team.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -231,6 +282,18 @@ func (c *Client) CreateUser(user *User, hash string) (*Result, *AppError) { } } +func (c *Client) CreateUserWithInvite(user *User, hash string, data string, inviteId string) (*Result, *AppError) { + + url := "/users/create?d=" + url.QueryEscape(data) + "&h=" + url.QueryEscape(hash) + "&iid=" + url.QueryEscape(inviteId) + + if r, err := c.DoApiPost(url, user.ToJson()); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil + } +} + func (c *Client) CreateUserFromSignup(user *User, data string, hash string) (*Result, *AppError) { if r, err := c.DoApiPost("/users/create?d="+url.QueryEscape(data)+"&h="+hash, user.ToJson()); err != nil { return nil, err @@ -241,7 +304,7 @@ func (c *Client) CreateUserFromSignup(user *User, data string, hash string) (*Re } func (c *Client) GetUser(id string, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/users/"+id, "", etag); err != nil { + if r, err := c.DoApiGet("/users/"+id+"/get", "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -258,6 +321,15 @@ func (c *Client) GetMe(etag string) (*Result, *AppError) { } } +func (c *Client) GetProfilesForDirectMessageList(teamId string) (*Result, *AppError) { + if r, err := c.DoApiGet("/users/profiles_for_dm_list/"+teamId, "", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil + } +} + func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) { if r, err := c.DoApiGet("/users/profiles/"+teamId, "", etag); err != nil { return nil, err @@ -267,6 +339,15 @@ func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) { } } +func (c *Client) GetDirectProfiles(etag string) (*Result, *AppError) { + if r, err := c.DoApiGet("/users/direct_profiles", "", etag); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil + } +} + func (c *Client) LoginById(id string, password string) (*Result, *AppError) { m := make(map[string]string) m["id"] = id @@ -274,26 +355,24 @@ func (c *Client) LoginById(id string, password string) (*Result, *AppError) { return c.login(m) } -func (c *Client) LoginByEmail(name string, email string, password string) (*Result, *AppError) { +func (c *Client) Login(loginId string, password string) (*Result, *AppError) { m := make(map[string]string) - m["name"] = name - m["email"] = email + m["login_id"] = loginId m["password"] = password return c.login(m) } -func (c *Client) LoginByUsername(name string, username string, password string) (*Result, *AppError) { +func (c *Client) LoginByLdap(loginId string, password string) (*Result, *AppError) { m := make(map[string]string) - m["name"] = name - m["username"] = username + m["login_id"] = loginId m["password"] = password + m["ldap_only"] = "true" return c.login(m) } -func (c *Client) LoginByEmailWithDevice(name string, email string, password string, deviceId string) (*Result, *AppError) { +func (c *Client) LoginWithDevice(loginId string, password string, deviceId string) (*Result, *AppError) { m := make(map[string]string) - m["name"] = name - m["email"] = email + m["login_id"] = loginId m["password"] = password m["device_id"] = deviceId return c.login(m) @@ -322,20 +401,57 @@ func (c *Client) Logout() (*Result, *AppError) { } else { c.AuthToken = "" c.AuthType = HEADER_BEARER + c.TeamId = "" return &Result{r.Header.Get(HEADER_REQUEST_ID), r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil } } -func (c *Client) SetOAuthToken(token string) { - c.AuthToken = token - c.AuthType = HEADER_TOKEN +func (c *Client) CheckMfa(loginId string) (*Result, *AppError) { + m := make(map[string]string) + m["login_id"] = loginId + + if r, err := c.DoApiPost("/users/mfa", MapToJson(m)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } } -func (c *Client) ClearOAuthToken() { - c.AuthToken = "" - c.AuthType = HEADER_BEARER +func (c *Client) GenerateMfaQrCode() (*Result, *AppError) { + if r, err := c.DoApiGet("/users/generate_mfa_qr", "", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), r.Body}, nil + } +} + +func (c *Client) UpdateMfa(activate bool, token string) (*Result, *AppError) { + m := make(map[string]interface{}) + m["activate"] = activate + m["token"] = token + + if r, err := c.DoApiPost("/users/update_mfa", StringInterfaceToJson(m)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + +func (c *Client) AdminResetMfa(userId string) (*Result, *AppError) { + m := make(map[string]string) + m["user_id"] = userId + + if r, err := c.DoApiPost("/admin/reset_mfa", MapToJson(m)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } } func (c *Client) RevokeSession(sessionAltId string) (*Result, *AppError) { @@ -359,8 +475,17 @@ func (c *Client) GetSessions(id string) (*Result, *AppError) { } } -func (c *Client) SwitchToSSO(m map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/users/switch_to_sso", MapToJson(m)); err != nil { +func (c *Client) EmailToOAuth(m map[string]string) (*Result, *AppError) { + if r, err := c.DoApiPost("/users/claim/email_to_sso", MapToJson(m)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + +func (c *Client) OAuthToEmail(m map[string]string) (*Result, *AppError) { + if r, err := c.DoApiPost("/users/claim/oauth_to_email", MapToJson(m)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -368,8 +493,17 @@ func (c *Client) SwitchToSSO(m map[string]string) (*Result, *AppError) { } } -func (c *Client) SwitchToEmail(m map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/users/switch_to_email", MapToJson(m)); err != nil { +func (c *Client) LDAPToEmail(m map[string]string) (*Result, *AppError) { + if r, err := c.DoApiPost("/users/claim/ldap_to_email", MapToJson(m)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + +func (c *Client) EmailToLDAP(m map[string]string) (*Result, *AppError) { + if r, err := c.DoApiPost("/users/claim/ldap_to_email", MapToJson(m)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -382,7 +516,7 @@ func (c *Client) Command(channelId string, command string, suggest bool) (*Resul m["command"] = command m["channelId"] = channelId m["suggest"] = strconv.FormatBool(suggest) - if r, err := c.DoApiPost("/commands/execute", MapToJson(m)); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/execute", MapToJson(m)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -391,7 +525,7 @@ func (c *Client) Command(channelId string, command string, suggest bool) (*Resul } func (c *Client) ListCommands() (*Result, *AppError) { - if r, err := c.DoApiGet("/commands/list", "", ""); err != nil { + if r, err := c.DoApiGet(c.GetTeamRoute()+"/commands/list", "", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -400,7 +534,7 @@ func (c *Client) ListCommands() (*Result, *AppError) { } func (c *Client) ListTeamCommands() (*Result, *AppError) { - if r, err := c.DoApiGet("/commands/list_team_commands", "", ""); err != nil { + if r, err := c.DoApiGet(c.GetTeamRoute()+"/commands/list_team_commands", "", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -409,7 +543,7 @@ func (c *Client) ListTeamCommands() (*Result, *AppError) { } func (c *Client) CreateCommand(cmd *Command) (*Result, *AppError) { - if r, err := c.DoApiPost("/commands/create", cmd.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/create", cmd.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -418,7 +552,7 @@ func (c *Client) CreateCommand(cmd *Command) (*Result, *AppError) { } func (c *Client) RegenCommandToken(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/commands/regen_token", MapToJson(data)); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/regen_token", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -427,7 +561,7 @@ func (c *Client) RegenCommandToken(data map[string]string) (*Result, *AppError) } func (c *Client) DeleteCommand(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/commands/delete", MapToJson(data)); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/delete", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -485,7 +619,7 @@ func (c *Client) SaveConfig(config *Config) (*Result, *AppError) { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), ConfigFromJson(r.Body)}, nil + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil } } @@ -498,6 +632,42 @@ func (c *Client) TestEmail(config *Config) (*Result, *AppError) { } } +func (c *Client) GetComplianceReports() (*Result, *AppError) { + if r, err := c.DoApiGet("/admin/compliance_reports", "", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), CompliancesFromJson(r.Body)}, nil + } +} + +func (c *Client) SaveComplianceReport(job *Compliance) (*Result, *AppError) { + if r, err := c.DoApiPost("/admin/save_compliance_report", job.ToJson()); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), ComplianceFromJson(r.Body)}, nil + } +} + +func (c *Client) DownloadComplianceReport(id string) (*Result, *AppError) { + var rq *http.Request + rq, _ = http.NewRequest("GET", c.ApiUrl+"/admin/download_compliance_report/"+id, nil) + + if len(c.AuthToken) > 0 { + rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) + } + + if rp, err := c.HttpClient.Do(rq); err != nil { + return nil, NewLocAppError("/admin/download_compliance_report", "model.client.connecting.app_error", nil, err.Error()) + } else if rp.StatusCode >= 300 { + return nil, AppErrorFromJson(rp.Body) + } else { + return &Result{rp.Header.Get(HEADER_REQUEST_ID), + rp.Header.Get(HEADER_ETAG_SERVER), rp.Body}, nil + } +} + func (c *Client) GetTeamAnalytics(teamId, name string) (*Result, *AppError) { if r, err := c.DoApiGet("/admin/analytics/"+teamId+"/"+name, "", ""); err != nil { return nil, err @@ -517,7 +687,7 @@ func (c *Client) GetSystemAnalytics(name string) (*Result, *AppError) { } func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/create", channel.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/create", channel.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -525,8 +695,10 @@ func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) { } } -func (c *Client) CreateDirectChannel(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/create_direct", MapToJson(data)); err != nil { +func (c *Client) CreateDirectChannel(userId string) (*Result, *AppError) { + data := make(map[string]string) + data["user_id"] = userId + if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/create_direct", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -535,7 +707,7 @@ func (c *Client) CreateDirectChannel(data map[string]string) (*Result, *AppError } func (c *Client) UpdateChannel(channel *Channel) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/update", channel.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update", channel.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -544,7 +716,7 @@ func (c *Client) UpdateChannel(channel *Channel) (*Result, *AppError) { } func (c *Client) UpdateChannelHeader(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/update_header", MapToJson(data)); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_header", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -553,7 +725,7 @@ func (c *Client) UpdateChannelHeader(data map[string]string) (*Result, *AppError } func (c *Client) UpdateChannelPurpose(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/update_purpose", MapToJson(data)); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_purpose", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -562,7 +734,7 @@ func (c *Client) UpdateChannelPurpose(data map[string]string) (*Result, *AppErro } func (c *Client) UpdateNotifyProps(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/update_notify_props", MapToJson(data)); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_notify_props", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -571,7 +743,7 @@ func (c *Client) UpdateNotifyProps(data map[string]string) (*Result, *AppError) } func (c *Client) GetChannels(etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/channels/", "", etag); err != nil { + if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/", "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -580,7 +752,7 @@ func (c *Client) GetChannels(etag string) (*Result, *AppError) { } func (c *Client) GetChannel(id, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/channels/"+id+"/", "", etag); err != nil { + if r, err := c.DoApiGet(c.GetChannelRoute(id)+"/", "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -589,7 +761,7 @@ func (c *Client) GetChannel(id, etag string) (*Result, *AppError) { } func (c *Client) GetMoreChannels(etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/channels/more", "", etag); err != nil { + if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/more", "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -598,7 +770,7 @@ func (c *Client) GetMoreChannels(etag string) (*Result, *AppError) { } func (c *Client) GetChannelCounts(etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/channels/counts", "", etag); err != nil { + if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/counts", "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -607,7 +779,16 @@ func (c *Client) GetChannelCounts(etag string) (*Result, *AppError) { } func (c *Client) JoinChannel(id string) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/"+id+"/join", ""); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/join", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), nil}, nil + } +} + +func (c *Client) JoinChannelByName(name string) (*Result, *AppError) { + if r, err := c.DoApiPost(c.GetChannelNameRoute(name)+"/join", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -616,7 +797,7 @@ func (c *Client) JoinChannel(id string) (*Result, *AppError) { } func (c *Client) LeaveChannel(id string) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/"+id+"/leave", ""); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/leave", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -625,7 +806,7 @@ func (c *Client) LeaveChannel(id string) (*Result, *AppError) { } func (c *Client) DeleteChannel(id string) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/"+id+"/delete", ""); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/delete", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -636,7 +817,7 @@ func (c *Client) DeleteChannel(id string) (*Result, *AppError) { func (c *Client) AddChannelMember(id, user_id string) (*Result, *AppError) { data := make(map[string]string) data["user_id"] = user_id - if r, err := c.DoApiPost("/channels/"+id+"/add", MapToJson(data)); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/add", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -647,7 +828,7 @@ func (c *Client) AddChannelMember(id, user_id string) (*Result, *AppError) { func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) { data := make(map[string]string) data["user_id"] = user_id - if r, err := c.DoApiPost("/channels/"+id+"/remove", MapToJson(data)); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/remove", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -656,7 +837,7 @@ func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) { } func (c *Client) UpdateLastViewedAt(channelId string) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/"+channelId+"/update_last_viewed_at", ""); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/update_last_viewed_at", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -665,7 +846,7 @@ func (c *Client) UpdateLastViewedAt(channelId string) (*Result, *AppError) { } func (c *Client) GetChannelExtraInfo(id string, memberLimit int, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/channels/"+id+"/extra_info/"+strconv.FormatInt(int64(memberLimit), 10), "", etag); err != nil { + if r, err := c.DoApiGet(c.GetChannelRoute(id)+"/extra_info/"+strconv.FormatInt(int64(memberLimit), 10), "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -674,7 +855,7 @@ func (c *Client) GetChannelExtraInfo(id string, memberLimit int, etag string) (* } func (c *Client) CreatePost(post *Post) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/create", post.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(post.ChannelId)+"/posts/create", post.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -683,7 +864,7 @@ func (c *Client) CreatePost(post *Post) (*Result, *AppError) { } func (c *Client) UpdatePost(post *Post) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/update", post.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(post.ChannelId)+"/posts/update", post.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -692,7 +873,7 @@ func (c *Client) UpdatePost(post *Post) (*Result, *AppError) { } func (c *Client) GetPosts(channelId string, offset int, limit int, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/posts/%v/%v", channelId, offset, limit), "", etag); err != nil { + if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/page/%v/%v", offset, limit), "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -701,7 +882,7 @@ func (c *Client) GetPosts(channelId string, offset int, limit int, etag string) } func (c *Client) GetPostsSince(channelId string, time int64) (*Result, *AppError) { - if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/posts/%v", channelId, time), "", ""); err != nil { + if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/since/%v", time), "", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -710,7 +891,7 @@ func (c *Client) GetPostsSince(channelId string, time int64) (*Result, *AppError } func (c *Client) GetPostsBefore(channelId string, postid string, offset int, limit int, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/post/%v/before/%v/%v", channelId, postid, offset, limit), "", etag); err != nil { + if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/before/%v/%v", postid, offset, limit), "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -719,7 +900,7 @@ func (c *Client) GetPostsBefore(channelId string, postid string, offset int, lim } func (c *Client) GetPostsAfter(channelId string, postid string, offset int, limit int, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/post/%v/after/%v/%v", channelId, postid, offset, limit), "", etag); err != nil { + if r, err := c.DoApiGet(fmt.Sprintf(c.GetChannelRoute(channelId)+"/posts/%v/after/%v/%v", postid, offset, limit), "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -728,7 +909,7 @@ func (c *Client) GetPostsAfter(channelId string, postid string, offset int, limi } func (c *Client) GetPost(channelId string, postId string, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/post/%v", channelId, postId), "", etag); err != nil { + if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/get", postId), "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -737,7 +918,7 @@ func (c *Client) GetPost(channelId string, postId string, etag string) (*Result, } func (c *Client) DeletePost(channelId string, postId string) (*Result, *AppError) { - if r, err := c.DoApiPost(fmt.Sprintf("/channels/%v/post/%v/delete", channelId, postId), ""); err != nil { + if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/delete", postId), ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -745,8 +926,11 @@ func (c *Client) DeletePost(channelId string, postId string) (*Result, *AppError } } -func (c *Client) SearchPosts(terms string) (*Result, *AppError) { - if r, err := c.DoApiGet("/posts/search?terms="+url.QueryEscape(terms), "", ""); err != nil { +func (c *Client) SearchPosts(terms string, isOrSearch bool) (*Result, *AppError) { + data := map[string]interface{}{} + data["terms"] = terms + data["is_or_search"] = isOrSearch + if r, err := c.DoApiPost(c.GetTeamRoute()+"/posts/search", StringInterfaceToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -754,8 +938,16 @@ func (c *Client) SearchPosts(terms string) (*Result, *AppError) { } } -func (c *Client) UploadFile(url string, data []byte, contentType string) (*Result, *AppError) { - rq, _ := http.NewRequest("POST", c.ApiUrl+url, bytes.NewReader(data)) +func (c *Client) UploadProfileFile(data []byte, contentType string) (*Result, *AppError) { + return c.uploadFile(c.ApiUrl+"/users/newimage", data, contentType) +} + +func (c *Client) UploadPostAttachment(data []byte, contentType string) (*Result, *AppError) { + return c.uploadFile(c.ApiUrl+c.GetTeamRoute()+"/files/upload", data, contentType) +} + +func (c *Client) uploadFile(url string, data []byte, contentType string) (*Result, *AppError) { + rq, _ := http.NewRequest("POST", url, bytes.NewReader(data)) rq.Header.Set("Content-Type", contentType) if len(c.AuthToken) > 0 { @@ -777,7 +969,7 @@ func (c *Client) GetFile(url string, isFullUrl bool) (*Result, *AppError) { if isFullUrl { rq, _ = http.NewRequest("GET", url, nil) } else { - rq, _ = http.NewRequest("GET", c.ApiUrl+"/files/get"+url, nil) + rq, _ = http.NewRequest("GET", c.ApiUrl+c.GetTeamRoute()+"/files/get"+url, nil) } if len(c.AuthToken) > 0 { @@ -796,7 +988,7 @@ func (c *Client) GetFile(url string, isFullUrl bool) (*Result, *AppError) { func (c *Client) GetFileInfo(url string) (*Result, *AppError) { var rq *http.Request - rq, _ = http.NewRequest("GET", c.ApiUrl+"/files/get_info"+url, nil) + rq, _ = http.NewRequest("GET", c.ApiUrl+c.GetTeamRoute()+"/files/get_info"+url, nil) if len(c.AuthToken) > 0 { rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) @@ -812,12 +1004,12 @@ func (c *Client) GetFileInfo(url string) (*Result, *AppError) { } } -func (c *Client) GetPublicLink(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/files/get_public_link", MapToJson(data)); err != nil { +func (c *Client) GetPublicLink(filename string) (*Result, *AppError) { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/files/get_public_link", MapToJson(map[string]string{"filename": filename})); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + r.Header.Get(HEADER_ETAG_SERVER), StringFromJson(r.Body)}, nil } } @@ -835,7 +1027,7 @@ func (c *Client) UpdateUserRoles(data map[string]string) (*Result, *AppError) { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil } } @@ -881,11 +1073,13 @@ func (c *Client) UpdateUserPassword(userId, currentPassword, newPassword string) return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil } } -func (c *Client) SendPasswordReset(data map[string]string) (*Result, *AppError) { +func (c *Client) SendPasswordReset(email string) (*Result, *AppError) { + data := map[string]string{} + data["email"] = email if r, err := c.DoApiPost("/users/send_password_reset", MapToJson(data)); err != nil { return nil, err } else { @@ -894,7 +1088,10 @@ func (c *Client) SendPasswordReset(data map[string]string) (*Result, *AppError) } } -func (c *Client) ResetPassword(data map[string]string) (*Result, *AppError) { +func (c *Client) ResetPassword(code, newPassword string) (*Result, *AppError) { + data := map[string]string{} + data["code"] = code + data["new_password"] = newPassword if r, err := c.DoApiPost("/users/reset_password", MapToJson(data)); err != nil { return nil, err } else { @@ -903,6 +1100,18 @@ func (c *Client) ResetPassword(data map[string]string) (*Result, *AppError) { } } +func (c *Client) AdminResetPassword(userId, newPassword string) (*Result, *AppError) { + data := map[string]string{} + data["user_id"] = userId + data["new_password"] = newPassword + if r, err := c.DoApiPost("/admin/reset_password", MapToJson(data)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + func (c *Client) GetStatuses(data []string) (*Result, *AppError) { if r, err := c.DoApiPost("/users/status", ArrayToJson(data)); err != nil { return nil, err @@ -913,7 +1122,7 @@ func (c *Client) GetStatuses(data []string) (*Result, *AppError) { } func (c *Client) GetMyTeam(etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/teams/me", "", etag); err != nil { + if r, err := c.DoApiGet(c.GetTeamRoute()+"/me", "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -921,6 +1130,15 @@ func (c *Client) GetMyTeam(etag string) (*Result, *AppError) { } } +func (c *Client) GetTeamMembers(teamId string) (*Result, *AppError) { + if r, err := c.DoApiGet("/teams/members/"+teamId, "", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), TeamMembersFromJson(r.Body)}, nil + } +} + func (c *Client) RegisterApp(app *OAuthApp) (*Result, *AppError) { if r, err := c.DoApiPost("/oauth/register", app.ToJson()); err != nil { return nil, err @@ -940,7 +1158,7 @@ func (c *Client) AllowOAuth(rspType, clientId, redirect, scope, state string) (* } func (c *Client) GetAccessToken(data url.Values) (*Result, *AppError) { - if r, err := c.DoPost("/oauth/access_token", data.Encode(), "application/x-www-form-urlencoded"); err != nil { + if r, err := c.DoApiPost("/oauth/access_token", data.Encode()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -949,7 +1167,7 @@ func (c *Client) GetAccessToken(data url.Values) (*Result, *AppError) { } func (c *Client) CreateIncomingWebhook(hook *IncomingWebhook) (*Result, *AppError) { - if r, err := c.DoApiPost("/hooks/incoming/create", hook.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/incoming/create", hook.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -966,8 +1184,10 @@ func (c *Client) PostToWebhook(id, payload string) (*Result, *AppError) { } } -func (c *Client) DeleteIncomingWebhook(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/hooks/incoming/delete", MapToJson(data)); err != nil { +func (c *Client) DeleteIncomingWebhook(id string) (*Result, *AppError) { + data := make(map[string]string) + data["id"] = id + if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/incoming/delete", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -976,7 +1196,7 @@ func (c *Client) DeleteIncomingWebhook(data map[string]string) (*Result, *AppErr } func (c *Client) ListIncomingWebhooks() (*Result, *AppError) { - if r, err := c.DoApiGet("/hooks/incoming/list", "", ""); err != nil { + if r, err := c.DoApiGet(c.GetTeamRoute()+"/hooks/incoming/list", "", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -1020,7 +1240,7 @@ func (c *Client) GetPreferenceCategory(category string) (*Result, *AppError) { } func (c *Client) CreateOutgoingWebhook(hook *OutgoingWebhook) (*Result, *AppError) { - if r, err := c.DoApiPost("/hooks/outgoing/create", hook.ToJson()); err != nil { + if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/create", hook.ToJson()); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -1028,8 +1248,10 @@ func (c *Client) CreateOutgoingWebhook(hook *OutgoingWebhook) (*Result, *AppErro } } -func (c *Client) DeleteOutgoingWebhook(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/hooks/outgoing/delete", MapToJson(data)); err != nil { +func (c *Client) DeleteOutgoingWebhook(id string) (*Result, *AppError) { + data := make(map[string]string) + data["id"] = id + if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/delete", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -1038,7 +1260,7 @@ func (c *Client) DeleteOutgoingWebhook(data map[string]string) (*Result, *AppErr } func (c *Client) ListOutgoingWebhooks() (*Result, *AppError) { - if r, err := c.DoApiGet("/hooks/outgoing/list", "", ""); err != nil { + if r, err := c.DoApiGet(c.GetTeamRoute()+"/hooks/outgoing/list", "", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -1046,8 +1268,10 @@ func (c *Client) ListOutgoingWebhooks() (*Result, *AppError) { } } -func (c *Client) RegenOutgoingWebhookToken(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/hooks/outgoing/regen_token", MapToJson(data)); err != nil { +func (c *Client) RegenOutgoingWebhookToken(id string) (*Result, *AppError) { + data := make(map[string]string) + data["id"] = id + if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/regen_token", MapToJson(data)); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -1059,3 +1283,21 @@ func (c *Client) MockSession(sessionToken string) { c.AuthToken = sessionToken c.AuthType = HEADER_BEARER } + +func (c *Client) GetClientLicenceConfig(etag string) (*Result, *AppError) { + if r, err := c.DoApiGet("/license/client_config", "", etag); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + +func (c *Client) GetInitialLoad() (*Result, *AppError) { + if r, err := c.DoApiGet("/users/initial_load", "", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), InitialLoadFromJson(r.Body)}, nil + } +} diff --git a/vendor/github.com/mattermost/platform/model/command.go b/vendor/github.com/mattermost/platform/model/command.go index 56d88f13..4d5f7ace 100644 --- a/vendor/github.com/mattermost/platform/model/command.go +++ b/vendor/github.com/mattermost/platform/model/command.go @@ -29,6 +29,7 @@ type Command struct { AutoCompleteDesc string `json:"auto_complete_desc"` AutoCompleteHint string `json:"auto_complete_hint"` DisplayName string `json:"display_name"` + Description string `json:"description"` URL string `json:"url"` } @@ -98,7 +99,7 @@ func (o *Command) IsValid() *AppError { return NewLocAppError("Command.IsValid", "model.command.is_valid.team_id.app_error", nil, "") } - if len(o.Trigger) > 1024 { + if len(o.Trigger) == 0 || len(o.Trigger) > 128 { return NewLocAppError("Command.IsValid", "model.command.is_valid.trigger.app_error", nil, "") } @@ -114,6 +115,14 @@ func (o *Command) IsValid() *AppError { return NewLocAppError("Command.IsValid", "model.command.is_valid.method.app_error", nil, "") } + if len(o.DisplayName) > 64 { + return NewLocAppError("Command.IsValid", "model.command.is_valid.display_name.app_error", nil, "") + } + + if len(o.Description) > 128 { + return NewLocAppError("Command.IsValid", "model.command.is_valid.description.app_error", nil, "") + } + return nil } diff --git a/vendor/github.com/mattermost/platform/model/config.go b/vendor/github.com/mattermost/platform/model/config.go index 82c51224..eb25948f 100644 --- a/vendor/github.com/mattermost/platform/model/config.go +++ b/vendor/github.com/mattermost/platform/model/config.go @@ -21,6 +21,18 @@ const ( SERVICE_GITLAB = "gitlab" SERVICE_GOOGLE = "google" + + WEBSERVER_MODE_REGULAR = "regular" + WEBSERVER_MODE_GZIP = "gzip" + WEBSERVER_MODE_DISABLED = "disabled" + + GENERIC_NOTIFICATION = "generic" + FULL_NOTIFICATION = "full" + + DIRECT_MESSAGE_ANY = "any" + DIRECT_MESSAGE_TEAM = "team" + + FAKE_SETTING = "********************************" ) type ServiceSettings struct { @@ -39,6 +51,7 @@ type ServiceSettings struct { EnableDeveloper *bool EnableSecurityFixAlert *bool EnableInsecureOutgoingConnections *bool + EnableMultifactorAuthentication *bool AllowCorsFrom *string SessionLengthWebInDays *int SessionLengthMobileInDays *int @@ -46,6 +59,7 @@ type ServiceSettings struct { SessionCacheInMinutes *int WebsocketSecurePort *int WebsocketPort *int + WebserverMode *string } type SSOSettings struct { @@ -116,6 +130,7 @@ type EmailSettings struct { PasswordResetSalt string SendPushNotifications *bool PushNotificationServer *string + PushNotificationContents *string } type RateLimitSettings struct { @@ -145,44 +160,63 @@ type TeamSettings struct { MaxUsersPerTeam int EnableTeamCreation bool EnableUserCreation bool + EnableOpenServer *bool RestrictCreationToDomains string RestrictTeamNames *bool - EnableTeamListing *bool + EnableCustomBrand *bool + CustomBrandText *string + RestrictDirectMessage *string } type LdapSettings struct { // Basic - Enable *bool - LdapServer *string - LdapPort *int - BaseDN *string - BindUsername *string - BindPassword *string + Enable *bool + LdapServer *string + LdapPort *int + ConnectionSecurity *string + BaseDN *string + BindUsername *string + BindPassword *string + + // Filtering + UserFilter *string // User Mapping FirstNameAttribute *string LastNameAttribute *string EmailAttribute *string UsernameAttribute *string + NicknameAttribute *string IdAttribute *string // Advanced - QueryTimeout *int + SkipCertificateVerification *bool + QueryTimeout *int + + // Customization + LoginFieldName *string +} + +type ComplianceSettings struct { + Enable *bool + Directory *string + EnableDaily *bool } type Config struct { - ServiceSettings ServiceSettings - TeamSettings TeamSettings - SqlSettings SqlSettings - LogSettings LogSettings - FileSettings FileSettings - EmailSettings EmailSettings - RateLimitSettings RateLimitSettings - PrivacySettings PrivacySettings - SupportSettings SupportSettings - GitLabSettings SSOSettings - GoogleSettings SSOSettings - LdapSettings LdapSettings + ServiceSettings ServiceSettings + TeamSettings TeamSettings + SqlSettings SqlSettings + LogSettings LogSettings + FileSettings FileSettings + EmailSettings EmailSettings + RateLimitSettings RateLimitSettings + PrivacySettings PrivacySettings + SupportSettings SupportSettings + GitLabSettings SSOSettings + GoogleSettings SSOSettings + LdapSettings LdapSettings + ComplianceSettings ComplianceSettings } func (o *Config) ToJson() string { @@ -259,14 +293,34 @@ func (o *Config) SetDefaults() { *o.ServiceSettings.EnableInsecureOutgoingConnections = false } + if o.ServiceSettings.EnableMultifactorAuthentication == nil { + o.ServiceSettings.EnableMultifactorAuthentication = new(bool) + *o.ServiceSettings.EnableMultifactorAuthentication = false + } + if o.TeamSettings.RestrictTeamNames == nil { o.TeamSettings.RestrictTeamNames = new(bool) *o.TeamSettings.RestrictTeamNames = true } - if o.TeamSettings.EnableTeamListing == nil { - o.TeamSettings.EnableTeamListing = new(bool) - *o.TeamSettings.EnableTeamListing = false + if o.TeamSettings.EnableCustomBrand == nil { + o.TeamSettings.EnableCustomBrand = new(bool) + *o.TeamSettings.EnableCustomBrand = false + } + + if o.TeamSettings.CustomBrandText == nil { + o.TeamSettings.CustomBrandText = new(string) + *o.TeamSettings.CustomBrandText = "" + } + + if o.TeamSettings.EnableOpenServer == nil { + o.TeamSettings.EnableOpenServer = new(bool) + *o.TeamSettings.EnableOpenServer = false + } + + if o.TeamSettings.RestrictDirectMessage == nil { + o.TeamSettings.RestrictDirectMessage = new(string) + *o.TeamSettings.RestrictDirectMessage = DIRECT_MESSAGE_ANY } if o.EmailSettings.EnableSignInWithEmail == nil { @@ -294,26 +348,51 @@ func (o *Config) SetDefaults() { *o.EmailSettings.PushNotificationServer = "" } + if o.EmailSettings.PushNotificationContents == nil { + o.EmailSettings.PushNotificationContents = new(string) + *o.EmailSettings.PushNotificationContents = GENERIC_NOTIFICATION + } + + if !IsSafeLink(o.SupportSettings.TermsOfServiceLink) { + o.SupportSettings.TermsOfServiceLink = nil + } + if o.SupportSettings.TermsOfServiceLink == nil { o.SupportSettings.TermsOfServiceLink = new(string) *o.SupportSettings.TermsOfServiceLink = "/static/help/terms.html" } + if !IsSafeLink(o.SupportSettings.PrivacyPolicyLink) { + o.SupportSettings.PrivacyPolicyLink = nil + } + if o.SupportSettings.PrivacyPolicyLink == nil { o.SupportSettings.PrivacyPolicyLink = new(string) *o.SupportSettings.PrivacyPolicyLink = "/static/help/privacy.html" } + if !IsSafeLink(o.SupportSettings.AboutLink) { + o.SupportSettings.AboutLink = nil + } + if o.SupportSettings.AboutLink == nil { o.SupportSettings.AboutLink = new(string) *o.SupportSettings.AboutLink = "/static/help/about.html" } + if !IsSafeLink(o.SupportSettings.HelpLink) { + o.SupportSettings.HelpLink = nil + } + if o.SupportSettings.HelpLink == nil { o.SupportSettings.HelpLink = new(string) *o.SupportSettings.HelpLink = "/static/help/help.html" } + if !IsSafeLink(o.SupportSettings.ReportAProblemLink) { + o.SupportSettings.ReportAProblemLink = nil + } + if o.SupportSettings.ReportAProblemLink == nil { o.SupportSettings.ReportAProblemLink = new(string) *o.SupportSettings.ReportAProblemLink = "/static/help/report_problem.html" @@ -339,6 +418,16 @@ func (o *Config) SetDefaults() { *o.LdapSettings.Enable = false } + if o.LdapSettings.UserFilter == nil { + o.LdapSettings.UserFilter = new(string) + *o.LdapSettings.UserFilter = "" + } + + if o.LdapSettings.LoginFieldName == nil { + o.LdapSettings.LoginFieldName = new(string) + *o.LdapSettings.LoginFieldName = "" + } + if o.ServiceSettings.SessionLengthWebInDays == nil { o.ServiceSettings.SessionLengthWebInDays = new(int) *o.ServiceSettings.SessionLengthWebInDays = 30 @@ -383,6 +472,41 @@ func (o *Config) SetDefaults() { o.ServiceSettings.AllowCorsFrom = new(string) *o.ServiceSettings.AllowCorsFrom = "" } + + if o.ServiceSettings.WebserverMode == nil { + o.ServiceSettings.WebserverMode = new(string) + *o.ServiceSettings.WebserverMode = "regular" + } + + if o.ComplianceSettings.Enable == nil { + o.ComplianceSettings.Enable = new(bool) + *o.ComplianceSettings.Enable = false + } + + if o.ComplianceSettings.Directory == nil { + o.ComplianceSettings.Directory = new(string) + *o.ComplianceSettings.Directory = "./data/" + } + + if o.ComplianceSettings.EnableDaily == nil { + o.ComplianceSettings.EnableDaily = new(bool) + *o.ComplianceSettings.EnableDaily = false + } + + if o.LdapSettings.ConnectionSecurity == nil { + o.LdapSettings.ConnectionSecurity = new(string) + *o.LdapSettings.ConnectionSecurity = "" + } + + if o.LdapSettings.SkipCertificateVerification == nil { + o.LdapSettings.SkipCertificateVerification = new(bool) + *o.LdapSettings.SkipCertificateVerification = false + } + + if o.LdapSettings.NicknameAttribute == nil { + o.LdapSettings.NicknameAttribute = new(string) + *o.LdapSettings.NicknameAttribute = "" + } } func (o *Config) IsValid() *AppError { @@ -399,6 +523,10 @@ func (o *Config) IsValid() *AppError { return NewLocAppError("Config.IsValid", "model.config.is_valid.max_users.app_error", nil, "") } + if !(*o.TeamSettings.RestrictDirectMessage == DIRECT_MESSAGE_ANY || *o.TeamSettings.RestrictDirectMessage == DIRECT_MESSAGE_TEAM) { + return NewLocAppError("Config.IsValid", "model.config.is_valid.restrict_direct_message.app_error", nil, "") + } + if len(o.SqlSettings.AtRestEncryptKey) < 32 { return NewLocAppError("Config.IsValid", "model.config.is_valid.encrypt_sql.app_error", nil, "") } @@ -471,13 +599,45 @@ func (o *Config) IsValid() *AppError { return NewLocAppError("Config.IsValid", "model.config.is_valid.rate_sec.app_error", nil, "") } + if !(*o.LdapSettings.ConnectionSecurity == CONN_SECURITY_NONE || *o.LdapSettings.ConnectionSecurity == CONN_SECURITY_TLS || *o.LdapSettings.ConnectionSecurity == CONN_SECURITY_STARTTLS) { + return NewLocAppError("Config.IsValid", "model.config.is_valid.ldap_security.app_error", nil, "") + } + return nil } -func (me *Config) GetSanitizeOptions() map[string]bool { +func (o *Config) GetSanitizeOptions() map[string]bool { options := map[string]bool{} - options["fullname"] = me.PrivacySettings.ShowFullName - options["email"] = me.PrivacySettings.ShowEmailAddress + options["fullname"] = o.PrivacySettings.ShowFullName + options["email"] = o.PrivacySettings.ShowEmailAddress return options } + +func (o *Config) Sanitize() { + if &o.LdapSettings != nil && len(*o.LdapSettings.BindPassword) > 0 { + *o.LdapSettings.BindPassword = FAKE_SETTING + } + + o.FileSettings.PublicLinkSalt = FAKE_SETTING + if len(o.FileSettings.AmazonS3SecretAccessKey) > 0 { + o.FileSettings.AmazonS3SecretAccessKey = FAKE_SETTING + } + + o.EmailSettings.InviteSalt = FAKE_SETTING + o.EmailSettings.PasswordResetSalt = FAKE_SETTING + if len(o.EmailSettings.SMTPPassword) > 0 { + o.EmailSettings.SMTPPassword = FAKE_SETTING + } + + if len(o.GitLabSettings.Secret) > 0 { + o.GitLabSettings.Secret = FAKE_SETTING + } + + o.SqlSettings.DataSource = FAKE_SETTING + o.SqlSettings.AtRestEncryptKey = FAKE_SETTING + + for i := range o.SqlSettings.DataSourceReplicas { + o.SqlSettings.DataSourceReplicas[i] = FAKE_SETTING + } +} diff --git a/vendor/github.com/mattermost/platform/model/gitlab/gitlab.go b/vendor/github.com/mattermost/platform/model/gitlab/gitlab.go index 3ca49997..fc70dd93 100644 --- a/vendor/github.com/mattermost/platform/model/gitlab/gitlab.go +++ b/vendor/github.com/mattermost/platform/model/gitlab/gitlab.go @@ -12,10 +12,6 @@ import ( "strings" ) -const ( - USER_AUTH_SERVICE_GITLAB = "gitlab" -) - type GitLabProvider struct { } @@ -29,7 +25,7 @@ type GitLabUser struct { func init() { provider := &GitLabProvider{} - einterfaces.RegisterOauthProvider(USER_AUTH_SERVICE_GITLAB, provider) + einterfaces.RegisterOauthProvider(model.USER_AUTH_SERVICE_GITLAB, provider) } func userFromGitLabUser(glu *GitLabUser) *model.User { @@ -49,9 +45,10 @@ func userFromGitLabUser(glu *GitLabUser) *model.User { } else { user.FirstName = glu.Name } + strings.TrimSpace(user.Email) user.Email = glu.Email - user.AuthData = strconv.FormatInt(glu.Id, 10) - user.AuthService = USER_AUTH_SERVICE_GITLAB + *user.AuthData = strconv.FormatInt(glu.Id, 10) + user.AuthService = model.USER_AUTH_SERVICE_GITLAB return user } @@ -84,7 +81,7 @@ func (glu *GitLabUser) getAuthData() string { } func (m *GitLabProvider) GetIdentifier() string { - return USER_AUTH_SERVICE_GITLAB + return model.USER_AUTH_SERVICE_GITLAB } func (m *GitLabProvider) GetUserFromJson(data io.Reader) *model.User { diff --git a/vendor/github.com/mattermost/platform/model/incoming_webhook.go b/vendor/github.com/mattermost/platform/model/incoming_webhook.go index 8432f5fe..0763b443 100644 --- a/vendor/github.com/mattermost/platform/model/incoming_webhook.go +++ b/vendor/github.com/mattermost/platform/model/incoming_webhook.go @@ -14,13 +14,15 @@ const ( ) type IncomingWebhook struct { - Id string `json:"id"` - CreateAt int64 `json:"create_at"` - UpdateAt int64 `json:"update_at"` - DeleteAt int64 `json:"delete_at"` - UserId string `json:"user_id"` - ChannelId string `json:"channel_id"` - TeamId string `json:"team_id"` + Id string `json:"id"` + CreateAt int64 `json:"create_at"` + UpdateAt int64 `json:"update_at"` + DeleteAt int64 `json:"delete_at"` + UserId string `json:"user_id"` + ChannelId string `json:"channel_id"` + TeamId string `json:"team_id"` + DisplayName string `json:"display_name"` + Description string `json:"description"` } type IncomingWebhookRequest struct { @@ -99,6 +101,14 @@ func (o *IncomingWebhook) IsValid() *AppError { return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.team_id.app_error", nil, "") } + if len(o.DisplayName) > 64 { + return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.display_name.app_error", nil, "") + } + + if len(o.Description) > 128 { + return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.description.app_error", nil, "") + } + return nil } diff --git a/vendor/github.com/mattermost/platform/model/license.go b/vendor/github.com/mattermost/platform/model/license.go index abb1be09..bc72ff9a 100644 --- a/vendor/github.com/mattermost/platform/model/license.go +++ b/vendor/github.com/mattermost/platform/model/license.go @@ -34,7 +34,10 @@ type Customer struct { type Features struct { Users *int `json:"users"` LDAP *bool `json:"ldap"` + MFA *bool `json:"mfa"` GoogleSSO *bool `json:"google_sso"` + Compliance *bool `json:"compliance"` + CustomBrand *bool `json:"custom_brand"` MHPNS *bool `json:"mhpns"` FutureFeatures *bool `json:"future_features"` } @@ -55,11 +58,26 @@ func (f *Features) SetDefaults() { *f.LDAP = *f.FutureFeatures } + if f.MFA == nil { + f.MFA = new(bool) + *f.MFA = *f.FutureFeatures + } + if f.GoogleSSO == nil { f.GoogleSSO = new(bool) *f.GoogleSSO = *f.FutureFeatures } + if f.Compliance == nil { + f.Compliance = new(bool) + *f.Compliance = *f.FutureFeatures + } + + if f.CustomBrand == nil { + f.CustomBrand = new(bool) + *f.CustomBrand = *f.FutureFeatures + } + if f.MHPNS == nil { f.MHPNS = new(bool) *f.MHPNS = *f.FutureFeatures diff --git a/vendor/github.com/mattermost/platform/model/message.go b/vendor/github.com/mattermost/platform/model/message.go index cce0ec09..a986af4d 100644 --- a/vendor/github.com/mattermost/platform/model/message.go +++ b/vendor/github.com/mattermost/platform/model/message.go @@ -13,7 +13,9 @@ const ( ACTION_POSTED = "posted" ACTION_POST_EDITED = "post_edited" ACTION_POST_DELETED = "post_deleted" + ACTION_CHANNEL_DELETED = "channel_deleted" ACTION_CHANNEL_VIEWED = "channel_viewed" + ACTION_DIRECT_ADDED = "direct_added" ACTION_NEW_USER = "new_user" ACTION_USER_ADDED = "user_added" ACTION_USER_REMOVED = "user_removed" diff --git a/vendor/github.com/mattermost/platform/model/outgoing_webhook.go b/vendor/github.com/mattermost/platform/model/outgoing_webhook.go index 70de4d26..ef1807e7 100644 --- a/vendor/github.com/mattermost/platform/model/outgoing_webhook.go +++ b/vendor/github.com/mattermost/platform/model/outgoing_webhook.go @@ -20,6 +20,8 @@ type OutgoingWebhook struct { TeamId string `json:"team_id"` TriggerWords StringArray `json:"trigger_words"` CallbackURLs StringArray `json:"callback_urls"` + DisplayName string `json:"display_name"` + Description string `json:"description"` } func (o *OutgoingWebhook) ToJson() string { @@ -96,6 +98,14 @@ func (o *OutgoingWebhook) IsValid() *AppError { return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.words.app_error", nil, "") } + if len(o.TriggerWords) != 0 { + for _, triggerWord := range o.TriggerWords { + if len(triggerWord) == 0 { + return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "") + } + } + } + if len(o.CallbackURLs) == 0 || len(fmt.Sprintf("%s", o.CallbackURLs)) > 1024 { return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.callback.app_error", nil, "") } @@ -106,6 +116,14 @@ func (o *OutgoingWebhook) IsValid() *AppError { } } + if len(o.DisplayName) > 64 { + return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.display_name.app_error", nil, "") + } + + if len(o.Description) > 128 { + return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.description.app_error", nil, "") + } + return nil } diff --git a/vendor/github.com/mattermost/platform/model/post.go b/vendor/github.com/mattermost/platform/model/post.go index 8a451831..173c99e3 100644 --- a/vendor/github.com/mattermost/platform/model/post.go +++ b/vendor/github.com/mattermost/platform/model/post.go @@ -16,6 +16,7 @@ const ( POST_SYSTEM_GENERIC = "system_generic" POST_JOIN_LEAVE = "system_join_leave" POST_HEADER_CHANGE = "system_header_change" + POST_CHANNEL_DELETED = "system_channel_deleted" POST_EPHEMERAL = "system_ephemeral" ) diff --git a/vendor/github.com/mattermost/platform/model/push_notification.go b/vendor/github.com/mattermost/platform/model/push_notification.go index 42feca2e..666dd8f7 100644 --- a/vendor/github.com/mattermost/platform/model/push_notification.go +++ b/vendor/github.com/mattermost/platform/model/push_notification.go @@ -11,7 +11,10 @@ import ( const ( PUSH_NOTIFY_APPLE = "apple" PUSH_NOTIFY_ANDROID = "android" - MHPNS = "https://push.mattermost.com" + + CATEGORY_DM = "DIRECT_MESSAGE" + + MHPNS = "https://push.mattermost.com" ) type PushNotification struct { @@ -23,6 +26,8 @@ type PushNotification struct { Message string `json:"message"` Badge int `json:"badge"` ContentAvailable int `json:"cont_ava"` + ChannelId string `json:"channel_id"` + ChannelName string `json:"channel_name"` } func (me *PushNotification) ToJson() string { diff --git a/vendor/github.com/mattermost/platform/model/search_params.go b/vendor/github.com/mattermost/platform/model/search_params.go index d3178269..250c8e1f 100644 --- a/vendor/github.com/mattermost/platform/model/search_params.go +++ b/vendor/github.com/mattermost/platform/model/search_params.go @@ -12,6 +12,7 @@ type SearchParams struct { IsHashtag bool InChannels []string FromUsers []string + OrTerms bool } var searchFlags = [...]string{"from", "channel", "in"} diff --git a/vendor/github.com/mattermost/platform/model/session.go b/vendor/github.com/mattermost/platform/model/session.go index 5d9424d6..8a5eec74 100644 --- a/vendor/github.com/mattermost/platform/model/session.go +++ b/vendor/github.com/mattermost/platform/model/session.go @@ -9,7 +9,7 @@ import ( ) const ( - SESSION_COOKIE_TOKEN = "MMTOKEN" + SESSION_COOKIE_TOKEN = "MMAUTHTOKEN" SESSION_CACHE_SIZE = 10000 SESSION_PROP_PLATFORM = "platform" SESSION_PROP_OS = "os" @@ -17,17 +17,17 @@ const ( ) type Session struct { - Id string `json:"id"` - Token string `json:"token"` - CreateAt int64 `json:"create_at"` - ExpiresAt int64 `json:"expires_at"` - LastActivityAt int64 `json:"last_activity_at"` - UserId string `json:"user_id"` - TeamId string `json:"team_id"` - DeviceId string `json:"device_id"` - Roles string `json:"roles"` - IsOAuth bool `json:"is_oauth"` - Props StringMap `json:"props"` + Id string `json:"id"` + Token string `json:"token"` + CreateAt int64 `json:"create_at"` + ExpiresAt int64 `json:"expires_at"` + LastActivityAt int64 `json:"last_activity_at"` + UserId string `json:"user_id"` + DeviceId string `json:"device_id"` + Roles string `json:"roles"` + IsOAuth bool `json:"is_oauth"` + Props StringMap `json:"props"` + TeamMembers []*TeamMember `json:"team_members" db:"-"` } func (me *Session) ToJson() string { @@ -95,6 +95,16 @@ func (me *Session) AddProp(key string, value string) { me.Props[key] = value } +func (me *Session) GetTeamByTeamId(teamId string) *TeamMember { + for _, team := range me.TeamMembers { + if team.TeamId == teamId { + return team + } + } + + return nil +} + func SessionsToJson(o []*Session) string { if b, err := json.Marshal(o); err != nil { return "[]" diff --git a/vendor/github.com/mattermost/platform/model/system.go b/vendor/github.com/mattermost/platform/model/system.go index b387749f..68d542c1 100644 --- a/vendor/github.com/mattermost/platform/model/system.go +++ b/vendor/github.com/mattermost/platform/model/system.go @@ -9,10 +9,11 @@ import ( ) const ( - SYSTEM_DIAGNOSTIC_ID = "DiagnosticId" - SYSTEM_RAN_UNIT_TESTS = "RanUnitTests" - SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime" - SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId" + SYSTEM_DIAGNOSTIC_ID = "DiagnosticId" + SYSTEM_RAN_UNIT_TESTS = "RanUnitTests" + SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime" + SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId" + SYSTEM_LAST_COMPLIANCE_TIME = "LastComplianceTime" ) type System struct { diff --git a/vendor/github.com/mattermost/platform/model/team.go b/vendor/github.com/mattermost/platform/model/team.go index 9e9eaa25..072e0a8c 100644 --- a/vendor/github.com/mattermost/platform/model/team.go +++ b/vendor/github.com/mattermost/platform/model/team.go @@ -18,19 +18,18 @@ const ( ) type Team struct { - Id string `json:"id"` - CreateAt int64 `json:"create_at"` - UpdateAt int64 `json:"update_at"` - DeleteAt int64 `json:"delete_at"` - DisplayName string `json:"display_name"` - Name string `json:"name"` - Email string `json:"email"` - Type string `json:"type"` - CompanyName string `json:"company_name"` - AllowedDomains string `json:"allowed_domains"` - InviteId string `json:"invite_id"` - AllowOpenInvite bool `json:"allow_open_invite"` - AllowTeamListing bool `json:"allow_team_listing"` + Id string `json:"id"` + CreateAt int64 `json:"create_at"` + UpdateAt int64 `json:"update_at"` + DeleteAt int64 `json:"delete_at"` + DisplayName string `json:"display_name"` + Name string `json:"name"` + Email string `json:"email"` + Type string `json:"type"` + CompanyName string `json:"company_name"` + AllowedDomains string `json:"allowed_domains"` + InviteId string `json:"invite_id"` + AllowOpenInvite bool `json:"allow_open_invite"` } type Invites struct { @@ -232,3 +231,12 @@ func (o *Team) Sanitize() { o.Email = "" o.AllowedDomains = "" } + +func (o *Team) SanitizeForNotLoggedIn() { + o.Email = "" + o.AllowedDomains = "" + o.CompanyName = "" + if !o.AllowOpenInvite { + o.InviteId = "" + } +} diff --git a/vendor/github.com/mattermost/platform/model/user.go b/vendor/github.com/mattermost/platform/model/user.go index 675a1ded..15c28140 100644 --- a/vendor/github.com/mattermost/platform/model/user.go +++ b/vendor/github.com/mattermost/platform/model/user.go @@ -15,17 +15,19 @@ import ( ) const ( - ROLE_TEAM_ADMIN = "admin" - ROLE_SYSTEM_ADMIN = "system_admin" - USER_AWAY_TIMEOUT = 5 * 60 * 1000 // 5 minutes - USER_OFFLINE_TIMEOUT = 1 * 60 * 1000 // 1 minute - USER_OFFLINE = "offline" - USER_AWAY = "away" - USER_ONLINE = "online" - USER_NOTIFY_ALL = "all" - USER_NOTIFY_MENTION = "mention" - USER_NOTIFY_NONE = "none" - DEFAULT_LOCALE = "en" + ROLE_SYSTEM_ADMIN = "system_admin" + USER_AWAY_TIMEOUT = 5 * 60 * 1000 // 5 minutes + USER_OFFLINE_TIMEOUT = 1 * 60 * 1000 // 1 minute + USER_OFFLINE = "offline" + USER_AWAY = "away" + USER_ONLINE = "online" + USER_NOTIFY_ALL = "all" + USER_NOTIFY_MENTION = "mention" + USER_NOTIFY_NONE = "none" + DEFAULT_LOCALE = "en" + USER_AUTH_SERVICE_EMAIL = "email" + USER_AUTH_SERVICE_USERNAME = "username" + MIN_PASSWORD_LENGTH = 5 ) type User struct { @@ -33,10 +35,9 @@ type User struct { CreateAt int64 `json:"create_at,omitempty"` UpdateAt int64 `json:"update_at,omitempty"` DeleteAt int64 `json:"delete_at"` - TeamId string `json:"team_id"` Username string `json:"username"` Password string `json:"password,omitempty"` - AuthData string `json:"auth_data,omitempty"` + AuthData *string `json:"auth_data,omitempty"` AuthService string `json:"auth_service"` Email string `json:"email"` EmailVerified bool `json:"email_verified,omitempty"` @@ -54,6 +55,8 @@ type User struct { LastPictureUpdate int64 `json:"last_picture_update,omitempty"` FailedAttempts int `json:"failed_attempts,omitempty"` Locale string `json:"locale"` + MfaActive bool `json:"mfa_active,omitempty"` + MfaSecret string `json:"mfa_secret,omitempty"` } // IsValid validates the user and returns an error if it isn't configured @@ -72,10 +75,6 @@ func (u *User) IsValid() *AppError { return NewLocAppError("User.IsValid", "model.user.is_valid.update_at.app_error", nil, "user_id="+u.Id) } - if len(u.TeamId) != 26 { - return NewLocAppError("User.IsValid", "model.user.is_valid.team_id.app_error", nil, "") - } - if !IsValidUsername(u.Username) { return NewLocAppError("User.IsValid", "model.user.is_valid.username.app_error", nil, "user_id="+u.Id) } @@ -100,15 +99,15 @@ func (u *User) IsValid() *AppError { return NewLocAppError("User.IsValid", "model.user.is_valid.pwd.app_error", nil, "user_id="+u.Id) } - if len(u.AuthData) > 128 { + 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 len(u.AuthData) > 0 && len(u.AuthService) == 0 { + 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) } - if len(u.Password) > 0 && len(u.AuthData) > 0 { + 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) } @@ -131,6 +130,10 @@ func (u *User) PreSave() { u.Username = NewId() } + if u.AuthData != nil && *u.AuthData == "" { + u.AuthData = nil + } + u.Username = strings.ToLower(u.Username) u.Email = strings.ToLower(u.Email) u.Locale = strings.ToLower(u.Locale) @@ -140,6 +143,8 @@ func (u *User) PreSave() { u.LastPasswordUpdate = u.CreateAt + u.MfaActive = false + if u.Locale == "" { u.Locale = DEFAULT_LOCALE } @@ -164,6 +169,10 @@ func (u *User) PreUpdate() { u.Locale = strings.ToLower(u.Locale) u.UpdateAt = GetMillis() + if u.AuthData != nil && *u.AuthData == "" { + u.AuthData = nil + } + if u.NotifyProps == nil || len(u.NotifyProps) == 0 { u.SetDefaultNotifications() } else if _, ok := u.NotifyProps["mention_keys"]; ok { @@ -185,13 +194,28 @@ func (u *User) SetDefaultNotifications() { u.NotifyProps["desktop"] = USER_NOTIFY_ALL u.NotifyProps["desktop_sound"] = "true" u.NotifyProps["mention_keys"] = u.Username + ",@" + u.Username - u.NotifyProps["first_name"] = "false" u.NotifyProps["all"] = "true" u.NotifyProps["channel"] = "true" - splitName := strings.Split(u.Nickname, " ") - if len(splitName) > 0 && splitName[0] != "" { + + if u.FirstName == "" { + u.NotifyProps["first_name"] = "false" + } else { u.NotifyProps["first_name"] = "true" - u.NotifyProps["mention_keys"] += "," + splitName[0] + } +} + +func (user *User) UpdateMentionKeysFromUsername(oldUsername string) { + nonUsernameKeys := []string{} + splitKeys := strings.Split(user.NotifyProps["mention_keys"], ",") + for _, key := range splitKeys { + if key != oldUsername && key != "@"+oldUsername { + nonUsernameKeys = append(nonUsernameKeys, key) + } + } + + user.NotifyProps["mention_keys"] = user.Username + ",@" + user.Username + if len(nonUsernameKeys) > 0 { + user.NotifyProps["mention_keys"] += "," + strings.Join(nonUsernameKeys, ",") } } @@ -221,7 +245,9 @@ func (u *User) IsAway() bool { // Remove any private data from the user object func (u *User) Sanitize(options map[string]bool) { u.Password = "" - u.AuthData = "" + u.AuthData = new(string) + *u.AuthData = "" + u.MfaSecret = "" if len(options) != 0 && !options["email"] { u.Email = "" @@ -238,8 +264,11 @@ func (u *User) Sanitize(options map[string]bool) { func (u *User) ClearNonProfileFields() { u.UpdateAt = 0 u.Password = "" - u.AuthData = "" + u.AuthData = new(string) + *u.AuthData = "" u.AuthService = "" + u.MfaActive = false + u.MfaSecret = "" u.EmailVerified = false u.LastPingAt = 0 u.AllowMarketing = false @@ -295,7 +324,7 @@ func (u *User) GetDisplayName() string { } } -func IsValidRoles(userRoles string) bool { +func IsValidUserRoles(userRoles string) bool { roles := strings.Split(userRoles, " ") @@ -313,10 +342,6 @@ func isValidRole(role string) bool { return true } - if role == ROLE_TEAM_ADMIN { - return true - } - if role == ROLE_SYSTEM_ADMIN { return true } @@ -345,8 +370,15 @@ func IsInRole(userRoles string, inRole string) bool { return false } -func (u *User) IsSSOUser() bool { - if len(u.AuthData) != 0 && len(u.AuthService) != 0 { +func (u *User) IsOAuthUser() bool { + if u.AuthService == USER_AUTH_SERVICE_GITLAB { + return true + } + return false +} + +func (u *User) IsLDAPUser() bool { + if u.AuthService == USER_AUTH_SERVICE_LDAP { return true } return false @@ -354,7 +386,8 @@ func (u *User) IsSSOUser() bool { func (u *User) PreExport() { u.Password = "" - u.AuthData = "" + u.AuthData = new(string) + *u.AuthData = "" u.LastActivityAt = 0 u.LastPingAt = 0 u.LastPasswordUpdate = 0 @@ -407,7 +440,7 @@ func HashPassword(password string) string { // ComparePassword compares the hash func ComparePassword(hash string, password string) bool { - if len(password) == 0 { + if len(password) == 0 || len(hash) == 0 { return false } diff --git a/vendor/github.com/mattermost/platform/model/utils.go b/vendor/github.com/mattermost/platform/model/utils.go index 808c89e3..443a34bc 100644 --- a/vendor/github.com/mattermost/platform/model/utils.go +++ b/vendor/github.com/mattermost/platform/model/utils.go @@ -41,12 +41,18 @@ func (er *AppError) Error() string { } func (er *AppError) Translate(T goi18n.TranslateFunc) { - if len(er.Message) == 0 { - if er.params == nil { - er.Message = T(er.Id) - } else { - er.Message = T(er.Id, er.params) - } + if er.params == nil { + er.Message = T(er.Id) + } else { + er.Message = T(er.Id, er.params) + } +} + +func (er *AppError) SystemMessage(T goi18n.TranslateFunc) string { + if er.params == nil { + return T(er.Id) + } else { + return T(er.Id, er.params) } } @@ -75,6 +81,7 @@ func NewLocAppError(where string, id string, params map[string]interface{}, deta ap := &AppError{} ap.Id = id ap.params = params + ap.Message = id ap.Where = where ap.DetailedError = details ap.StatusCode = 500 @@ -171,6 +178,26 @@ func StringInterfaceFromJson(data io.Reader) map[string]interface{} { } } +func StringToJson(s string) string { + b, err := json.Marshal(s) + if err != nil { + return "" + } else { + return string(b) + } +} + +func StringFromJson(data io.Reader) string { + decoder := json.NewDecoder(data) + + var s string + if err := decoder.Decode(&s); err != nil { + return "" + } else { + return s + } +} + func IsLower(s string) bool { if strings.ToLower(s) == s { return true @@ -367,3 +394,29 @@ func IsValidHttpUrl(rawUrl string) bool { return true } + +func IsValidHttpsUrl(rawUrl string) bool { + if strings.Index(rawUrl, "https://") != 0 { + return false + } + + if _, err := url.ParseRequestURI(rawUrl); err != nil { + return false + } + + return true +} + +func IsSafeLink(link *string) bool { + if link != nil { + if IsValidHttpUrl(*link) { + return true + } else if strings.HasPrefix(*link, "/") { + return true + } else { + return false + } + } + + return true +} diff --git a/vendor/github.com/mattermost/platform/model/version.go b/vendor/github.com/mattermost/platform/model/version.go index fe90644b..4a47f06e 100644 --- a/vendor/github.com/mattermost/platform/model/version.go +++ b/vendor/github.com/mattermost/platform/model/version.go @@ -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.0.0", "2.2.0", "2.1.0", "2.0.0", @@ -29,10 +30,10 @@ var versions = []string{ } var CurrentVersion string = versions[0] -var BuildNumber = "_BUILD_NUMBER_" -var BuildDate = "_BUILD_DATE_" -var BuildHash = "_BUILD_HASH_" -var BuildEnterpriseReady = "_BUILD_ENTERPRISE_READY_" +var BuildNumber string +var BuildDate string +var BuildHash string +var BuildEnterpriseReady string var versionsWithoutHotFixes []string func init() { @@ -119,5 +120,10 @@ func IsPreviousVersionsSupported(versionToCheck string) bool { return true } + // Current - 3 Supported + if versionsWithoutHotFixes[3] == versionToCheckStr { + return true + } + return false } -- cgit v1.2.3