diff --git a/content b/content index 44f1bc7..5d5a17a 160000 --- a/content +++ b/content @@ -1 +1 @@ -Subproject commit 44f1bc75bb646bf15914671c300b704790a4e27a +Subproject commit 5d5a17a613c27f0043ef0ef18148f2a2ed47e246 diff --git a/src/controllers/accessController.js b/src/controllers/accessController.js index d16833f..318f8f7 100644 --- a/src/controllers/accessController.js +++ b/src/controllers/accessController.js @@ -9,7 +9,7 @@ try { res.renderWithBaseContext("pages/credentials.handlebars", { - title: "Portfolio Access", + title: "Guest Access", token: token ?? "", }); } catch (err) { diff --git a/src/utils/evaluateRules.js b/src/utils/evaluateRules.js index 5dd8068..b2539ff 100644 --- a/src/utils/evaluateRules.js +++ b/src/utils/evaluateRules.js @@ -1,29 +1,59 @@ -// src/utils/evaluateRules.js /** - * Evaluates access rules against the current identity context. - * * Rules: - * - Outer array: Logical OR (Success if any requirement block passes) - * - Inner array: Logical AND (Success if all rules in the block pass) - * * @param {Array>} rules - Nested rule set - * @param {Object} auth - { isAuthenticated, user, groups } + * src/utils/evaluateRules.js + */ + +function checkRequirement(rule, identity, groups) { + const [type, value] = rule.split(":"); + if (type === "group") return groups.includes(value); + if (type === "user") return identity === value; + return false; +} + +/** + * Validates a single requirement block (Inner Array - Logical AND). + */ +function validateBlock(block, identity, groups) { + const requirements = Array.isArray(block) ? block : [block]; + return requirements.every((rule) => checkRequirement(rule, identity, groups)); +} + +/** + * Evaluates the full rule set (Outer Array - Logical OR). */ function evaluateRules(rules, session) { if (!rules || !rules.length) return true; - const { user, groups = [] } = session; + const identity = session.user || session.preferred_username || session.name; + const groups = session.groups || []; - return rules.some((requirement) => - requirement.every((rule) => { - const [type, value] = rule.split(":"); - switch (type) { - case "group": - return groups.includes(value); - case "user": - return user === value; - default: - return false; - } - }), - ); + return rules.some((block) => validateBlock(block, identity, groups)); } + module.exports = { evaluateRules }; + +/** + * Default policy is allow + * + * Policy types: + * Allow: The item and its public children are visible + * deny: Item only visible if the user and/or group rules match + * deny-children: Item is visible, but children are not visible unless user and/or group match + * + * Rules Examples: + * + * rules: [] // -- No rules + * rules: [ "user:username" ] // -- Allow user + * rules: [ "group:groupname" ] // -- Allow group + * rules: [ + * "user:username", // Can match user + * "group:groupname", // Can match group + * ] + * rules: [ // Multiple rules + * ["group:group_a", "group:group_b"] // -- Must be in both groups + * ["user:username"] // -- Or can be user + * "user:username" // -- This means the same as the line above + * ["group:groupname"] // -- Or can be group + * "group:groupname" // -- This means the same as the line above + * ] // -- Allow group + * + */ diff --git a/src/utils/processMenuLinks.js b/src/utils/processMenuLinks.js index 63482b3..20ac820 100644 --- a/src/utils/processMenuLinks.js +++ b/src/utils/processMenuLinks.js @@ -7,6 +7,8 @@ */ function promoteAttributes(parent, child) { const promote = child.promote; + if (!promote) return; + let keys = []; if (promote === "true" || promote === true) {