Adapt ACL configuration to make it more flexible
Basically, the ACL configuration was very static and it was not allowed to remove 'any', 'groups', 'users'. The application crashed when those keys did not exist. After this fix, every key is optional and replaced by a default value for the app configuration to be complete and used by Authelia. Later, a configuration validator will be implemented to detect issues with configuration at startup.pull/127/head
parent
f3f61d4e13
commit
267cf2921d
|
@ -7,10 +7,10 @@ import {
|
|||
UserLdapConfiguration
|
||||
} from "./Configuration";
|
||||
import Util = require("util");
|
||||
import { ACLAdapter } from "./adapters/ACLAdapter";
|
||||
|
||||
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)) {
|
||||
|
@ -80,7 +80,7 @@ function adaptFromUserConfiguration(userConfiguration: UserConfiguration): AppCo
|
|||
},
|
||||
logs_level: get_optional<string>(userConfiguration, "logs_level", "info"),
|
||||
notifier: ObjectPath.get<object, NotifierConfiguration>(userConfiguration, "notifier"),
|
||||
access_control: ObjectPath.get<object, ACLConfiguration>(userConfiguration, "access_control"),
|
||||
access_control: ACLAdapter.adapt(userConfiguration.access_control),
|
||||
regulation: userConfiguration.regulation
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import { ACLConfiguration } from "../Configuration";
|
||||
|
||||
function clone(obj: any): any {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
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 = clone(configuration);
|
||||
adaptDefaultPolicy(newConfiguration);
|
||||
adaptAny(newConfiguration);
|
||||
adaptGroups(newConfiguration);
|
||||
adaptUsers(newConfiguration);
|
||||
return newConfiguration;
|
||||
}
|
||||
}
|
|
@ -173,8 +173,8 @@ describe("test access control manager", function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe("check all rules", function () {
|
||||
it("should control access when all rules are defined", function () {
|
||||
describe("check any rules", function () {
|
||||
it("should control access when any rules are defined", function () {
|
||||
configuration.any = [{
|
||||
domain: "home.example.com",
|
||||
policy: "allow",
|
||||
|
@ -307,7 +307,7 @@ describe("test access control manager", function () {
|
|||
Assert(!accessController.isAccessAllowed("home.example.com", "/dev/bob", "john", ["dev"]));
|
||||
});
|
||||
|
||||
it("should control access when allowed at all level and denied at user level", function () {
|
||||
it("should control access when allowed at 'any' level and denied at user level", function () {
|
||||
configuration.any = [{
|
||||
domain: "home.example.com",
|
||||
policy: "allow",
|
||||
|
@ -323,7 +323,7 @@ describe("test access control manager", function () {
|
|||
Assert(!accessController.isAccessAllowed("home.example.com", "/dev/bob", "john", ["dev"]));
|
||||
});
|
||||
|
||||
it("should control access when allowed at all level and denied at group level", function () {
|
||||
it("should control access when allowed at 'any' level and denied at group level", function () {
|
||||
configuration.any = [{
|
||||
domain: "home.example.com",
|
||||
policy: "allow",
|
||||
|
|
|
@ -43,18 +43,20 @@ describe("test config adapter", function () {
|
|||
return yaml_config;
|
||||
}
|
||||
|
||||
it("should read the port from the yaml file", function () {
|
||||
const yaml_config = build_yaml_config();
|
||||
yaml_config.port = 7070;
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.equal(config.port, 7070);
|
||||
});
|
||||
describe("port", function () {
|
||||
it("should read the port from the yaml file", function () {
|
||||
const yaml_config = build_yaml_config();
|
||||
yaml_config.port = 7070;
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.equal(config.port, 7070);
|
||||
});
|
||||
|
||||
it("should default the port to 8080 if not provided", function () {
|
||||
const yaml_config = build_yaml_config();
|
||||
delete yaml_config.port;
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.equal(config.port, 8080);
|
||||
it("should default the port to 8080 if not provided", function () {
|
||||
const yaml_config = build_yaml_config();
|
||||
delete yaml_config.port;
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.equal(config.port, 8080);
|
||||
});
|
||||
});
|
||||
|
||||
it("should get the session attributes", function () {
|
||||
|
@ -94,20 +96,51 @@ describe("test config adapter", function () {
|
|||
});
|
||||
});
|
||||
|
||||
it("should get the access_control config", function () {
|
||||
const yaml_config = build_yaml_config();
|
||||
yaml_config.access_control = {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
users: {},
|
||||
groups: {}
|
||||
};
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.deepEqual(config.access_control, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
users: {},
|
||||
groups: {}
|
||||
} as ACLConfiguration);
|
||||
describe("access_control", function() {
|
||||
it("should adapt access_control when it is already ok", function () {
|
||||
const yaml_config = build_yaml_config();
|
||||
yaml_config.access_control = {
|
||||
default_policy: "deny",
|
||||
any: [{
|
||||
domain: "public.example.com",
|
||||
policy: "allow"
|
||||
}],
|
||||
users: {
|
||||
"user": [{
|
||||
domain: "www.example.com",
|
||||
policy: "allow"
|
||||
}]
|
||||
},
|
||||
groups: {}
|
||||
};
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.deepEqual(config.access_control, {
|
||||
default_policy: "deny",
|
||||
any: [{
|
||||
domain: "public.example.com",
|
||||
policy: "allow"
|
||||
}],
|
||||
users: {
|
||||
"user": [{
|
||||
domain: "www.example.com",
|
||||
policy: "allow"
|
||||
}]
|
||||
},
|
||||
groups: {}
|
||||
} as ACLConfiguration);
|
||||
});
|
||||
|
||||
|
||||
it("should adapt access_control when it is empty", function () {
|
||||
const yaml_config = build_yaml_config();
|
||||
yaml_config.access_control = {} as any;
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.deepEqual(config.access_control, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
users: {},
|
||||
groups: {}
|
||||
} as ACLConfiguration);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
import { ACLAdapter } from "../../../src/lib/configuration/adapters/ACLAdapter";
|
||||
import Assert = require("assert");
|
||||
|
||||
describe("test ACL configuration adapter", function () {
|
||||
|
||||
describe("bad default_policy", function () {
|
||||
it("should adapt a configuration missing default_policy", function () {
|
||||
const userConfiguration: any = {
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("should adapt a configuration with bad default_policy value", function () {
|
||||
const userConfiguration: any = {
|
||||
default_policy: "anything", // it should be 'allow' or 'deny'
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("should adapt a configuration with bad default_policy type", function () {
|
||||
const userConfiguration: any = {
|
||||
default_policy: {}, // it should be 'allow' or 'deny'
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("bad any", function () {
|
||||
it("should adapt a configuration missing any key", function () {
|
||||
const userConfiguration: any = {
|
||||
default_policy: "deny",
|
||||
groups: {},
|
||||
users: {}
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("should adapt a configuration with any not being an array", function () {
|
||||
const userConfiguration: any = {
|
||||
default_policy: "deny",
|
||||
any: "abc",
|
||||
groups: {},
|
||||
users: {}
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("bad groups", function () {
|
||||
it("should adapt a configuration missing groups key", function () {
|
||||
const userConfiguration: any = {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
users: {}
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("should adapt configuration with groups being of wrong type", function () {
|
||||
const userConfiguration: any = {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: [],
|
||||
users: {}
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("bad users", function () {
|
||||
it("should adapt a configuration missing users key", function () {
|
||||
const userConfiguration: any = {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {}
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("should adapt a configuration with users being of wrong type", function () {
|
||||
const userConfiguration: any = {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: []
|
||||
};
|
||||
|
||||
const appConfiguration = ACLAdapter.adapt(userConfiguration);
|
||||
Assert.deepStrictEqual(appConfiguration, {
|
||||
default_policy: "deny",
|
||||
any: [],
|
||||
groups: {},
|
||||
users: {}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue