mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
Rework the configuration of the access control to allow default policy for certain domains
This commit is contained in:
parent
38a4570b24
commit
b403cfe2f8
|
@ -43,17 +43,19 @@ ldap:
|
||||||
# is allowed to everyone.
|
# is allowed to everyone.
|
||||||
# Otherwise, the default policy is denied for any user and any subdomain.
|
# Otherwise, the default policy is denied for any user and any subdomain.
|
||||||
access_control:
|
access_control:
|
||||||
- group: admin
|
default:
|
||||||
allowed_domains:
|
- home.test.local
|
||||||
- secret.test.local
|
groups:
|
||||||
- secret1.test.local
|
admin:
|
||||||
- secret2.test.local
|
- '*.test.local'
|
||||||
- group: dev
|
dev:
|
||||||
allowed_domains:
|
- secret.test.local
|
||||||
- secret2.test.local
|
- secret2.test.local
|
||||||
- user: harry
|
users:
|
||||||
allowed_domains:
|
harry:
|
||||||
- secret1.test.local
|
- secret1.test.local
|
||||||
|
bob:
|
||||||
|
- '*.mail.test.local'
|
||||||
|
|
||||||
|
|
||||||
# Configuration of session cookies
|
# Configuration of session cookies
|
||||||
|
|
|
@ -3,8 +3,81 @@
|
||||||
<title>Home page</title>
|
<title>Home page</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
You need to <a href="https://auth.test.local:8080/authentication/login?redirect=https://secret.test.local:8080/">log in</a> to access the <a href="/secret.html">secret</a>!<br/><br/>
|
<h1>Access the secret</h1>
|
||||||
But you can also access it from another <a href="https://secret1.test.local:8080/secret.html">domain</a> or still <a href="https://secret2.test.local:8080/secret.html">another one</a>.<br/><br/>
|
You need to log in to access the secret!<br/><br/>
|
||||||
You can also log off by visiting the following <a href="https://auth.test.local:8080/authentication/logout?redirect=https://secret.test.local:8080/">link</a>.
|
Try to access it via one of the following links.<br/>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://secret.test.local:8080/secret.html">secret.test.local</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://secret1.test.local:8080/secret.html">secret1.test.local</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://secret2.test.local:8080/secret.html">secret2.test.local</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://home.test.local:8080/secret.html">home.test.local</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://mx1.mail.test.local:8080/secret.html">mx1.mail.test.local</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://mx2.mail.test.local:8080/secret.html">mx2.mail.test.local</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
You can also log off by visiting the following <a href="https://auth.test.local:8080/authentication/logout?redirect=https://home.test.local:8080/">link</a>.
|
||||||
|
|
||||||
|
<h1>List of users</h1>
|
||||||
|
Here is the list of credentials you can log in with to test access control.
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><strong>john / password</strong>: belongs to <em>admin</em> and <em>dev</em> groups.</li>
|
||||||
|
<li><strong>bob / password</strong>: belongs to <em>dev</em> group only.</li>
|
||||||
|
<li><strong>harry / password</strong>: does not belong to any group.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h1>Access control rules</h1>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><strong>Default policy</strong>
|
||||||
|
<ul>
|
||||||
|
<li>home.test.local</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li><strong>Groups policy</strong>
|
||||||
|
<ul>
|
||||||
|
<li>admin
|
||||||
|
<ul>
|
||||||
|
<li>*.test.local</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>dev
|
||||||
|
<ul>
|
||||||
|
<li>secret.test.local</li>
|
||||||
|
<li>secret2.test.local</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li><strong>Users policy</strong>
|
||||||
|
<ul>
|
||||||
|
<li>harry
|
||||||
|
<ul>
|
||||||
|
<li>secret1.test.local</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>bob
|
||||||
|
<ul>
|
||||||
|
<li>*.mail.test.local</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -60,7 +60,9 @@ http {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
|
|
||||||
server_name secret1.test.local secret2.test.local secret.test.local localhost;
|
server_name secret1.test.local secret2.test.local secret.test.local
|
||||||
|
home.test.local mx1.mail.test.local mx2.mail.test.local
|
||||||
|
localhost;
|
||||||
|
|
||||||
ssl on;
|
ssl on;
|
||||||
ssl_certificate /etc/ssl/server.crt;
|
ssl_certificate /etc/ssl/server.crt;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<title>Secret</title>
|
<title>Secret</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
This is a very important secret!
|
This is a very important secret!<br/>
|
||||||
|
Go back to <a href="https://home.test.local:8080/">home page</a>.
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
84
src/lib/access_control.js
Normal file
84
src/lib/access_control.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
|
||||||
|
module.exports = function(logger, acl_config) {
|
||||||
|
return {
|
||||||
|
builder: new AccessControlBuilder(logger, acl_config),
|
||||||
|
matcher: new AccessControlMatcher(logger)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var objectPath = require('object-path');
|
||||||
|
|
||||||
|
// *************** PER DOMAIN MATCHER ***************
|
||||||
|
function AccessControlMatcher(logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessControlMatcher.prototype.is_domain_allowed = function(domain, allowed_domains) {
|
||||||
|
// Allow all matcher
|
||||||
|
if(allowed_domains.length == 1 && allowed_domains[0] == '*') return true;
|
||||||
|
|
||||||
|
this.logger.debug('ACL: trying to match %s with %s', domain,
|
||||||
|
JSON.stringify(allowed_domains));
|
||||||
|
for(var i = 0; i < allowed_domains.length; ++i) {
|
||||||
|
var allowed_domain = allowed_domains[i];
|
||||||
|
if(allowed_domain.startsWith('*') &&
|
||||||
|
domain.endsWith(allowed_domain.substr(1))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(domain == allowed_domain) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// *************** MATCHER BUILDER ***************
|
||||||
|
function AccessControlBuilder(logger, acl_config) {
|
||||||
|
this.logger = logger;
|
||||||
|
this.config = acl_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessControlBuilder.prototype.extract_per_group = function(groups) {
|
||||||
|
var allowed_domains = [];
|
||||||
|
var groups_policy = objectPath.get(this.config, 'groups');
|
||||||
|
if(groups_policy) {
|
||||||
|
for(var i=0; i<groups.length; ++i) {
|
||||||
|
var group = groups[i];
|
||||||
|
if(group in groups_policy) {
|
||||||
|
allowed_domains = allowed_domains.concat(groups_policy[group]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allowed_domains;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessControlBuilder.prototype.extract_per_user = function(user) {
|
||||||
|
var allowed_domains = [];
|
||||||
|
var users_policy = objectPath.get(this.config, 'users');
|
||||||
|
if(users_policy) {
|
||||||
|
if(user in users_policy) {
|
||||||
|
allowed_domains = allowed_domains.concat(users_policy[user]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allowed_domains;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessControlBuilder.prototype.get_allowed_domains = function(user, groups) {
|
||||||
|
var allowed_domains = [];
|
||||||
|
var default_policy = objectPath.get(this.config, 'default');
|
||||||
|
if(default_policy) {
|
||||||
|
allowed_domains = allowed_domains.concat(default_policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
allowed_domains = allowed_domains.concat(this.extract_per_group(groups));
|
||||||
|
allowed_domains = allowed_domains.concat(this.extract_per_user(user));
|
||||||
|
|
||||||
|
this.logger.debug('ACL: user \'%s\' is allowed access to %s', user,
|
||||||
|
JSON.stringify(allowed_domains));
|
||||||
|
return allowed_domains;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessControlBuilder.prototype.get_any_domain = function() {
|
||||||
|
return ['*'];
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ function first_factor(req, res) {
|
||||||
var ldap = req.app.get('ldap');
|
var ldap = req.app.get('ldap');
|
||||||
var config = req.app.get('config');
|
var config = req.app.get('config');
|
||||||
var regulator = req.app.get('authentication regulator');
|
var regulator = req.app.get('authentication regulator');
|
||||||
|
var acl_builder = req.app.get('access control').builder;
|
||||||
|
|
||||||
logger.info('1st factor: Starting authentication of user "%s"', username);
|
logger.info('1st factor: Starting authentication of user "%s"', username);
|
||||||
logger.debug('1st factor: Start bind operation against LDAP');
|
logger.debug('1st factor: Start bind operation against LDAP');
|
||||||
|
@ -56,22 +57,21 @@ function first_factor(req, res) {
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
var emails = data[0];
|
var emails = data[0];
|
||||||
var groups = data[1];
|
var groups = data[1];
|
||||||
|
var allowed_domains;
|
||||||
|
|
||||||
if(!emails && emails.length <= 0) throw new Error('No email found');
|
if(!emails && emails.length <= 0) throw new Error('No email found');
|
||||||
logger.debug('1st factor: Retrieved email are %s', emails);
|
logger.debug('1st factor: Retrieved email are %s', emails);
|
||||||
objectPath.set(req, 'session.auth_session.email', emails[0]);
|
objectPath.set(req, 'session.auth_session.email', emails[0]);
|
||||||
|
|
||||||
if(config.access_control) {
|
if(config.access_control) {
|
||||||
var allowed_domains = get_allowed_domains(config.access_control,
|
allowed_domains = acl_builder.get_allowed_domains(username, groups);
|
||||||
username, groups);
|
|
||||||
logger.debug('1st factor: allowed domains are %s', allowed_domains);
|
|
||||||
objectPath.set(req, 'session.auth_session.allowed_domains',
|
|
||||||
allowed_domains);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
allowed_domains = acl_builder.get_any_domain();
|
||||||
logger.debug('1st factor: no access control rules found.' +
|
logger.debug('1st factor: no access control rules found.' +
|
||||||
'Default policy to allow all.');
|
'Default policy to allow all.');
|
||||||
}
|
}
|
||||||
|
objectPath.set(req, 'session.auth_session.allowed_domains', allowed_domains);
|
||||||
|
|
||||||
regulator.mark(username, true);
|
regulator.mark(username, true);
|
||||||
res.status(204);
|
res.status(204);
|
||||||
|
|
|
@ -19,19 +19,17 @@ function verify_filter(req, res) {
|
||||||
if(!objectPath.has(req, 'session.auth_session.userid'))
|
if(!objectPath.has(req, 'session.auth_session.userid'))
|
||||||
return Promise.reject('No userid variable');
|
return Promise.reject('No userid variable');
|
||||||
|
|
||||||
var config = req.app.get('config');
|
if(!objectPath.has(req, 'session.auth_session.allowed_domains'))
|
||||||
var access_control = config.access_control;
|
return Promise.reject('No allowed_domains variable');
|
||||||
|
|
||||||
if(access_control) {
|
// Get the session ACL matcher
|
||||||
var allowed_domains = objectPath.get(req, 'session.auth_session.allowed_domains');
|
var allowed_domains = objectPath.get(req, 'session.auth_session.allowed_domains');
|
||||||
var host = objectPath.get(req, 'headers.host');
|
var host = objectPath.get(req, 'headers.host');
|
||||||
var domain = host.split(':')[0];
|
var domain = host.split(':')[0];
|
||||||
logger.debug('Trying to access domain: %s', domain);
|
var acl_matcher = req.app.get('access control').matcher;
|
||||||
logger.debug('User has access to %s', JSON.stringify(allowed_domains));
|
|
||||||
|
|
||||||
if(allowed_domains.indexOf(domain) < 0)
|
if(!acl_matcher.is_domain_allowed(domain, allowed_domains))
|
||||||
return Promise.reject('Access restricted by ACL rules');
|
return Promise.reject('Access restricted by ACL rules');
|
||||||
}
|
|
||||||
|
|
||||||
if(!req.session.auth_session.first_factor ||
|
if(!req.session.auth_session.first_factor ||
|
||||||
!req.session.auth_session.second_factor)
|
!req.session.auth_session.second_factor)
|
||||||
|
|
|
@ -12,6 +12,7 @@ var AuthenticationRegulator = require('./authentication_regulator');
|
||||||
var setup_endpoints = require('./setup_endpoints');
|
var setup_endpoints = require('./setup_endpoints');
|
||||||
var config_adapter = require('./config_adapter');
|
var config_adapter = require('./config_adapter');
|
||||||
var Ldap = require('./ldap');
|
var Ldap = require('./ldap');
|
||||||
|
var AccessControl = require('./access_control');
|
||||||
|
|
||||||
function run(yaml_config, deps, fn) {
|
function run(yaml_config, deps, fn) {
|
||||||
var config = config_adapter(yaml_config);
|
var config = config_adapter(yaml_config);
|
||||||
|
@ -51,6 +52,7 @@ function run(yaml_config, deps, fn) {
|
||||||
var regulator = new AuthenticationRegulator(data_store, five_minutes);
|
var regulator = new AuthenticationRegulator(data_store, five_minutes);
|
||||||
var notifier = new Notifier(config.notifier, deps);
|
var notifier = new Notifier(config.notifier, deps);
|
||||||
var ldap = new Ldap(deps, config.ldap);
|
var ldap = new Ldap(deps, config.ldap);
|
||||||
|
var access_control = AccessControl(deps.winston, config.access_control);
|
||||||
|
|
||||||
app.set('logger', deps.winston);
|
app.set('logger', deps.winston);
|
||||||
app.set('ldap', ldap);
|
app.set('ldap', ldap);
|
||||||
|
@ -60,6 +62,7 @@ function run(yaml_config, deps, fn) {
|
||||||
app.set('notifier', notifier);
|
app.set('notifier', notifier);
|
||||||
app.set('authentication regulator', regulator);
|
app.set('authentication regulator', regulator);
|
||||||
app.set('config', config);
|
app.set('config', config);
|
||||||
|
app.set('access control', access_control);
|
||||||
|
|
||||||
setup_endpoints(app);
|
setup_endpoints(app);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ var winston = require('winston');
|
||||||
var first_factor = require('../../../src/lib/routes/first_factor');
|
var first_factor = require('../../../src/lib/routes/first_factor');
|
||||||
var exceptions = require('../../../src/lib/exceptions');
|
var exceptions = require('../../../src/lib/exceptions');
|
||||||
var Ldap = require('../../../src/lib/ldap');
|
var Ldap = require('../../../src/lib/ldap');
|
||||||
|
var AccessControl = require('../../../src/lib/access_control');
|
||||||
|
|
||||||
describe('test the first factor validation route', function() {
|
describe('test the first factor validation route', function() {
|
||||||
var req, res;
|
var req, res;
|
||||||
|
@ -13,6 +14,7 @@ describe('test the first factor validation route', function() {
|
||||||
var emails;
|
var emails;
|
||||||
var search_res_ok;
|
var search_res_ok;
|
||||||
var regulator;
|
var regulator;
|
||||||
|
var access_control;
|
||||||
var config;
|
var config;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
|
@ -34,11 +36,22 @@ describe('test the first factor validation route', function() {
|
||||||
regulator.mark.returns(Promise.resolve());
|
regulator.mark.returns(Promise.resolve());
|
||||||
regulator.regulate.returns(Promise.resolve());
|
regulator.regulate.returns(Promise.resolve());
|
||||||
|
|
||||||
|
access_control = {
|
||||||
|
builder: {
|
||||||
|
get_allowed_domains: sinon.stub(),
|
||||||
|
get_any_domain: sinon.stub(),
|
||||||
|
},
|
||||||
|
matcher: {
|
||||||
|
is_domain_allowed: sinon.stub()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var app_get = sinon.stub();
|
var app_get = sinon.stub();
|
||||||
app_get.withArgs('ldap').returns(ldap_interface_mock);
|
app_get.withArgs('ldap').returns(ldap_interface_mock);
|
||||||
app_get.withArgs('config').returns(config);
|
app_get.withArgs('config').returns(config);
|
||||||
app_get.withArgs('logger').returns(winston);
|
app_get.withArgs('logger').returns(winston);
|
||||||
app_get.withArgs('authentication regulator').returns(regulator);
|
app_get.withArgs('authentication regulator').returns(regulator);
|
||||||
|
app_get.withArgs('access control').returns(access_control);
|
||||||
|
|
||||||
req = {
|
req = {
|
||||||
app: {
|
app: {
|
||||||
|
@ -74,16 +87,13 @@ describe('test the first factor validation route', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('store the allowed domains in the auth session', function() {
|
describe('store the ACL matcher in the auth session', function() {
|
||||||
it('should store the per group allowed domains', function() {
|
it('should store the allowed domains in the auth session', function() {
|
||||||
config.access_control = [];
|
config.access_control = {};
|
||||||
config.access_control.push({
|
access_control.builder.get_allowed_domains.returns(['example.com', 'test.example.com']);
|
||||||
group: 'group1',
|
|
||||||
allowed_domains: ['domain1.example.com', 'domain2.example.com']
|
|
||||||
});
|
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
res.send = sinon.spy(function(data) {
|
res.send = sinon.spy(function(data) {
|
||||||
assert.deepEqual(['domain1.example.com', 'domain2.example.com'],
|
assert.deepEqual(['example.com', 'test.example.com'],
|
||||||
req.session.auth_session.allowed_domains);
|
req.session.auth_session.allowed_domains);
|
||||||
assert.equal(204, res.status.getCall(0).args[0]);
|
assert.equal(204, res.status.getCall(0).args[0]);
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -95,16 +105,11 @@ describe('test the first factor validation route', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should store the per group allowed domains', function() {
|
it('should store the allow all ACL matcher in the auth session', function() {
|
||||||
config.access_control = [];
|
access_control.builder.get_any_domain.returns(['*']);
|
||||||
config.access_control.push({
|
|
||||||
user: 'username',
|
|
||||||
allowed_domains: ['domain1.example.com', 'domain2.example.com']
|
|
||||||
});
|
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
res.send = sinon.spy(function(data) {
|
res.send = sinon.spy(function(data) {
|
||||||
assert.deepEqual(['domain1.example.com', 'domain2.example.com'],
|
assert(req.session.auth_session.allowed_domains);
|
||||||
req.session.auth_session.allowed_domains);
|
|
||||||
assert.equal(204, res.status.getCall(0).args[0]);
|
assert.equal(204, res.status.getCall(0).args[0]);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,8 +7,15 @@ var winston = require('winston');
|
||||||
describe('test authentication token verification', function() {
|
describe('test authentication token verification', function() {
|
||||||
var req, res;
|
var req, res;
|
||||||
var config_mock;
|
var config_mock;
|
||||||
|
var acl_matcher;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
|
acl_matcher = {
|
||||||
|
is_domain_allowed: sinon.stub().returns(true)
|
||||||
|
};
|
||||||
|
var access_control = {
|
||||||
|
matcher: acl_matcher
|
||||||
|
}
|
||||||
config_mock = {};
|
config_mock = {};
|
||||||
req = {};
|
req = {};
|
||||||
res = {};
|
res = {};
|
||||||
|
@ -18,6 +25,7 @@ describe('test authentication token verification', function() {
|
||||||
req.app.get = sinon.stub();
|
req.app.get = sinon.stub();
|
||||||
req.app.get.withArgs('config').returns(config_mock);
|
req.app.get.withArgs('config').returns(config_mock);
|
||||||
req.app.get.withArgs('logger').returns(winston);
|
req.app.get.withArgs('logger').returns(winston);
|
||||||
|
req.app.get.withArgs('access control').returns(access_control);
|
||||||
res.status = sinon.spy();
|
res.status = sinon.spy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,7 +35,7 @@ describe('test authentication token verification', function() {
|
||||||
first_factor: true,
|
first_factor: true,
|
||||||
second_factor: true,
|
second_factor: true,
|
||||||
userid: 'myuser',
|
userid: 'myuser',
|
||||||
group: 'mygroup'
|
allowed_domains: ['*']
|
||||||
};
|
};
|
||||||
|
|
||||||
res.send = sinon.spy(function() {
|
res.send = sinon.spy(function() {
|
||||||
|
@ -86,25 +94,16 @@ describe('test authentication token verification', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reply unauthorized when the domain is restricted', function() {
|
it('should reply unauthorized when the domain is restricted', function() {
|
||||||
config_mock.access_control = [];
|
acl_matcher.is_domain_allowed.returns(false);
|
||||||
config_mock.access_control.push({
|
|
||||||
group: 'abc',
|
|
||||||
allowed_domains: ['secret.example.com']
|
|
||||||
});
|
|
||||||
return test_unauthorized({
|
return test_unauthorized({
|
||||||
first_factor: true,
|
first_factor: true,
|
||||||
second_factor: true,
|
second_factor: true,
|
||||||
userid: 'user',
|
userid: 'user',
|
||||||
allowed_domains: ['restricted.example.com']
|
allowed_domains: []
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reply authorized when the domain is allowed', function() {
|
it('should reply authorized when the domain is allowed', function() {
|
||||||
config_mock.access_control = [];
|
|
||||||
config_mock.access_control.push({
|
|
||||||
group: 'abc',
|
|
||||||
allowed_domains: ['secret.example.com']
|
|
||||||
});
|
|
||||||
return test_authorized({
|
return test_authorized({
|
||||||
first_factor: true,
|
first_factor: true,
|
||||||
second_factor: true,
|
second_factor: true,
|
||||||
|
|
160
test/unitary/test_access_control.js
Normal file
160
test/unitary/test_access_control.js
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
|
||||||
|
var assert = require('assert');
|
||||||
|
var winston = require('winston');
|
||||||
|
var AccessControl = require('../../src/lib/access_control');
|
||||||
|
|
||||||
|
describe('test access control manager', function() {
|
||||||
|
var access_control;
|
||||||
|
var acl_config;
|
||||||
|
var acl_builder;
|
||||||
|
var acl_matcher;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
acl_config = {};
|
||||||
|
access_control = AccessControl(winston, acl_config);
|
||||||
|
acl_builder = access_control.builder;
|
||||||
|
acl_matcher = access_control.matcher;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('building user group access control matcher', function() {
|
||||||
|
it('should deny all if nothing is defined in the config', function() {
|
||||||
|
var allowed_domains = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert.deepEqual(allowed_domains, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow domain test.example.com to all users if defined in' +
|
||||||
|
' default policy', function() {
|
||||||
|
acl_config.default = ['test.example.com'];
|
||||||
|
|
||||||
|
var allowed_domains = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert.deepEqual(allowed_domains, ['test.example.com']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow domain test.example.com to all users in group mygroup', function() {
|
||||||
|
var allowed_domains0 = acl_builder.get_allowed_domains('user', ['group1', 'group1']);
|
||||||
|
assert.deepEqual(allowed_domains0, []);
|
||||||
|
|
||||||
|
acl_config.groups = {
|
||||||
|
mygroup: ['test.example.com']
|
||||||
|
};
|
||||||
|
|
||||||
|
var allowed_domains1 = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert.deepEqual(allowed_domains1, []);
|
||||||
|
|
||||||
|
var allowed_domains2 = acl_builder.get_allowed_domains('user', ['group1', 'mygroup']);
|
||||||
|
assert.deepEqual(allowed_domains2, ['test.example.com']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow domain test.example.com based on per user config', function() {
|
||||||
|
var allowed_domains0 = acl_builder.get_allowed_domains('user', ['group1']);
|
||||||
|
assert.deepEqual(allowed_domains0, []);
|
||||||
|
|
||||||
|
acl_config.users = {
|
||||||
|
user1: ['test.example.com']
|
||||||
|
};
|
||||||
|
|
||||||
|
var allowed_domains1 = acl_builder.get_allowed_domains('user', ['group1', 'mygroup']);
|
||||||
|
assert.deepEqual(allowed_domains1, []);
|
||||||
|
|
||||||
|
var allowed_domains2 = acl_builder.get_allowed_domains('user1', ['group1', 'mygroup']);
|
||||||
|
assert.deepEqual(allowed_domains2, ['test.example.com']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow domains from user and groups', function() {
|
||||||
|
acl_config.groups = {
|
||||||
|
group2: ['secret.example.com', 'secret1.example.com']
|
||||||
|
};
|
||||||
|
acl_config.users = {
|
||||||
|
user: ['test.example.com']
|
||||||
|
};
|
||||||
|
|
||||||
|
var allowed_domains0 = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert.deepEqual(allowed_domains0, [
|
||||||
|
'secret.example.com',
|
||||||
|
'secret1.example.com',
|
||||||
|
'test.example.com',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow domains from several groups', function() {
|
||||||
|
acl_config.groups = {
|
||||||
|
group1: ['secret2.example.com'],
|
||||||
|
group2: ['secret.example.com', 'secret1.example.com']
|
||||||
|
};
|
||||||
|
|
||||||
|
var allowed_domains0 = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert.deepEqual(allowed_domains0, [
|
||||||
|
'secret2.example.com',
|
||||||
|
'secret.example.com',
|
||||||
|
'secret1.example.com',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow domains from several groups and default policy', function() {
|
||||||
|
acl_config.default = ['home.example.com'];
|
||||||
|
acl_config.groups = {
|
||||||
|
group1: ['secret2.example.com'],
|
||||||
|
group2: ['secret.example.com', 'secret1.example.com']
|
||||||
|
};
|
||||||
|
|
||||||
|
var allowed_domains0 = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert.deepEqual(allowed_domains0, [
|
||||||
|
'home.example.com',
|
||||||
|
'secret2.example.com',
|
||||||
|
'secret.example.com',
|
||||||
|
'secret1.example.com',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('building user group access control matcher', function() {
|
||||||
|
it('should allow access to any subdomain', function() {
|
||||||
|
var allowed_domains = acl_builder.get_any_domain();
|
||||||
|
assert(acl_matcher.is_domain_allowed('example.com', allowed_domains));
|
||||||
|
assert(acl_matcher.is_domain_allowed('mail.example.com', allowed_domains));
|
||||||
|
assert(acl_matcher.is_domain_allowed('test.example.com', allowed_domains));
|
||||||
|
assert(acl_matcher.is_domain_allowed('user.mail.example.com', allowed_domains));
|
||||||
|
assert(acl_matcher.is_domain_allowed('public.example.com', allowed_domains));
|
||||||
|
assert(acl_matcher.is_domain_allowed('example2.com', allowed_domains));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('check access control matching', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
acl_config.default = ['home.example.com', '*.public.example.com'];
|
||||||
|
acl_config.users = {
|
||||||
|
user1: ['user1.example.com', 'user1.mail.example.com']
|
||||||
|
};
|
||||||
|
acl_config.groups = {
|
||||||
|
group1: ['secret2.example.com'],
|
||||||
|
group2: ['secret.example.com', 'secret1.example.com']
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow access to secret.example.com', function() {
|
||||||
|
var allowed_domains = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert(acl_matcher.is_domain_allowed('secret.example.com', allowed_domains));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should deny access to secret3.example.com', function() {
|
||||||
|
var allowed_domains = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert(!acl_matcher.is_domain_allowed('secret3.example.com', allowed_domains));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow access to home.example.com', function() {
|
||||||
|
var allowed_domains = acl_builder.get_allowed_domains('user', ['group1', 'group2']);
|
||||||
|
assert(acl_matcher.is_domain_allowed('home.example.com', allowed_domains));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow access to user1.example.com', function() {
|
||||||
|
var allowed_domains = acl_builder.get_allowed_domains('user1', ['group1', 'group2']);
|
||||||
|
assert(acl_matcher.is_domain_allowed('user1.example.com', allowed_domains));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow access *.public.example.com', function() {
|
||||||
|
var allowed_domains = acl_builder.get_allowed_domains('nouser', []);
|
||||||
|
assert(acl_matcher.is_domain_allowed('user.public.example.com', allowed_domains));
|
||||||
|
assert(acl_matcher.is_domain_allowed('test.public.example.com', allowed_domains));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user