Add a schema validator to check user configuration
parent
1ab09b71d4
commit
2a3fde5ee7
|
@ -15,6 +15,11 @@ module.exports = function (grunt) {
|
||||||
cmd: "./node_modules/.bin/tsc",
|
cmd: "./node_modules/.bin/tsc",
|
||||||
args: ['-p', 'server/tsconfig.json']
|
args: ['-p', 'server/tsconfig.json']
|
||||||
},
|
},
|
||||||
|
"generate-config-schema": {
|
||||||
|
cmd: "./node_modules/.bin/typescript-json-schema",
|
||||||
|
args: ["-o", `${buildDir}/server/src/lib/configuration/Configuration.schema.json`, "--strictNullChecks",
|
||||||
|
"--required", "server/tsconfig.json", "UserConfiguration"]
|
||||||
|
},
|
||||||
"compile-client": {
|
"compile-client": {
|
||||||
cmd: "./node_modules/.bin/tsc",
|
cmd: "./node_modules/.bin/tsc",
|
||||||
args: ['-p', 'client/tsconfig.json']
|
args: ['-p', 'client/tsconfig.json']
|
||||||
|
@ -178,7 +183,7 @@ module.exports = function (grunt) {
|
||||||
grunt.registerTask('copy-resources', ['copy:resources', 'copy:views', 'copy:images', 'copy:thirdparties', 'concat:css']);
|
grunt.registerTask('copy-resources', ['copy:resources', 'copy:views', 'copy:images', 'copy:thirdparties', 'concat:css']);
|
||||||
|
|
||||||
grunt.registerTask('build-client', ['compile-client', 'browserify']);
|
grunt.registerTask('build-client', ['compile-client', 'browserify']);
|
||||||
grunt.registerTask('build-server', ['compile-server', 'copy-resources']);
|
grunt.registerTask('build-server', ['compile-server', 'copy-resources', 'run:generate-config-schema']);
|
||||||
|
|
||||||
grunt.registerTask('build', ['build-client', 'build-server']);
|
grunt.registerTask('build', ['build-client', 'build-server']);
|
||||||
grunt.registerTask('build-dist', ['build', 'run:minify', 'cssmin', 'run:include-minified-script']);
|
grunt.registerTask('build-dist', ['build', 'run:minify', 'cssmin', 'run:include-minified-script']);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"title": "Authelia API documentation"
|
"title": "Authelia API documentation"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ajv": "^5.2.3",
|
||||||
"bluebird": "^3.4.7",
|
"bluebird": "^3.4.7",
|
||||||
"body-parser": "^1.15.2",
|
"body-parser": "^1.15.2",
|
||||||
"connect-redis": "^3.3.0",
|
"connect-redis": "^3.3.0",
|
||||||
|
@ -106,6 +107,7 @@
|
||||||
"ts-node": "^3.3.0",
|
"ts-node": "^3.3.0",
|
||||||
"tslint": "^5.2.0",
|
"tslint": "^5.2.0",
|
||||||
"typescript": "^2.3.2",
|
"typescript": "^2.3.2",
|
||||||
|
"typescript-json-schema": "^0.17.0",
|
||||||
"u2f-api": "0.0.9",
|
"u2f-api": "0.0.9",
|
||||||
"uglify-es": "^3.0.15"
|
"uglify-es": "^3.0.15"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,374 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
|
"definitions": {
|
||||||
|
"ACLConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"any": {
|
||||||
|
"items": {
|
||||||
|
"properties": {
|
||||||
|
"domain": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"$ref": "#/definitions/ACLPolicy"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"domain",
|
||||||
|
"policy"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"default_policy": {
|
||||||
|
"$ref": "#/definitions/ACLPolicy"
|
||||||
|
},
|
||||||
|
"groups": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"items": {
|
||||||
|
"properties": {
|
||||||
|
"domain": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"$ref": "#/definitions/ACLPolicy"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"domain",
|
||||||
|
"policy"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"items": {
|
||||||
|
"properties": {
|
||||||
|
"domain": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"$ref": "#/definitions/ACLPolicy"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"domain",
|
||||||
|
"policy"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"any",
|
||||||
|
"default_policy",
|
||||||
|
"groups",
|
||||||
|
"users"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"ACLPolicy": {
|
||||||
|
"enum": [
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"AuthenticationMethod": {
|
||||||
|
"enum": [
|
||||||
|
"basic_auth",
|
||||||
|
"two_factor"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"AuthenticationMethodsConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"default_method": {
|
||||||
|
"$ref": "#/definitions/AuthenticationMethod"
|
||||||
|
},
|
||||||
|
"per_subdomain_methods": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"enum": [
|
||||||
|
"basic_auth",
|
||||||
|
"two_factor"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"default_method",
|
||||||
|
"per_subdomain_methods"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"FileSystemNotifierConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"filename": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"filename"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"GmailNotifierConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"sender": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"password",
|
||||||
|
"sender",
|
||||||
|
"username"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"LocalStorageConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"in_memory": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"MongoStorageConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"url"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"NotifierConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"filesystem": {
|
||||||
|
"$ref": "#/definitions/FileSystemNotifierConfiguration"
|
||||||
|
},
|
||||||
|
"gmail": {
|
||||||
|
"$ref": "#/definitions/GmailNotifierConfiguration"
|
||||||
|
},
|
||||||
|
"smtp": {
|
||||||
|
"$ref": "#/definitions/SmtpNotifierConfiguration"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"RegulationConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"ban_time": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"find_time": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"max_retries": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"ban_time",
|
||||||
|
"find_time",
|
||||||
|
"max_retries"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"SessionCookieConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"domain": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"expiration": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"redis": {
|
||||||
|
"$ref": "#/definitions/SessionRedisOptions"
|
||||||
|
},
|
||||||
|
"secret": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"secret"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"SessionRedisOptions": {
|
||||||
|
"properties": {
|
||||||
|
"host": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"host",
|
||||||
|
"port"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"SmtpNotifierConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"host": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"secure": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"sender": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"host",
|
||||||
|
"password",
|
||||||
|
"port",
|
||||||
|
"secure",
|
||||||
|
"sender",
|
||||||
|
"username"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"StorageConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"local": {
|
||||||
|
"$ref": "#/definitions/LocalStorageConfiguration"
|
||||||
|
},
|
||||||
|
"mongo": {
|
||||||
|
"$ref": "#/definitions/MongoStorageConfiguration"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"UserLdapConfiguration": {
|
||||||
|
"properties": {
|
||||||
|
"additional_groups_dn": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"additional_users_dn": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"base_dn": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"group_name_attribute": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groups_filter": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mail_attribute": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"users_filter": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"base_dn",
|
||||||
|
"password",
|
||||||
|
"url",
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"access_control": {
|
||||||
|
"$ref": "#/definitions/ACLConfiguration"
|
||||||
|
},
|
||||||
|
"authentication_methods": {
|
||||||
|
"$ref": "#/definitions/AuthenticationMethodsConfiguration"
|
||||||
|
},
|
||||||
|
"ldap": {
|
||||||
|
"$ref": "#/definitions/UserLdapConfiguration"
|
||||||
|
},
|
||||||
|
"logs_level": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"notifier": {
|
||||||
|
"$ref": "#/definitions/NotifierConfiguration"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"regulation": {
|
||||||
|
"$ref": "#/definitions/RegulationConfiguration"
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"$ref": "#/definitions/SessionCookieConfiguration"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"$ref": "#/definitions/StorageConfiguration"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"ldap",
|
||||||
|
"notifier",
|
||||||
|
"regulation",
|
||||||
|
"session",
|
||||||
|
"storage"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
import Util = require("util");
|
import Util = require("util");
|
||||||
import { ACLAdapter } from "./adapters/ACLAdapter";
|
import { ACLAdapter } from "./adapters/ACLAdapter";
|
||||||
import { AuthenticationMethodsAdapter } from "./adapters/AuthenticationMethodsAdapter";
|
import { AuthenticationMethodsAdapter } from "./adapters/AuthenticationMethodsAdapter";
|
||||||
|
import { Validator } from "./Validator";
|
||||||
|
|
||||||
const LDAP_URL_ENV_VARIABLE = "LDAP_URL";
|
const LDAP_URL_ENV_VARIABLE = "LDAP_URL";
|
||||||
|
|
||||||
|
@ -58,9 +59,8 @@ function adaptLdapConfiguration(userConfig: UserLdapConfiguration): LdapConfigur
|
||||||
|
|
||||||
function adaptFromUserConfiguration(userConfiguration: UserConfiguration)
|
function adaptFromUserConfiguration(userConfiguration: UserConfiguration)
|
||||||
: AppConfiguration {
|
: AppConfiguration {
|
||||||
ensure_key_existence(userConfiguration, "ldap");
|
if (!Validator.isValid(userConfiguration))
|
||||||
ensure_key_existence(userConfiguration, "session.secret");
|
throw new Error("Configuration is malformed. Please double check your configuration file.");
|
||||||
ensure_key_existence(userConfiguration, "regulation");
|
|
||||||
|
|
||||||
const port = userConfiguration.port || 8080;
|
const port = userConfiguration.port || 8080;
|
||||||
const ldapConfiguration = adaptLdapConfiguration(userConfiguration.ldap);
|
const ldapConfiguration = adaptLdapConfiguration(userConfiguration.ldap);
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import Ajv = require("ajv");
|
||||||
|
import Path = require("path");
|
||||||
|
|
||||||
|
export class Validator {
|
||||||
|
static isValid(configuration: any) {
|
||||||
|
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-04.json"));
|
||||||
|
const valid = ajv.validate(schema, configuration);
|
||||||
|
if (!valid) {
|
||||||
|
for (const i in ajv.errors) {
|
||||||
|
console.log(ajv.errorsText([ajv.errors[i]]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { Validator } from "../../src/lib/configuration/Validator";
|
||||||
|
import Assert = require("assert");
|
||||||
|
|
||||||
|
describe.only("test validator", function() {
|
||||||
|
it("should validate a correct user configuration", function() {
|
||||||
|
Assert(Validator.validate({
|
||||||
|
ldap: {}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue