1
0
mirror of https://github.com/0rangebananaspy/authelia.git synced 2024-09-14 22:47:21 +07:00
authelia/server/src/lib/authorization/Authorizer.ts
Clement Michaud 9fc55543fd Integrate more policy options in ACL rules.
The possible values for ACL policies are now: bypass, one_factor, two_factor,
deny.

This change also deprecate auth_methods because the method is now associated
directly to a resource in the ACLs instead of a domain.
2018-11-17 18:08:29 +01:00

78 lines
2.9 KiB
TypeScript

import { ACLConfiguration, ACLPolicy, ACLRule } from "../configuration/schema/AclConfiguration";
import { IAuthorizer } from "./IAuthorizer";
import { Winston } from "../../../types/Dependencies";
import { MultipleDomainMatcher } from "./MultipleDomainMatcher";
import { Level } from "./Level";
function MatchDomain(actualDomain: string) {
return function (rule: ACLRule): boolean {
return MultipleDomainMatcher.match(actualDomain, rule.domain);
};
}
function MatchResource(actualResource: string) {
return function (rule: ACLRule): boolean {
// If resources key is not provided, the rule applies to all resources.
if (!rule.resources) return true;
for (let i = 0; i < rule.resources.length; ++i) {
const regexp = new RegExp(rule.resources[i]);
if (regexp.test(actualResource)) return true;
}
return false;
};
}
export class Authorizer implements IAuthorizer {
private logger: Winston;
private readonly configuration: ACLConfiguration;
constructor(configuration: ACLConfiguration, logger_: Winston) {
this.logger = logger_;
this.configuration = configuration;
}
private getMatchingUserRules(user: string, domain: string, resource: string): ACLRule[] {
const userRules = this.configuration.users[user];
if (!userRules) return [];
return userRules.filter(MatchDomain(domain)).filter(MatchResource(resource));
}
private getMatchingGroupRules(groups: string[], domain: string, resource: string): ACLRule[] {
const that = this;
// There is no ordering between group rules. That is, when a user belongs to 2 groups, there is no
// guarantee one set of rules has precedence on the other one.
const groupRules = groups.reduce(function (rules: ACLRule[], group: string) {
const groupRules = that.configuration.groups[group];
if (groupRules) rules = rules.concat(groupRules);
return rules;
}, []);
return groupRules.filter(MatchDomain(domain)).filter(MatchResource(resource));
}
private getMatchingAllRules(domain: string, resource: string): ACLRule[] {
const rules = this.configuration.any;
if (!rules) return [];
return rules.filter(MatchDomain(domain)).filter(MatchResource(resource));
}
authorization(domain: string, resource: string, user: string, groups: string[]): Level {
if (!this.configuration) return Level.BYPASS;
const allRules = this.getMatchingAllRules(domain, resource);
const groupRules = this.getMatchingGroupRules(groups, domain, resource);
const userRules = this.getMatchingUserRules(user, domain, resource);
const rules = allRules.concat(groupRules).concat(userRules).reverse();
const policy = rules.map(r => r.policy).concat([this.configuration.default_policy])[0];
if (policy == "bypass") {
return Level.BYPASS;
} else if (policy == "one_factor") {
return Level.ONE_FACTOR;
} else if (policy == "two_factor") {
return Level.TWO_FACTOR;
}
return Level.DENY;
}
}