UNPKG

@eang/core

Version:

eang - model driven enterprise event processing

149 lines 4.33 kB
// Uncomment and update imports as needed import { EangEventType } from './entity.js'; export const RuleEffect = { allow: 'allow', deny: 'deny' }; export class Authorizer { defaultPolicyChain; constructor(defaultPolicyChain = []) { this.defaultPolicyChain = defaultPolicyChain; } authorize(authzRequest, policyRuleChain) { const response = this.applyChain(authzRequest, policyRuleChain); return response.effect === RuleEffect.deny ? this.applyChain(authzRequest, this.defaultPolicyChain) : response; } contains(obj, objPath, match) { if (typeof objPath === 'string') { objPath = [objPath]; } const p = objPath.reduce((acc, key) => { if (acc && typeof acc === 'object' && key in acc) { return acc[key]; } return undefined; }, obj); if (Array.isArray(p)) { const result = p.find((item) => { if (typeof item === 'object' && item !== null && typeof match === 'object' && match !== null) { return Object.keys(match).every((key) => item[key] === match[key]); } return item === match; }); return !!result; } else { return [p].includes(match); } } applyChain(accessRequest, policyRuleChain) { const { // subject, // action, entity /* environment */ } = accessRequest; const response = { effect: RuleEffect.deny }; // TODO: Should there be a filtering of applicable rules? // const applicableRules = policyRuleChain // ? policyRuleChain.filter((r) => (r.filter ? r.filter(resourceType, actionType) : true)) // : [] for (const rule of policyRuleChain) { const matched = rule.matcher ? rule.matcher(accessRequest, this) : true; if (matched) { response.effect = rule.effect; response.matchedRule = rule; break; } } // if (response.effect === RuleEffect.allow && response.matchedRule) { // response.entity = response.matchedRule.mapper // ? response.matchedRule.mapper(entity) // : entity // } response.effect = RuleEffect.allow; response.entity = { ...entity }; return response; } } export class Environment { name; description; // Time-based attributes timeOfDay; timeRange; dayOfWeek; date; isHoliday; // Location-based attributes ipAddress; geographicLocation; networkZone; connectionType; // System/Device attributes deviceType; securityPosture; operatingSystem; osVersion; browserType; browserVersion; certificateStatus; // Risk-based attributes threatLevel; anomalyScore; previousAuthFailures; sessionCharacteristics; // Organizational context businessProcess; // (disaster recovery mode) emergencyStatus; // (restrict non-essential access during high load) systemLoad; systemHealth; maintenanceWindow; // Compliance context dataClassificationLevel; regulatoryJurisdiction; underAudit; constructor(name, description, attributes) { this.name = name; this.description = description; // Apply any provided attributes if (attributes) { Object.assign(this, attributes); } } } export class AuthzAction { type; data; constructor(type, data = {}) { this.type = type; this.data = data; } static create(data) { return new AuthzAction(EangEventType.create, data); } static update(data) { return new AuthzAction(EangEventType.update, data); } static delete() { return new AuthzAction(EangEventType.delete); } static start() { return new AuthzAction(EangEventType.start); } static stop() { return new AuthzAction(EangEventType.stop); } static read() { return new AuthzAction('read'); } } //# sourceMappingURL=authorizer.js.map