summaryrefslogtreecommitdiffstats
path: root/model
diff options
context:
space:
mode:
Diffstat (limited to 'model')
-rw-r--r--model/client.go308
-rw-r--r--model/command.go2
-rw-r--r--model/command_test.go81
-rw-r--r--model/config.go18
-rw-r--r--model/gitlab.go8
-rw-r--r--model/gitlab/gitlab.go10
-rw-r--r--model/initial_load.go40
-rw-r--r--model/initial_load_test.go20
-rw-r--r--model/password_recovery.go37
-rw-r--r--model/session.go32
-rw-r--r--model/team.go25
-rw-r--r--model/team_member.go78
-rw-r--r--model/team_member_test.go43
-rw-r--r--model/user.go20
-rw-r--r--model/user_test.go9
-rw-r--r--model/utils.go11
-rw-r--r--model/version.go1
17 files changed, 596 insertions, 147 deletions
diff --git a/model/client.go b/model/client.go
index 89b4d134f..4edb859e2 100644
--- a/model/client.go
+++ b/model/client.go
@@ -28,7 +28,10 @@ const (
HEADER_AUTH = "Authorization"
HEADER_REQUESTED_WITH = "X-Requested-With"
HEADER_REQUESTED_WITH_XML = "XMLHttpRequest"
- API_URL_SUFFIX = "/api/v1"
+
+ API_URL_SUFFIX_V1 = "/api/v1"
+ API_URL_SUFFIX_V3 = "/api/v3"
+ API_URL_SUFFIX = API_URL_SUFFIX_V3
)
type Result struct {
@@ -39,16 +42,52 @@ 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) DoPost(url, data, contentType string) (*http.Response, *AppError) {
@@ -162,10 +201,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 {
@@ -179,8 +227,32 @@ func (c *Client) FindTeamByName(name string, allServers bool) (*Result, *AppErro
}
}
+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), MapFromJson(r.Body)}, 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), 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),
@@ -189,7 +261,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),
@@ -206,6 +278,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
@@ -216,7 +300,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),
@@ -242,6 +326,24 @@ func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) {
}
}
+func (c *Client) GetProfilesForTeam(teamId string, etag string) (*Result, *AppError) {
+ if r, err := c.DoApiGet("/users/profiles/"+teamId+"?skip_direct=true", "", 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) 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,6 +376,26 @@ func (c *Client) LoginByEmailWithDevice(name string, email string, password stri
return c.login(m)
}
+func (c *Client) LoginByLdap(userid string, password string, mfatoken string) (*Result, *AppError) {
+ m := make(map[string]string)
+ m["id"] = userid
+ m["password"] = password
+ m["token"] = mfatoken
+ if r, err := c.DoApiPost("/users/login_ldap", MapToJson(m)); err != nil {
+ return nil, err
+ } else {
+ c.AuthToken = r.Header.Get(HEADER_TOKEN)
+ c.AuthType = HEADER_BEARER
+ sessionToken := getCookie(SESSION_COOKIE_TOKEN, r)
+
+ if c.AuthToken != sessionToken.Value {
+ NewLocAppError("/users/login_ldap", "model.client.login.app_error", nil, "")
+ }
+ return &Result{r.Header.Get(HEADER_REQUEST_ID),
+ r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
+ }
+}
+
func (c *Client) login(m map[string]string) (*Result, *AppError) {
if r, err := c.DoApiPost("/users/login", MapToJson(m)); err != nil {
return nil, err
@@ -297,16 +419,16 @@ 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) CheckMfa(method, teamName, loginId string) (*Result, *AppError) {
+func (c *Client) CheckMfa(method, loginId string) (*Result, *AppError) {
m := make(map[string]string)
m["method"] = method
- m["team_name"] = teamName
m["login_id"] = loginId
if r, err := c.DoApiPost("/users/mfa", MapToJson(m)); err != nil {
@@ -339,14 +461,16 @@ func (c *Client) UpdateMfa(activate bool, token string) (*Result, *AppError) {
}
}
-func (c *Client) SetOAuthToken(token string) {
- c.AuthToken = token
- c.AuthType = HEADER_TOKEN
-}
+func (c *Client) AdminResetMfa(userId string) (*Result, *AppError) {
+ m := make(map[string]string)
+ m["user_id"] = userId
-func (c *Client) ClearOAuthToken() {
- c.AuthToken = ""
- c.AuthType = HEADER_BEARER
+ 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) {
@@ -411,7 +535,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),
@@ -420,7 +544,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),
@@ -429,7 +553,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),
@@ -438,7 +562,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),
@@ -447,7 +571,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),
@@ -456,7 +580,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),
@@ -582,7 +706,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),
@@ -590,8 +714,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),
@@ -600,7 +726,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),
@@ -609,7 +735,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),
@@ -618,7 +744,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),
@@ -627,7 +753,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),
@@ -636,7 +762,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),
@@ -645,7 +771,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),
@@ -654,7 +780,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),
@@ -663,7 +789,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),
@@ -672,7 +798,7 @@ 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),
@@ -681,7 +807,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),
@@ -690,7 +816,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),
@@ -701,7 +827,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),
@@ -712,7 +838,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),
@@ -721,7 +847,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),
@@ -730,7 +856,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),
@@ -739,7 +865,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),
@@ -748,7 +874,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),
@@ -757,7 +883,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),
@@ -766,7 +892,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),
@@ -775,7 +901,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),
@@ -784,7 +910,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),
@@ -793,7 +919,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),
@@ -802,7 +928,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),
@@ -811,7 +937,7 @@ 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 {
+ if r, err := c.DoApiGet(c.GetTeamRoute()+"/posts/search?terms="+url.QueryEscape(terms), "", ""); err != nil {
return nil, err
} else {
return &Result{r.Header.Get(HEADER_REQUEST_ID),
@@ -819,8 +945,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 {
@@ -842,7 +976,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 {
@@ -861,7 +995,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)
@@ -878,7 +1012,7 @@ 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 {
+ if r, err := c.DoApiPost(c.GetTeamRoute()+"/files/get_public_link", MapToJson(data)); err != nil {
return nil, err
} else {
return &Result{r.Header.Get(HEADER_REQUEST_ID),
@@ -950,7 +1084,9 @@ func (c *Client) UpdateUserPassword(userId, currentPassword, newPassword string)
}
}
-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 {
@@ -959,7 +1095,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 {
@@ -968,6 +1107,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
@@ -978,7 +1129,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),
@@ -986,6 +1137,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
@@ -1014,7 +1174,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),
@@ -1031,8 +1191,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),
@@ -1041,7 +1203,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),
@@ -1085,7 +1247,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),
@@ -1093,8 +1255,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),
@@ -1103,7 +1267,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),
@@ -1111,8 +1275,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),
@@ -1134,11 +1300,11 @@ func (c *Client) GetClientLicenceConfig(etag string) (*Result, *AppError) {
}
}
-func (c *Client) GetMeLoggedIn() (*Result, *AppError) {
- if r, err := c.DoApiGet("/users/me_logged_in", "", ""); err != 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), MapFromJson(r.Body)}, nil
+ r.Header.Get(HEADER_ETAG_SERVER), InitialLoadFromJson(r.Body)}, nil
}
}
diff --git a/model/command.go b/model/command.go
index b854ae76a..4d5f7ace9 100644
--- a/model/command.go
+++ b/model/command.go
@@ -99,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) > 128 {
+ if len(o.Trigger) == 0 || len(o.Trigger) > 128 {
return NewLocAppError("Command.IsValid", "model.command.is_valid.trigger.app_error", nil, "")
}
diff --git a/model/command_test.go b/model/command_test.go
index d362d8f2c..2376e2ef7 100644
--- a/model/command_test.go
+++ b/model/command_test.go
@@ -19,63 +19,115 @@ func TestCommandJson(t *testing.T) {
}
func TestCommandIsValid(t *testing.T) {
- o := Command{}
+ o := Command{
+ Id: NewId(),
+ Token: NewId(),
+ CreateAt: GetMillis(),
+ UpdateAt: GetMillis(),
+ CreatorId: NewId(),
+ TeamId: NewId(),
+ Trigger: "trigger",
+ URL: "http://example.com",
+ Method: COMMAND_METHOD_GET,
+ DisplayName: "",
+ Description: "",
+ }
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ o.Id = ""
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
o.Id = NewId()
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ o.Token = ""
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
- o.CreateAt = GetMillis()
+ o.Token = NewId()
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ o.CreateAt = 0
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
- o.UpdateAt = GetMillis()
+ o.CreateAt = GetMillis()
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ o.UpdateAt = 0
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
- o.CreatorId = "123"
+ o.UpdateAt = GetMillis()
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ o.CreatorId = ""
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
o.CreatorId = NewId()
- if err := o.IsValid(); err == nil {
- t.Fatal("should be invalid")
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
}
- o.Token = "123"
+ o.TeamId = ""
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
- o.Token = NewId()
+ o.TeamId = NewId()
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ o.Trigger = ""
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
- o.TeamId = "123"
+ o.Trigger = strings.Repeat("1", 129)
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
- o.TeamId = NewId()
+ o.Trigger = strings.Repeat("1", 128)
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ o.URL = ""
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
- o.URL = "nowhere.com/"
+ o.URL = "1234"
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
- o.URL = "http://nowhere.com/"
+ o.URL = "https://example.com"
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ o.Method = "https://example.com"
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
}
@@ -85,6 +137,11 @@ func TestCommandIsValid(t *testing.T) {
t.Fatal(err)
}
+ o.Method = COMMAND_METHOD_POST
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
o.DisplayName = strings.Repeat("1", 65)
if err := o.IsValid(); err == nil {
t.Fatal("should be invalid")
diff --git a/model/config.go b/model/config.go
index 6803fe069..fd033c7cf 100644
--- a/model/config.go
+++ b/model/config.go
@@ -155,9 +155,9 @@ type TeamSettings struct {
MaxUsersPerTeam int
EnableTeamCreation bool
EnableUserCreation bool
+ EnableOpenServer *bool
RestrictCreationToDomains string
RestrictTeamNames *bool
- EnableTeamListing *bool
EnableCustomBrand *bool
CustomBrandText *string
}
@@ -180,6 +180,7 @@ type LdapSettings struct {
LastNameAttribute *string
EmailAttribute *string
UsernameAttribute *string
+ NicknameAttribute *string
IdAttribute *string
// Advanced
@@ -297,11 +298,6 @@ func (o *Config) SetDefaults() {
*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
@@ -312,6 +308,11 @@ func (o *Config) SetDefaults() {
*o.TeamSettings.CustomBrandText = ""
}
+ if o.TeamSettings.EnableOpenServer == nil {
+ o.TeamSettings.EnableOpenServer = new(bool)
+ *o.TeamSettings.EnableOpenServer = false
+ }
+
if o.EmailSettings.EnableSignInWithEmail == nil {
o.EmailSettings.EnableSignInWithEmail = new(bool)
@@ -476,6 +477,11 @@ func (o *Config) SetDefaults() {
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 {
diff --git a/model/gitlab.go b/model/gitlab.go
new file mode 100644
index 000000000..3dfb1016a
--- /dev/null
+++ b/model/gitlab.go
@@ -0,0 +1,8 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+const (
+ USER_AUTH_SERVICE_GITLAB = "gitlab"
+)
diff --git a/model/gitlab/gitlab.go b/model/gitlab/gitlab.go
index 3ca499976..7df29c139 100644
--- a/model/gitlab/gitlab.go
+++ b/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 {
@@ -51,7 +47,7 @@ func userFromGitLabUser(glu *GitLabUser) *model.User {
}
user.Email = glu.Email
user.AuthData = strconv.FormatInt(glu.Id, 10)
- user.AuthService = USER_AUTH_SERVICE_GITLAB
+ user.AuthService = model.USER_AUTH_SERVICE_GITLAB
return user
}
@@ -84,7 +80,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/model/initial_load.go b/model/initial_load.go
new file mode 100644
index 000000000..d7587e6d4
--- /dev/null
+++ b/model/initial_load.go
@@ -0,0 +1,40 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "io"
+)
+
+type InitialLoad struct {
+ User *User `json:"user"`
+ TeamMembers []*TeamMember `json:"team_members"`
+ Teams []*Team `json:"teams"`
+ DirectProfiles map[string]*User `json:"direct_profiles"`
+ Preferences Preferences `json:"preferences"`
+ ClientCfg map[string]string `json:"client_cfg"`
+ LicenseCfg map[string]string `json:"license_cfg"`
+ NoAccounts bool `json:"no_accounts"`
+}
+
+func (me *InitialLoad) ToJson() string {
+ b, err := json.Marshal(me)
+ if err != nil {
+ return ""
+ } else {
+ return string(b)
+ }
+}
+
+func InitialLoadFromJson(data io.Reader) *InitialLoad {
+ decoder := json.NewDecoder(data)
+ var o InitialLoad
+ err := decoder.Decode(&o)
+ if err == nil {
+ return &o
+ } else {
+ return nil
+ }
+}
diff --git a/model/initial_load_test.go b/model/initial_load_test.go
new file mode 100644
index 000000000..24a07e412
--- /dev/null
+++ b/model/initial_load_test.go
@@ -0,0 +1,20 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestInitialLoadJson(t *testing.T) {
+ u := &User{Id: NewId()}
+ o := InitialLoad{User: u}
+ json := o.ToJson()
+ ro := InitialLoadFromJson(strings.NewReader(json))
+
+ if o.User.Id != ro.User.Id {
+ t.Fatal("Ids do not match")
+ }
+}
diff --git a/model/password_recovery.go b/model/password_recovery.go
new file mode 100644
index 000000000..303d4a12e
--- /dev/null
+++ b/model/password_recovery.go
@@ -0,0 +1,37 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+const (
+ PASSWORD_RECOVERY_CODE_SIZE = 128
+ PASSWORD_RECOVER_EXPIRY_TIME = 1000 * 60 * 60 // 1 hour
+)
+
+type PasswordRecovery struct {
+ UserId string
+ Code string
+ CreateAt int64
+}
+
+func (p *PasswordRecovery) IsValid() *AppError {
+
+ if len(p.UserId) != 26 {
+ return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.user_id.app_error", nil, "")
+ }
+
+ if len(p.Code) != PASSWORD_RECOVERY_CODE_SIZE {
+ return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.code.app_error", nil, "")
+ }
+
+ if p.CreateAt == 0 {
+ return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.create_at.app_error", nil, "")
+ }
+
+ return nil
+}
+
+func (p *PasswordRecovery) PreSave() {
+ p.Code = NewRandomString(PASSWORD_RECOVERY_CODE_SIZE)
+ p.CreateAt = GetMillis()
+}
diff --git a/model/session.go b/model/session.go
index bf0d9531e..8a5eec74c 100644
--- a/model/session.go
+++ b/model/session.go
@@ -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/model/team.go b/model/team.go
index d95dea110..072e0a8c0 100644
--- a/model/team.go
+++ b/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 {
diff --git a/model/team_member.go b/model/team_member.go
new file mode 100644
index 000000000..80ca9f2a3
--- /dev/null
+++ b/model/team_member.go
@@ -0,0 +1,78 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "io"
+ "strings"
+)
+
+const (
+ ROLE_TEAM_ADMIN = "admin"
+)
+
+type TeamMember struct {
+ TeamId string `json:"team_id"`
+ UserId string `json:"user_id"`
+ Roles string `json:"roles"`
+}
+
+func (o *TeamMember) ToJson() string {
+ b, err := json.Marshal(o)
+ if err != nil {
+ return ""
+ } else {
+ return string(b)
+ }
+}
+
+func TeamMemberFromJson(data io.Reader) *TeamMember {
+ decoder := json.NewDecoder(data)
+ var o TeamMember
+ err := decoder.Decode(&o)
+ if err == nil {
+ return &o
+ } else {
+ return nil
+ }
+}
+
+func TeamMembersToJson(o []*TeamMember) string {
+ if b, err := json.Marshal(o); err != nil {
+ return "[]"
+ } else {
+ return string(b)
+ }
+}
+
+func TeamMembersFromJson(data io.Reader) []*TeamMember {
+ decoder := json.NewDecoder(data)
+ var o []*TeamMember
+ err := decoder.Decode(&o)
+ if err == nil {
+ return o
+ } else {
+ return nil
+ }
+}
+
+func (o *TeamMember) IsValid() *AppError {
+
+ if len(o.TeamId) != 26 {
+ return NewLocAppError("TeamMember.IsValid", "model.team_member.is_valid.team_id.app_error", nil, "")
+ }
+
+ if len(o.UserId) != 26 {
+ return NewLocAppError("TeamMember.IsValid", "model.team_member.is_valid.user_id.app_error", nil, "")
+ }
+
+ for _, role := range strings.Split(o.Roles, " ") {
+ if !(role == "" || role == ROLE_TEAM_ADMIN) {
+ return NewLocAppError("TeamMember.IsValid", "model.team_member.is_valid.role.app_error", nil, "role="+role)
+ }
+ }
+
+ return nil
+}
diff --git a/model/team_member_test.go b/model/team_member_test.go
new file mode 100644
index 000000000..d5b2e3b79
--- /dev/null
+++ b/model/team_member_test.go
@@ -0,0 +1,43 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestTeamMemberJson(t *testing.T) {
+ o := TeamMember{TeamId: NewId(), UserId: NewId()}
+ json := o.ToJson()
+ ro := TeamMemberFromJson(strings.NewReader(json))
+
+ if o.TeamId != ro.TeamId {
+ t.Fatal("Ids do not match")
+ }
+}
+
+func TestTeamMemberIsValid(t *testing.T) {
+ o := TeamMember{}
+
+ if err := o.IsValid(); err == nil {
+ t.Fatal("should be invalid")
+ }
+
+ o.TeamId = NewId()
+ if err := o.IsValid(); err == nil {
+ t.Fatal("should be invalid")
+ }
+
+ o.UserId = NewId()
+ o.Roles = "blahblah"
+ if err := o.IsValid(); err == nil {
+ t.Fatal("should be invalid")
+ }
+
+ o.Roles = ""
+ if err := o.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/model/user.go b/model/user.go
index 173fe2b4e..f43fc2089 100644
--- a/model/user.go
+++ b/model/user.go
@@ -15,7 +15,6 @@ 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
@@ -28,6 +27,7 @@ const (
DEFAULT_LOCALE = "en"
USER_AUTH_SERVICE_EMAIL = "email"
USER_AUTH_SERVICE_USERNAME = "username"
+ MIN_PASSWORD_LENGTH = 5
)
type User struct {
@@ -35,7 +35,6 @@ 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"`
@@ -76,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)
}
@@ -228,6 +223,7 @@ func (u *User) IsAway() bool {
func (u *User) Sanitize(options map[string]bool) {
u.Password = ""
u.AuthData = ""
+ u.MfaSecret = ""
if len(options) != 0 && !options["email"] {
u.Email = ""
@@ -246,6 +242,8 @@ func (u *User) ClearNonProfileFields() {
u.Password = ""
u.AuthData = ""
u.AuthService = ""
+ u.MfaActive = false
+ u.MfaSecret = ""
u.EmailVerified = false
u.LastPingAt = 0
u.AllowMarketing = false
@@ -301,7 +299,7 @@ func (u *User) GetDisplayName() string {
}
}
-func IsValidRoles(userRoles string) bool {
+func IsValidUserRoles(userRoles string) bool {
roles := strings.Split(userRoles, " ")
@@ -319,10 +317,6 @@ func isValidRole(role string) bool {
return true
}
- if role == ROLE_TEAM_ADMIN {
- return true
- }
-
if role == ROLE_SYSTEM_ADMIN {
return true
}
@@ -351,8 +345,8 @@ func IsInRole(userRoles string, inRole string) bool {
return false
}
-func (u *User) IsSSOUser() bool {
- if len(u.AuthData) != 0 && len(u.AuthService) != 0 && u.AuthService != USER_AUTH_SERVICE_LDAP {
+func (u *User) IsOAuthUser() bool {
+ if u.AuthService == USER_AUTH_SERVICE_GITLAB {
return true
}
return false
diff --git a/model/user_test.go b/model/user_test.go
index 662ae35a6..286c92a66 100644
--- a/model/user_test.go
+++ b/model/user_test.go
@@ -63,11 +63,6 @@ func TestUserIsValid(t *testing.T) {
t.Fatal()
}
- user.TeamId = NewId()
- if err := user.IsValid(); err == nil {
- t.Fatal()
- }
-
user.Username = NewId() + "^hello#"
if err := user.IsValid(); err == nil {
t.Fatal()
@@ -195,11 +190,11 @@ func TestCleanUsername(t *testing.T) {
func TestRoles(t *testing.T) {
- if !IsValidRoles("admin") {
+ if IsValidUserRoles("admin") {
t.Fatal()
}
- if IsValidRoles("junk") {
+ if IsValidUserRoles("junk") {
t.Fatal()
}
diff --git a/model/utils.go b/model/utils.go
index bb02f345d..03215490d 100644
--- a/model/utils.go
+++ b/model/utils.go
@@ -41,12 +41,10 @@ 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)
}
}
@@ -83,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
diff --git a/model/version.go b/model/version.go
index e9a2c2bd0..4a47f06ef 100644
--- a/model/version.go
+++ b/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",