summaryrefslogtreecommitdiffstats
path: root/api4
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2018-03-13 13:36:23 +0000
committerGeorge Goldberg <george@gberg.me>2018-03-13 13:36:23 +0000
commitfadcdd271a68b38571b75d1d38ab023f940ac83a (patch)
tree7f413edd35401b54b2f4eb4a687da1ac273bcd4b /api4
parentb66e4bc932ed76c1cfd2b5f4ec0cfce70cd9fbb4 (diff)
parentf2d26801b9647715fb43af873354d8def753868b (diff)
downloadchat-fadcdd271a68b38571b75d1d38ab023f940ac83a.tar.gz
chat-fadcdd271a68b38571b75d1d38ab023f940ac83a.tar.bz2
chat-fadcdd271a68b38571b75d1d38ab023f940ac83a.zip
Merge branch 'master' into advanced-permissions-phase-1
Diffstat (limited to 'api4')
-rw-r--r--api4/apitestlib.go43
-rw-r--r--api4/channel_test.go3
-rw-r--r--api4/compliance.go7
-rw-r--r--api4/system.go10
-rw-r--r--api4/user.go14
-rw-r--r--api4/user_test.go143
-rw-r--r--api4/webhook.go1
7 files changed, 175 insertions, 46 deletions
diff --git a/api4/apitestlib.go b/api4/apitestlib.go
index a788d4311..2de031f9b 100644
--- a/api4/apitestlib.go
+++ b/api4/apitestlib.go
@@ -468,6 +468,22 @@ func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) {
utils.EnableDebugLogForTest()
}
+func (me *TestHelper) AddUserToChannel(user *model.User, channel *model.Channel) *model.ChannelMember {
+ utils.DisableDebugLogForTest()
+
+ member, err := me.App.AddUserToChannel(user, channel)
+ if err != nil {
+ l4g.Error(err.Error())
+ l4g.Close()
+ time.Sleep(time.Second)
+ panic(err)
+ }
+
+ utils.EnableDebugLogForTest()
+
+ return member
+}
+
func (me *TestHelper) GenerateTestEmail() string {
if me.App.Config().EmailSettings.SMTPServer != "dockerhost" && os.Getenv("CI_INBUCKET_PORT") == "" {
return strings.ToLower("success+" + model.NewId() + "@simulator.amazonses.com")
@@ -511,18 +527,6 @@ func CheckUserSanitization(t *testing.T, user *model.User) {
}
}
-func CheckTeamSanitization(t *testing.T, team *model.Team) {
- t.Helper()
-
- if team.Email != "" {
- t.Fatal("email wasn't blank")
- }
-
- if team.AllowedDomains != "" {
- t.Fatal("'allowed domains' wasn't blank")
- }
-}
-
func CheckEtag(t *testing.T, data interface{}, resp *model.Response) {
t.Helper()
@@ -670,21 +674,6 @@ func CheckInternalErrorStatus(t *testing.T, resp *model.Response) {
}
}
-func CheckPayLoadTooLargeStatus(t *testing.T, resp *model.Response) {
- t.Helper()
-
- if resp.Error == nil {
- t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusRequestEntityTooLarge))
- return
- }
-
- if resp.StatusCode != http.StatusRequestEntityTooLarge {
- t.Log("actual: " + strconv.Itoa(resp.StatusCode))
- t.Log("expected: " + strconv.Itoa(http.StatusRequestEntityTooLarge))
- t.Fatal("wrong status code")
- }
-}
-
func readTestFile(name string) ([]byte, error) {
path, _ := utils.FindDir("tests")
file, err := os.Open(path + "/" + name)
diff --git a/api4/channel_test.go b/api4/channel_test.go
index 1b74ea880..b9ee5bc7d 100644
--- a/api4/channel_test.go
+++ b/api4/channel_test.go
@@ -13,7 +13,6 @@ import (
"testing"
"github.com/mattermost/mattermost-server/model"
- "github.com/mattermost/mattermost-server/store/sqlstore"
)
func TestCreateChannel(t *testing.T) {
@@ -874,7 +873,7 @@ func TestDeleteChannel(t *testing.T) {
// successful delete by channel admin
th.MakeUserChannelAdmin(user, publicChannel6)
th.MakeUserChannelAdmin(user, privateChannel7)
- sqlstore.ClearChannelCaches()
+ th.App.Srv.Store.Channel().ClearCaches()
_, resp = Client.DeleteChannel(publicChannel6.Id)
CheckNoError(t, resp)
diff --git a/api4/compliance.go b/api4/compliance.go
index 71f0fa81d..4035afb77 100644
--- a/api4/compliance.go
+++ b/api4/compliance.go
@@ -7,8 +7,8 @@ import (
"net/http"
"strconv"
+ "github.com/avct/uasurfer"
"github.com/mattermost/mattermost-server/model"
- "github.com/mssola/user_agent"
)
func (api *API) InitCompliance() {
@@ -108,12 +108,11 @@ func downloadComplianceReport(c *Context, w http.ResponseWriter, r *http.Request
w.Header().Del("Content-Type") // Content-Type will be set automatically by the http writer
// attach extra headers to trigger a download on IE, Edge, and Safari
- ua := user_agent.New(r.UserAgent())
- bname, _ := ua.Browser()
+ ua := uasurfer.Parse(r.UserAgent())
w.Header().Set("Content-Disposition", "attachment;filename=\""+job.JobName()+".zip\"")
- if bname == "Edge" || bname == "Internet Explorer" || bname == "Safari" {
+ if ua.Browser.Name == uasurfer.BrowserIE || ua.Browser.Name == uasurfer.BrowserSafari {
// trim off anything before the final / so we just get the file's name
w.Header().Set("Content-Type", "application/octet-stream")
}
diff --git a/api4/system.go b/api4/system.go
index aab65bf20..c1541f0b5 100644
--- a/api4/system.go
+++ b/api4/system.go
@@ -8,7 +8,6 @@ import (
"io"
"net/http"
"runtime"
- "strconv"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/model"
@@ -247,14 +246,7 @@ func getClientConfig(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- respCfg := map[string]string{}
- for k, v := range c.App.ClientConfig() {
- respCfg[k] = v
- }
-
- respCfg["NoAccounts"] = strconv.FormatBool(c.App.IsFirstUserAccount())
-
- w.Write([]byte(model.MapToJson(respCfg)))
+ w.Write([]byte(model.MapToJson(c.App.ClientConfigWithNoAccounts())))
}
func getClientLicense(c *Context, w http.ResponseWriter, r *http.Request) {
diff --git a/api4/user.go b/api4/user.go
index f82a6e3d5..8f8f08c75 100644
--- a/api4/user.go
+++ b/api4/user.go
@@ -290,16 +290,21 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if sort != "" && sort != "last_activity_at" && sort != "create_at" {
+ if sort != "" && sort != "last_activity_at" && sort != "create_at" && sort != "status" {
c.SetInvalidUrlParam("sort")
return
}
// Currently only supports sorting on a team
+ // or sort="status" on inChannelId
if (sort == "last_activity_at" || sort == "create_at") && (inTeamId == "" || notInTeamId != "" || inChannelId != "" || notInChannelId != "" || withoutTeam != "") {
c.SetInvalidUrlParam("sort")
return
}
+ if sort == "status" && inChannelId == "" {
+ c.SetInvalidUrlParam("sort")
+ return
+ }
var profiles []*model.User
var err *model.AppError
@@ -355,8 +360,11 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
return
}
-
- profiles, err = c.App.GetUsersInChannelPage(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
+ if sort == "status" {
+ profiles, err = c.App.GetUsersInChannelPageByStatus(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
+ } else {
+ profiles, err = c.App.GetUsersInChannelPage(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
+ }
} else {
// No permission check required
diff --git a/api4/user_test.go b/api4/user_test.go
index 4613a8ea9..f04cd6ab2 100644
--- a/api4/user_test.go
+++ b/api4/user_test.go
@@ -2650,3 +2650,146 @@ func TestUserAccessTokenDisableConfig(t *testing.T) {
_, resp = Client.GetMe("")
CheckNoError(t, resp)
}
+
+func TestGetUsersByStatus(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ team, err := th.App.CreateTeam(&model.Team{
+ DisplayName: "dn_" + model.NewId(),
+ Name: GenerateTestTeamName(),
+ Email: th.GenerateTestEmail(),
+ Type: model.TEAM_OPEN,
+ })
+ if err != nil {
+ t.Fatalf("failed to create team: %v", err)
+ }
+
+ channel, err := th.App.CreateChannel(&model.Channel{
+ DisplayName: "dn_" + model.NewId(),
+ Name: "name_" + model.NewId(),
+ Type: model.CHANNEL_OPEN,
+ TeamId: team.Id,
+ CreatorId: model.NewId(),
+ }, false)
+ if err != nil {
+ t.Fatalf("failed to create channel: %v", err)
+ }
+
+ createUserWithStatus := func(username string, status string) *model.User {
+ id := model.NewId()
+
+ user, err := th.App.CreateUser(&model.User{
+ Email: "success+" + id + "@simulator.amazonses.com",
+ Username: "un_" + username + "_" + id,
+ Nickname: "nn_" + id,
+ Password: "Password1",
+ })
+ if err != nil {
+ t.Fatalf("failed to create user: %v", err)
+ }
+
+ th.LinkUserToTeam(user, team)
+ th.AddUserToChannel(user, channel)
+
+ th.App.SaveAndBroadcastStatus(&model.Status{
+ UserId: user.Id,
+ Status: status,
+ Manual: true,
+ })
+
+ return user
+ }
+
+ // Creating these out of order in case that affects results
+ offlineUser1 := createUserWithStatus("offline1", model.STATUS_OFFLINE)
+ offlineUser2 := createUserWithStatus("offline2", model.STATUS_OFFLINE)
+ awayUser1 := createUserWithStatus("away1", model.STATUS_AWAY)
+ awayUser2 := createUserWithStatus("away2", model.STATUS_AWAY)
+ onlineUser1 := createUserWithStatus("online1", model.STATUS_ONLINE)
+ onlineUser2 := createUserWithStatus("online2", model.STATUS_ONLINE)
+ dndUser1 := createUserWithStatus("dnd1", model.STATUS_DND)
+ dndUser2 := createUserWithStatus("dnd2", model.STATUS_DND)
+
+ client := th.CreateClient()
+ if _, resp := client.Login(onlineUser2.Username, "Password1"); resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ t.Run("sorting by status then alphabetical", func(t *testing.T) {
+ usersByStatus, resp := client.GetUsersInChannelByStatus(channel.Id, 0, 8, "")
+ if resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ expectedUsersByStatus := []*model.User{
+ onlineUser1,
+ onlineUser2,
+ awayUser1,
+ awayUser2,
+ dndUser1,
+ dndUser2,
+ offlineUser1,
+ offlineUser2,
+ }
+
+ if len(usersByStatus) != len(expectedUsersByStatus) {
+ t.Fatalf("received only %v users, expected %v", len(usersByStatus), len(expectedUsersByStatus))
+ }
+
+ for i := range usersByStatus {
+ if usersByStatus[i].Id != expectedUsersByStatus[i].Id {
+ t.Fatalf("received user %v at index %v, expected %v", usersByStatus[i].Username, i, expectedUsersByStatus[i].Username)
+ }
+ }
+ })
+
+ t.Run("paging", func(t *testing.T) {
+ usersByStatus, resp := client.GetUsersInChannelByStatus(channel.Id, 0, 3, "")
+ if resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ if len(usersByStatus) != 3 {
+ t.Fatal("received too many users")
+ }
+
+ if usersByStatus[0].Id != onlineUser1.Id && usersByStatus[1].Id != onlineUser2.Id {
+ t.Fatal("expected to receive online users first")
+ }
+
+ if usersByStatus[2].Id != awayUser1.Id {
+ t.Fatal("expected to receive away users second")
+ }
+
+ usersByStatus, resp = client.GetUsersInChannelByStatus(channel.Id, 1, 3, "")
+ if resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ if usersByStatus[0].Id != awayUser2.Id {
+ t.Fatal("expected to receive away users second")
+ }
+
+ if usersByStatus[1].Id != dndUser1.Id && usersByStatus[2].Id != dndUser2.Id {
+ t.Fatal("expected to receive dnd users third")
+ }
+
+ usersByStatus, resp = client.GetUsersInChannelByStatus(channel.Id, 1, 4, "")
+ if resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ if len(usersByStatus) != 4 {
+ t.Fatal("received too many users")
+ }
+
+ if usersByStatus[0].Id != dndUser1.Id && usersByStatus[1].Id != dndUser2.Id {
+ t.Fatal("expected to receive dnd users third")
+ }
+
+ if usersByStatus[2].Id != offlineUser1.Id && usersByStatus[3].Id != offlineUser2.Id {
+ t.Fatal("expected to receive offline users last")
+ }
+ })
+}
diff --git a/api4/webhook.go b/api4/webhook.go
index dcbf6c2af..52c4ea331 100644
--- a/api4/webhook.go
+++ b/api4/webhook.go
@@ -522,7 +522,6 @@ func commandWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
}
func decodePayload(payload io.Reader) (*model.IncomingWebhookRequest, *model.AppError) {
- decodeError := &model.AppError{}
incomingWebhookPayload, decodeError := model.IncomingWebhookRequestFromJson(payload)
if decodeError != nil {