Add integration test for keep me logged in feature.
parent
4c3b5cfbb3
commit
05c423c6f8
|
@ -53,6 +53,10 @@ module.exports = function (grunt) {
|
|||
cmd: "./node_modules/.bin/mocha",
|
||||
args: ['--colors', '--require', 'ts-node/register', 'test/minimal-config/**/*.ts']
|
||||
},
|
||||
"test-inactivity": {
|
||||
cmd: "./node_modules/.bin/mocha",
|
||||
args: ['--colors', '--require', 'ts-node/register', 'test/inactivity/**/*.ts']
|
||||
},
|
||||
"docker-build": {
|
||||
cmd: "docker",
|
||||
args: ['build', '-t', 'clems4ever/authelia', '.']
|
||||
|
@ -191,7 +195,7 @@ module.exports = function (grunt) {
|
|||
grunt.registerTask('test-server', ['env:env-test-server-unit', 'run:test-server-unit'])
|
||||
grunt.registerTask('test-client', ['env:env-test-client-unit', 'run:test-client-unit'])
|
||||
grunt.registerTask('test-unit', ['test-server', 'test-client']);
|
||||
grunt.registerTask('test-int', ['run:test-cucumber', 'run:test-minimal-config', 'run:test-complete-config']);
|
||||
grunt.registerTask('test-int', ['run:test-cucumber', 'run:test-minimal-config', 'run:test-complete-config', 'run:test-inactivity']);
|
||||
|
||||
grunt.registerTask('copy-resources', ['copy:resources', 'copy:views', 'copy:images', 'copy:thirdparties', 'concat:css']);
|
||||
grunt.registerTask('generate-config-schema', ['run:generate-config-schema', 'copy:schema']);
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
# Authelia minimal configuration #
|
||||
###############################################################
|
||||
|
||||
logs_level: debug
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
path: /etc/authelia/users_database.yml
|
||||
|
@ -11,7 +9,6 @@ authentication_backend:
|
|||
session:
|
||||
secret: unsecure_session_secret
|
||||
domain: example.com
|
||||
inactivity: 30000
|
||||
|
||||
# Configuration of the storage backend used to store data and secrets. i.e. totp data
|
||||
storage:
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
version: '2'
|
||||
services:
|
||||
authelia:
|
||||
build: .
|
||||
restart: always
|
||||
volumes:
|
||||
- ./config.test.yml:/etc/authelia/config.yml:ro
|
||||
- ./users_database.test.yml:/etc/authelia/users_database.yml:rw
|
||||
- /tmp/authelia:/tmp/authelia
|
||||
environment:
|
||||
- NODE_TLS_REJECT_UNAUTHORIZED=0
|
||||
networks:
|
||||
- example-network
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,32 @@
|
|||
import Bluebird = require("bluebird");
|
||||
import YamlJS = require("yamljs");
|
||||
import Fs = require("fs");
|
||||
import ChildProcess = require("child_process");
|
||||
|
||||
const execAsync = Bluebird.promisify(ChildProcess.exec);
|
||||
|
||||
export class Configuration {
|
||||
private outputPath: string;
|
||||
|
||||
setup(
|
||||
inputPath: string,
|
||||
outputPath: string,
|
||||
updateFn: (configuration: any) => void)
|
||||
: Bluebird<void> {
|
||||
|
||||
console.log("[CONFIGURATION] setup");
|
||||
this.outputPath = outputPath;
|
||||
return new Bluebird((resolve, reject) => {
|
||||
const configuration = YamlJS.load(inputPath);
|
||||
updateFn(configuration);
|
||||
const configurationStr = YamlJS.stringify(configuration);
|
||||
Fs.writeFileSync(outputPath, configurationStr);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
cleanup(): Bluebird<{}> {
|
||||
console.log("[CONFIGURATION] cleanup");
|
||||
return execAsync(`rm ${this.outputPath}`);
|
||||
}
|
||||
}
|
|
@ -13,9 +13,9 @@ export class Environment {
|
|||
}
|
||||
|
||||
private runCommand(command: string, timeout?: number): Bluebird<void> {
|
||||
return new Bluebird<void>(function(resolve, reject) {
|
||||
return new Bluebird<void>((resolve, reject) => {
|
||||
console.log('[ENVIRONMENT] Running: %s', command);
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
exec(command, (err, stdout, stderr) => {
|
||||
if(err) {
|
||||
reject(err);
|
||||
return;
|
||||
|
@ -34,10 +34,13 @@ export class Environment {
|
|||
}
|
||||
|
||||
cleanup(): Bluebird<void> {
|
||||
if(process.env.KEEP_ENV != "true") {
|
||||
const command = docker_compose(this.includes) + ' down'
|
||||
console.log('[ENVIRONMENT] Cleaning up...');
|
||||
return this.runCommand(command);
|
||||
}
|
||||
return Bluebird.resolve();
|
||||
}
|
||||
|
||||
stop_service(serviceName: string): Bluebird<void> {
|
||||
const command = docker_compose(this.includes) + ' stop ' + serviceName;
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
import Bluebird = require("bluebird");
|
||||
import SeleniumWebdriver = require("selenium-webdriver");
|
||||
|
||||
export default function(driver: any, username: string, password: string) {
|
||||
export default function(
|
||||
driver: any,
|
||||
username: string,
|
||||
password: string,
|
||||
keepMeLoggedIn: boolean = false) {
|
||||
return driver.wait(SeleniumWebdriver.until.elementLocated(SeleniumWebdriver.By.id("username")), 5000)
|
||||
.then(function () {
|
||||
.then(() => {
|
||||
return driver.findElement(SeleniumWebdriver.By.id("username"))
|
||||
.sendKeys(username);
|
||||
})
|
||||
.then(function () {
|
||||
.then(() => {
|
||||
return driver.findElement(SeleniumWebdriver.By.id("password"))
|
||||
.sendKeys(password);
|
||||
})
|
||||
.then(function () {
|
||||
.then(() => {
|
||||
if (keepMeLoggedIn) {
|
||||
return driver.findElement(SeleniumWebdriver.By.id("keep_me_logged_in"))
|
||||
.click();
|
||||
}
|
||||
return Bluebird.resolve();
|
||||
})
|
||||
.then(() => {
|
||||
return driver.findElement(SeleniumWebdriver.By.tagName("button"))
|
||||
.click();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
require("chromedriver");
|
||||
import Bluebird = require("bluebird");
|
||||
import Configuration = require("../configuration");
|
||||
import Environment = require("../environment");
|
||||
|
||||
import ChildProcess = require('child_process');
|
||||
const execAsync = Bluebird.promisify(ChildProcess.exec);
|
||||
|
||||
const includes = [
|
||||
"docker-compose.test.yml",
|
||||
"example/compose/docker-compose.base.yml",
|
||||
"example/compose/nginx/minimal/docker-compose.yml",
|
||||
]
|
||||
|
||||
|
||||
before(function() {
|
||||
this.timeout(20000);
|
||||
this.environment = new Environment.Environment(includes);
|
||||
this.configuration = new Configuration.Configuration();
|
||||
|
||||
return this.configuration.setup(
|
||||
"config.minimal.yml",
|
||||
"config.test.yml",
|
||||
conf => {
|
||||
conf.session.inactivity = 2000;
|
||||
})
|
||||
.then(() => execAsync("cp users_database.yml users_database.test.yml"))
|
||||
.then(() => this.environment.setup(2000));
|
||||
});
|
||||
|
||||
after(function() {
|
||||
this.timeout(30000);
|
||||
return this.configuration.cleanup()
|
||||
.then(() => execAsync("rm users_database.test.yml"))
|
||||
.then(() => this.environment.cleanup());
|
||||
});
|
|
@ -0,0 +1,48 @@
|
|||
import Bluebird = require("bluebird");
|
||||
import loginAndRegisterTotp from "../helpers/login-and-register-totp";
|
||||
import VisitPage from "../helpers/visit-page";
|
||||
import FillLoginPageWithUserAndPasswordAndClick from "../helpers/fill-login-page-and-click";
|
||||
import WithDriver from "../helpers/with-driver";
|
||||
import ValidateTotp from "../helpers/validate-totp";
|
||||
import WaitRedirected from "../helpers/wait-redirected";
|
||||
|
||||
describe("Keep me logged in", function() {
|
||||
this.timeout(15000);
|
||||
WithDriver();
|
||||
|
||||
before(function() {
|
||||
const that = this;
|
||||
return loginAndRegisterTotp(this.driver, "john")
|
||||
.then(function(secret: string) {
|
||||
that.secret = secret;
|
||||
if(!secret) return Bluebird.reject(new Error("No secret!"));
|
||||
return Bluebird.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
it("should disconnect user after inactivity period", function() {
|
||||
const that = this;
|
||||
const driver = this.driver;
|
||||
return VisitPage(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html")
|
||||
.then(() => FillLoginPageWithUserAndPasswordAndClick(driver, 'john', 'password', false))
|
||||
.then(() => ValidateTotp(driver, that.secret))
|
||||
.then(() => WaitRedirected(driver, "https://admin.example.com:8080/secret.html"))
|
||||
.then(() => VisitPage(driver, "https://home.example.com:8080/"))
|
||||
.then(() => driver.sleep(3000))
|
||||
.then(() => driver.get("https://admin.example.com:8080/secret.html"))
|
||||
.then(() => WaitRedirected(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html"))
|
||||
});
|
||||
|
||||
it.only("should keep user logged in after inactivity period", function() {
|
||||
const that = this;
|
||||
const driver = this.driver;
|
||||
return VisitPage(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html")
|
||||
.then(() => FillLoginPageWithUserAndPasswordAndClick(driver, 'john', 'password', true))
|
||||
.then(() => ValidateTotp(driver, that.secret))
|
||||
.then(() => WaitRedirected(driver, "https://admin.example.com:8080/secret.html"))
|
||||
.then(() => VisitPage(driver, "https://home.example.com:8080/"))
|
||||
.then(() => driver.sleep(5000))
|
||||
.then(() => driver.get("https://admin.example.com:8080/secret.html"))
|
||||
.then(() => WaitRedirected(driver, "https://admin.example.com:8080/secret.html"))
|
||||
});
|
||||
});
|
|
@ -37,13 +37,13 @@ describe('Validate TOTP factor', function() {
|
|||
const driver = this.driver;
|
||||
|
||||
return VisitPage(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html")
|
||||
.then(function() {
|
||||
.then(() => {
|
||||
return FillLoginPageWithUserAndPasswordAndClick(driver, 'john', 'password');
|
||||
})
|
||||
.then(function () {
|
||||
.then(() => {
|
||||
return ValidateTotp(driver, secret);
|
||||
})
|
||||
.then(function() {
|
||||
.then(() => {
|
||||
return WaitRedirected(driver, "https://admin.example.com:8080/secret.html")
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue