Skip to content

Commit

Permalink
[MM-7854] revoke sessions for all users redux (mattermost#866)
Browse files Browse the repository at this point in the history
* [MM-7854] revoke sessions for all users redux

* [MM-7854] fix routes to match server

* [MM-7854] remove userid from revoke action
  • Loading branch information
Willyfrog authored and grundleborg committed Jul 4, 2019
1 parent c0163e9 commit 67baf4a
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/action_types/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default keyMirror({
LOGOUT_FAILURE: null,

REVOKE_ALL_USER_SESSIONS_SUCCESS: null,
REVOKE_SESSIONS_FOR_ALL_USERS_SUCCESS: null,

CHECK_MFA_REQUEST: null,
CHECK_MFA_SUCCESS: null,
Expand Down
18 changes: 18 additions & 0 deletions src/actions/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,23 @@ export function revokeAllSessionsForUser(userId: string): ActionFunc {
};
}

export function revokeSessionsForAllUsers(): ActionFunc {
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
try {
await Client4.revokeSessionsForAllUsers();
} catch (error) {
forceLogoutIfNecessary(error, dispatch, getState);
dispatch(logError(error));
return {error};
}
dispatch({
type: UserTypes.REVOKE_SESSIONS_FOR_ALL_USERS_SUCCESS,
data: null,
});
return {data: true};
};
}

export function loadProfilesForDirect(): ActionFunc {
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
const state = getState();
Expand Down Expand Up @@ -1432,6 +1449,7 @@ export default {
loadProfilesForDirect,
revokeSession,
revokeAllSessionsForUser,
revokeSessionsForAllUsers,
getUserAudits,
searchProfiles,
startPeriodicStatusUpdates,
Expand Down
53 changes: 53 additions & 0 deletions src/actions/users.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,59 @@ describe('Actions.Users', () => {
await TestHelper.basicClient4.login(TestHelper.basicUser.email, 'password1');
});

it('revokeSessionsForAllUsers', async () => {
const user = TestHelper.basicUser;
nock(Client4.getUsersRoute()).
post('/logout').
reply(200, OK_RESPONSE);
await TestHelper.basicClient4.logout();
let sessions = store.getState().entities.users.mySessions;

assert.strictEqual(sessions.length, 0);

TestHelper.mockLogin();
await Actions.loginById(user.id, 'password1')(store.dispatch, store.getState);

nock(Client4.getUsersRoute()).
post('/login').
reply(200, TestHelper.basicUser);
await TestHelper.basicClient4.login(TestHelper.basicUser.email, 'password1');

nock(Client4.getBaseRoute()).
get(`/users/${user.id}/sessions`).
reply(200, [{id: TestHelper.generateId(), create_at: 1507756921338, expires_at: 1510348921338, last_activity_at: 1507821125630, user_id: TestHelper.basicUser.id, device_id: '', roles: 'system_admin system_user'}, {id: TestHelper.generateId(), create_at: 1507756921338, expires_at: 1510348921338, last_activity_at: 1507821125630, user_id: TestHelper.basicUser.id, device_id: '', roles: 'system_admin system_user'}]);
await Actions.getSessions(user.id)(store.dispatch, store.getState);

sessions = store.getState().entities.users.mySessions;
assert.ok(sessions.length > 1);

nock(Client4.getBaseRoute()).
post('/users/sessions/revoke/all').
reply(200, OK_RESPONSE);
const {data} = await Actions.revokeSessionsForAllUsers(user.id)(store.dispatch, store.getState);
assert.deepEqual(data, true);

nock(Client4.getUsersRoute()).
get('').
query(true).
reply(401, {});
await Actions.getProfiles(0)(store.dispatch, store.getState);

const logoutRequest = store.getState().requests.users.logout;
if (logoutRequest.status === RequestStatus.FAILURE) {
throw new Error(JSON.stringify(logoutRequest.error));
}

sessions = store.getState().entities.users.mySessions;

assert.strictEqual(sessions.length, 0);

nock(Client4.getUsersRoute()).
post('/login').
reply(200, TestHelper.basicUser);
await TestHelper.basicClient4.login(TestHelper.basicUser.email, 'password1');
});

it('getUserAudits', async () => {
nock(Client4.getUsersRoute()).
get(`/${TestHelper.basicUser.id}/audits`).
Expand Down
7 changes: 7 additions & 0 deletions src/client/client4.js
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,13 @@ export default class Client4 {
);
};

revokeSessionsForAllUsers = async () => {
return this.doFetch(
`${this.getUsersRoute()}/sessions/revoke/all`,
{method: 'post'}
);
};

getUserAudits = async (userId, page = 0, perPage = PER_PAGE_DEFAULT) => {
return this.doFetch(
`${this.getUserRoute(userId)}/audits${buildQueryString({page, per_page: perPage})}`,
Expand Down
3 changes: 3 additions & 0 deletions src/reducers/entities/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ function mySessions(state = [], action) {
}
return state;

case UserTypes.REVOKE_SESSIONS_FOR_ALL_USERS_SUCCESS:
return [];

case UserTypes.LOGOUT_SUCCESS:
return [];

Expand Down

0 comments on commit 67baf4a

Please sign in to comment.