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",
|
||||
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": {
|
||||
cmd: "./node_modules/.bin/tsc",
|
||||
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('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-dist', ['build', 'run:minify', 'cssmin', 'run:include-minified-script']);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"title": "Authelia API documentation"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": "^5.2.3",
|
||||
"bluebird": "^3.4.7",
|
||||
"body-parser": "^1.15.2",
|
||||
"connect-redis": "^3.3.0",
|
||||
|
@ -106,6 +107,7 @@
|
|||
"ts-node": "^3.3.0",
|
||||
"tslint": "^5.2.0",
|
||||
"typescript": "^2.3.2",
|
||||
"typescript-json-schema": "^0.17.0",
|
||||
"u2f-api": "0.0.9",
|
||||
"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 { ACLAdapter } from "./adapters/ACLAdapter";
|
||||
import { AuthenticationMethodsAdapter } from "./adapters/AuthenticationMethodsAdapter";
|
||||
import { Validator } from "./Validator";
|
||||
|
||||
const LDAP_URL_ENV_VARIABLE = "LDAP_URL";
|
||||
|
||||
|
@ -58,9 +59,8 @@ function adaptLdapConfiguration(userConfig: UserLdapConfiguration): LdapConfigur
|
|||
|
||||
function adaptFromUserConfiguration(userConfiguration: UserConfiguration)
|
||||
: AppConfiguration {
|
||||
ensure_key_existence(userConfiguration, "ldap");
|
||||
ensure_key_existence(userConfiguration, "session.secret");
|
||||
ensure_key_existence(userConfiguration, "regulation");
|
||||
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);
|
||||
|
|
|
@ -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