Skip to content

Commit 46207a3

Browse files
authored
[MM-27130] Add local implementations for get user related endpoints (mattermost#15070)
Automatic Merge
1 parent b660e21 commit 46207a3

File tree

2 files changed

+324
-134
lines changed

2 files changed

+324
-134
lines changed

api4/user_local.go

+182-3
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,21 @@ package api4
55

66
import (
77
"net/http"
8+
"strconv"
89

910
"github.com/mattermost/mattermost-server/v5/audit"
1011
"github.com/mattermost/mattermost-server/v5/model"
12+
"github.com/mattermost/mattermost-server/v5/store"
1113
)
1214

1315
func (api *API) InitUserLocal() {
14-
api.BaseRoutes.Users.Handle("", api.ApiLocal(getUsers)).Methods("GET")
16+
api.BaseRoutes.Users.Handle("", api.ApiLocal(localGetUsers)).Methods("GET")
1517
api.BaseRoutes.Users.Handle("", api.ApiLocal(localPermanentDeleteAllUsers)).Methods("DELETE")
1618
api.BaseRoutes.Users.Handle("", api.ApiLocal(createUser)).Methods("POST")
1719
api.BaseRoutes.Users.Handle("/password/reset/send", api.ApiLocal(sendPasswordReset)).Methods("POST")
18-
api.BaseRoutes.Users.Handle("/ids", api.ApiLocal(getUsersByIds)).Methods("POST")
20+
api.BaseRoutes.Users.Handle("/ids", api.ApiLocal(localGetUsersByIds)).Methods("POST")
1921

20-
api.BaseRoutes.User.Handle("", api.ApiLocal(getUser)).Methods("GET")
22+
api.BaseRoutes.User.Handle("", api.ApiLocal(localGetUser)).Methods("GET")
2123
api.BaseRoutes.User.Handle("", api.ApiLocal(updateUser)).Methods("PUT")
2224
api.BaseRoutes.User.Handle("", api.ApiLocal(localDeleteUser)).Methods("DELETE")
2325
api.BaseRoutes.User.Handle("/roles", api.ApiLocal(updateUserRoles)).Methods("PUT")
@@ -34,6 +36,171 @@ func (api *API) InitUserLocal() {
3436
api.BaseRoutes.User.Handle("/tokens", api.ApiLocal(createUserAccessToken)).Methods("POST")
3537
}
3638

39+
func localGetUsers(c *Context, w http.ResponseWriter, r *http.Request) {
40+
inTeamId := r.URL.Query().Get("in_team")
41+
notInTeamId := r.URL.Query().Get("not_in_team")
42+
inChannelId := r.URL.Query().Get("in_channel")
43+
notInChannelId := r.URL.Query().Get("not_in_channel")
44+
groupConstrained := r.URL.Query().Get("group_constrained")
45+
withoutTeam := r.URL.Query().Get("without_team")
46+
inactive := r.URL.Query().Get("inactive")
47+
role := r.URL.Query().Get("role")
48+
sort := r.URL.Query().Get("sort")
49+
50+
if len(notInChannelId) > 0 && len(inTeamId) == 0 {
51+
c.SetInvalidUrlParam("team_id")
52+
return
53+
}
54+
55+
if sort != "" && sort != "last_activity_at" && sort != "create_at" && sort != "status" {
56+
c.SetInvalidUrlParam("sort")
57+
return
58+
}
59+
60+
// Currently only supports sorting on a team
61+
// or sort="status" on inChannelId
62+
if (sort == "last_activity_at" || sort == "create_at") && (inTeamId == "" || notInTeamId != "" || inChannelId != "" || notInChannelId != "" || withoutTeam != "") {
63+
c.SetInvalidUrlParam("sort")
64+
return
65+
}
66+
if sort == "status" && inChannelId == "" {
67+
c.SetInvalidUrlParam("sort")
68+
return
69+
}
70+
71+
withoutTeamBool, _ := strconv.ParseBool(withoutTeam)
72+
groupConstrainedBool, _ := strconv.ParseBool(groupConstrained)
73+
inactiveBool, _ := strconv.ParseBool(inactive)
74+
75+
userGetOptions := &model.UserGetOptions{
76+
InTeamId: inTeamId,
77+
InChannelId: inChannelId,
78+
NotInTeamId: notInTeamId,
79+
NotInChannelId: notInChannelId,
80+
GroupConstrained: groupConstrainedBool,
81+
WithoutTeam: withoutTeamBool,
82+
Inactive: inactiveBool,
83+
Role: role,
84+
Sort: sort,
85+
Page: c.Params.Page,
86+
PerPage: c.Params.PerPage,
87+
ViewRestrictions: nil,
88+
}
89+
90+
var err *model.AppError
91+
var profiles []*model.User
92+
etag := ""
93+
94+
if withoutTeamBool, _ := strconv.ParseBool(withoutTeam); withoutTeamBool {
95+
profiles, err = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin())
96+
} else if len(notInChannelId) > 0 {
97+
profiles, err = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil)
98+
} else if len(notInTeamId) > 0 {
99+
etag = c.App.GetUsersNotInTeamEtag(inTeamId, "")
100+
if c.HandleEtag(etag, "Get Users Not in Team", w, r) {
101+
return
102+
}
103+
104+
profiles, err = c.App.GetUsersNotInTeamPage(notInTeamId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil)
105+
} else if len(inTeamId) > 0 {
106+
if sort == "last_activity_at" {
107+
profiles, err = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil)
108+
} else if sort == "create_at" {
109+
profiles, err = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil)
110+
} else {
111+
etag = c.App.GetUsersInTeamEtag(inTeamId, "")
112+
if c.HandleEtag(etag, "Get Users in Team", w, r) {
113+
return
114+
}
115+
profiles, err = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin())
116+
}
117+
} else if len(inChannelId) > 0 {
118+
if sort == "status" {
119+
profiles, err = c.App.GetUsersInChannelPageByStatus(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
120+
} else {
121+
profiles, err = c.App.GetUsersInChannelPage(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
122+
}
123+
} else {
124+
profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin())
125+
}
126+
127+
if err != nil {
128+
c.Err = err
129+
return
130+
}
131+
132+
if len(etag) > 0 {
133+
w.Header().Set(model.HEADER_ETAG_SERVER, etag)
134+
}
135+
w.Write([]byte(model.UserListToJson(profiles)))
136+
}
137+
138+
func localGetUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
139+
userIds := model.ArrayFromJson(r.Body)
140+
141+
if len(userIds) == 0 {
142+
c.SetInvalidParam("user_ids")
143+
return
144+
}
145+
146+
sinceString := r.URL.Query().Get("since")
147+
148+
options := &store.UserGetByIdsOpts{
149+
IsAdmin: c.IsSystemAdmin(),
150+
}
151+
152+
if len(sinceString) > 0 {
153+
since, parseError := strconv.ParseInt(sinceString, 10, 64)
154+
if parseError != nil {
155+
c.SetInvalidParam("since")
156+
return
157+
}
158+
options.Since = since
159+
}
160+
161+
users, err := c.App.GetUsersByIds(userIds, options)
162+
if err != nil {
163+
c.Err = err
164+
return
165+
}
166+
167+
w.Write([]byte(model.UserListToJson(users)))
168+
}
169+
170+
func localGetUser(c *Context, w http.ResponseWriter, r *http.Request) {
171+
c.RequireUserId()
172+
if c.Err != nil {
173+
return
174+
}
175+
176+
user, err := c.App.GetUser(c.Params.UserId)
177+
if err != nil {
178+
c.Err = err
179+
return
180+
}
181+
182+
userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
183+
if err != nil && err.StatusCode != http.StatusNotFound {
184+
c.Err = err
185+
return
186+
}
187+
188+
if userTermsOfService != nil {
189+
user.TermsOfServiceId = userTermsOfService.TermsOfServiceId
190+
user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
191+
}
192+
193+
etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
194+
195+
if c.HandleEtag(etag, "Get User", w, r) {
196+
return
197+
}
198+
199+
c.App.SanitizeProfile(user, c.IsSystemAdmin())
200+
w.Header().Set(model.HEADER_ETAG_SERVER, etag)
201+
w.Write([]byte(user.ToJson()))
202+
}
203+
37204
func localDeleteUser(c *Context, w http.ResponseWriter, r *http.Request) {
38205
c.RequireUserId()
39206
if c.Err != nil {
@@ -87,9 +254,21 @@ func localGetUserByUsername(c *Context, w http.ResponseWriter, r *http.Request)
87254

88255
user, err := c.App.GetUserByUsername(c.Params.Username)
89256
if err != nil {
257+
c.Err = err
90258
return
91259
}
92260

261+
userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
262+
if err != nil && err.StatusCode != http.StatusNotFound {
263+
c.Err = err
264+
return
265+
}
266+
267+
if userTermsOfService != nil {
268+
user.TermsOfServiceId = userTermsOfService.TermsOfServiceId
269+
user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
270+
}
271+
93272
etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
94273

95274
if c.HandleEtag(etag, "Get User", w, r) {

0 commit comments

Comments
 (0)