Skip to content

Commit 8209b6b

Browse files
MM-54366 Check guest access to other members (#4871) (#4884) (#4888)
* check guest access to other members * lint fix (cherry picked from commit 134422d) Co-authored-by: Scott Bishel <[email protected]> (cherry picked from commit c120e12)
1 parent 4c579d3 commit 8209b6b

File tree

5 files changed

+127
-15
lines changed

5 files changed

+127
-15
lines changed

server/api/users.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,25 @@ func (a *API) handleGetUsersList(w http.ResponseWriter, r *http.Request) {
9393
session := ctx.Value(sessionContextKey).(*model.Session)
9494
isSystemAdmin := a.permissions.HasPermissionTo(session.UserID, model.PermissionManageSystem)
9595

96+
sanitizedUsers := make([]*model.User, 0)
9697
for _, user := range users {
98+
canSeeUser, err2 := a.app.CanSeeUser(session.UserID, user.ID)
99+
if err2 != nil {
100+
a.errorResponse(w, r, err2)
101+
return
102+
}
103+
if !canSeeUser {
104+
continue
105+
}
97106
if user.ID == session.UserID {
98107
user.Sanitize(map[string]bool{})
99108
} else {
100109
a.app.SanitizeProfile(user, isSystemAdmin)
101110
}
111+
sanitizedUsers = append(sanitizedUsers, user)
102112
}
103113

104-
usersList, err := json.Marshal(users)
114+
usersList, err := json.Marshal(sanitizedUsers)
105115
if err != nil {
106116
a.errorResponse(w, r, err)
107117
return

server/client/client.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,26 @@ func (c *Client) GetUser(id string) (*model.User, *Response) {
634634
return user, BuildResponse(r)
635635
}
636636

637+
func (c *Client) GetUserList(ids []string) ([]model.User, *Response) {
638+
r, err := c.DoAPIPost("/users", toJSON(ids))
639+
if err != nil {
640+
return nil, BuildErrorResponse(r, err)
641+
}
642+
defer closeBody(r)
643+
644+
requestBody, err := io.ReadAll(r.Body)
645+
if err != nil {
646+
return nil, BuildErrorResponse(r, err)
647+
}
648+
649+
var users []model.User
650+
err = json.Unmarshal(requestBody, &users)
651+
if err != nil {
652+
return nil, BuildErrorResponse(r, err)
653+
}
654+
return users, BuildResponse(r)
655+
}
656+
637657
func (c *Client) GetUserChangePasswordRoute(id string) string {
638658
return fmt.Sprintf("/users/%s/changepassword", id)
639659
}

server/integrationtests/pluginteststore.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ func (s *PluginTestStore) GetUserByID(userID string) (*model.User, error) {
127127
return user, nil
128128
}
129129

130+
func (s *PluginTestStore) GetUsersList(userIDs []string, showEmail, showName bool) ([]*model.User, error) {
131+
var users []*model.User
132+
for _, id := range userIDs {
133+
user := s.users[id]
134+
if user != nil {
135+
users = append(users, user)
136+
}
137+
}
138+
return users, nil
139+
}
140+
130141
func (s *PluginTestStore) GetUserByEmail(email string) (*model.User, error) {
131142
for _, user := range s.users {
132143
if user.Email == email {

server/integrationtests/user_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,79 @@ func TestGetUser(t *testing.T) {
164164
})
165165
}
166166

167+
func TestGetUserList(t *testing.T) {
168+
th := SetupTestHelperPluginMode(t)
169+
defer th.TearDown()
170+
clients := setupClients(th)
171+
th.Client = clients.TeamMember
172+
th.Client2 = clients.Editor
173+
174+
me, resp := th.Client.GetMe()
175+
require.NoError(t, resp.Error)
176+
require.NotNil(t, me)
177+
178+
userID1 := me.ID
179+
userID2 := th.GetUser2().ID
180+
181+
// Admin user should return both
182+
returnUsers, resp := clients.Admin.GetUserList([]string{userID1, userID2})
183+
require.NoError(t, resp.Error)
184+
require.NotNil(t, returnUsers)
185+
require.Equal(t, 2, len(returnUsers))
186+
187+
// Guest user should return none
188+
returnUsers2, resp := clients.Guest.GetUserList([]string{userID1, userID2})
189+
require.NoError(t, resp.Error)
190+
require.NotNil(t, returnUsers2)
191+
require.Equal(t, 0, len(returnUsers2))
192+
193+
newBoard := &model.Board{
194+
Title: "title",
195+
Type: model.BoardTypeOpen,
196+
TeamID: testTeamID,
197+
}
198+
board, err := th.Server.App().CreateBoard(newBoard, userID1, true)
199+
require.NoError(t, err)
200+
201+
// add Guest as board member
202+
newGuestMember := &model.BoardMember{
203+
UserID: userGuestID,
204+
BoardID: board.ID,
205+
SchemeViewer: true,
206+
SchemeCommenter: true,
207+
SchemeEditor: true,
208+
SchemeAdmin: false,
209+
}
210+
guestMember, err := th.Server.App().AddMemberToBoard(newGuestMember)
211+
require.NoError(t, err)
212+
require.NotNil(t, guestMember)
213+
214+
// Guest user should now return one of members
215+
guestUsers, resp := clients.Guest.GetUserList([]string{th.GetUser1().ID, th.GetUser2().ID})
216+
require.NoError(t, resp.Error)
217+
require.NotNil(t, guestUsers)
218+
require.Equal(t, 1, len(guestUsers))
219+
220+
// add other user as board member
221+
newBoardMember := &model.BoardMember{
222+
UserID: userID2,
223+
BoardID: board.ID,
224+
SchemeViewer: true,
225+
SchemeCommenter: true,
226+
SchemeEditor: true,
227+
SchemeAdmin: false,
228+
}
229+
newMember, err := th.Server.App().AddMemberToBoard(newBoardMember)
230+
require.NoError(t, err)
231+
require.NotNil(t, newMember)
232+
233+
// Guest user should now return both
234+
guestUsers, resp = clients.Guest.GetUserList([]string{th.GetUser1().ID, th.GetUser2().ID})
235+
require.NoError(t, resp.Error)
236+
require.NotNil(t, guestUsers)
237+
require.Equal(t, 2, len(guestUsers))
238+
}
239+
167240
func TestUserChangePassword(t *testing.T) {
168241
th := SetupTestHelper(t).Start()
169242
defer th.TearDown()

server/services/store/mattermostauthlayer/mattermostauthlayer.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,17 +1297,16 @@ func (s *MattermostAuthLayer) CanSeeUser(seerID string, seenID string) (bool, er
12971297

12981298
query := s.getQueryBuilder().
12991299
Select("1").
1300-
From(s.tablePrefix + "board_members AS BM1").
1301-
Join(s.tablePrefix + "board_members AS BM2 ON BM1.BoardID=BM2.BoardID").
1302-
LeftJoin("Bots b ON ( b.UserId = u.id )").
1300+
From(s.tablePrefix + "board_members AS bm1").
1301+
Join(s.tablePrefix + "board_members AS bm2 ON bm1.board_id=bm2.board_id").
13031302
Where(sq.Or{
13041303
sq.And{
1305-
sq.Eq{"BM1.UserID": seerID},
1306-
sq.Eq{"BM2.UserID": seenID},
1304+
sq.Eq{"bm1.user_id": seerID},
1305+
sq.Eq{"bm2.user_id": seenID},
13071306
},
13081307
sq.And{
1309-
sq.Eq{"BM1.UserID": seenID},
1310-
sq.Eq{"BM2.UserID": seerID},
1308+
sq.Eq{"bm1.user_id": seenID},
1309+
sq.Eq{"bm2.user_id": seerID},
13111310
},
13121311
}).Limit(1)
13131312

@@ -1323,17 +1322,16 @@ func (s *MattermostAuthLayer) CanSeeUser(seerID string, seenID string) (bool, er
13231322

13241323
query = s.getQueryBuilder().
13251324
Select("1").
1326-
From("ChannelMembers AS CM1").
1327-
Join("ChannelMembers AS CM2 ON CM1.BoardID=CM2.BoardID").
1328-
LeftJoin("Bots b ON ( b.UserId = u.id )").
1325+
From("channelmembers AS cm1").
1326+
Join("channelmembers AS cm2 ON cm1.channelid=cm2.channelid").
13291327
Where(sq.Or{
13301328
sq.And{
1331-
sq.Eq{"CM1.UserID": seerID},
1332-
sq.Eq{"CM2.UserID": seenID},
1329+
sq.Eq{"cm1.userid": seerID},
1330+
sq.Eq{"cm2.userid": seenID},
13331331
},
13341332
sq.And{
1335-
sq.Eq{"CM1.UserID": seenID},
1336-
sq.Eq{"CM2.UserID": seerID},
1333+
sq.Eq{"cm1.userid": seenID},
1334+
sq.Eq{"cm2.userid": seerID},
13371335
},
13381336
}).Limit(1)
13391337

0 commit comments

Comments
 (0)