summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRick Batka <rick.batka@gmail.com>2017-10-16 23:50:31 -0400
committerChris <ccbrown112@gmail.com>2017-10-16 20:50:31 -0700
commit89dc3cb126ba46b486997c433adfdf34982fcc81 (patch)
tree57ed40c1c193aeec17cea8ab7f7e52d63e44fad4
parenta649602fc373615665ae2eaec95a4e9063eb699d (diff)
downloadchat-89dc3cb126ba46b486997c433adfdf34982fcc81.tar.gz
chat-89dc3cb126ba46b486997c433adfdf34982fcc81.tar.bz2
chat-89dc3cb126ba46b486997c433adfdf34982fcc81.zip
[PLT-7396] Add the ability to revoke user sessions in System Console > Users #7493 (#7623)
* add endpoint and tests for revoking all sessions for a user * fix failing test build
-rw-r--r--api4/user.go20
-rw-r--r--api4/user_test.go45
-rw-r--r--model/client4.go10
3 files changed, 75 insertions, 0 deletions
diff --git a/api4/user.go b/api4/user.go
index ae1b2418c..07f223bd6 100644
--- a/api4/user.go
+++ b/api4/user.go
@@ -53,6 +53,7 @@ func (api *API) InitUser() {
api.BaseRoutes.User.Handle("/sessions", api.ApiSessionRequired(getSessions)).Methods("GET")
api.BaseRoutes.User.Handle("/sessions/revoke", api.ApiSessionRequired(revokeSession)).Methods("POST")
+ api.BaseRoutes.User.Handle("/sessions/revoke/all", api.ApiSessionRequired(revokeAllSessionsForUser)).Methods("POST")
api.BaseRoutes.Users.Handle("/sessions/device", api.ApiSessionRequired(attachDeviceId)).Methods("PUT")
api.BaseRoutes.User.Handle("/audits", api.ApiSessionRequired(getUserAudits)).Methods("GET")
@@ -986,6 +987,25 @@ func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) {
ReturnStatusOK(w)
}
+func revokeAllSessionsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireUserId()
+ if c.Err != nil {
+ return
+ }
+
+ if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
+ c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
+ return
+ }
+
+ if err := c.App.RevokeAllSessions(c.Params.UserId); err != nil {
+ c.Err = err
+ return
+ }
+
+ ReturnStatusOK(w)
+}
+
func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
props := model.MapFromJson(r.Body)
diff --git a/api4/user_test.go b/api4/user_test.go
index 0913819cc..3a1579e14 100644
--- a/api4/user_test.go
+++ b/api4/user_test.go
@@ -1971,6 +1971,51 @@ func TestRevokeSessions(t *testing.T) {
CheckNoError(t, resp)
}
+func TestRevokeAllSessions(t *testing.T) {
+ th := Setup().InitBasic()
+ defer th.TearDown()
+ Client := th.Client
+
+ user := th.BasicUser
+ Client.Login(user.Email, user.Password)
+
+ _, resp := Client.RevokeAllSessions(th.BasicUser2.Id)
+ CheckForbiddenStatus(t, resp)
+
+ th.InitSystemAdmin()
+
+ _, resp = Client.RevokeAllSessions("junk" + user.Id)
+ CheckBadRequestStatus(t, resp)
+
+ status, resp := Client.RevokeAllSessions(user.Id)
+ if status == false {
+ t.Fatal("user all sessions revoke unsuccessful")
+ }
+ CheckNoError(t, resp)
+
+ Client.Logout()
+ _, resp = Client.RevokeAllSessions(user.Id)
+ CheckUnauthorizedStatus(t, resp)
+
+ Client.Login(user.Email, user.Password)
+
+ sessions, _ := Client.GetSessions(user.Id, "")
+ if len(sessions) < 1 {
+ t.Fatal("session should exist")
+ }
+
+ _, resp = Client.RevokeAllSessions(user.Id)
+ CheckNoError(t, resp)
+
+ sessions, _ = th.SystemAdminClient.GetSessions(user.Id, "")
+ if len(sessions) != 0 {
+ t.Fatal("no sessions should exist for user")
+ }
+
+ _, resp = Client.RevokeAllSessions(user.Id)
+ CheckUnauthorizedStatus(t, resp)
+}
+
func TestAttachDeviceId(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()
diff --git a/model/client4.go b/model/client4.go
index a7ee3df86..941145043 100644
--- a/model/client4.go
+++ b/model/client4.go
@@ -901,6 +901,16 @@ func (c *Client4) RevokeSession(userId, sessionId string) (bool, *Response) {
}
}
+// RevokeAllSessions revokes all sessions for the provided user id string.
+func (c *Client4) RevokeAllSessions(userId string) (bool, *Response) {
+ if r, err := c.DoApiPost(c.GetUserRoute(userId)+"/sessions/revoke/all", ""); err != nil {
+ return false, BuildErrorResponse(r, err)
+ } else {
+ defer closeBody(r)
+ return CheckStatusOK(r), BuildResponse(r)
+ }
+}
+
// AttachDeviceId attaches a mobile device ID to the current session.
func (c *Client4) AttachDeviceId(deviceId string) (bool, *Response) {
requestBody := map[string]string{"device_id": deviceId}