authelia/server/test/access_control/AccessController.test.ts

368 lines
17 KiB
TypeScript

import Assert = require("assert");
import winston = require("winston");
import { AccessController } from "../../src/lib/access_control/AccessController";
import { ACLConfiguration, ACLRule } from "../../src/lib/configuration/Configuration";
describe("test access control manager", function () {
let accessController: AccessController;
let configuration: ACLConfiguration;
describe("configuration is null", function() {
it("should allow access to anything, anywhere for anybody", function() {
configuration = undefined;
accessController = new AccessController(configuration, winston);
Assert(accessController.isAccessAllowed("home.test.local", "/", "user1", ["group1", "group2"]));
Assert(accessController.isAccessAllowed("home.test.local", "/abc", "user1", ["group1", "group2"]));
Assert(accessController.isAccessAllowed("home.test.local", "/", "user2", ["group1", "group2"]));
Assert(accessController.isAccessAllowed("admin.test.local", "/", "user3", ["group3"]));
});
});
describe("configuration is not null", function () {
beforeEach(function () {
configuration = {
default_policy: "deny",
any: [],
users: {},
groups: {}
};
accessController = new AccessController(configuration, winston);
});
describe("check access control with default policy to deny", function () {
beforeEach(function () {
configuration.default_policy = "deny";
});
it("should deny access when no rule is provided", function () {
Assert(!accessController.isAccessAllowed("home.example.com", "/", "user1", ["group1"]));
});
it("should control access when multiple domain matcher is provided", function () {
configuration.users["user1"] = [{
domain: "*.mail.example.com",
policy: "allow",
resources: [".*"]
}];
Assert(!accessController.isAccessAllowed("home.example.com", "/", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("mx1.mail.example.com", "/", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("mx1.server.mail.example.com", "/", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("mail.example.com", "/", "user1", ["group1"]));
});
it("should allow access to all resources when resources is not provided", function () {
configuration.users["user1"] = [{
domain: "*.mail.example.com",
policy: "allow"
}];
Assert(!accessController.isAccessAllowed("home.example.com", "/", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("mx1.mail.example.com", "/", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("mx1.server.mail.example.com", "/", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("mail.example.com", "/", "user1", ["group1"]));
});
describe("check user rules", function () {
it("should allow access when user has a matching allowing rule", function () {
configuration.users["user1"] = [{
domain: "home.example.com",
policy: "allow",
resources: [".*"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/another/resource", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("another.home.example.com", "/", "user1", ["group1"]));
});
it("should deny to other users", function () {
configuration.users["user1"] = [{
domain: "home.example.com",
policy: "allow",
resources: [".*"]
}];
Assert(!accessController.isAccessAllowed("home.example.com", "/", "user2", ["group1"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/another/resource", "user2", ["group1"]));
Assert(!accessController.isAccessAllowed("another.home.example.com", "/", "user2", ["group1"]));
});
it("should allow user access only to specific resources", function () {
configuration.users["user1"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["/private/.*", "^/begin", "/end$"]
}];
Assert(!accessController.isAccessAllowed("home.example.com", "/", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/private", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/private/class", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/middle/private/class", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/begin", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/not/begin", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/abc/end", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/abc/end/x", "user1", ["group1"]));
});
it("should allow access to multiple domains", function () {
configuration.users["user1"] = [{
domain: "home.example.com",
policy: "allow",
resources: [".*"]
}, {
domain: "home1.example.com",
policy: "allow",
resources: [".*"]
}, {
domain: "home2.example.com",
policy: "deny",
resources: [".*"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home1.example.com", "/", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("home2.example.com", "/", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("home3.example.com", "/", "user1", ["group1"]));
});
it("should always apply latest rule", function () {
configuration.users["user1"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/my/.*"]
}, {
domain: "home.example.com",
policy: "deny",
resources: ["^/my/private/.*"]
}, {
domain: "home.example.com",
policy: "allow",
resources: ["/my/private/resource"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/my/poney", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/my/private/duck", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/my/private/resource", "user1", ["group1"]));
});
});
describe("check group rules", function () {
it("should allow access when user is in group having a matching allowing rule", function () {
configuration.groups["group1"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/$"]
}];
configuration.groups["group2"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/test$"]
}, {
domain: "home.example.com",
policy: "deny",
resources: ["^/private$"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/", "user1",
["group1", "group2", "group3"]));
Assert(accessController.isAccessAllowed("home.example.com", "/test", "user1",
["group1", "group2", "group3"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/private", "user1",
["group1", "group2", "group3"]));
Assert(!accessController.isAccessAllowed("another.home.example.com", "/", "user1",
["group1", "group2", "group3"]));
});
});
});
describe("check all rules", function () {
it("should control access when all rules are defined", function () {
configuration.any = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/public$"]
}, {
domain: "home.example.com",
policy: "deny",
resources: ["^/private$"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/public", "user1",
["group1", "group2", "group3"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/private", "user1",
["group1", "group2", "group3"]));
Assert(accessController.isAccessAllowed("home.example.com", "/public", "user4",
["group5"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/private", "user4",
["group5"]));
});
});
describe("check access control with default policy to allow", function () {
beforeEach(function () {
configuration.default_policy = "allow";
});
it("should allow access to anything when no rule is provided", function () {
Assert(accessController.isAccessAllowed("home.example.com", "/", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/test", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/dev", "user1", ["group1"]));
});
it("should deny access to one resource when defined", function () {
configuration.users["user1"] = [{
domain: "home.example.com",
policy: "deny",
resources: ["/test"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/", "user1", ["group1"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/test", "user1", ["group1"]));
Assert(accessController.isAccessAllowed("home.example.com", "/dev", "user1", ["group1"]));
});
});
describe("check access control with complete use case", function () {
beforeEach(function () {
configuration.default_policy = "deny";
});
it("should control access of multiple user (real use case)", function () {
// Let say we have three users: admin, john, harry.
// admin is in groups ["admins"]
// john is in groups ["dev", "admin-private"]
// harry is in groups ["dev"]
configuration.any = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/public$", "^/$"]
}];
configuration.groups["dev"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/dev/?.*$"]
}];
configuration.groups["admins"] = [{
domain: "home.example.com",
policy: "allow",
resources: [".*"]
}];
configuration.groups["admin-private"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/private/?.*"]
}];
configuration.users["john"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/private/john$"]
}];
configuration.users["harry"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/private/harry"]
}, {
domain: "home.example.com",
policy: "deny",
resources: ["^/dev/b.*$"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/", "admin", ["admins"]));
Assert(accessController.isAccessAllowed("home.example.com", "/public", "admin", ["admins"]));
Assert(accessController.isAccessAllowed("home.example.com", "/dev", "admin", ["admins"]));
Assert(accessController.isAccessAllowed("home.example.com", "/dev/bob", "admin", ["admins"]));
Assert(accessController.isAccessAllowed("home.example.com", "/admin", "admin", ["admins"]));
Assert(accessController.isAccessAllowed("home.example.com", "/private/josh", "admin", ["admins"]));
Assert(accessController.isAccessAllowed("home.example.com", "/private/john", "admin", ["admins"]));
Assert(accessController.isAccessAllowed("home.example.com", "/private/harry", "admin", ["admins"]));
Assert(accessController.isAccessAllowed("home.example.com", "/", "john", ["dev", "admin-private"]));
Assert(accessController.isAccessAllowed("home.example.com", "/public", "john", ["dev", "admin-private"]));
Assert(accessController.isAccessAllowed("home.example.com", "/dev", "john", ["dev", "admin-private"]));
Assert(accessController.isAccessAllowed("home.example.com", "/dev/bob", "john", ["dev", "admin-private"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/admin", "john", ["dev", "admin-private"]));
Assert(accessController.isAccessAllowed("home.example.com", "/private/josh", "john", ["dev", "admin-private"]));
Assert(accessController.isAccessAllowed("home.example.com", "/private/john", "john", ["dev", "admin-private"]));
Assert(accessController.isAccessAllowed("home.example.com", "/private/harry", "john", ["dev", "admin-private"]));
Assert(accessController.isAccessAllowed("home.example.com", "/", "harry", ["dev"]));
Assert(accessController.isAccessAllowed("home.example.com", "/public", "harry", ["dev"]));
Assert(accessController.isAccessAllowed("home.example.com", "/dev", "harry", ["dev"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/dev/bob", "harry", ["dev"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/admin", "harry", ["dev"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/private/josh", "harry", ["dev"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/private/john", "harry", ["dev"]));
Assert(accessController.isAccessAllowed("home.example.com", "/private/harry", "harry", ["dev"]));
});
it("should control access when allowed at group level and denied at user level", function () {
configuration.groups["dev"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/dev/?.*$"]
}];
configuration.users["john"] = [{
domain: "home.example.com",
policy: "deny",
resources: ["^/dev/bob$"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/dev/john", "john", ["dev"]));
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 () {
configuration.any = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/dev/?.*$"]
}];
configuration.users["john"] = [{
domain: "home.example.com",
policy: "deny",
resources: ["^/dev/bob$"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/dev/john", "john", ["dev"]));
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 () {
configuration.any = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/dev/?.*$"]
}];
configuration.groups["dev"] = [{
domain: "home.example.com",
policy: "deny",
resources: ["^/dev/bob$"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/dev/john", "john", ["dev"]));
Assert(!accessController.isAccessAllowed("home.example.com", "/dev/bob", "john", ["dev"]));
});
it("should respect rules precedence", function () {
// the priority from least to most is 'default_policy', 'all', 'group', 'user'
// and the first rules in each category as a lower priority than the latest.
// You can think of it that way: they override themselves inside each category.
configuration.any = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/dev/?.*$"]
}];
configuration.groups["dev"] = [{
domain: "home.example.com",
policy: "deny",
resources: ["^/dev/bob$"]
}];
configuration.users["john"] = [{
domain: "home.example.com",
policy: "allow",
resources: ["^/dev/?.*$"]
}];
Assert(accessController.isAccessAllowed("home.example.com", "/dev/john", "john", ["dev"]));
Assert(accessController.isAccessAllowed("home.example.com", "/dev/bob", "john", ["dev"]));
});
});
});
});