Refactor configuration to remove optional sections from minimal template
Also move tests from dedicated directory to source dir with .spec.ts extensionpull/242/head
parent
97e0ee8ff6
commit
c82f910da3
|
@ -1,6 +1,4 @@
|
|||
dist: trusty
|
||||
language: node_js
|
||||
sudo: required
|
||||
node_js:
|
||||
- "8"
|
||||
services:
|
||||
|
|
|
@ -19,7 +19,7 @@ module.exports = function (grunt) {
|
|||
"generate-config-schema": {
|
||||
cmd: "./node_modules/.bin/typescript-json-schema",
|
||||
args: ["-o", schemaDir, "--strictNullChecks",
|
||||
"--required", "server/tsconfig.json", "UserConfiguration"]
|
||||
"--required", "server/tsconfig.json", "Configuration"]
|
||||
},
|
||||
"compile-client": {
|
||||
cmd: "./node_modules/.bin/tsc",
|
||||
|
@ -35,11 +35,11 @@ module.exports = function (grunt) {
|
|||
},
|
||||
"test-server-unit": {
|
||||
cmd: "./node_modules/.bin/mocha",
|
||||
args: ['--colors', '--compilers', 'ts:ts-node/register', '--recursive', 'server/test']
|
||||
args: ['--colors', '--require', 'ts-node/register', 'server/src/**/*.spec.ts']
|
||||
},
|
||||
"test-client-unit": {
|
||||
cmd: "./node_modules/.bin/mocha",
|
||||
args: ['--colors', '--compilers', 'ts:ts-node/register', '--recursive', 'client/test']
|
||||
args: ['--colors', '--require', 'ts-node/register', 'client/test/**/*.test.ts']
|
||||
},
|
||||
"test-int": {
|
||||
cmd: "./scripts/run-cucumber.sh",
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
###############################################################
|
||||
# Authelia minimal configuration #
|
||||
###############################################################
|
||||
|
||||
ldap:
|
||||
url: ldap://openldap
|
||||
base_dn: dc=example,dc=com
|
||||
|
||||
additional_users_dn: ou=users
|
||||
additional_groups_dn: ou=groups
|
||||
|
||||
groups_filter: (&(member={dn})(objectclass=groupOfNames))
|
||||
|
||||
user: cn=admin,dc=example,dc=com
|
||||
password: password
|
||||
|
||||
session:
|
||||
# The secret to encrypt the session cookies.
|
||||
secret: unsecure_session_secret
|
||||
|
||||
# The domain to protect.
|
||||
# Note: the authenticator must also be in that domain. If empty, the cookie
|
||||
# is restricted to the subdomain of the issuer.
|
||||
domain: example.com
|
|
@ -191,10 +191,11 @@ session:
|
|||
# time.
|
||||
regulation:
|
||||
# The number of failed login attempts before user is banned.
|
||||
# Set it to 0 for disabling regulation.
|
||||
# Set it to 0 to disable regulation.
|
||||
max_retries: 3
|
||||
|
||||
# The length of time between login attempts before user is banned.
|
||||
# The time range during which the user can attempt login before being banned.
|
||||
# The user is banned if the authenticaction failed `max_retries` times in a `find_time` seconds window.
|
||||
find_time: 120
|
||||
|
||||
# The length of time before a banned user can login again.
|
||||
|
|
|
@ -29,7 +29,7 @@ export class AuthenticationSessionHandler {
|
|||
|
||||
static get(req: express.Request, logger: IRequestLogger): AuthenticationSession {
|
||||
if (!req.session) {
|
||||
const errorMsg = "Something is wrong with session cookies. Please check Redis is running and Authelia can contact it.";
|
||||
const errorMsg = "Something is wrong with session cookies. Please check Redis is running and Authelia can connect to it.";
|
||||
logger.error(req, errorMsg);
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
|
||||
import sinon = require("sinon");
|
||||
import IdentityValidator = require("../src/lib/IdentityCheckMiddleware");
|
||||
import IdentityValidator = require("./IdentityCheckMiddleware");
|
||||
import { AuthenticationSessionHandler }
|
||||
from "../src/lib/AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../types/AuthenticationSession";
|
||||
import { UserDataStore } from "../src/lib/storage/UserDataStore";
|
||||
import exceptions = require("../src/lib/Exceptions");
|
||||
import { ServerVariables } from "../src/lib/ServerVariables";
|
||||
from "./AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../types/AuthenticationSession";
|
||||
import { UserDataStore } from "./storage/UserDataStore";
|
||||
import exceptions = require("./Exceptions");
|
||||
import { ServerVariables } from "./ServerVariables";
|
||||
import Assert = require("assert");
|
||||
import express = require("express");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import ExpressMock = require("./mocks/express");
|
||||
import NotifierMock = require("./mocks/Notifier");
|
||||
import IdentityValidatorMock = require("./mocks/IdentityValidator");
|
||||
import { RequestLoggerStub } from "./mocks/RequestLoggerStub";
|
||||
import ExpressMock = require("./stubs/express.spec");
|
||||
import NotifierMock = require("./notifiers/NotifierStub.spec");
|
||||
import { IdentityValidableStub } from "./IdentityValidableStub.spec";
|
||||
import { RequestLoggerStub } from "./logging/RequestLoggerStub.spec";
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder }
|
||||
from "./mocks/ServerVariablesMockBuilder";
|
||||
from "./ServerVariablesMockBuilder.spec";
|
||||
import { PRE_VALIDATION_TEMPLATE }
|
||||
from "../src/lib/IdentityCheckPreValidationTemplate";
|
||||
from "./IdentityCheckPreValidationTemplate";
|
||||
|
||||
|
||||
describe("test identity check process", function () {
|
||||
describe("IdentityCheckMiddleware", function () {
|
||||
let req: ExpressMock.RequestMock;
|
||||
let res: ExpressMock.ResponseMock;
|
||||
let app: express.Application;
|
||||
let app_get: sinon.SinonStub;
|
||||
let app_post: sinon.SinonStub;
|
||||
let identityValidable: IdentityValidatorMock.IdentityValidableMock;
|
||||
let identityValidable: IdentityValidableStub;
|
||||
let mocks: ServerVariablesMock;
|
||||
let vars: ServerVariables;
|
||||
|
||||
|
@ -38,8 +38,6 @@ describe("test identity check process", function () {
|
|||
req = ExpressMock.RequestMock();
|
||||
res = ExpressMock.ResponseMock();
|
||||
|
||||
identityValidable = IdentityValidatorMock.IdentityValidableMock();
|
||||
|
||||
req.headers = {};
|
||||
req.originalUrl = "/non-api/xxx";
|
||||
req.session = {};
|
||||
|
@ -47,6 +45,8 @@ describe("test identity check process", function () {
|
|||
req.query = {};
|
||||
req.app = {};
|
||||
|
||||
identityValidable = new IdentityValidableStub();
|
||||
|
||||
mocks.notifier.notifyStub.returns(BluebirdPromise.resolve());
|
||||
mocks.userDataStore.produceIdentityValidationTokenStub
|
||||
.returns(BluebirdPromise.resolve());
|
||||
|
@ -66,7 +66,7 @@ describe("test identity check process", function () {
|
|||
describe("test start GET", function () {
|
||||
it("should redirect to error 401 if pre validation initialization \
|
||||
throws a first factor error", function () {
|
||||
identityValidable.preValidationInit.returns(BluebirdPromise.reject(
|
||||
identityValidable.preValidationInitStub.returns(BluebirdPromise.reject(
|
||||
new exceptions.FirstFactorValidationError(
|
||||
"Error during prevalidation")));
|
||||
const callback = IdentityValidator.get_start_validation(
|
||||
|
@ -83,14 +83,14 @@ throws a first factor error", function () {
|
|||
it("should send 200 if email is missing in provided identity", function () {
|
||||
const identity = { userid: "abc" };
|
||||
|
||||
identityValidable.preValidationInit
|
||||
identityValidable.preValidationInitStub
|
||||
.returns(BluebirdPromise.resolve(identity));
|
||||
const callback = IdentityValidator
|
||||
.get_start_validation(identityValidable, "/endpoint", vars);
|
||||
|
||||
return callback(req as any, res as any, undefined)
|
||||
.then(function () {
|
||||
Assert(identityValidable.preValidationResponse.called);
|
||||
Assert(identityValidable.preValidationResponseStub.called);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -100,14 +100,14 @@ throws a first factor error", function () {
|
|||
const endpoint = "/protected";
|
||||
const identity = { email: "abc@example.com" };
|
||||
|
||||
identityValidable.preValidationInit
|
||||
identityValidable.preValidationInitStub
|
||||
.returns(BluebirdPromise.resolve(identity));
|
||||
const callback = IdentityValidator
|
||||
.get_start_validation(identityValidable, "/endpoint", vars);
|
||||
|
||||
return callback(req as any, res as any, undefined)
|
||||
.then(function () {
|
||||
Assert(identityValidable.preValidationResponse.called);
|
||||
Assert(identityValidable.preValidationResponseStub.called);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -116,7 +116,7 @@ throws a first factor error", function () {
|
|||
const identity = { userid: "user", email: "abc@example.com" };
|
||||
req.get = sinon.stub().withArgs("Host").returns("localhost");
|
||||
|
||||
identityValidable.preValidationInit
|
||||
identityValidable.preValidationInitStub
|
||||
.returns(BluebirdPromise.resolve(identity));
|
||||
const callback = IdentityValidator
|
||||
.get_start_validation(identityValidable, "/finish_endpoint", vars);
|
||||
|
@ -177,24 +177,5 @@ valid", function () {
|
|||
Assert(res.redirect.calledWith("/error/401"));
|
||||
});
|
||||
});
|
||||
|
||||
it("should set the identity_check session object even if session does \
|
||||
not exist yet", function () {
|
||||
req.query.identity_token = "token";
|
||||
|
||||
req.session = {};
|
||||
const authSession =
|
||||
AuthenticationSessionHandler.get(req as any, vars.logger);
|
||||
const callback = IdentityValidator
|
||||
.get_finish_validation(identityValidable, vars);
|
||||
|
||||
return callback(req as any, res as any, undefined)
|
||||
.then(function () {
|
||||
return BluebirdPromise.reject("Should fail");
|
||||
})
|
||||
.catch(function () {
|
||||
Assert.equal(authSession.identity_check.userid, "user");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import objectPath = require("object-path");
|
||||
import randomstring = require("randomstring");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
|
@ -12,6 +11,7 @@ import ErrorReplies = require("./ErrorReplies");
|
|||
import { AuthenticationSessionHandler } from "./AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../types/AuthenticationSession";
|
||||
import { ServerVariables } from "./ServerVariables";
|
||||
import { IdentityValidable } from "./IdentityValidable";
|
||||
|
||||
import Identity = require("../../types/Identity");
|
||||
import { IdentityValidationDocument }
|
||||
|
@ -20,26 +20,9 @@ import { IdentityValidationDocument }
|
|||
const filePath = __dirname + "/../resources/email-template.ejs";
|
||||
const email_template = fs.readFileSync(filePath, "utf8");
|
||||
|
||||
// IdentityValidator allows user to go through a identity validation process
|
||||
// in two steps:
|
||||
// - Request an operation to be performed (password reset, registration).
|
||||
// - Confirm operation with email.
|
||||
|
||||
export interface IdentityValidable {
|
||||
challenge(): string;
|
||||
preValidationInit(req: Express.Request): BluebirdPromise<Identity.Identity>;
|
||||
postValidationInit(req: Express.Request): BluebirdPromise<void>;
|
||||
|
||||
// Serves a page after identity check request
|
||||
preValidationResponse(req: Express.Request, res: Express.Response): void;
|
||||
// Serves the page if identity validated
|
||||
postValidationResponse(req: Express.Request, res: Express.Response): void;
|
||||
mailSubject(): string;
|
||||
}
|
||||
|
||||
function createAndSaveToken(userid: string, challenge: string,
|
||||
userDataStore: IUserDataStore)
|
||||
: BluebirdPromise<string> {
|
||||
userDataStore: IUserDataStore): BluebirdPromise<string> {
|
||||
|
||||
const five_minutes = 4 * 60 * 1000;
|
||||
const token = randomstring.generate({ length: 64 });
|
||||
const that = this;
|
||||
|
@ -80,8 +63,10 @@ function checkIdentityToken(req: Express.Request, identityToken: string)
|
|||
export function get_finish_validation(handler: IdentityValidable,
|
||||
vars: ServerVariables)
|
||||
: Express.RequestHandler {
|
||||
|
||||
return function (req: Express.Request, res: Express.Response)
|
||||
: BluebirdPromise<void> {
|
||||
|
||||
let authSession: AuthenticationSession;
|
||||
const identityToken = objectPath.get<Express.Request, string>(
|
||||
req, "query.identity_token");
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import Bluebird = require("bluebird");
|
||||
import Identity = require("../../types/Identity");
|
||||
|
||||
// IdentityValidator allows user to go through a identity validation process
|
||||
// in two steps:
|
||||
// - Request an operation to be performed (password reset, registration).
|
||||
// - Confirm operation with email.
|
||||
|
||||
export interface IdentityValidable {
|
||||
challenge(): string;
|
||||
preValidationInit(req: Express.Request): Bluebird<Identity.Identity>;
|
||||
postValidationInit(req: Express.Request): Bluebird<void>;
|
||||
|
||||
// Serves a page after identity check request
|
||||
preValidationResponse(req: Express.Request, res: Express.Response): void;
|
||||
// Serves the page if identity validated
|
||||
postValidationResponse(req: Express.Request, res: Express.Response): void;
|
||||
mailSubject(): string;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
import Sinon = require("sinon");
|
||||
import { IdentityValidable } from "./IdentityValidable";
|
||||
import express = require("express");
|
||||
import Bluebird = require("bluebird");
|
||||
import { Identity } from "../../types/Identity";
|
||||
|
||||
|
||||
export class IdentityValidableStub implements IdentityValidable {
|
||||
challengeStub: Sinon.SinonStub;
|
||||
preValidationInitStub: Sinon.SinonStub;
|
||||
postValidationInitStub: Sinon.SinonStub;
|
||||
preValidationResponseStub: Sinon.SinonStub;
|
||||
postValidationResponseStub: Sinon.SinonStub;
|
||||
mailSubjectStub: Sinon.SinonStub;
|
||||
|
||||
constructor() {
|
||||
this.challengeStub = Sinon.stub();
|
||||
|
||||
this.preValidationInitStub = Sinon.stub();
|
||||
this.postValidationResponseStub = Sinon.stub();
|
||||
|
||||
this.preValidationResponseStub = Sinon.stub();
|
||||
this.postValidationResponseStub = Sinon.stub();
|
||||
|
||||
this.mailSubjectStub = Sinon.stub();
|
||||
}
|
||||
|
||||
challenge(): string {
|
||||
return this.challengeStub();
|
||||
}
|
||||
|
||||
preValidationInit(req: Express.Request): Bluebird<Identity> {
|
||||
return this.preValidationInitStub(req);
|
||||
}
|
||||
|
||||
postValidationInit(req: Express.Request): Bluebird<void> {
|
||||
return this.postValidationInitStub(req);
|
||||
}
|
||||
|
||||
preValidationResponse(req: Express.Request, res: Express.Response): void {
|
||||
return this.preValidationResponseStub(req, res);
|
||||
}
|
||||
|
||||
postValidationResponse(req: Express.Request, res: Express.Response): void {
|
||||
return this.postValidationResponseStub(req, res);
|
||||
}
|
||||
|
||||
mailSubject(): string {
|
||||
return this.mailSubjectStub();
|
||||
}
|
||||
}
|
|
@ -7,13 +7,13 @@ import winston = require("winston");
|
|||
import speakeasy = require("speakeasy");
|
||||
import u2f = require("u2f");
|
||||
import session = require("express-session");
|
||||
import { AppConfiguration, UserConfiguration } from "../src/lib/configuration/Configuration";
|
||||
import { GlobalDependencies } from "../types/Dependencies";
|
||||
import Server from "../src/lib/Server";
|
||||
import { LdapjsMock, LdapjsClientMock } from "./mocks/ldapjs";
|
||||
import { Configuration } from "./configuration/schema/Configuration";
|
||||
import { GlobalDependencies } from "../../types/Dependencies";
|
||||
import Server from "./Server";
|
||||
import { LdapjsMock, LdapjsClientMock } from "./stubs/ldapjs.spec";
|
||||
|
||||
|
||||
describe("test server configuration", function () {
|
||||
describe("Server", function () {
|
||||
let deps: GlobalDependencies;
|
||||
let sessionMock: Sinon.SinonSpy;
|
||||
let ldapjsMock: LdapjsMock;
|
||||
|
@ -36,7 +36,7 @@ describe("test server configuration", function () {
|
|||
|
||||
|
||||
it("should set cookie scope to domain set in the config", function () {
|
||||
const config: UserConfiguration = {
|
||||
const config: Configuration = {
|
||||
port: 8081,
|
||||
session: {
|
||||
domain: "example.com",
|
|
@ -2,7 +2,7 @@ import BluebirdPromise = require("bluebird");
|
|||
import ObjectPath = require("object-path");
|
||||
|
||||
import { AccessController } from "./access_control/AccessController";
|
||||
import { AppConfiguration, UserConfiguration } from "./configuration/Configuration";
|
||||
import { Configuration } from "./configuration/schema/Configuration";
|
||||
import { GlobalDependencies } from "../../types/Dependencies";
|
||||
import { UserDataStore } from "./storage/UserDataStore";
|
||||
import { ConfigurationParser } from "./configuration/ConfigurationParser";
|
||||
|
@ -31,33 +31,22 @@ export default class Server {
|
|||
this.requestLogger = new RequestLogger(deps.winston);
|
||||
}
|
||||
|
||||
private displayConfigurations(userConfiguration: UserConfiguration,
|
||||
appConfiguration: AppConfiguration) {
|
||||
const displayableUserConfiguration = clone(userConfiguration);
|
||||
const displayableAppConfiguration = clone(appConfiguration);
|
||||
private displayConfigurations(configuration: Configuration) {
|
||||
const displayableConfiguration: Configuration = clone(configuration);
|
||||
const STARS = "*****";
|
||||
|
||||
displayableUserConfiguration.ldap.password = STARS;
|
||||
displayableUserConfiguration.session.secret = STARS;
|
||||
if (displayableUserConfiguration.notifier && displayableUserConfiguration.notifier.email)
|
||||
displayableUserConfiguration.notifier.email.password = STARS;
|
||||
if (displayableUserConfiguration.notifier && displayableUserConfiguration.notifier.smtp)
|
||||
displayableUserConfiguration.notifier.smtp.password = STARS;
|
||||
|
||||
displayableAppConfiguration.ldap.password = STARS;
|
||||
displayableAppConfiguration.session.secret = STARS;
|
||||
if (displayableAppConfiguration.notifier && displayableAppConfiguration.notifier.email)
|
||||
displayableAppConfiguration.notifier.email.password = STARS;
|
||||
if (displayableAppConfiguration.notifier && displayableAppConfiguration.notifier.smtp)
|
||||
displayableAppConfiguration.notifier.smtp.password = STARS;
|
||||
displayableConfiguration.ldap.password = STARS;
|
||||
displayableConfiguration.session.secret = STARS;
|
||||
if (displayableConfiguration.notifier && displayableConfiguration.notifier.email)
|
||||
displayableConfiguration.notifier.email.password = STARS;
|
||||
if (displayableConfiguration.notifier && displayableConfiguration.notifier.smtp)
|
||||
displayableConfiguration.notifier.smtp.password = STARS;
|
||||
|
||||
this.globalLogger.debug("User configuration is %s",
|
||||
JSON.stringify(displayableUserConfiguration, undefined, 2));
|
||||
this.globalLogger.debug("Adapted configuration is %s",
|
||||
JSON.stringify(displayableAppConfiguration, undefined, 2));
|
||||
JSON.stringify(displayableConfiguration, undefined, 2));
|
||||
}
|
||||
|
||||
private setup(config: AppConfiguration, app: Express.Application, deps: GlobalDependencies): BluebirdPromise<void> {
|
||||
private setup(config: Configuration, app: Express.Application, deps: GlobalDependencies): BluebirdPromise<void> {
|
||||
const that = this;
|
||||
return ServerVariablesInitializer.initialize(config, this.requestLogger, deps)
|
||||
.then(function (vars: ServerVariables) {
|
||||
|
@ -76,16 +65,16 @@ export default class Server {
|
|||
});
|
||||
}
|
||||
|
||||
start(userConfiguration: UserConfiguration, deps: GlobalDependencies)
|
||||
start(configuration: Configuration, deps: GlobalDependencies)
|
||||
: BluebirdPromise<void> {
|
||||
const that = this;
|
||||
const app = Express();
|
||||
|
||||
const appConfiguration = ConfigurationParser.parse(userConfiguration);
|
||||
const appConfiguration = ConfigurationParser.parse(configuration);
|
||||
|
||||
// by default the level of logs is info
|
||||
deps.winston.level = userConfiguration.logs_level;
|
||||
this.displayConfigurations(userConfiguration, appConfiguration);
|
||||
deps.winston.level = configuration.logs_level;
|
||||
this.displayConfigurations(configuration);
|
||||
|
||||
return this.setup(appConfiguration, app, deps)
|
||||
.then(function () {
|
||||
|
|
|
@ -7,7 +7,7 @@ import { IU2fHandler } from "./authentication/u2f/IU2fHandler";
|
|||
import { IUserDataStore } from "./storage/IUserDataStore";
|
||||
import { INotifier } from "./notifiers/INotifier";
|
||||
import { IRegulator } from "./regulation/IRegulator";
|
||||
import { AppConfiguration } from "./configuration/Configuration";
|
||||
import { Configuration } from "./configuration/schema/Configuration";
|
||||
import { IAccessController } from "./access_control/IAccessController";
|
||||
|
||||
export interface ServerVariables {
|
||||
|
@ -20,6 +20,6 @@ export interface ServerVariables {
|
|||
userDataStore: IUserDataStore;
|
||||
notifier: INotifier;
|
||||
regulator: IRegulator;
|
||||
config: AppConfiguration;
|
||||
config: Configuration;
|
||||
accessController: IAccessController;
|
||||
}
|
|
@ -26,7 +26,7 @@ import { UserDataStore } from "./storage/UserDataStore";
|
|||
import { INotifier } from "./notifiers/INotifier";
|
||||
import { Regulator } from "./regulation/Regulator";
|
||||
import { IRegulator } from "./regulation/IRegulator";
|
||||
import Configuration = require("./configuration/Configuration");
|
||||
import Configuration = require("./configuration/schema/Configuration");
|
||||
import { AccessController } from "./access_control/AccessController";
|
||||
import { IAccessController } from "./access_control/IAccessController";
|
||||
import { CollectionFactoryFactory } from "./storage/CollectionFactoryFactory";
|
||||
|
@ -40,7 +40,7 @@ import { ServerVariables } from "./ServerVariables";
|
|||
import { MethodCalculator } from "./authentication/MethodCalculator";
|
||||
|
||||
class UserDataStoreFactory {
|
||||
static create(config: Configuration.AppConfiguration): BluebirdPromise<UserDataStore> {
|
||||
static create(config: Configuration.Configuration): BluebirdPromise<UserDataStore> {
|
||||
if (config.storage.local) {
|
||||
const nedbOptions: Nedb.DataStoreOptions = {
|
||||
filename: config.storage.local.path,
|
||||
|
@ -64,7 +64,7 @@ class UserDataStoreFactory {
|
|||
}
|
||||
|
||||
export class ServerVariablesInitializer {
|
||||
static initialize(config: Configuration.AppConfiguration, requestLogger: IRequestLogger,
|
||||
static initialize(config: Configuration.Configuration, requestLogger: IRequestLogger,
|
||||
deps: GlobalDependencies): BluebirdPromise<ServerVariables> {
|
||||
const mailSenderBuilder = new MailSenderBuilder(Nodemailer);
|
||||
const notifier = NotifierFactory.build(config.notifier, mailSenderBuilder);
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import { ServerVariables } from "../../src/lib/ServerVariables";
|
||||
import { ServerVariables } from "./ServerVariables";
|
||||
|
||||
import { AppConfiguration } from "../../src/lib/configuration/Configuration";
|
||||
import { AuthenticatorStub } from "./ldap/AuthenticatorStub";
|
||||
import { EmailsRetrieverStub } from "./ldap/EmailsRetrieverStub";
|
||||
import { PasswordUpdaterStub } from "./ldap/PasswordUpdaterStub";
|
||||
import { AccessControllerStub } from "./AccessControllerStub";
|
||||
import { RequestLoggerStub } from "./RequestLoggerStub";
|
||||
import { NotifierStub } from "./NotifierStub";
|
||||
import { RegulatorStub } from "./RegulatorStub";
|
||||
import { TotpHandlerStub } from "./TotpHandlerStub";
|
||||
import { UserDataStoreStub } from "./storage/UserDataStoreStub";
|
||||
import { U2fHandlerStub } from "./U2fHandlerStub";
|
||||
import { Configuration } from "./configuration/schema/Configuration";
|
||||
import { AuthenticatorStub } from "./ldap/AuthenticatorStub.spec";
|
||||
import { EmailsRetrieverStub } from "./ldap/EmailsRetrieverStub.spec";
|
||||
import { PasswordUpdaterStub } from "./ldap/PasswordUpdaterStub.spec";
|
||||
import { AccessControllerStub } from "./access_control/AccessControllerStub.spec";
|
||||
import { RequestLoggerStub } from "./logging/RequestLoggerStub.spec";
|
||||
import { NotifierStub } from "./notifiers/NotifierStub.spec";
|
||||
import { RegulatorStub } from "./regulation/RegulatorStub.spec";
|
||||
import { TotpHandlerStub } from "./authentication/totp/TotpHandlerStub.spec";
|
||||
import { UserDataStoreStub } from "./storage/UserDataStoreStub.spec";
|
||||
import { U2fHandlerStub } from "./authentication/u2f/U2fHandlerStub.spec";
|
||||
|
||||
export interface ServerVariablesMock {
|
||||
accessController: AccessControllerStub;
|
||||
config: AppConfiguration;
|
||||
config: Configuration;
|
||||
ldapAuthenticator: AuthenticatorStub;
|
||||
ldapEmailsRetriever: EmailsRetrieverStub;
|
||||
ldapPasswordUpdater: PasswordUpdaterStub;
|
||||
|
@ -40,11 +40,12 @@ export class ServerVariablesMockBuilder {
|
|||
},
|
||||
ldap: {
|
||||
url: "ldap://ldap",
|
||||
base_dn: "dc=example,dc=com",
|
||||
user: "user",
|
||||
password: "password",
|
||||
mail_attribute: "mail",
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
users_filter: "cn={0}",
|
||||
groups_filter: "member={dn}",
|
||||
group_name_attribute: "cn"
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
import Assert = require("assert");
|
||||
import winston = require("winston");
|
||||
import { AccessController } from "../../src/lib/access_control/AccessController";
|
||||
import { ACLConfiguration, ACLRule } from "../../src/lib/configuration/Configuration";
|
||||
import { AccessController } from "./AccessController";
|
||||
import { ACLConfiguration, ACLRule } from "../configuration/schema/AclConfiguration";
|
||||
|
||||
describe("test access control manager", function () {
|
||||
describe("access_control/AccessController", function () {
|
||||
let accessController: AccessController;
|
||||
let configuration: ACLConfiguration;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
import { ACLConfiguration, ACLPolicy, ACLRule } from "../configuration/Configuration";
|
||||
import { ACLConfiguration, ACLPolicy, ACLRule } from "../configuration/schema/AclConfiguration";
|
||||
import { IAccessController } from "./IAccessController";
|
||||
import { Winston } from "../../../types/Dependencies";
|
||||
import { MultipleDomainMatcher } from "./MultipleDomainMatcher";
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
import Sinon = require("sinon");
|
||||
import { IAccessController } from "../../src/lib/access_control/IAccessController";
|
||||
import { IAccessController } from "./IAccessController";
|
||||
|
||||
export class AccessControllerStub implements IAccessController {
|
||||
isAccessAllowedMock: Sinon.SinonStub;
|
|
@ -1,10 +1,9 @@
|
|||
import { MethodCalculator }
|
||||
from "../../src/lib/authentication/MethodCalculator";
|
||||
import { MethodCalculator } from "./MethodCalculator";
|
||||
import { AuthenticationMethodsConfiguration }
|
||||
from "../../src/lib/configuration/Configuration";
|
||||
from "../configuration/schema/AuthenticationMethodsConfiguration";
|
||||
import Assert = require("assert");
|
||||
|
||||
describe("test MethodCalculator", function () {
|
||||
describe("authentication/MethodCalculator", function () {
|
||||
describe("test compute method", function () {
|
||||
it("should return default method when sub domain not overriden",
|
||||
function () {
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
AuthenticationMethod,
|
||||
AuthenticationMethodsConfiguration
|
||||
} from "../configuration/Configuration";
|
||||
} from "../configuration/schema/AuthenticationMethodsConfiguration";
|
||||
|
||||
function computeIsSingleFactorOnlyMode(
|
||||
configuration: AuthenticationMethodsConfiguration): boolean {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
import { TotpHandler } from "../../../src/lib/authentication/totp/TotpHandler";
|
||||
import { TotpHandler } from "./TotpHandler";
|
||||
import Sinon = require("sinon");
|
||||
import Speakeasy = require("speakeasy");
|
||||
import Assert = require("assert");
|
||||
|
||||
describe("test TOTP validation", function() {
|
||||
describe("authentication/totp/TotpHandler", function() {
|
||||
let totpValidator: TotpHandler;
|
||||
let validateStub: Sinon.SinonStub;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import { ITotpHandler } from "../../src/lib/authentication/totp/ITotpHandler";
|
||||
import { TOTPSecret } from "../../types/TOTPSecret";
|
||||
import { ITotpHandler } from "./ITotpHandler";
|
||||
import { TOTPSecret } from "../../../../types/TOTPSecret";
|
||||
|
||||
export class TotpHandlerStub implements ITotpHandler {
|
||||
generateStub: Sinon.SinonStub;
|
|
@ -1,7 +1,7 @@
|
|||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import U2f = require("u2f");
|
||||
import { IU2fHandler } from "../../src/lib/authentication/u2f/IU2fHandler";
|
||||
import { IU2fHandler } from "./IU2fHandler";
|
||||
|
||||
|
||||
export class U2fHandlerStub implements IU2fHandler {
|
|
@ -1,155 +0,0 @@
|
|||
export interface UserLdapConfiguration {
|
||||
url: string;
|
||||
base_dn: string;
|
||||
|
||||
additional_users_dn?: string;
|
||||
users_filter?: string;
|
||||
|
||||
additional_groups_dn?: string;
|
||||
groups_filter?: string;
|
||||
|
||||
group_name_attribute?: string;
|
||||
mail_attribute?: string;
|
||||
|
||||
user: string; // admin username
|
||||
password: string; // admin password
|
||||
}
|
||||
|
||||
export interface LdapConfiguration {
|
||||
url: string;
|
||||
|
||||
users_dn: string;
|
||||
users_filter: string;
|
||||
|
||||
groups_dn: string;
|
||||
groups_filter: string;
|
||||
|
||||
group_name_attribute: string;
|
||||
mail_attribute: string;
|
||||
|
||||
user: string; // admin username
|
||||
password: string; // admin password
|
||||
}
|
||||
|
||||
type UserName = string;
|
||||
type GroupName = string;
|
||||
type DomainPattern = string;
|
||||
|
||||
export type ACLPolicy = 'deny' | 'allow';
|
||||
|
||||
export type ACLRule = {
|
||||
domain: string;
|
||||
policy: ACLPolicy;
|
||||
resources?: string[];
|
||||
}
|
||||
|
||||
export type ACLDefaultRules = ACLRule[];
|
||||
export type ACLGroupsRules = { [group: string]: ACLRule[]; };
|
||||
export type ACLUsersRules = { [user: string]: ACLRule[]; };
|
||||
|
||||
export interface ACLConfiguration {
|
||||
default_policy?: ACLPolicy;
|
||||
any?: ACLDefaultRules;
|
||||
groups?: ACLGroupsRules;
|
||||
users?: ACLUsersRules;
|
||||
}
|
||||
|
||||
export interface SessionRedisOptions {
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
interface SessionCookieConfiguration {
|
||||
secret: string;
|
||||
expiration?: number;
|
||||
inactivity?: number;
|
||||
domain: string;
|
||||
redis?: SessionRedisOptions;
|
||||
}
|
||||
|
||||
export interface EmailNotifierConfiguration {
|
||||
username: string;
|
||||
password: string;
|
||||
sender: string;
|
||||
service: string;
|
||||
}
|
||||
|
||||
export interface SmtpNotifierConfiguration {
|
||||
username?: string;
|
||||
password?: string;
|
||||
host: string;
|
||||
port: number;
|
||||
secure: boolean;
|
||||
sender: string;
|
||||
}
|
||||
|
||||
export interface FileSystemNotifierConfiguration {
|
||||
filename: string;
|
||||
}
|
||||
|
||||
export interface NotifierConfiguration {
|
||||
email?: EmailNotifierConfiguration;
|
||||
smtp?: SmtpNotifierConfiguration;
|
||||
filesystem?: FileSystemNotifierConfiguration;
|
||||
}
|
||||
|
||||
export interface MongoStorageConfiguration {
|
||||
url: string;
|
||||
database: string;
|
||||
}
|
||||
|
||||
export interface LocalStorageConfiguration {
|
||||
path?: string;
|
||||
in_memory?: boolean;
|
||||
}
|
||||
|
||||
export interface StorageConfiguration {
|
||||
local?: LocalStorageConfiguration;
|
||||
mongo?: MongoStorageConfiguration;
|
||||
}
|
||||
|
||||
export interface RegulationConfiguration {
|
||||
max_retries: number;
|
||||
find_time: number;
|
||||
ban_time: number;
|
||||
}
|
||||
|
||||
declare type AuthenticationMethod = 'two_factor' | 'single_factor';
|
||||
declare type AuthenticationMethodPerSubdomain = { [subdomain: string]: AuthenticationMethod }
|
||||
|
||||
export interface AuthenticationMethodsConfiguration {
|
||||
default_method: AuthenticationMethod;
|
||||
per_subdomain_methods?: AuthenticationMethodPerSubdomain;
|
||||
}
|
||||
|
||||
export interface TOTPConfiguration {
|
||||
issuer: string;
|
||||
}
|
||||
|
||||
export interface UserConfiguration {
|
||||
port?: number;
|
||||
logs_level?: string;
|
||||
ldap: UserLdapConfiguration;
|
||||
session: SessionCookieConfiguration;
|
||||
storage: StorageConfiguration;
|
||||
notifier: NotifierConfiguration;
|
||||
authentication_methods?: AuthenticationMethodsConfiguration;
|
||||
access_control?: ACLConfiguration;
|
||||
regulation: RegulationConfiguration;
|
||||
default_redirection_url?: string;
|
||||
totp?: TOTPConfiguration;
|
||||
}
|
||||
|
||||
export interface AppConfiguration {
|
||||
port: number;
|
||||
logs_level: string;
|
||||
ldap: LdapConfiguration;
|
||||
session: SessionCookieConfiguration;
|
||||
storage: StorageConfiguration;
|
||||
notifier: NotifierConfiguration;
|
||||
authentication_methods: AuthenticationMethodsConfiguration;
|
||||
access_control?: ACLConfiguration;
|
||||
regulation: RegulationConfiguration;
|
||||
default_redirection_url?: string;
|
||||
totp: TOTPConfiguration;
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
import * as Assert from "assert";
|
||||
import {
|
||||
UserConfiguration,
|
||||
LdapConfiguration, ACLConfiguration
|
||||
} from "../../src/lib/configuration/Configuration";
|
||||
import { ConfigurationParser } from "../../src/lib/configuration/ConfigurationParser";
|
||||
import { Configuration } from "./schema/Configuration";
|
||||
import { ACLConfiguration } from "./schema/AclConfiguration";
|
||||
import { ConfigurationParser } from "./ConfigurationParser";
|
||||
|
||||
describe("test config parser", function () {
|
||||
function buildYamlConfig(): UserConfiguration {
|
||||
const yaml_config: UserConfiguration = {
|
||||
describe("configuration/ConfigurationParser", function () {
|
||||
function buildYamlConfig(): Configuration {
|
||||
const yaml_config: Configuration = {
|
||||
port: 8080,
|
||||
ldap: {
|
||||
url: "http://ldap",
|
||||
|
@ -160,11 +158,11 @@ describe("test config parser", function () {
|
|||
userConfig.access_control = {} as any;
|
||||
const config = ConfigurationParser.parse(userConfig);
|
||||
Assert.deepEqual(config.access_control, {
|
||||
default_policy: "deny",
|
||||
default_policy: "allow",
|
||||
any: [],
|
||||
users: {},
|
||||
groups: {}
|
||||
} as ACLConfiguration);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,109 +1,39 @@
|
|||
|
||||
import * as ObjectPath from "object-path";
|
||||
import {
|
||||
AppConfiguration, UserConfiguration, NotifierConfiguration,
|
||||
ACLConfiguration, LdapConfiguration, SessionRedisOptions,
|
||||
MongoStorageConfiguration, LocalStorageConfiguration,
|
||||
UserLdapConfiguration
|
||||
} from "./Configuration";
|
||||
import { Configuration, complete } from "./schema/Configuration";
|
||||
import Ajv = require("ajv");
|
||||
import Path = require("path");
|
||||
import Util = require("util");
|
||||
import { ACLAdapter } from "./adapters/ACLAdapter";
|
||||
import { TOTPAdapter } from "./adapters/TOTPAdapter";
|
||||
import { AuthenticationMethodsAdapter } from "./adapters/AuthenticationMethodsAdapter";
|
||||
import { Validator } from "./Validator";
|
||||
|
||||
const LDAP_URL_ENV_VARIABLE = "LDAP_URL";
|
||||
|
||||
function get_optional<T>(config: object, path: string, default_value: T): T {
|
||||
let entry = default_value;
|
||||
if (ObjectPath.has(config, path)) {
|
||||
entry = ObjectPath.get<object, T>(config, path);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
function ensure_key_existence(config: object, path: string): void {
|
||||
if (!ObjectPath.has(config, path)) {
|
||||
throw new Error(`Configuration error: key '${path}' is missing in configuration file`);
|
||||
}
|
||||
}
|
||||
|
||||
function adaptLdapConfiguration(userConfig: UserLdapConfiguration): LdapConfiguration {
|
||||
const DEFAULT_USERS_FILTER = "cn={0}";
|
||||
const DEFAULT_GROUPS_FILTER = "member={dn}";
|
||||
const DEFAULT_GROUP_NAME_ATTRIBUTE = "cn";
|
||||
const DEFAULT_MAIL_ATTRIBUTE = "mail";
|
||||
|
||||
let usersDN = userConfig.base_dn;
|
||||
if (userConfig.additional_users_dn)
|
||||
usersDN = userConfig.additional_users_dn + "," + usersDN;
|
||||
|
||||
let groupsDN = userConfig.base_dn;
|
||||
if (userConfig.additional_groups_dn)
|
||||
groupsDN = userConfig.additional_groups_dn + "," + groupsDN;
|
||||
|
||||
return {
|
||||
url: userConfig.url,
|
||||
users_dn: usersDN,
|
||||
users_filter: userConfig.users_filter || DEFAULT_USERS_FILTER,
|
||||
groups_dn: groupsDN,
|
||||
groups_filter: userConfig.groups_filter || DEFAULT_GROUPS_FILTER,
|
||||
group_name_attribute: userConfig.group_name_attribute || DEFAULT_GROUP_NAME_ATTRIBUTE,
|
||||
mail_attribute: userConfig.mail_attribute || DEFAULT_MAIL_ATTRIBUTE,
|
||||
password: userConfig.password,
|
||||
user: userConfig.user
|
||||
};
|
||||
}
|
||||
|
||||
function adaptFromUserConfiguration(userConfiguration: UserConfiguration)
|
||||
: AppConfiguration {
|
||||
if (!Validator.isValid(userConfiguration))
|
||||
throw new Error("Configuration is malformed. Please double check your configuration file.");
|
||||
|
||||
const port = userConfiguration.port || 8080;
|
||||
const ldapConfiguration = adaptLdapConfiguration(userConfiguration.ldap);
|
||||
const authenticationMethods = AuthenticationMethodsAdapter
|
||||
.adapt(userConfiguration.authentication_methods);
|
||||
const totpConfiguration = TOTPAdapter.adapt(userConfiguration.totp);
|
||||
|
||||
return {
|
||||
port: port,
|
||||
ldap: ldapConfiguration,
|
||||
session: {
|
||||
domain: ObjectPath.get<object, string>(userConfiguration, "session.domain"),
|
||||
secret: ObjectPath.get<object, string>(userConfiguration, "session.secret"),
|
||||
expiration: get_optional<number>(userConfiguration, "session.expiration", 3600000), // in ms
|
||||
inactivity: get_optional<number>(userConfiguration, "session.inactivity", undefined),
|
||||
redis: ObjectPath.get<object, SessionRedisOptions>(userConfiguration, "session.redis")
|
||||
},
|
||||
storage: {
|
||||
local: get_optional<LocalStorageConfiguration>(userConfiguration, "storage.local", undefined),
|
||||
mongo: get_optional<MongoStorageConfiguration>(userConfiguration, "storage.mongo", undefined)
|
||||
},
|
||||
logs_level: get_optional<string>(userConfiguration, "logs_level", "info"),
|
||||
notifier: ObjectPath.get<object, NotifierConfiguration>(userConfiguration, "notifier"),
|
||||
access_control: ACLAdapter.adapt(userConfiguration.access_control),
|
||||
regulation: userConfiguration.regulation,
|
||||
authentication_methods: authenticationMethods,
|
||||
default_redirection_url: userConfiguration.default_redirection_url,
|
||||
totp: totpConfiguration
|
||||
};
|
||||
}
|
||||
|
||||
export class ConfigurationParser {
|
||||
static parse(userConfiguration: UserConfiguration): AppConfiguration {
|
||||
const errors = Validator.isValid(userConfiguration);
|
||||
if (errors.length > 0) {
|
||||
errors.forEach((e: string) => { console.log(e); });
|
||||
private static parseTypes(configuration: Configuration): string[] {
|
||||
const schema = require(Path.resolve(__dirname, "./Configuration.schema.json"));
|
||||
const ajv = new Ajv({
|
||||
allErrors: true,
|
||||
missingRefs: "fail"
|
||||
});
|
||||
ajv.addMetaSchema(require("ajv/lib/refs/json-schema-draft-06.json"));
|
||||
const valid = ajv.validate(schema, configuration);
|
||||
if (!valid)
|
||||
return ajv.errors.map(
|
||||
(e: Ajv.ErrorObject) => { return ajv.errorsText([e]); });
|
||||
return [];
|
||||
}
|
||||
|
||||
static parse(configuration: Configuration): Configuration {
|
||||
const validationErrors = this.parseTypes(configuration);
|
||||
if (validationErrors.length > 0) {
|
||||
validationErrors.forEach((e: string) => { console.log(e); });
|
||||
throw new Error("Malformed configuration. Please double-check your configuration file.");
|
||||
}
|
||||
const appConfiguration = adaptFromUserConfiguration(userConfiguration);
|
||||
|
||||
const ldapUrl = process.env[LDAP_URL_ENV_VARIABLE];
|
||||
if (ldapUrl)
|
||||
appConfiguration.ldap.url = ldapUrl;
|
||||
const [newConfiguration, completionErrors] = complete(configuration);
|
||||
|
||||
return appConfiguration;
|
||||
if (completionErrors.length > 0) {
|
||||
completionErrors.forEach((e: string) => { console.log(e); });
|
||||
throw new Error("Malformed configuration. Please double-check your configuration file.");
|
||||
}
|
||||
return newConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { SessionConfigurationBuilder } from "../src/lib/configuration/SessionConfigurationBuilder";
|
||||
import { AppConfiguration } from "../src/lib/configuration/Configuration";
|
||||
import { GlobalDependencies } from "../types/Dependencies";
|
||||
import { SessionConfigurationBuilder } from "./SessionConfigurationBuilder";
|
||||
import { Configuration } from "./schema/Configuration";
|
||||
import { GlobalDependencies } from "../../../types/Dependencies";
|
||||
|
||||
import ExpressSession = require("express-session");
|
||||
import ConnectRedis = require("connect-redis");
|
||||
import Sinon = require("sinon");
|
||||
import Assert = require("assert");
|
||||
|
||||
describe("test session configuration builder", function () {
|
||||
describe("configuration/SessionConfigurationBuilder", function () {
|
||||
it("should return session options without redis options", function () {
|
||||
const configuration: AppConfiguration = {
|
||||
const configuration: Configuration = {
|
||||
access_control: {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
|
@ -22,9 +22,10 @@ describe("test session configuration builder", function () {
|
|||
ldap: {
|
||||
url: "ldap://ldap",
|
||||
user: "user",
|
||||
base_dn: "dc=example,dc=com",
|
||||
password: "password",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
additional_groups_dn: "ou=groups",
|
||||
additional_users_dn: "ou=users",
|
||||
group_name_attribute: "",
|
||||
groups_filter: "",
|
||||
mail_attribute: "",
|
||||
|
@ -87,7 +88,7 @@ describe("test session configuration builder", function () {
|
|||
});
|
||||
|
||||
it("should return session options with redis options", function () {
|
||||
const configuration: AppConfiguration = {
|
||||
const configuration: Configuration = {
|
||||
access_control: {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
|
@ -101,8 +102,9 @@ describe("test session configuration builder", function () {
|
|||
url: "ldap://ldap",
|
||||
user: "user",
|
||||
password: "password",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
base_dn: "dc=example,dc=com",
|
||||
additional_groups_dn: "ou=groups",
|
||||
additional_users_dn: "ou=users",
|
||||
group_name_attribute: "",
|
||||
groups_filter: "",
|
||||
mail_attribute: "",
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
import ExpressSession = require("express-session");
|
||||
import { AppConfiguration } from "./Configuration";
|
||||
import { Configuration } from "./schema/Configuration";
|
||||
import { GlobalDependencies } from "../../../types/Dependencies";
|
||||
|
||||
export class SessionConfigurationBuilder {
|
||||
|
||||
static build(configuration: AppConfiguration, deps: GlobalDependencies): ExpressSession.SessionOptions {
|
||||
static build(configuration: Configuration, deps: GlobalDependencies): ExpressSession.SessionOptions {
|
||||
const sessionOptions: ExpressSession.SessionOptions = {
|
||||
secret: configuration.session.secret,
|
||||
resave: false,
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
import Ajv = require("ajv");
|
||||
import Path = require("path");
|
||||
import Util = require("util");
|
||||
import {
|
||||
UserConfiguration, StorageConfiguration,
|
||||
NotifierConfiguration, AuthenticationMethodsConfiguration
|
||||
} from "./Configuration";
|
||||
import { MethodCalculator } from "../authentication/MethodCalculator";
|
||||
|
||||
function validateSchema(configuration: UserConfiguration): string[] {
|
||||
const schema = require(Path.resolve(__dirname, "./Configuration.schema.json"));
|
||||
const ajv = new Ajv({
|
||||
allErrors: true,
|
||||
missingRefs: "fail"
|
||||
});
|
||||
ajv.addMetaSchema(require("ajv/lib/refs/json-schema-draft-06.json"));
|
||||
const valid = ajv.validate(schema, configuration);
|
||||
if (!valid)
|
||||
return ajv.errors.map(
|
||||
(e: Ajv.ErrorObject) => { return ajv.errorsText([e]); });
|
||||
return [];
|
||||
}
|
||||
|
||||
function diff(a: string[], b: string[]) {
|
||||
return a.filter(function(i) {return b.indexOf(i) < 0; });
|
||||
}
|
||||
|
||||
function validateUnknownKeys(path: string, obj: any, knownKeys: string[]) {
|
||||
const keysSet = Object.keys(obj);
|
||||
|
||||
const unknownKeysSet = diff(keysSet, knownKeys);
|
||||
if (unknownKeysSet.length > 0) {
|
||||
const unknownKeys = Array.from(unknownKeysSet);
|
||||
return unknownKeys.map((k: string) => { return Util.format("data.%s has unknown key '%s'", path, k); });
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function validateStorage(storage: any): string[] {
|
||||
const ERROR = "Storage must be either 'local' or 'mongo'";
|
||||
|
||||
if (!storage)
|
||||
return [];
|
||||
|
||||
const errors = validateUnknownKeys("storage", storage, ["local", "mongo"]);
|
||||
if (errors.length > 0)
|
||||
return errors;
|
||||
|
||||
if (storage.local && storage.mongo)
|
||||
return [ERROR];
|
||||
|
||||
if (!storage.local && !storage.mongo)
|
||||
return [ERROR];
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function validateNotifier(notifier: NotifierConfiguration,
|
||||
authenticationMethods: AuthenticationMethodsConfiguration): string[] {
|
||||
const ERROR = "Notifier must be either 'filesystem', 'email' or 'smtp'";
|
||||
|
||||
if (!notifier)
|
||||
return [];
|
||||
|
||||
if (!MethodCalculator.isSingleFactorOnlyMode(authenticationMethods)) {
|
||||
if (Object.keys(notifier).length != 1)
|
||||
return ["A notifier needs to be declared when server is used with two-factor"];
|
||||
|
||||
if (notifier && notifier.filesystem && notifier.email && notifier.smtp)
|
||||
return [ERROR];
|
||||
|
||||
if (notifier && !notifier.filesystem && !notifier.email && !notifier.smtp)
|
||||
return [ERROR];
|
||||
}
|
||||
|
||||
const errors = validateUnknownKeys("notifier", notifier, ["filesystem", "email", "smtp"]);
|
||||
if (errors.length > 0)
|
||||
return errors;
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
export class Validator {
|
||||
static isValid(configuration: any): string[] {
|
||||
const schemaErrors = validateSchema(configuration);
|
||||
const storageErrors = validateStorage(configuration.storage);
|
||||
const notifierErrors = validateNotifier(configuration.notifier,
|
||||
configuration.authentication_methods);
|
||||
|
||||
return schemaErrors
|
||||
.concat(storageErrors)
|
||||
.concat(notifierErrors);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
import { ACLConfiguration } from "../Configuration";
|
||||
import { ObjectCloner } from "../../utils/ObjectCloner";
|
||||
|
||||
const DEFAULT_POLICY = "deny";
|
||||
|
||||
function adaptDefaultPolicy(configuration: ACLConfiguration) {
|
||||
if (!configuration.default_policy)
|
||||
configuration.default_policy = DEFAULT_POLICY;
|
||||
if (configuration.default_policy != "deny" && configuration.default_policy != "allow")
|
||||
configuration.default_policy = DEFAULT_POLICY;
|
||||
}
|
||||
|
||||
function adaptAny(configuration: ACLConfiguration) {
|
||||
if (!configuration.any || !(configuration.any.constructor === Array))
|
||||
configuration.any = [];
|
||||
}
|
||||
|
||||
function adaptGroups(configuration: ACLConfiguration) {
|
||||
if (!configuration.groups || !(configuration.groups.constructor === Object))
|
||||
configuration.groups = {};
|
||||
}
|
||||
|
||||
function adaptUsers(configuration: ACLConfiguration) {
|
||||
if (!configuration.users || !(configuration.users.constructor === Object))
|
||||
configuration.users = {};
|
||||
}
|
||||
|
||||
export class ACLAdapter {
|
||||
static adapt(configuration: ACLConfiguration): ACLConfiguration {
|
||||
if (!configuration) return;
|
||||
|
||||
const newConfiguration: ACLConfiguration = ObjectCloner.clone(configuration);
|
||||
adaptDefaultPolicy(newConfiguration);
|
||||
adaptAny(newConfiguration);
|
||||
adaptGroups(newConfiguration);
|
||||
adaptUsers(newConfiguration);
|
||||
return newConfiguration;
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
import { AuthenticationMethodsConfiguration } from "../Configuration";
|
||||
import { ObjectCloner } from "../../utils/ObjectCloner";
|
||||
|
||||
function clone(obj: any): any {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
export class AuthenticationMethodsAdapter {
|
||||
static adapt(authentication_methods: AuthenticationMethodsConfiguration)
|
||||
: AuthenticationMethodsConfiguration {
|
||||
if (!authentication_methods) {
|
||||
return {
|
||||
default_method: "two_factor",
|
||||
per_subdomain_methods: {}
|
||||
};
|
||||
}
|
||||
|
||||
const newAuthMethods: AuthenticationMethodsConfiguration
|
||||
= ObjectCloner.clone(authentication_methods);
|
||||
|
||||
if (!newAuthMethods.default_method)
|
||||
newAuthMethods.default_method = "two_factor";
|
||||
|
||||
if (!newAuthMethods.per_subdomain_methods ||
|
||||
newAuthMethods.per_subdomain_methods.constructor !== Object)
|
||||
newAuthMethods.per_subdomain_methods = {};
|
||||
|
||||
return newAuthMethods;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import { TOTPConfiguration } from "../Configuration";
|
||||
import { ObjectCloner } from "../../utils/ObjectCloner";
|
||||
|
||||
const DEFAULT_ISSUER = "authelia.com";
|
||||
|
||||
export class TOTPAdapter {
|
||||
static adapt(configuration: TOTPConfiguration): TOTPConfiguration {
|
||||
const newConfiguration = {
|
||||
issuer: DEFAULT_ISSUER
|
||||
};
|
||||
|
||||
if (!configuration)
|
||||
return newConfiguration;
|
||||
|
||||
if (configuration && configuration.issuer)
|
||||
newConfiguration.issuer = configuration.issuer;
|
||||
|
||||
return newConfiguration;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { ACLConfiguration, complete } from "./AclConfiguration";
|
||||
import Assert = require("assert");
|
||||
|
||||
describe("configuration/schema/AclConfiguration", function() {
|
||||
it("should complete ACLConfiguration", function() {
|
||||
const configuration: ACLConfiguration = {};
|
||||
const newConfiguration = complete(configuration);
|
||||
|
||||
Assert.deepEqual(newConfiguration.default_policy, "allow");
|
||||
Assert.deepEqual(newConfiguration.any, []);
|
||||
Assert.deepEqual(newConfiguration.groups, {});
|
||||
Assert.deepEqual(newConfiguration.users, {});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
export type ACLPolicy = "deny" | "allow";
|
||||
|
||||
export type ACLRule = {
|
||||
domain: string;
|
||||
policy: ACLPolicy;
|
||||
resources?: string[];
|
||||
};
|
||||
|
||||
export type ACLDefaultRules = ACLRule[];
|
||||
export type ACLGroupsRules = { [group: string]: ACLRule[]; };
|
||||
export type ACLUsersRules = { [user: string]: ACLRule[]; };
|
||||
|
||||
export interface ACLConfiguration {
|
||||
default_policy?: ACLPolicy;
|
||||
any?: ACLDefaultRules;
|
||||
groups?: ACLGroupsRules;
|
||||
users?: ACLUsersRules;
|
||||
}
|
||||
|
||||
export function complete(configuration: ACLConfiguration): ACLConfiguration {
|
||||
const newConfiguration: ACLConfiguration = (configuration)
|
||||
? JSON.parse(JSON.stringify(configuration)) : {};
|
||||
|
||||
if (!newConfiguration.default_policy) {
|
||||
newConfiguration.default_policy = "allow";
|
||||
}
|
||||
|
||||
if (!newConfiguration.any) {
|
||||
newConfiguration.any = [];
|
||||
}
|
||||
|
||||
if (!newConfiguration.groups) {
|
||||
newConfiguration.groups = {};
|
||||
}
|
||||
|
||||
if (!newConfiguration.users) {
|
||||
newConfiguration.users = {};
|
||||
}
|
||||
|
||||
return newConfiguration;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import Assert = require("assert");
|
||||
import { AuthenticationMethodsConfiguration, complete } from "./AuthenticationMethodsConfiguration";
|
||||
|
||||
describe("configuration/schema/AuthenticationMethodsConfiguration", function() {
|
||||
it("should ensure at least one key is provided", function() {
|
||||
const configuration: AuthenticationMethodsConfiguration = {};
|
||||
const newConfiguration = complete(configuration);
|
||||
|
||||
Assert.deepEqual(newConfiguration.default_method, "two_factor");
|
||||
Assert.deepEqual(newConfiguration.per_subdomain_methods, []);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
export type AuthenticationMethod = "two_factor" | "single_factor";
|
||||
export type AuthenticationMethodPerSubdomain = { [subdomain: string]: AuthenticationMethod };
|
||||
|
||||
export interface AuthenticationMethodsConfiguration {
|
||||
default_method?: AuthenticationMethod;
|
||||
per_subdomain_methods?: AuthenticationMethodPerSubdomain;
|
||||
}
|
||||
|
||||
export function complete(configuration: AuthenticationMethodsConfiguration): AuthenticationMethodsConfiguration {
|
||||
const newConfiguration: AuthenticationMethodsConfiguration = (configuration) ? JSON.parse(JSON.stringify(configuration)) : {};
|
||||
|
||||
if (!newConfiguration.default_method) {
|
||||
newConfiguration.default_method = "two_factor";
|
||||
}
|
||||
|
||||
if (!newConfiguration.per_subdomain_methods) {
|
||||
newConfiguration.per_subdomain_methods = {};
|
||||
}
|
||||
|
||||
return newConfiguration;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import { ACLConfiguration, complete as AclConfigurationComplete } from "./AclConfiguration";
|
||||
import { AuthenticationMethodsConfiguration, complete as AuthenticationMethodsConfigurationComplete } from "./AuthenticationMethodsConfiguration";
|
||||
import { LdapConfiguration, complete as LdapConfigurationComplete } from "./LdapConfiguration";
|
||||
import { NotifierConfiguration, complete as NotifierConfigurationComplete } from "./NotifierConfiguration";
|
||||
import { RegulationConfiguration, complete as RegulationConfigurationComplete } from "./RegulationConfiguration";
|
||||
import { SessionConfiguration, complete as SessionConfigurationComplete } from "./SessionConfiguration";
|
||||
import { StorageConfiguration, complete as StorageConfigurationComplete } from "./StorageConfiguration";
|
||||
import { TotpConfiguration, complete as TotpConfigurationComplete } from "./TotpConfiguration";
|
||||
import { MethodCalculator } from "../../authentication/MethodCalculator";
|
||||
|
||||
export interface Configuration {
|
||||
access_control?: ACLConfiguration;
|
||||
ldap: LdapConfiguration;
|
||||
authentication_methods?: AuthenticationMethodsConfiguration;
|
||||
default_redirection_url?: string;
|
||||
logs_level?: string;
|
||||
notifier?: NotifierConfiguration;
|
||||
port?: number;
|
||||
regulation?: RegulationConfiguration;
|
||||
session?: SessionConfiguration;
|
||||
storage?: StorageConfiguration;
|
||||
totp?: TotpConfiguration;
|
||||
}
|
||||
|
||||
export function complete(configuration: Configuration): [Configuration, string[]] {
|
||||
const newConfiguration: Configuration = JSON.parse(JSON.stringify(configuration));
|
||||
const errors: string[] = [];
|
||||
|
||||
newConfiguration.access_control = AclConfigurationComplete(newConfiguration.access_control);
|
||||
newConfiguration.ldap = LdapConfigurationComplete(newConfiguration.ldap);
|
||||
|
||||
newConfiguration.authentication_methods = AuthenticationMethodsConfigurationComplete(newConfiguration.authentication_methods);
|
||||
|
||||
if (!newConfiguration.logs_level) {
|
||||
newConfiguration.logs_level = "info";
|
||||
}
|
||||
|
||||
// In single factor mode, notifier section is optional.
|
||||
if (!MethodCalculator.isSingleFactorOnlyMode(newConfiguration.authentication_methods)) {
|
||||
const [notifier, error] = NotifierConfigurationComplete(newConfiguration.notifier);
|
||||
newConfiguration.notifier = notifier;
|
||||
if (error) errors.push(error);
|
||||
}
|
||||
|
||||
if (!newConfiguration.port) {
|
||||
newConfiguration.port = 8080;
|
||||
}
|
||||
|
||||
newConfiguration.regulation = RegulationConfigurationComplete(newConfiguration.regulation);
|
||||
newConfiguration.session = SessionConfigurationComplete(newConfiguration.session);
|
||||
newConfiguration.storage = StorageConfigurationComplete(newConfiguration.storage);
|
||||
newConfiguration.totp = TotpConfigurationComplete(newConfiguration.totp);
|
||||
|
||||
return [newConfiguration, errors];
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import Assert = require("assert");
|
||||
import { LdapConfiguration, complete } from "./LdapConfiguration";
|
||||
|
||||
describe("configuration/schema/AuthenticationMethodsConfiguration", function() {
|
||||
it("should ensure at least one key is provided", function() {
|
||||
const configuration: LdapConfiguration = {
|
||||
url: "ldap.example.com",
|
||||
base_dn: "dc=example,dc=com",
|
||||
user: "admin",
|
||||
password: "password"
|
||||
};
|
||||
const newConfiguration = complete(configuration);
|
||||
|
||||
Assert.deepEqual(newConfiguration, {
|
||||
url: "ldap.example.com",
|
||||
base_dn: "dc=example,dc=com",
|
||||
user: "admin",
|
||||
password: "password",
|
||||
users_filter: "cn={0}",
|
||||
group_name_attribute: "cn",
|
||||
groups_filter: "member={dn}",
|
||||
mail_attribute: "mail"
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
import Util = require("util");
|
||||
|
||||
export interface LdapConfiguration {
|
||||
url: string;
|
||||
base_dn: string;
|
||||
|
||||
additional_users_dn?: string;
|
||||
users_filter?: string;
|
||||
|
||||
additional_groups_dn?: string;
|
||||
groups_filter?: string;
|
||||
|
||||
group_name_attribute?: string;
|
||||
mail_attribute?: string;
|
||||
|
||||
user: string; // admin username
|
||||
password: string; // admin password
|
||||
}
|
||||
|
||||
export function complete(configuration: LdapConfiguration): LdapConfiguration {
|
||||
const newConfiguration: LdapConfiguration = (configuration) ? JSON.parse(JSON.stringify(configuration)) : {};
|
||||
|
||||
if (!newConfiguration.users_filter) {
|
||||
newConfiguration.users_filter = "cn={0}";
|
||||
}
|
||||
|
||||
if (!newConfiguration.groups_filter) {
|
||||
newConfiguration.groups_filter = "member={dn}";
|
||||
}
|
||||
|
||||
if (!newConfiguration.group_name_attribute) {
|
||||
newConfiguration.group_name_attribute = "cn";
|
||||
}
|
||||
|
||||
if (!newConfiguration.mail_attribute) {
|
||||
newConfiguration.mail_attribute = "mail";
|
||||
}
|
||||
|
||||
return newConfiguration;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
import Assert = require("assert");
|
||||
import { NotifierConfiguration, complete } from "./NotifierConfiguration";
|
||||
|
||||
describe("configuration/schema/NotifierConfiguration", function() {
|
||||
it("should ensure at least one key is provided", function() {
|
||||
const configuration: NotifierConfiguration = {};
|
||||
const [newConfiguration, error] = complete(configuration);
|
||||
|
||||
Assert.equal(error, "Notifier must have one of the following keys: 'filesystem', 'email' or 'smtp'");
|
||||
});
|
||||
|
||||
it("should ensure there is no more than one key", function() {
|
||||
const configuration: NotifierConfiguration = {
|
||||
smtp: {
|
||||
host: "smtp.example.com",
|
||||
port: 25,
|
||||
secure: false,
|
||||
sender: "test@example.com"
|
||||
},
|
||||
email: {
|
||||
username: "test",
|
||||
password: "test",
|
||||
sender: "test@example.com",
|
||||
service: "gmail"
|
||||
}
|
||||
};
|
||||
const [newConfiguration, error] = complete(configuration);
|
||||
|
||||
Assert.equal(error, "Notifier must have one of the following keys: 'filesystem', 'email' or 'smtp'");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
export interface EmailNotifierConfiguration {
|
||||
username: string;
|
||||
password: string;
|
||||
sender: string;
|
||||
service: string;
|
||||
}
|
||||
|
||||
export interface SmtpNotifierConfiguration {
|
||||
username?: string;
|
||||
password?: string;
|
||||
host: string;
|
||||
port: number;
|
||||
secure: boolean;
|
||||
sender: string;
|
||||
}
|
||||
|
||||
export interface FileSystemNotifierConfiguration {
|
||||
filename: string;
|
||||
}
|
||||
|
||||
export interface NotifierConfiguration {
|
||||
email?: EmailNotifierConfiguration;
|
||||
smtp?: SmtpNotifierConfiguration;
|
||||
filesystem?: FileSystemNotifierConfiguration;
|
||||
}
|
||||
|
||||
export function complete(configuration: NotifierConfiguration): [NotifierConfiguration, string] {
|
||||
const newConfiguration: NotifierConfiguration = (configuration) ? JSON.parse(JSON.stringify(configuration)) : {};
|
||||
|
||||
const ERROR = "Notifier must have one of the following keys: 'filesystem', 'email' or 'smtp'";
|
||||
|
||||
if (Object.keys(newConfiguration).length != 1)
|
||||
return [newConfiguration, ERROR];
|
||||
|
||||
const key = Object.keys(newConfiguration)[0];
|
||||
|
||||
if (key != "filesystem" && key != "smtp" && key != "email")
|
||||
return [newConfiguration, ERROR];
|
||||
|
||||
return [newConfiguration, undefined];
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import Assert = require("assert");
|
||||
import { RegulationConfiguration, complete } from "./RegulationConfiguration";
|
||||
|
||||
describe("configuration/schema/RegulationConfiguration", function() {
|
||||
it("should return default regulation configuration", function() {
|
||||
const configuration: RegulationConfiguration = {};
|
||||
const newConfiguration = complete(configuration);
|
||||
|
||||
Assert.equal(newConfiguration.ban_time, 300);
|
||||
Assert.equal(newConfiguration.find_time, 120);
|
||||
Assert.equal(newConfiguration.max_retries, 3);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
export interface RegulationConfiguration {
|
||||
max_retries?: number;
|
||||
find_time?: number;
|
||||
ban_time?: number;
|
||||
}
|
||||
|
||||
export function complete(configuration: RegulationConfiguration): RegulationConfiguration {
|
||||
const newConfiguration: RegulationConfiguration = (configuration) ? JSON.parse(JSON.stringify(configuration)) : {};
|
||||
|
||||
if (!newConfiguration.max_retries) {
|
||||
newConfiguration.max_retries = 3;
|
||||
}
|
||||
|
||||
if (!newConfiguration.find_time) {
|
||||
newConfiguration.find_time = 120; // seconds
|
||||
}
|
||||
|
||||
if (!newConfiguration.ban_time) {
|
||||
newConfiguration.ban_time = 300; // seconds
|
||||
}
|
||||
|
||||
return newConfiguration;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import Assert = require("assert");
|
||||
import { SessionConfiguration, complete } from "./SessionConfiguration";
|
||||
|
||||
describe("configuration/schema/SessionConfiguration", function() {
|
||||
it("should return default regulation configuration", function() {
|
||||
const configuration: SessionConfiguration = {
|
||||
domain: "example.com",
|
||||
secret: "unsecure_secret"
|
||||
};
|
||||
const newConfiguration = complete(configuration);
|
||||
|
||||
Assert.equal(newConfiguration.expiration, 3600000);
|
||||
Assert.equal(newConfiguration.inactivity, undefined);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
export interface SessionRedisOptions {
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
export interface SessionConfiguration {
|
||||
domain: string;
|
||||
secret: string;
|
||||
expiration?: number;
|
||||
inactivity?: number;
|
||||
redis?: SessionRedisOptions;
|
||||
}
|
||||
|
||||
export function complete(configuration: SessionConfiguration): SessionConfiguration {
|
||||
const newConfiguration: SessionConfiguration = (configuration) ? JSON.parse(JSON.stringify(configuration)) : {};
|
||||
|
||||
if (!newConfiguration.expiration) {
|
||||
newConfiguration.expiration = 3600000; // 1 hour
|
||||
}
|
||||
|
||||
if (!newConfiguration.inactivity) {
|
||||
newConfiguration.inactivity = undefined; // disabled
|
||||
}
|
||||
|
||||
return newConfiguration;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import Assert = require("assert");
|
||||
import { StorageConfiguration, complete } from "./StorageConfiguration";
|
||||
|
||||
describe("configuration/schema/StorageConfiguration", function() {
|
||||
it("should return default regulation configuration", function() {
|
||||
const configuration: StorageConfiguration = {};
|
||||
const newConfiguration = complete(configuration);
|
||||
|
||||
Assert.deepEqual(newConfiguration, {
|
||||
local: {
|
||||
in_memory: true
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
export interface MongoStorageConfiguration {
|
||||
url: string;
|
||||
database: string;
|
||||
}
|
||||
|
||||
export interface LocalStorageConfiguration {
|
||||
path?: string;
|
||||
in_memory?: boolean;
|
||||
}
|
||||
|
||||
export interface StorageConfiguration {
|
||||
local?: LocalStorageConfiguration;
|
||||
mongo?: MongoStorageConfiguration;
|
||||
}
|
||||
|
||||
export function complete(configuration: StorageConfiguration): StorageConfiguration {
|
||||
const newConfiguration: StorageConfiguration = (configuration) ? JSON.parse(JSON.stringify(configuration)) : {};
|
||||
|
||||
if (!newConfiguration.local && !newConfiguration.mongo) {
|
||||
newConfiguration.local = {
|
||||
in_memory: true
|
||||
};
|
||||
}
|
||||
return newConfiguration;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
export interface TotpConfiguration {
|
||||
issuer: string;
|
||||
}
|
||||
|
||||
export function complete(configuration: TotpConfiguration): TotpConfiguration {
|
||||
const newConfiguration: TotpConfiguration = (configuration) ? JSON.parse(JSON.stringify(configuration)) : {};
|
||||
|
||||
if (!newConfiguration.issuer) {
|
||||
newConfiguration.issuer = "authelia.com";
|
||||
}
|
||||
|
||||
return newConfiguration;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
export interface UserInfo {
|
||||
username: string;
|
||||
password_hash: string;
|
||||
email: string;
|
||||
groups?: string[];
|
||||
}
|
||||
|
||||
export type UserDatabaseConfiguration = UserInfo[];
|
|
@ -1,9 +1,9 @@
|
|||
import Assert = require("assert");
|
||||
import Sinon = require("sinon");
|
||||
import MongoDB = require("mongodb");
|
||||
import { MongoClient } from "../../../src/lib/connectors/mongo/MongoClient";
|
||||
import { MongoClient } from "./MongoClient";
|
||||
|
||||
describe("MongoClient", function () {
|
||||
describe("connectors/mongo/MongoClient", function () {
|
||||
let mongoClientConnectStub: Sinon.SinonStub;
|
||||
let mongoDatabase: any;
|
||||
let mongoDatabaseCollectionStub: Sinon.SinonStub;
|
|
@ -2,10 +2,10 @@ import Assert = require("assert");
|
|||
import Sinon = require("sinon");
|
||||
import MongoDB = require("mongodb");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import { IMongoClient } from "../../../src/lib/connectors/mongo/IMongoClient";
|
||||
import { MongoConnector } from "../../../src/lib/connectors/mongo/MongoConnector";
|
||||
import { IMongoClient } from "./IMongoClient";
|
||||
import { MongoConnector } from "./MongoConnector";
|
||||
|
||||
describe("MongoConnector", function () {
|
||||
describe("connectors/mongo/MongoConnector", function () {
|
||||
let mongoClientConnectStub: Sinon.SinonStub;
|
||||
|
||||
describe("create", function () {
|
|
@ -1,7 +1,7 @@
|
|||
import Assert = require("assert");
|
||||
import { MongoConnectorFactory } from "../../../src/lib/connectors/mongo/MongoConnectorFactory";
|
||||
import { MongoConnectorFactory } from "./MongoConnectorFactory";
|
||||
|
||||
describe("MongoConnectorFactory", function () {
|
||||
describe("connectors/mongo/MongoConnectorFactory", function () {
|
||||
describe("create", function () {
|
||||
it("should create a connector", function () {
|
||||
const factory = new MongoConnectorFactory();
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
import { Authenticator } from "../../src/lib/ldap/Authenticator";
|
||||
import { LdapConfiguration } from "../../src/lib/configuration/Configuration";
|
||||
import { Authenticator } from "./Authenticator";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
|
||||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import Assert = require("assert");
|
||||
|
||||
import { ClientFactoryStub } from "../mocks/ldap/ClientFactoryStub";
|
||||
import { ClientStub } from "../mocks/ldap/ClientStub";
|
||||
import { ClientFactoryStub } from "./ClientFactoryStub.spec";
|
||||
import { ClientStub } from "./ClientStub.spec";
|
||||
|
||||
|
||||
describe("test ldap authentication", function () {
|
||||
describe("ldap/Authenticator", function () {
|
||||
const USERNAME = "username";
|
||||
const PASSWORD = "password";
|
||||
|
||||
|
@ -31,9 +31,10 @@ describe("test ldap authentication", function () {
|
|||
|
||||
ldapConfig = {
|
||||
url: "http://localhost:324",
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
base_dn: "dc=example,dc=com",
|
||||
users_filter: "cn={0}",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
groups_filter: "member={0}",
|
||||
mail_attribute: "mail",
|
||||
group_name_attribute: "cn",
|
|
@ -6,7 +6,7 @@ import { IClientFactory } from "./IClientFactory";
|
|||
import { GroupsAndEmails } from "./IClient";
|
||||
|
||||
import { IAuthenticator } from "./IAuthenticator";
|
||||
import { LdapConfiguration } from "../configuration/Configuration";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
import { EmailsAndGroupsRetriever } from "./EmailsAndGroupsRetriever";
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import BluebirdPromise = require("bluebird");
|
||||
import { IAuthenticator } from "../../../src/lib/ldap/IAuthenticator";
|
||||
import { GroupsAndEmails } from "../../../src/lib/ldap/IClient";
|
||||
import { GroupsAndEmails } from "./IClient";
|
||||
import Sinon = require("sinon");
|
||||
|
||||
export class AuthenticatorStub implements IAuthenticator {
|
|
@ -1,15 +1,15 @@
|
|||
|
||||
import { LdapConfiguration } from "../../src/lib/configuration/Configuration";
|
||||
import { Client } from "../../src/lib/ldap/Client";
|
||||
import { LdapClientFactoryStub } from "../mocks/ldap/LdapClientFactoryStub";
|
||||
import { LdapClientStub } from "../mocks/ldap/LdapClientStub";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
import { Client } from "./Client";
|
||||
import { LdapClientFactoryStub } from "./LdapClientFactoryStub.spec";
|
||||
import { LdapClientStub } from "./LdapClientStub.spec";
|
||||
|
||||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import Assert = require("assert");
|
||||
import Winston = require("winston");
|
||||
|
||||
describe("test authelia ldap client", function () {
|
||||
describe("ldap/Client", function () {
|
||||
const USERNAME = "username";
|
||||
const ADMIN_USER_DN = "cn=admin,dc=example,dc=com";
|
||||
const ADMIN_PASSWORD = "password";
|
||||
|
@ -17,9 +17,10 @@ describe("test authelia ldap client", function () {
|
|||
it("should replace {0} by username when searching for groups in LDAP", function () {
|
||||
const options: LdapConfiguration = {
|
||||
url: "ldap://ldap",
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
base_dn: "dc=example,dc=com",
|
||||
users_filter: "cn={0}",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
groups_filter: "member=cn={0},ou=users,dc=example,dc=com",
|
||||
group_name_attribute: "cn",
|
||||
mail_attribute: "mail",
|
||||
|
@ -46,9 +47,10 @@ describe("test authelia ldap client", function () {
|
|||
const USER_DN = "cn=user1,ou=users,dc=example,dc=com";
|
||||
const options: LdapConfiguration = {
|
||||
url: "ldap://ldap",
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
base_dn: "dc=example,dc=com",
|
||||
users_filter: "cn={0}",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
groups_filter: "member={dn}",
|
||||
group_name_attribute: "cn",
|
||||
mail_attribute: "mail",
|
||||
|
@ -91,9 +93,10 @@ describe("test authelia ldap client", function () {
|
|||
const USER_DN = "cn=user1,ou=users,dc=example,dc=com";
|
||||
const options: LdapConfiguration = {
|
||||
url: "ldap://ldap",
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
base_dn: "dc=example,dc=com",
|
||||
users_filter: "cn={0}",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
groups_filter: "member={dn}",
|
||||
group_name_attribute: "cn",
|
||||
mail_attribute: "custom_mail",
|
|
@ -4,7 +4,7 @@ import { EventEmitter } from "events";
|
|||
import { IClient, GroupsAndEmails } from "./IClient";
|
||||
import { ILdapClient } from "./ILdapClient";
|
||||
import { ILdapClientFactory } from "./ILdapClientFactory";
|
||||
import { LdapConfiguration } from "../configuration/Configuration";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
import { Winston } from "../../../types/Dependencies";
|
||||
import Util = require("util");
|
||||
import { HashGenerator } from "../utils/HashGenerator";
|
||||
|
@ -16,6 +16,9 @@ export class Client implements IClient {
|
|||
private logger: Winston;
|
||||
private options: LdapConfiguration;
|
||||
|
||||
private groupsSearchBase: string;
|
||||
private usersSearchBase: string;
|
||||
|
||||
constructor(userDN: string, password: string, options: LdapConfiguration,
|
||||
ldapClientFactory: ILdapClientFactory, logger: Winston) {
|
||||
this.options = options;
|
||||
|
@ -23,6 +26,14 @@ export class Client implements IClient {
|
|||
this.userDN = userDN;
|
||||
this.password = password;
|
||||
this.ldapClient = ldapClientFactory.create();
|
||||
|
||||
this.groupsSearchBase = (this.options.additional_groups_dn)
|
||||
? Util.format("%s,%s", this.options.additional_groups_dn, this.options.base_dn)
|
||||
: this.options.base_dn;
|
||||
|
||||
this.usersSearchBase = (this.options.additional_users_dn)
|
||||
? Util.format("%s,%s", this.options.additional_users_dn, this.options.base_dn)
|
||||
: this.options.base_dn;
|
||||
}
|
||||
|
||||
open(): BluebirdPromise<void> {
|
||||
|
@ -64,7 +75,7 @@ export class Client implements IClient {
|
|||
attributes: [that.options.group_name_attribute],
|
||||
filter: groupsFilter
|
||||
};
|
||||
return that.ldapClient.searchAsync(that.options.groups_dn, query);
|
||||
return that.ldapClient.searchAsync(that.groupsSearchBase, query);
|
||||
})
|
||||
.then(function (docs: { cn: string }[]) {
|
||||
const groups = docs.map((doc: any) => { return doc.cn; });
|
||||
|
@ -85,7 +96,7 @@ export class Client implements IClient {
|
|||
};
|
||||
|
||||
that.logger.debug("LDAP: searching for user dn of %s", username);
|
||||
return that.ldapClient.searchAsync(this.options.users_dn, query)
|
||||
return that.ldapClient.searchAsync(this.usersSearchBase, query)
|
||||
.then(function (users: { dn: string }[]) {
|
||||
if (users.length > 0) {
|
||||
that.logger.debug("LDAP: retrieved user dn is %s", users[0].dn);
|
||||
|
|
|
@ -3,7 +3,7 @@ import { IClient } from "./IClient";
|
|||
import { Client } from "./Client";
|
||||
import { SanitizedClient } from "./SanitizedClient";
|
||||
import { ILdapClientFactory } from "./ILdapClientFactory";
|
||||
import { LdapConfiguration } from "../configuration/Configuration";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
import Ldapjs = require("ldapjs");
|
||||
import Winston = require("winston");
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import { IClient, GroupsAndEmails } from "../../../src/lib/ldap/IClient";
|
||||
import { IClient, GroupsAndEmails } from "./IClient";
|
||||
import Sinon = require("sinon");
|
||||
|
||||
export class ClientStub implements IClient {
|
|
@ -3,7 +3,7 @@ import exceptions = require("../Exceptions");
|
|||
import ldapjs = require("ldapjs");
|
||||
import { Client } from "./Client";
|
||||
import { IClientFactory } from "./IClientFactory";
|
||||
import { LdapConfiguration } from "../configuration/Configuration";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
import { GroupsAndEmails } from "./IClient";
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
|
||||
import { EmailsRetriever } from "../../src/lib/ldap/EmailsRetriever";
|
||||
import { LdapConfiguration } from "../../src/lib/configuration/Configuration";
|
||||
import { EmailsRetriever } from "./EmailsRetriever";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
|
||||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import Assert = require("assert");
|
||||
|
||||
import { ClientFactoryStub } from "../mocks/ldap/ClientFactoryStub";
|
||||
import { ClientStub } from "../mocks/ldap/ClientStub";
|
||||
import { ClientFactoryStub } from "./ClientFactoryStub.spec";
|
||||
import { ClientStub } from "./ClientStub.spec";
|
||||
|
||||
describe("test emails retriever", function () {
|
||||
describe("ldap/EmailsRetriever", function () {
|
||||
const USERNAME = "username";
|
||||
const ADMIN_USER_DN = "cn=admin,dc=example,dc=com";
|
||||
const ADMIN_PASSWORD = "password";
|
||||
|
@ -28,8 +28,9 @@ describe("test emails retriever", function () {
|
|||
url: "http://ldap",
|
||||
user: ADMIN_USER_DN,
|
||||
password: ADMIN_PASSWORD,
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
base_dn: "dc=example,dc=com",
|
||||
group_name_attribute: "cn",
|
||||
groups_filter: "cn={0}",
|
||||
mail_attribute: "mail",
|
|
@ -5,7 +5,7 @@ import { Client } from "./Client";
|
|||
|
||||
import { IClientFactory } from "./IClientFactory";
|
||||
import { IEmailsRetriever } from "./IEmailsRetriever";
|
||||
import { LdapConfiguration } from "../configuration/Configuration";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
|
||||
|
||||
export class EmailsRetriever implements IEmailsRetriever {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import BluebirdPromise = require("bluebird");
|
||||
import { IClient } from "../../../src/lib/ldap/IClient";
|
||||
import { IEmailsRetriever } from "../../../src/lib/ldap/IEmailsRetriever";
|
||||
import { IClient } from "./IClient";
|
||||
import { IEmailsRetriever } from "./IEmailsRetriever";
|
||||
import Sinon = require("sinon");
|
||||
|
||||
export class EmailsRetrieverStub implements IEmailsRetriever {
|
|
@ -1,7 +1,7 @@
|
|||
import Assert = require("assert");
|
||||
import { InputsSanitizer } from "../../src/lib/ldap/InputsSanitizer";
|
||||
import { InputsSanitizer } from "./InputsSanitizer";
|
||||
|
||||
describe("test InputsSanitizer", function () {
|
||||
describe("ldap/InputsSanitizer", function () {
|
||||
it("should fail when special characters are used", function () {
|
||||
Assert.throws(() => { InputsSanitizer.sanitize("ab,c"); }, Error);
|
||||
Assert.throws(() => { InputsSanitizer.sanitize("a\\bc"); }, Error);
|
|
@ -1,7 +1,7 @@
|
|||
import { ILdapClientFactory } from "./ILdapClientFactory";
|
||||
import { ILdapClient } from "./ILdapClient";
|
||||
import { LdapClient } from "./LdapClient";
|
||||
import { LdapConfiguration } from "../configuration/Configuration";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
|
||||
import Ldapjs = require("ldapjs");
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import { ILdapClientFactory } from "../../../src/lib/ldap/ILdapClientFactory";
|
||||
import { ILdapClient } from "../../../src/lib/ldap/ILdapClient";
|
||||
import { ILdapClientFactory } from "./ILdapClientFactory";
|
||||
import { ILdapClient } from "./ILdapClient";
|
||||
|
||||
export class LdapClientFactoryStub implements ILdapClientFactory {
|
||||
createStub: Sinon.SinonStub;
|
|
@ -1,6 +1,6 @@
|
|||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import { ILdapClient } from "../../../src/lib/ldap/ILdapClient";
|
||||
import { ILdapClient } from "./ILdapClient";
|
||||
|
||||
export class LdapClientStub implements ILdapClient {
|
||||
bindAsyncStub: Sinon.SinonStub;
|
|
@ -1,13 +1,13 @@
|
|||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import Assert = require("assert");
|
||||
import { PasswordUpdater } from "../../src/lib/ldap/PasswordUpdater";
|
||||
import { LdapConfiguration } from "../../src/lib/configuration/Configuration";
|
||||
import { ClientFactoryStub } from "../mocks/ldap/ClientFactoryStub";
|
||||
import { ClientStub } from "../mocks/ldap/ClientStub";
|
||||
import { HashGenerator } from "../../src/lib/utils/HashGenerator";
|
||||
import { PasswordUpdater } from "./PasswordUpdater";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
import { ClientFactoryStub } from "./ClientFactoryStub.spec";
|
||||
import { ClientStub } from "./ClientStub.spec";
|
||||
import { HashGenerator } from "../utils/HashGenerator";
|
||||
|
||||
describe("test password update", function () {
|
||||
describe("ldap/PasswordUpdater", function () {
|
||||
const USERNAME = "username";
|
||||
const NEW_PASSWORD = "new-password";
|
||||
|
||||
|
@ -28,8 +28,9 @@ describe("test password update", function () {
|
|||
url: "http://ldap",
|
||||
user: ADMIN_USER_DN,
|
||||
password: ADMIN_PASSWORD,
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
base_dn: "dc=example,dc=com",
|
||||
group_name_attribute: "cn",
|
||||
groups_filter: "cn={0}",
|
||||
mail_attribute: "mail",
|
|
@ -4,7 +4,7 @@ import ldapjs = require("ldapjs");
|
|||
import { Client } from "./Client";
|
||||
|
||||
import { IPasswordUpdater } from "./IPasswordUpdater";
|
||||
import { LdapConfiguration } from "../configuration/Configuration";
|
||||
import { LdapConfiguration } from "../configuration/schema/LdapConfiguration";
|
||||
import { IClientFactory } from "./IClientFactory";
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import BluebirdPromise = require("bluebird");
|
||||
import { IClient } from "../../../src/lib/ldap/IClient";
|
||||
import { IPasswordUpdater } from "../../../src/lib/ldap/IPasswordUpdater";
|
||||
import { IClient } from "./IClient";
|
||||
import { IPasswordUpdater } from "./IPasswordUpdater";
|
||||
import Sinon = require("sinon");
|
||||
|
||||
export class PasswordUpdaterStub implements IPasswordUpdater {
|
|
@ -1,8 +1,8 @@
|
|||
import BluebirdPromise = require("bluebird");
|
||||
import { ClientStub } from "../mocks/ldap/ClientStub";
|
||||
import { SanitizedClient } from "../../src/lib/ldap/SanitizedClient";
|
||||
import { ClientStub } from "./ClientStub.spec";
|
||||
import { SanitizedClient } from "./SanitizedClient";
|
||||
|
||||
describe("test SanitizedClient", function () {
|
||||
describe("ldap/SanitizedClient", function () {
|
||||
let client: SanitizedClient;
|
||||
|
||||
beforeEach(function () {
|
|
@ -1,6 +1,6 @@
|
|||
import { IRequestLogger } from "../../src/lib/logging/IRequestLogger";
|
||||
import { IRequestLogger } from "./IRequestLogger";
|
||||
import Sinon = require("sinon");
|
||||
import { RequestLogger } from "../../src/lib/logging/RequestLogger";
|
||||
import { RequestLogger } from "./RequestLogger";
|
||||
import Winston = require("winston");
|
||||
import Express = require("express");
|
||||
|
|
@ -2,11 +2,11 @@ import * as sinon from "sinon";
|
|||
import * as Assert from "assert";
|
||||
import BluebirdPromise = require("bluebird");
|
||||
|
||||
import { MailSenderStub } from "../mocks/notifiers/MailSenderStub";
|
||||
import EMailNotifier = require("../../src/lib/notifiers/EMailNotifier");
|
||||
import { MailSenderStub } from "./MailSenderStub.spec";
|
||||
import EmailNotifier = require("./EmailNotifier");
|
||||
|
||||
|
||||
describe("test email notifier", function () {
|
||||
describe("notifiers/EmailNotifier", function () {
|
||||
it("should send an email to given user", function () {
|
||||
const mailSender = new MailSenderStub();
|
||||
const options = {
|
||||
|
@ -17,7 +17,7 @@ describe("test email notifier", function () {
|
|||
};
|
||||
|
||||
mailSender.sendStub.returns(BluebirdPromise.resolve());
|
||||
const sender = new EMailNotifier.EMailNotifier(options, mailSender);
|
||||
const sender = new EmailNotifier.EmailNotifier(options, mailSender);
|
||||
const subject = "subject";
|
||||
const url = "http://test.com";
|
||||
|
||||
|
@ -39,7 +39,7 @@ describe("test email notifier", function () {
|
|||
};
|
||||
|
||||
mailSender.sendStub.returns(BluebirdPromise.reject(new Error("Failed to send mail")));
|
||||
const sender = new EMailNotifier.EMailNotifier(options, mailSender);
|
||||
const sender = new EmailNotifier.EmailNotifier(options, mailSender);
|
||||
const subject = "subject";
|
||||
const url = "http://test.com";
|
||||
|
|
@ -2,10 +2,10 @@
|
|||
import * as BluebirdPromise from "bluebird";
|
||||
|
||||
import { AbstractEmailNotifier } from "../notifiers/AbstractEmailNotifier";
|
||||
import { EmailNotifierConfiguration } from "../configuration/Configuration";
|
||||
import { EmailNotifierConfiguration } from "../configuration/schema/NotifierConfiguration";
|
||||
import { IMailSender } from "./IMailSender";
|
||||
|
||||
export class EMailNotifier extends AbstractEmailNotifier {
|
||||
export class EmailNotifier extends AbstractEmailNotifier {
|
||||
private mailSender: IMailSender;
|
||||
private sender: string;
|
||||
|
|
@ -4,7 +4,7 @@ import * as Fs from "fs";
|
|||
import { INotifier } from "./INotifier";
|
||||
import { Identity } from "../../../types/Identity";
|
||||
|
||||
import { FileSystemNotifierConfiguration } from "../configuration/Configuration";
|
||||
import { FileSystemNotifierConfiguration } from "../configuration/schema/NotifierConfiguration";
|
||||
|
||||
export class FileSystemNotifier implements INotifier {
|
||||
private filename: string;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IMailSender } from "./IMailSender";
|
||||
import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../configuration/Configuration";
|
||||
import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../configuration/schema/NotifierConfiguration";
|
||||
|
||||
export interface IMailSenderBuilder {
|
||||
buildEmail(options: EmailNotifierConfiguration): IMailSender;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
import { MailSenderBuilder } from "../../src/lib/notifiers/MailSenderBuilder";
|
||||
import { MailSenderBuilder } from ".//MailSenderBuilder";
|
||||
import Nodemailer = require("nodemailer");
|
||||
import Sinon = require("sinon");
|
||||
import Assert = require("assert");
|
||||
|
||||
describe("test MailSenderBuilder", function() {
|
||||
describe("notifiers/MailSenderBuilder", function() {
|
||||
let createTransportStub: Sinon.SinonStub;
|
||||
beforeEach(function() {
|
||||
createTransportStub = Sinon.stub(Nodemailer, "createTransport");
|
|
@ -3,7 +3,7 @@ import { IMailSenderBuilder } from "./IMailSenderBuilder";
|
|||
import { MailSender } from "./MailSender";
|
||||
import Nodemailer = require("nodemailer");
|
||||
import NodemailerSmtpTransport = require("nodemailer-smtp-transport");
|
||||
import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../configuration/Configuration";
|
||||
import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../configuration/schema/NotifierConfiguration";
|
||||
|
||||
export class MailSenderBuilder implements IMailSenderBuilder {
|
||||
private nodemailer: typeof Nodemailer;
|
||||
|
|
|
@ -3,7 +3,7 @@ import BluebirdPromise = require("bluebird");
|
|||
import Nodemailer = require("nodemailer");
|
||||
import Sinon = require("sinon");
|
||||
import { IMailSender } from "../../../src/lib/notifiers/IMailSender";
|
||||
import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../../../src/lib/configuration/Configuration";
|
||||
import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../../../src/lib/configuration/schema/NotifierConfiguration";
|
||||
|
||||
export class MailSenderBuilderStub implements IMailSenderBuilder {
|
||||
buildEmailStub: Sinon.SinonStub;
|
|
@ -3,13 +3,13 @@ import * as sinon from "sinon";
|
|||
import * as BluebirdPromise from "bluebird";
|
||||
import * as assert from "assert";
|
||||
|
||||
import { NotifierFactory } from "../../src/lib/notifiers/NotifierFactory";
|
||||
import { EMailNotifier } from "../../src/lib/notifiers/EMailNotifier";
|
||||
import { SmtpNotifier } from "../../src/lib/notifiers/SmtpNotifier";
|
||||
import { MailSenderBuilderStub } from "../mocks/notifiers/MailSenderBuilderStub";
|
||||
import { NotifierFactory } from "./NotifierFactory";
|
||||
import { EmailNotifier } from "./EmailNotifier";
|
||||
import { SmtpNotifier } from "./SmtpNotifier";
|
||||
import { MailSenderBuilderStub } from "./MailSenderBuilderStub.spec";
|
||||
|
||||
|
||||
describe("test notifier factory", function () {
|
||||
describe("notifiers/NotifierFactory", function () {
|
||||
let mailSenderBuilderStub: MailSenderBuilderStub;
|
||||
it("should build a Email Notifier", function () {
|
||||
const options = {
|
||||
|
@ -21,7 +21,7 @@ describe("test notifier factory", function () {
|
|||
}
|
||||
};
|
||||
mailSenderBuilderStub = new MailSenderBuilderStub();
|
||||
assert(NotifierFactory.build(options, mailSenderBuilderStub) instanceof EMailNotifier);
|
||||
assert(NotifierFactory.build(options, mailSenderBuilderStub) instanceof EmailNotifier);
|
||||
});
|
||||
|
||||
it("should build a SMTP Notifier", function () {
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
import { NotifierConfiguration } from "../configuration/Configuration";
|
||||
import { NotifierConfiguration } from "../configuration/schema/NotifierConfiguration";
|
||||
import Nodemailer = require("nodemailer");
|
||||
import { INotifier } from "./INotifier";
|
||||
|
||||
import { FileSystemNotifier } from "./FileSystemNotifier";
|
||||
import { EMailNotifier } from "./EMailNotifier";
|
||||
import { EmailNotifier } from "./EmailNotifier";
|
||||
import { SmtpNotifier } from "./SmtpNotifier";
|
||||
import { IMailSender } from "./IMailSender";
|
||||
import { IMailSenderBuilder } from "./IMailSenderBuilder";
|
||||
|
@ -13,7 +13,7 @@ export class NotifierFactory {
|
|||
static build(options: NotifierConfiguration, mailSenderBuilder: IMailSenderBuilder): INotifier {
|
||||
if ("email" in options) {
|
||||
const mailSender = mailSenderBuilder.buildEmail(options.email);
|
||||
return new EMailNotifier(options.email, mailSender);
|
||||
return new EmailNotifier(options.email, mailSender);
|
||||
}
|
||||
else if ("smtp" in options) {
|
||||
const mailSender = mailSenderBuilder.buildSmtp(options.smtp);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
|
||||
import { INotifier } from "../../src/lib/notifiers/INotifier";
|
||||
import { INotifier } from "./INotifier";
|
||||
|
||||
export class NotifierStub implements INotifier {
|
||||
notifyStub: Sinon.SinonStub;
|
|
@ -4,7 +4,7 @@ import * as BluebirdPromise from "bluebird";
|
|||
|
||||
import { IMailSender } from "./IMailSender";
|
||||
import { AbstractEmailNotifier } from "../notifiers/AbstractEmailNotifier";
|
||||
import { SmtpNotifierConfiguration } from "../configuration/Configuration";
|
||||
import { SmtpNotifierConfiguration } from "../configuration/schema/NotifierConfiguration";
|
||||
|
||||
export class SmtpNotifier extends AbstractEmailNotifier {
|
||||
private mailSender: IMailSender;
|
||||
|
|
|
@ -3,12 +3,12 @@ import Sinon = require("sinon");
|
|||
import BluebirdPromise = require("bluebird");
|
||||
import Assert = require("assert");
|
||||
|
||||
import { Regulator } from "../../src/lib/regulation/Regulator";
|
||||
import { Regulator } from "./Regulator";
|
||||
import MockDate = require("mockdate");
|
||||
import exceptions = require("../../src/lib/Exceptions");
|
||||
import { UserDataStoreStub } from "../mocks/storage/UserDataStoreStub";
|
||||
import exceptions = require("../Exceptions");
|
||||
import { UserDataStoreStub } from "../storage/UserDataStoreStub.spec";
|
||||
|
||||
describe("test authentication regulator", function () {
|
||||
describe("regulation/Regulator", function () {
|
||||
const USER1 = "USER1";
|
||||
const USER2 = "USER2";
|
||||
let userDataStoreStub: UserDataStoreStub;
|
|
@ -0,0 +1,22 @@
|
|||
import Bluebird = require("bluebird");
|
||||
import Sinon = require("sinon");
|
||||
import { IRegulator } from "./IRegulator";
|
||||
|
||||
|
||||
export class RegulatorStub implements IRegulator {
|
||||
markStub: Sinon.SinonStub;
|
||||
regulateStub: Sinon.SinonStub;
|
||||
|
||||
constructor() {
|
||||
this.markStub = Sinon.stub();
|
||||
this.regulateStub = Sinon.stub();
|
||||
}
|
||||
|
||||
mark(userId: string, isAuthenticationSuccessful: boolean): Bluebird<void> {
|
||||
return this.markStub(userId, isAuthenticationSuccessful);
|
||||
}
|
||||
|
||||
regulate(userId: string): Bluebird<void> {
|
||||
return this.regulateStub(userId);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
import Sinon = require("sinon");
|
||||
import Express = require("express");
|
||||
import Assert = require("assert");
|
||||
import Get401 from "../../../../src/lib/routes/error/401/get";
|
||||
import { ServerVariables } from "../../../../src/lib/ServerVariables";
|
||||
import Get401 from "./get";
|
||||
import { ServerVariables } from "../../../ServerVariables";
|
||||
import { ServerVariablesMockBuilder, ServerVariablesMock }
|
||||
from "../../../mocks/ServerVariablesMockBuilder";
|
||||
from "../../../ServerVariablesMockBuilder.spec";
|
||||
|
||||
describe("Server error 401", function () {
|
||||
describe("routes/error/401/get", function () {
|
||||
let vars: ServerVariables;
|
||||
let mocks: ServerVariablesMock;
|
||||
let req: any;
|
|
@ -1,12 +1,12 @@
|
|||
import Sinon = require("sinon");
|
||||
import Express = require("express");
|
||||
import Assert = require("assert");
|
||||
import Get403 from "../../../../src/lib/routes/error/403/get";
|
||||
import { ServerVariables } from "../../../../src/lib/ServerVariables";
|
||||
import Get403 from "./get";
|
||||
import { ServerVariables } from "../../../ServerVariables";
|
||||
import { ServerVariablesMockBuilder, ServerVariablesMock }
|
||||
from "../../../mocks/ServerVariablesMockBuilder";
|
||||
from "../../../ServerVariablesMockBuilder.spec";
|
||||
|
||||
describe("Server error 403", function () {
|
||||
describe("routes/error/403/get", function () {
|
||||
let vars: ServerVariables;
|
||||
let mocks: ServerVariablesMock;
|
||||
let req: any;
|
|
@ -1,9 +1,9 @@
|
|||
import Sinon = require("sinon");
|
||||
import Express = require("express");
|
||||
import Assert = require("assert");
|
||||
import Get404 from "../../../../src/lib/routes/error/404/get";
|
||||
import Get404 from "./get";
|
||||
|
||||
describe("Server error 404", function () {
|
||||
describe("routes/error/404/get", function () {
|
||||
it("should render the page", function () {
|
||||
const req = {} as Express.Request;
|
||||
const res = {
|
|
@ -2,18 +2,18 @@
|
|||
import Sinon = require("sinon");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import Assert = require("assert");
|
||||
import FirstFactorPost = require("../../../src/lib/routes/firstfactor/post");
|
||||
import exceptions = require("../../../src/lib/Exceptions");
|
||||
import { AuthenticationSessionHandler } from "../../../src/lib/AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../../types/AuthenticationSession";
|
||||
import Endpoints = require("../../../../shared/api");
|
||||
import AuthenticationRegulatorMock = require("../../mocks/AuthenticationRegulator");
|
||||
import { AccessControllerStub } from "../../mocks/AccessControllerStub";
|
||||
import ExpressMock = require("../../mocks/express");
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder } from "../../mocks/ServerVariablesMockBuilder";
|
||||
import { ServerVariables } from "../../../src/lib/ServerVariables";
|
||||
import FirstFactorPost = require("./post");
|
||||
import exceptions = require("../../Exceptions");
|
||||
import { AuthenticationSessionHandler } from "../../AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../../../types/AuthenticationSession";
|
||||
import Endpoints = require("../../../../../shared/api");
|
||||
import AuthenticationRegulatorMock = require("../../regulation/RegulatorStub.spec");
|
||||
import { AccessControllerStub } from "../../access_control/AccessControllerStub.spec";
|
||||
import ExpressMock = require("../../stubs/express.spec");
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder } from "../../ServerVariablesMockBuilder.spec";
|
||||
import { ServerVariables } from "../../ServerVariables";
|
||||
|
||||
describe("test the first factor validation route", function () {
|
||||
describe("routes/firstfactor/post", function () {
|
||||
let req: ExpressMock.RequestMock;
|
||||
let res: ExpressMock.ResponseMock;
|
||||
let emails: string[];
|
|
@ -1,17 +1,17 @@
|
|||
|
||||
import PasswordResetFormPost = require("../../../src/lib/routes/password-reset/form/post");
|
||||
import { PasswordUpdater } from "../../../src/lib/ldap/PasswordUpdater";
|
||||
import { AuthenticationSessionHandler } from "../../../src/lib/AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../../types/AuthenticationSession";
|
||||
import { UserDataStore } from "../../../src/lib/storage/UserDataStore";
|
||||
import PasswordResetFormPost = require("./post");
|
||||
import { PasswordUpdater } from "../../../ldap/PasswordUpdater";
|
||||
import { AuthenticationSessionHandler } from "../../../AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../../../../types/AuthenticationSession";
|
||||
import { UserDataStore } from "../../../storage/UserDataStore";
|
||||
import Sinon = require("sinon");
|
||||
import Assert = require("assert");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import ExpressMock = require("../../mocks/express");
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder } from "../../mocks/ServerVariablesMockBuilder";
|
||||
import { ServerVariables } from "../../../src/lib/ServerVariables";
|
||||
import ExpressMock = require("../../../stubs/express.spec");
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder } from "../../../ServerVariablesMockBuilder.spec";
|
||||
import { ServerVariables } from "../../../ServerVariables";
|
||||
|
||||
describe("test reset password route", function () {
|
||||
describe("routes/password-reset/form/post", function () {
|
||||
let req: ExpressMock.RequestMock;
|
||||
let res: ExpressMock.ResponseMock;
|
||||
let vars: ServerVariables;
|
||||
|
@ -48,8 +48,9 @@ describe("test reset password route", function () {
|
|||
mail_attribute: "mail",
|
||||
user: "user",
|
||||
password: "password",
|
||||
users_dn: "ou=users,dc=example,dc=com",
|
||||
groups_dn: "ou=groups,dc=example,dc=com",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
base_dn: "dc=example,dc=com",
|
||||
users_filter: "user",
|
||||
group_name_attribute: "cn",
|
||||
groups_filter: "groups"
|
|
@ -1,18 +1,18 @@
|
|||
|
||||
import PasswordResetHandler
|
||||
from "../../../../src/lib/routes/password-reset/identity/PasswordResetHandler";
|
||||
import PasswordUpdater = require("../../../../src/lib/ldap/PasswordUpdater");
|
||||
import { UserDataStore } from "../../../../src/lib/storage/UserDataStore";
|
||||
from "./PasswordResetHandler";
|
||||
import PasswordUpdater = require("../../../ldap/PasswordUpdater");
|
||||
import { UserDataStore } from "../../../storage/UserDataStore";
|
||||
import Sinon = require("sinon");
|
||||
import winston = require("winston");
|
||||
import assert = require("assert");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import ExpressMock = require("../../../mocks/express");
|
||||
import ExpressMock = require("../../../stubs/express.spec");
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder }
|
||||
from "../../../mocks/ServerVariablesMockBuilder";
|
||||
import { ServerVariables } from "../../../../src/lib/ServerVariables";
|
||||
from "../../../ServerVariablesMockBuilder.spec";
|
||||
import { ServerVariables } from "../../../ServerVariables";
|
||||
|
||||
describe("test reset password identity check", function () {
|
||||
describe("routes/password-reset/identity/PasswordResetHandler", function () {
|
||||
let req: ExpressMock.RequestMock;
|
||||
let res: ExpressMock.ResponseMock;
|
||||
let mocks: ServerVariablesMock;
|
|
@ -4,7 +4,7 @@ import objectPath = require("object-path");
|
|||
|
||||
import exceptions = require("../../../Exceptions");
|
||||
import { Identity } from "../../../../../types/Identity";
|
||||
import { IdentityValidable } from "../../../IdentityCheckMiddleware";
|
||||
import { IdentityValidable } from "../../../IdentityValidable";
|
||||
import { PRE_VALIDATION_TEMPLATE } from "../../../IdentityCheckPreValidationTemplate";
|
||||
import Constants = require("../constants");
|
||||
import { IRequestLogger } from "../../../logging/IRequestLogger";
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import SecondFactorGet from "../../../src/lib/routes/secondfactor/get";
|
||||
import SecondFactorGet from "./get";
|
||||
import { ServerVariablesMockBuilder, ServerVariablesMock }
|
||||
from "../../mocks/ServerVariablesMockBuilder";
|
||||
import { ServerVariables } from "../../../src/lib/ServerVariables";
|
||||
from "../../ServerVariablesMockBuilder.spec";
|
||||
import { ServerVariables } from "../../ServerVariables";
|
||||
import Sinon = require("sinon");
|
||||
import ExpressMock = require("../../mocks/express");
|
||||
import ExpressMock = require("../../stubs/express.spec");
|
||||
import Assert = require("assert");
|
||||
import Endpoints = require("../../../../shared/api");
|
||||
import Endpoints = require("../../../../../shared/api");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
|
||||
describe("test second factor GET endpoint handler", function () {
|
||||
describe("routes/secondfactor/get", function () {
|
||||
let mocks: ServerVariablesMock;
|
||||
let vars: ServerVariables;
|
||||
let req: ExpressMock.RequestMock;
|
|
@ -1,11 +1,11 @@
|
|||
import Redirect from "../../../src/lib/routes/secondfactor/redirect";
|
||||
import ExpressMock = require("../../mocks/express");
|
||||
import Redirect from "./redirect";
|
||||
import ExpressMock = require("../../stubs/express.spec");
|
||||
import { ServerVariablesMockBuilder, ServerVariablesMock }
|
||||
from "../../mocks/ServerVariablesMockBuilder";
|
||||
import { ServerVariables } from "../../../src/lib/ServerVariables";
|
||||
from "../../ServerVariablesMockBuilder.spec";
|
||||
import { ServerVariables } from "../../ServerVariables";
|
||||
import Assert = require("assert");
|
||||
|
||||
describe("test second factor redirect", function() {
|
||||
describe("routes/secondfactor/redirect", function() {
|
||||
let req: ExpressMock.RequestMock;
|
||||
let res: ExpressMock.ResponseMock;
|
||||
let mocks: ServerVariablesMock;
|
|
@ -1,15 +1,15 @@
|
|||
import Sinon = require("sinon");
|
||||
import RegistrationHandler from "../../../../../src/lib/routes/secondfactor/totp/identity/RegistrationHandler";
|
||||
import { Identity } from "../../../../../types/Identity";
|
||||
import { UserDataStore } from "../../../../../src/lib/storage/UserDataStore";
|
||||
import RegistrationHandler from "./RegistrationHandler";
|
||||
import { Identity } from "../../../../../../types/Identity";
|
||||
import { UserDataStore } from "../../../../storage/UserDataStore";
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import ExpressMock = require("../../../../mocks/express");
|
||||
import ExpressMock = require("../../../../stubs/express.spec");
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder }
|
||||
from "../../../../mocks/ServerVariablesMockBuilder";
|
||||
import { ServerVariables } from "../../../../../src/lib/ServerVariables";
|
||||
from "../../../../ServerVariablesMockBuilder.spec";
|
||||
import { ServerVariables } from "../../../../ServerVariables";
|
||||
import Assert = require("assert");
|
||||
|
||||
describe("test totp register", function () {
|
||||
describe("routes/secondfactor/totp/identity/RegistrationHandler", function () {
|
||||
let req: ExpressMock.RequestMock;
|
||||
let res: ExpressMock.ResponseMock;
|
||||
let mocks: ServerVariablesMock;
|
|
@ -4,7 +4,7 @@ import BluebirdPromise = require("bluebird");
|
|||
import objectPath = require("object-path");
|
||||
|
||||
import { Identity } from "../../../../../../types/Identity";
|
||||
import { IdentityValidable } from "../../../../IdentityCheckMiddleware";
|
||||
import { IdentityValidable } from "../../../../IdentityValidable";
|
||||
import { PRE_VALIDATION_TEMPLATE } from "../../../../IdentityCheckPreValidationTemplate";
|
||||
import Constants = require("../constants");
|
||||
import Endpoints = require("../../../../../../../shared/api");
|
||||
|
@ -16,18 +16,18 @@ import { IRequestLogger } from "../../../../logging/IRequestLogger";
|
|||
import { IUserDataStore } from "../../../../storage/IUserDataStore";
|
||||
import { ITotpHandler } from "../../../../authentication/totp/ITotpHandler";
|
||||
import { TOTPSecret } from "../../../../../../types/TOTPSecret";
|
||||
import { TOTPConfiguration } from "../../../../configuration/Configuration";
|
||||
import { TotpConfiguration } from "../../../../configuration/schema/TotpConfiguration";
|
||||
|
||||
|
||||
export default class RegistrationHandler implements IdentityValidable {
|
||||
private logger: IRequestLogger;
|
||||
private userDataStore: IUserDataStore;
|
||||
private totp: ITotpHandler;
|
||||
private configuration: TOTPConfiguration;
|
||||
private configuration: TotpConfiguration;
|
||||
|
||||
constructor(logger: IRequestLogger,
|
||||
userDataStore: IUserDataStore,
|
||||
totp: ITotpHandler, configuration: TOTPConfiguration) {
|
||||
totp: ITotpHandler, configuration: TotpConfiguration) {
|
||||
this.logger = logger;
|
||||
this.userDataStore = userDataStore;
|
||||
this.totp = totp;
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
import BluebirdPromise = require("bluebird");
|
||||
import Sinon = require("sinon");
|
||||
import Assert = require("assert");
|
||||
import Exceptions = require("../../../../../src/lib/Exceptions");
|
||||
import { AuthenticationSessionHandler } from "../../../../../src/lib/AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../../../../types/AuthenticationSession";
|
||||
import SignPost = require("../../../../../src/lib/routes/secondfactor/totp/sign/post");
|
||||
import { ServerVariables } from "../../../../../src/lib/ServerVariables";
|
||||
import Exceptions = require("../../../../Exceptions");
|
||||
import { AuthenticationSessionHandler } from "../../../../AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../../../../../types/AuthenticationSession";
|
||||
import SignPost = require("./post");
|
||||
import { ServerVariables } from "../../../../ServerVariables";
|
||||
|
||||
import ExpressMock = require("../../../../mocks/express");
|
||||
import { UserDataStoreStub } from "../../../../mocks/storage/UserDataStoreStub";
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder } from "../../../../mocks/ServerVariablesMockBuilder";
|
||||
import ExpressMock = require("../../../../stubs/express.spec");
|
||||
import { UserDataStoreStub } from "../../../../storage/UserDataStoreStub.spec";
|
||||
import { ServerVariablesMock, ServerVariablesMockBuilder } from "../../../../ServerVariablesMockBuilder.spec";
|
||||
|
||||
describe("test totp route", function () {
|
||||
describe("routes/secondfactor/totp/sign/post", function () {
|
||||
let req: ExpressMock.RequestMock;
|
||||
let res: ExpressMock.ResponseMock;
|
||||
let authSession: AuthenticationSession;
|
|
@ -1,11 +1,9 @@
|
|||
import Bluebird = require("bluebird");
|
||||
import Express = require("express");
|
||||
|
||||
import exceptions = require("../../../../Exceptions");
|
||||
import objectPath = require("object-path");
|
||||
import express = require("express");
|
||||
import { TOTPSecretDocument } from "../../../../storage/TOTPSecretDocument";
|
||||
import BluebirdPromise = require("bluebird");
|
||||
import Endpoints = require("../../../../../../../shared/api");
|
||||
import redirect from "../../redirect";
|
||||
import Redirect from "../../redirect";
|
||||
import ErrorReplies = require("../../../../ErrorReplies");
|
||||
import { AuthenticationSessionHandler } from "../../../../AuthenticationSessionHandler";
|
||||
import { AuthenticationSession } from "../../../../../../types/AuthenticationSession";
|
||||
|
@ -15,11 +13,11 @@ import { ServerVariables } from "../../../../ServerVariables";
|
|||
const UNAUTHORIZED_MESSAGE = "Unauthorized access";
|
||||
|
||||
export default function (vars: ServerVariables) {
|
||||
function handler(req: express.Request, res: express.Response): BluebirdPromise<void> {
|
||||
function handler(req: Express.Request, res: Express.Response): Bluebird<void> {
|
||||
let authSession: AuthenticationSession;
|
||||
const token = req.body.token;
|
||||
|
||||
return new BluebirdPromise(function (resolve, reject) {
|
||||
return new Bluebird(function (resolve, reject) {
|
||||
authSession = AuthenticationSessionHandler.get(req, vars.logger);
|
||||
vars.logger.info(req, "Initiate TOTP validation for user \"%s\".", authSession.userid);
|
||||
resolve();
|
||||
|
@ -29,12 +27,12 @@ export default function (vars: ServerVariables) {
|
|||
})
|
||||
.then(function (doc: TOTPSecretDocument) {
|
||||
if (!vars.totpHandler.validate(token, doc.secret.base32))
|
||||
return BluebirdPromise.reject(new Error("Invalid TOTP token."));
|
||||
return Bluebird.reject(new Error("Invalid TOTP token."));
|
||||
|
||||
vars.logger.debug(req, "TOTP validation succeeded.");
|
||||
authSession.second_factor = true;
|
||||
redirect(vars)(req, res);
|
||||
return BluebirdPromise.resolve();
|
||||
Redirect(vars)(req, res);
|
||||
return Bluebird.resolve();
|
||||
})
|
||||
.catch(ErrorReplies.replyWithError200(req, res, vars.logger,
|
||||
UserMessages.OPERATION_FAILED));
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue