Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -0,0 +1,234 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {getAdminAccount} from '../../../../support/env';
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @not_cloud @extend_session
|
||||
|
||||
describe('MM-T2575 Extend Session - Email Login', () => {
|
||||
let offTopicUrl;
|
||||
const oneDay = 24 * 60 * 60 * 1000;
|
||||
const admin = getAdminAccount();
|
||||
let testUser;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
// * Verify that the server has license and its database matches with the DB client and config at "cypress.json"
|
||||
cy.apiRequireLicense();
|
||||
cy.apiRequireServerDBToMatch();
|
||||
|
||||
cy.apiInitSetup().then(({user, offTopicUrl: url}) => {
|
||||
testUser = user;
|
||||
offTopicUrl = url;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as sysadmin and revoke sessions of the test user
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRevokeUserSessions(testUser.id);
|
||||
});
|
||||
|
||||
it('should redirect to login page when session expired', () => {
|
||||
// # Update system config
|
||||
const setting = {
|
||||
ServiceSettings: {
|
||||
ExtendSessionLengthWithActivity: true,
|
||||
SessionLengthWebInHours: 1,
|
||||
},
|
||||
} as Cypress.AdminConfig;
|
||||
|
||||
cy.apiUpdateConfig(setting);
|
||||
|
||||
// # Login as test user and go to town-square channel
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Get active user sessions as baseline reference
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: initialSessions}) => {
|
||||
// Post a message to a channel
|
||||
cy.postMessage(`${Date.now()}`);
|
||||
|
||||
const expiredSession = parseDateTime(initialSessions[0].createat) + 1;
|
||||
|
||||
// # Update user with expired session
|
||||
cy.dbUpdateUserSession({
|
||||
userId: initialSessions[0].userid,
|
||||
sessionId: initialSessions[0].id,
|
||||
fieldsToUpdate: {expiresat: expiredSession},
|
||||
}).then(({session: updatedSession}) => {
|
||||
// * Verify that the session is updated
|
||||
expect(parseDateTime(updatedSession.expiresat)).to.equal(expiredSession);
|
||||
|
||||
// # Invalidate cache and reload to take effect the expired session
|
||||
cy.externalRequest({user: admin, method: 'POST', path: 'caches/invalidate'});
|
||||
cy.reload();
|
||||
|
||||
// # Try to visit town-square channel
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// * Verify that it redirects to login page due to expired session
|
||||
cy.url().should('include', `/login?redirect_to=${offTopicUrl.replace(/\//g, '%2F')}`);
|
||||
|
||||
// * Get user's active session of test user and verify that it remained as expired and is not extended
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: activeSessions}) => {
|
||||
expect(activeSessions.length).to.equal(0);
|
||||
|
||||
cy.dbGetUserSession({sessionId: initialSessions[0].id}).then(({session: unExtendedSession}) => {
|
||||
expect(parseDateTime(unExtendedSession.expiresat)).to.equal(expiredSession);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const visitAChannel = () => {
|
||||
cy.visit(offTopicUrl);
|
||||
cy.url().should('not.include', '/login?redirect_to');
|
||||
cy.url().should('include', offTopicUrl);
|
||||
};
|
||||
|
||||
const postAMessage = (now) => {
|
||||
cy.postMessage(now);
|
||||
cy.getLastPost().should('contain', now);
|
||||
};
|
||||
|
||||
const testCases = [{
|
||||
name: 'on visit to a channel',
|
||||
fn: visitAChannel,
|
||||
sessionLengthInHours: 24,
|
||||
}, {
|
||||
name: 'on posting a message',
|
||||
fn: postAMessage,
|
||||
sessionLengthInHours: 48,
|
||||
}, {
|
||||
name: 'on visit to a channel',
|
||||
fn: visitAChannel,
|
||||
sessionLengthInHours: 74,
|
||||
}, {
|
||||
name: 'on posting a message',
|
||||
fn: postAMessage,
|
||||
sessionLengthInHours: 96,
|
||||
}];
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
it(`with SessionLengthWebInHours ${testCase.sessionLengthInHours} and threshold not met, should not extend session ${testCase.name}`, () => {
|
||||
// # Update system config
|
||||
const setting = {
|
||||
ServiceSettings: {
|
||||
ExtendSessionLengthWithActivity: true,
|
||||
SessionLengthWebInHours: testCase.sessionLengthInHours,
|
||||
},
|
||||
} as Cypress.AdminConfig;
|
||||
cy.apiUpdateConfig(setting);
|
||||
|
||||
// # Login as test user and go to town-square channel
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Get active user sessions as baseline reference
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: initialSessions}) => {
|
||||
const initialSession = initialSessions[0];
|
||||
|
||||
// Post a message to a channel
|
||||
cy.postMessage(`${Date.now()}`);
|
||||
|
||||
// Elapsed time of 0.9% or a bit below 1.00%
|
||||
const elapsedBelowThreshold = parseDateTime(initialSession.expiresat) - (testCase.sessionLengthInHours * oneDay * 0.0004);
|
||||
|
||||
// # Update the user session with new expiration to simulate that
|
||||
// # the session has elapsed just below 1% of session length.
|
||||
cy.dbUpdateUserSession({
|
||||
userId: initialSession.userid,
|
||||
sessionId: initialSession.id,
|
||||
fieldsToUpdate: {expiresat: elapsedBelowThreshold},
|
||||
}).then(({session: updatedSession}) => {
|
||||
// * Verify that the session is updated
|
||||
expect(parseDateTime(updatedSession.expiresat)).to.equal(elapsedBelowThreshold);
|
||||
|
||||
// # Invalidate cache and reload to take effect the new session
|
||||
cy.externalRequest({user: admin, method: 'POST', path: 'caches/invalidate'});
|
||||
cy.reload();
|
||||
|
||||
// # Visit a channel or post a message
|
||||
const now = Date.now();
|
||||
testCase.fn(now);
|
||||
|
||||
// * Get active session of test user and verify that the session has remained the same and has not extended
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: unExtendedSessions}) => {
|
||||
const unExtendedSession = unExtendedSessions[0];
|
||||
expect(initialSession.id).to.equal(unExtendedSession.id);
|
||||
expect(elapsedBelowThreshold).to.equal(parseDateTime(unExtendedSession.expiresat));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
it(`with SessionLengthWebInHours ${testCase.sessionLengthInHours} and threshold met, should extend session ${testCase.name}`, () => {
|
||||
// # Update system config
|
||||
const setting = {
|
||||
ServiceSettings: {
|
||||
ExtendSessionLengthWithActivity: true,
|
||||
SessionLengthWebInHours: testCase.sessionLengthInHours,
|
||||
},
|
||||
} as Cypress.AdminConfig;
|
||||
cy.apiUpdateConfig(setting);
|
||||
|
||||
// # Login as test user and go to town-square channel
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Get active user sessions as baseline reference
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: initialSessions}) => {
|
||||
const initialSession = initialSessions[0];
|
||||
|
||||
// Post a message to a channel
|
||||
cy.postMessage(`${Date.now()}`);
|
||||
|
||||
// Elapsed time of 1.1% or a bit above 1.00%
|
||||
const elapsedAboveThreshold = parseDateTime(initialSession.expiresat) - (testCase.sessionLengthInHours * oneDay * 0.011);
|
||||
|
||||
// # Update the user session with new expiration to simulate that
|
||||
// # the session has elapsed just above 1% of session length.
|
||||
cy.dbUpdateUserSession({
|
||||
userId: initialSession.userid,
|
||||
sessionId: initialSession.id,
|
||||
fieldsToUpdate: {expiresat: elapsedAboveThreshold},
|
||||
}).then(({session: updatedSession}) => {
|
||||
// * Verify that the session is updated
|
||||
expect(parseDateTime(updatedSession.expiresat)).to.equal(elapsedAboveThreshold);
|
||||
|
||||
// # Invalidate cache and reload to take effect the new session
|
||||
cy.externalRequest({user: admin, method: 'POST', path: 'caches/invalidate'});
|
||||
cy.reload();
|
||||
|
||||
// # Visit a channel or post a message
|
||||
const now = Date.now();
|
||||
testCase.fn(now);
|
||||
|
||||
// * Get active session of test user and verify that the session has been extended depending on SessionLengthWebInHours setting
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: extendedSessions}) => {
|
||||
expect(extendedSessions[0].id).to.equal(updatedSession.id);
|
||||
expect(parseDateTime(extendedSessions[0].expiresat)).to.be.greaterThan(parseDateTime(updatedSession.expiresat));
|
||||
const twentySeconds = 20000;
|
||||
expect(parseDateTime(extendedSessions[0].expiresat)).to.be.closeTo(new Date().setHours(new Date().getHours() + testCase.sessionLengthInHours), twentySeconds);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function parseDateTime(value: string) {
|
||||
return parseInt(value, 10);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,127 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {getAdminAccount} from '../../../../../support/env';
|
||||
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
|
||||
|
||||
const admin = getAdminAccount();
|
||||
const oneDay = 24 * 60 * 60 * 1000;
|
||||
const thirtySeconds = 30 * 1000;
|
||||
|
||||
export function verifyExtendedSession(testUser, sessionLengthInDays, channelUrl) {
|
||||
// # Login as test user and visit default channel
|
||||
cy.visit(channelUrl);
|
||||
|
||||
// # Get active user sessions as baseline reference
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: initialSessions}) => {
|
||||
expect(initialSessions.length).to.equal(1);
|
||||
const initialSession = initialSessions[0];
|
||||
|
||||
// # Post a message to a channel
|
||||
const now = Date.now();
|
||||
cy.postMessage(now);
|
||||
|
||||
// # Update user session which is to expire 20 sec from now
|
||||
const soonToExpire = getExpirationFromNow(thirtySeconds);
|
||||
cy.dbUpdateUserSession({
|
||||
userId: initialSession.userid,
|
||||
sessionId: initialSession.id,
|
||||
fieldsToUpdate: {expiresat: soonToExpire},
|
||||
}).then(({session: updatedSession}) => {
|
||||
// * Verify that the session is updated
|
||||
expect(parseInt(updatedSession.expiresat, 10)).to.equal(soonToExpire);
|
||||
|
||||
// # Invalidate cache and reload to take effect the soon to expire session
|
||||
cy.externalRequest({user: admin, method: 'POST', path: 'caches/invalidate'});
|
||||
cy.reload();
|
||||
|
||||
// # Visit default channel
|
||||
cy.visit(channelUrl);
|
||||
|
||||
// # Get active session of test user
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: extendedSessions}) => {
|
||||
expect(extendedSessions.length).to.equal(1);
|
||||
const extendedSession = extendedSessions[0];
|
||||
|
||||
// * Verify that the session has been extended depending on session length (in days) setting
|
||||
expect(extendedSession.id).to.equal(updatedSession.id);
|
||||
expect(parseInt(extendedSession.expiresat, 10)).to.be.greaterThan(parseInt(updatedSession.expiresat, 10));
|
||||
expect(parseInt(extendedSession.expiresat, 10)).to.be.greaterThan(parseInt(initialSession.expiresat, 10));
|
||||
|
||||
expect(parseInt(extendedSession.expiresat, 10)).to.be.closeTo(now + (sessionLengthInDays * oneDay * 0.042), thirtySeconds);
|
||||
});
|
||||
|
||||
// # Post multiple times to check that the session continues and doesn't redirect to login page
|
||||
Cypress._.times(20, (i) => {
|
||||
cy.postMessage(i);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function verifyNotExtendedSession(testUser, channelUrl) {
|
||||
// # Login as test user and visit default channel
|
||||
cy.visit(channelUrl);
|
||||
|
||||
// # Get active user sessions as baseline reference
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: initialSessions}) => {
|
||||
expect(initialSessions.length).to.equal(1);
|
||||
const initialSession = initialSessions[0];
|
||||
expect(parseInt(initialSession.expiresat, 10)).to.be.greaterThan(0);
|
||||
|
||||
// # Post a message to a channel
|
||||
const now = Date.now();
|
||||
cy.postMessage(`now: ${now}`);
|
||||
|
||||
// # Update user session which is to expire 20 sec from now
|
||||
const soonToExpire = getExpirationFromNow(thirtySeconds);
|
||||
cy.dbUpdateUserSession({
|
||||
userId: initialSession.userid,
|
||||
sessionId: initialSession.id,
|
||||
fieldsToUpdate: {expiresat: soonToExpire},
|
||||
}).then(({session: updatedSession}) => {
|
||||
// * Verify that the session is updated
|
||||
expect(parseInt(updatedSession.expiresat, 10)).to.equal(soonToExpire);
|
||||
|
||||
// # Invalidate cache and reload to take effect the soon to expire session
|
||||
cy.externalRequest({user: admin, method: 'POST', path: 'caches/invalidate'});
|
||||
cy.reload();
|
||||
|
||||
// # Visit default channel
|
||||
cy.visit(channelUrl);
|
||||
|
||||
// # Get active session of test user
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: soonToExpireSessions}) => {
|
||||
// * Verify that the session was not extended
|
||||
expect(soonToExpireSessions.length).to.equal(1);
|
||||
expect(soonToExpireSessions[0].id).to.equal(updatedSession.id);
|
||||
expect(parseInt(soonToExpireSessions[0].expiresat, 10)).to.equal(parseInt(updatedSession.expiresat, 10));
|
||||
|
||||
// * Verify that it redirects to login page due to expired session
|
||||
cy.waitUntil(() => {
|
||||
return cy.url().then((url) => {
|
||||
return url.includes('/login');
|
||||
});
|
||||
}, {
|
||||
timeout: TIMEOUTS.TWO_MIN,
|
||||
interval: TIMEOUTS.TWO_SEC,
|
||||
});
|
||||
|
||||
// * Verify that user has no active session
|
||||
cy.dbGetActiveUserSessions({username: testUser.username}).then(({sessions: activeSessions}) => {
|
||||
expect(activeSessions.length).to.equal(0);
|
||||
});
|
||||
|
||||
// * Verify that the session has not been extended
|
||||
cy.dbGetUserSession({sessionId: initialSession.id}).then(({session: unExtendedSession}) => {
|
||||
expect(parseInt(unExtendedSession.expiresat, 10)).to.equal(soonToExpire);
|
||||
expect(parseInt(unExtendedSession.expiresat, 10)).to.be.lessThan(Date.now());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getExpirationFromNow(duration = 0) {
|
||||
return Date.now() + duration;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @enterprise @not_cloud @extend_session
|
||||
|
||||
import {verifyExtendedSession, verifyNotExtendedSession} from './helpers';
|
||||
|
||||
describe('Extended Session Length', () => {
|
||||
const sessionLengthInHours = 1;
|
||||
const setting = {
|
||||
ServiceSettings: {
|
||||
SessionLengthWebInHours: sessionLengthInHours,
|
||||
},
|
||||
};
|
||||
let emailUser;
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.apiRequireLicense();
|
||||
|
||||
// * Server database should match with the DB client and config at "cypress.json"
|
||||
cy.apiRequireServerDBToMatch();
|
||||
|
||||
cy.apiInitSetup().then(({user, offTopicUrl: url}) => {
|
||||
emailUser = user;
|
||||
offTopicUrl = url;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRevokeUserSessions(emailUser.id);
|
||||
});
|
||||
|
||||
it('MM-T4045_1 Email user session should have extended due to user activity when enabled', () => {
|
||||
// # Enable ExtendSessionLengthWithActivity
|
||||
setting.ServiceSettings.ExtendSessionLengthWithActivity = true;
|
||||
cy.apiUpdateConfig(setting);
|
||||
|
||||
cy.apiLogin(emailUser);
|
||||
verifyExtendedSession(emailUser, sessionLengthInHours, offTopicUrl);
|
||||
});
|
||||
|
||||
it('MM-T4045_2 Email user session should not extend even with user activity when disabled', () => {
|
||||
// # Disable ExtendSessionLengthWithActivity
|
||||
setting.ServiceSettings.ExtendSessionLengthWithActivity = false;
|
||||
cy.apiUpdateConfig(setting);
|
||||
|
||||
cy.apiLogin(emailUser);
|
||||
verifyNotExtendedSession(emailUser, offTopicUrl);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @enterprise @not_cloud @extend_session @ldap
|
||||
|
||||
import ldapUsers from '../../../../../fixtures/ldap_users.json';
|
||||
|
||||
import {verifyExtendedSession, verifyNotExtendedSession} from './helpers';
|
||||
|
||||
describe('Extended Session Length', () => {
|
||||
const sessionLengthInHours = 1;
|
||||
const setting = {
|
||||
ServiceSettings: {
|
||||
SessionLengthWebInHours: sessionLengthInHours,
|
||||
},
|
||||
};
|
||||
let testLdapUser;
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.apiRequireLicense();
|
||||
|
||||
// * Server database should match with the DB client and config at "cypress.json"
|
||||
cy.apiRequireServerDBToMatch();
|
||||
|
||||
const ldapUser = ldapUsers['test-1'];
|
||||
cy.apiSyncLDAPUser({ldapUser}).then((user) => {
|
||||
testLdapUser = user;
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, offTopicUrl: url}) => {
|
||||
offTopicUrl = url;
|
||||
cy.apiAddUserToTeam(team.id, testLdapUser.id);
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRevokeUserSessions(testLdapUser.id);
|
||||
});
|
||||
|
||||
it('MM-T4046_1 LDAP user session should have extended due to user activity when enabled', () => {
|
||||
// # Enable ExtendSessionLengthWithActivity
|
||||
setting.ServiceSettings.ExtendSessionLengthWithActivity = true;
|
||||
cy.apiUpdateConfig(setting);
|
||||
|
||||
cy.apiLogin(testLdapUser);
|
||||
verifyExtendedSession(testLdapUser, sessionLengthInHours, offTopicUrl);
|
||||
});
|
||||
|
||||
it('MM-T4046_2 LDAP user session should not extend even with user activity when disabled', () => {
|
||||
// # Disable ExtendSessionLengthWithActivity
|
||||
setting.ServiceSettings.ExtendSessionLengthWithActivity = false;
|
||||
cy.apiUpdateConfig(setting);
|
||||
|
||||
cy.apiLogin(testLdapUser);
|
||||
verifyNotExtendedSession(testLdapUser, offTopicUrl);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// - Requires openldap and keycloak running
|
||||
// - Requires keycloak certificate at fixtures folder
|
||||
// -> copy ./mattermost-server/build/docker/keycloak/keycloak.crt to ./mattermost-webapp/e2e/cypress/tests/fixtures/keycloak.crt
|
||||
// - Requires Cypress' chromeWebSecurity to be false
|
||||
|
||||
// Group: @channels @enterprise @not_cloud @extend_session @ldap @saml @keycloak
|
||||
|
||||
import {getKeycloakServerSettings} from '../../../../../utils/config';
|
||||
|
||||
import {verifyExtendedSession, verifyNotExtendedSession} from './helpers';
|
||||
|
||||
describe('Extended Session Length', () => {
|
||||
const sessionLengthInDays = 1;
|
||||
const samlConfig = getKeycloakServerSettings();
|
||||
const sessionConfig = {
|
||||
ServiceSettings: {
|
||||
SessionLengthSSOInDays: sessionLengthInDays,
|
||||
},
|
||||
};
|
||||
|
||||
let testTeamId;
|
||||
let testSamlUser;
|
||||
let offTopicUrl;
|
||||
let samlLdapUser;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.apiRequireLicenseForFeature('LDAP', 'SAML');
|
||||
|
||||
// * Server database should match with the DB client and config at "cypress.json"
|
||||
cy.apiRequireServerDBToMatch();
|
||||
|
||||
// # Create new LDAP user
|
||||
cy.createLDAPUser().then((user) => {
|
||||
samlLdapUser = user;
|
||||
});
|
||||
|
||||
// # Create new team
|
||||
cy.apiCreateTeam('saml-team', 'SAML Team').then(({team}) => {
|
||||
testTeamId = team.id;
|
||||
offTopicUrl = `/${team.name}/channels/off-topic`;
|
||||
});
|
||||
|
||||
cy.apiUpdateConfig(samlConfig).then(() => {
|
||||
// # Require keycloak with realm setup
|
||||
cy.apiRequireKeycloak();
|
||||
|
||||
// # Upload certificate, overwrite existing
|
||||
cy.apiUploadSAMLIDPCert('keycloak.crt');
|
||||
|
||||
// # Create Keycloak user and login for the first time
|
||||
cy.keycloakCreateUsers([samlLdapUser]);
|
||||
cy.doKeycloakLogin(samlLdapUser);
|
||||
|
||||
// # Wait for the UI to be ready which indicates SAML registration is complete
|
||||
cy.findByText('Logout').click();
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiGetUserByEmail(samlLdapUser.email).then(({user}) => {
|
||||
testSamlUser = user;
|
||||
cy.apiAddUserToTeam(testTeamId, user.id);
|
||||
cy.apiRevokeUserSessions(user.id);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4047_1 SAML/SSO user session should have extended due to user activity when enabled', () => {
|
||||
// # Enable ExtendSessionLengthWithActivity
|
||||
sessionConfig.ServiceSettings.ExtendSessionLengthWithActivity = true;
|
||||
cy.apiUpdateConfig({...samlConfig, ...sessionConfig});
|
||||
|
||||
// # Login via Keycloak
|
||||
cy.doKeycloakLogin(samlLdapUser);
|
||||
cy.postMessage('hello');
|
||||
|
||||
// # Verify session is extended
|
||||
verifyExtendedSession(testSamlUser, sessionLengthInDays, offTopicUrl);
|
||||
});
|
||||
|
||||
it('MM-T4047_2 SAML/SSO user session should not extend even with user activity when disabled', () => {
|
||||
// # Disable ExtendSessionLengthWithActivity
|
||||
sessionConfig.ServiceSettings.ExtendSessionLengthWithActivity = false;
|
||||
cy.apiUpdateConfig({...samlConfig, ...sessionConfig});
|
||||
|
||||
// # Login via Keycloak
|
||||
cy.doKeycloakLogin(samlLdapUser);
|
||||
cy.postMessage('hello');
|
||||
|
||||
// # Verify session is not extended
|
||||
verifyNotExtendedSession(testSamlUser, offTopicUrl);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @not_cloud @system_console
|
||||
|
||||
// # Goes to the System Scheme page as System Admin
|
||||
const goToSessionLengths = () => {
|
||||
cy.apiAdminLogin();
|
||||
cy.visit('/admin_console/environment/session_lengths');
|
||||
};
|
||||
|
||||
// # Wait's until the Saving text becomes Save
|
||||
const waitUntilConfigSave = () => {
|
||||
cy.waitUntil(() => cy.get('#saveSetting').then((el) => {
|
||||
return el[0].innerText === 'Save';
|
||||
}));
|
||||
};
|
||||
|
||||
// Clicks the save button in the system console page.
|
||||
// waitUntilConfigSaved: If we need to wait for the save button to go from saving -> save.
|
||||
// Usually we need to wait unless we are doing this in team override scheme
|
||||
const saveConfig = (waitUntilConfigSaved = true, clickConfirmationButton = false) => {
|
||||
// # Save if possible (if previous test ended abruptly all permissions may already be enabled)
|
||||
cy.get('#saveSetting').then((btn) => {
|
||||
if (btn.is(':enabled')) {
|
||||
btn.click();
|
||||
}
|
||||
});
|
||||
if (clickConfirmationButton) {
|
||||
cy.get('#confirmModalButton').click();
|
||||
}
|
||||
if (waitUntilConfigSaved) {
|
||||
waitUntilConfigSave();
|
||||
}
|
||||
};
|
||||
|
||||
describe('MM-T2574 Session Lengths', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.apiRequireLicense();
|
||||
goToSessionLengths();
|
||||
});
|
||||
|
||||
describe('"Extend session length with activity" defaults to true', () => {
|
||||
it('"Extend session length with activity" radio is checked', () => {
|
||||
cy.get('#extendSessionLengthWithActivitytrue').check().should('be.checked');
|
||||
});
|
||||
it('"Session idle timeout" setting should not exist', () => {
|
||||
cy.get('#sessionIdleTimeoutInMinutes').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Setting "Extend session length with activity" to false alters subsequent settings', () => {
|
||||
before(() => cy.get('#extendSessionLengthWithActivityfalse').check());
|
||||
it('In enterprise edition, "Session idle timeout" setting should exist on page', () => {
|
||||
cy.get('#sessionIdleTimeoutInMinutes').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Session Lengths settings should save successfully', () => {
|
||||
before(() => cy.get('#extendSessionLengthWithActivityfalse').check());
|
||||
it('Setting "Session Idle Timeout (minutes)" should save in UI', () => {
|
||||
cy.get('#sessionIdleTimeoutInMinutes').
|
||||
should('have.value', '43200').
|
||||
clear().type('43201');
|
||||
saveConfig();
|
||||
cy.get('#sessionIdleTimeoutInMinutes').should('have.value', '43201');
|
||||
});
|
||||
it('Setting "Session Cache (minutes)" should be saved in the server configuration', () => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const setting = config.ServiceSettings.SessionIdleTimeoutInMinutes;
|
||||
expect(setting).to.equal(43201);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should match help text', () => {
|
||||
const helpText = {
|
||||
extendSessionLengthWithActivity: {
|
||||
false: 'When true, sessions will be automatically extended when the user is active in their Mattermost client. Users sessions will only expire if they are not active in their Mattermost client for the entire duration of the session lengths defined in the fields below. When false, sessions will not extend with activity in Mattermost. User sessions will immediately expire at the end of the session length or idle timeouts defined below. ',
|
||||
true: 'When true, sessions will be automatically extended when the user is active in their Mattermost client. Users sessions will only expire if they are not active in their Mattermost client for the entire duration of the session lengths defined in the fields below. When false, sessions will not extend with activity in Mattermost. User sessions will immediately expire at the end of the session length or idle timeouts defined below. ',
|
||||
},
|
||||
sessionLengthWebInHours: {
|
||||
false: 'The number of hours from the last time a user entered their credentials to the expiry of the user\'s session. After changing this setting, the new session length will take effect after the next time the user enters their credentials.',
|
||||
true: 'Set the number of hours from the last activity in Mattermost to the expiry of the user’s session when using email and AD/LDAP authentication. After changing this setting, the new session length will take effect after the next time the user enters their credentials.',
|
||||
},
|
||||
sessionLengthMobileInHours: {
|
||||
false: 'The number of hours from the last time a user entered their credentials to the expiry of the user\'s session. After changing this setting, the new session length will take effect after the next time the user enters their credentials.',
|
||||
true: 'Set the number of hours from the last activity in Mattermost to the expiry of the user’s session on mobile. After changing this setting, the new session length will take effect after the next time the user enters their credentials.',
|
||||
},
|
||||
sessionLengthSSOInHours: {
|
||||
false: 'The number of hours from the last time a user entered their credentials to the expiry of the user\'s session. If the authentication method is SAML or GitLab, the user may automatically be logged back in to Mattermost if they are already logged in to SAML or GitLab. After changing this setting, the setting will take effect after the next time the user enters their credentials.',
|
||||
true: 'Set the number of hours from the last activity in Mattermost to the expiry of the user’s session for SSO authentication, such as SAML, GitLab and OAuth 2.0. If the authentication method is SAML or GitLab, the user may automatically be logged back in to Mattermost if they are already logged in to SAML or GitLab. After changing this setting, the setting will take effect after the next time the user enters their credentials.',
|
||||
},
|
||||
sessionCacheInMinutes: {
|
||||
false: 'The number of minutes to cache a session in memory.',
|
||||
true: 'The number of minutes to cache a session in memory.',
|
||||
},
|
||||
sessionIdleTimeoutInMinutes: {
|
||||
false: 'The number of minutes from the last time a user was active on the system to the expiry of the user\'s session. Once expired, the user will need to log in to continue. Minimum is 5 minutes, and 0 is unlimited.Applies to the desktop app and browsers. For mobile apps, use an EMM provider to lock the app when not in use. In High Availability mode, enable IP hash load balancing for reliable timeout measurement.',
|
||||
true: false,
|
||||
},
|
||||
};
|
||||
|
||||
cy.get('#extendSessionLengthWithActivityfalse').check();
|
||||
Object.entries(helpText).forEach(([key, value]) => {
|
||||
cy.findByTestId(key).should('exist');
|
||||
cy.findByTestId(`${key}help-text`).should('have.text', value.false);
|
||||
});
|
||||
|
||||
cy.get('#extendSessionLengthWithActivitytrue').check();
|
||||
Object.entries(helpText).forEach(([key, value]) => {
|
||||
if (value.true) {
|
||||
cy.findByTestId(key).should('exist');
|
||||
cy.findByTestId(`${key}help-text`).should('have.text', value.true);
|
||||
} else {
|
||||
cy.findByTestId(key).should('not.exist');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Ссылка в новой задаче
Block a user