UNPKG

rbac-engine

Version:

Role-based access control engine with policy-based permissions

145 lines 7.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const client_dynamodb_1 = require("@aws-sdk/client-dynamodb"); const index_1 = require("../index"); const dynamodb_repo_1 = require("../db/dynamodb-repo"); const uuid_1 = require("uuid"); const dynamoClient = new client_dynamodb_1.DynamoDBClient({ region: "us-east-1", }); const accessControl = new index_1.AccessControl(dynamoClient, dynamodb_repo_1.DynamoDBRepository); async function run() { var _a; try { console.log("Setting up tables..."); await accessControl.init(); console.log("=".repeat(60)); console.log("RBAC Engine - Builder Pattern vs Traditional Approach"); console.log("=".repeat(60)); console.log("\n1. TRADITIONAL APPROACH (Object-based)"); console.log("-".repeat(40)); const traditionalPolicyDocument = { Version: "2023-11-15", Statement: [ { Effect: index_1.Effect.Allow, Action: ["read", "write", "update"], Resource: ["document/*"], Condition: { department: "engineering" } }, { Effect: index_1.Effect.Deny, Action: ["delete"], Resource: ["document/confidential/*"] } ] }; const traditionalPolicy = await accessControl.createPolicy({ id: `traditional-policy-${(0, uuid_1.v4)()}`, document: traditionalPolicyDocument }); console.log("✓ Created policy using traditional approach:"); console.log(` Policy ID: ${traditionalPolicy.id}`); console.log(` Statements: ${traditionalPolicy.document.Statement.length}`); console.log(` Actions in first statement: ${traditionalPolicy.document.Statement[0].Action.join(', ')}`); console.log("\n2. BUILDER PATTERN APPROACH (New & Fluent)"); console.log("-".repeat(40)); console.log("\nA) Simple Builder (Single Statement):"); const simpleBuilderPolicy = await accessControl.createPolicy(new index_1.PolicyBuilder(`simple-builder-${(0, uuid_1.v4)()}`) .version("2023-11-15") .allow(["read", "list"]) .on(["document/*", "folder/*"]) .when({ role: "viewer" })); console.log("✓ Created policy using simple builder:"); console.log(` Policy ID: ${simpleBuilderPolicy.id}`); console.log(` Effect: ${simpleBuilderPolicy.document.Statement[0].Effect}`); console.log(` Actions: ${simpleBuilderPolicy.document.Statement[0].Action.join(', ')}`); console.log("\nB) Complex Builder (Multiple Statements):"); const complexBuilderPolicy = await accessControl.createPolicy(new index_1.PolicyBuilder(`complex-builder-${(0, uuid_1.v4)()}`) .version("2023-11-15") .statement(new index_1.StatementBuilder() .allow(["read", "write"]) .on(["project/*"]) .when({ department: "engineering", clearance: "standard" })) .statement(new index_1.StatementBuilder() .allow(["admin"]) .on(["project/*"]) .when({ role: "project-manager" }) .activeFrom("2025-01-01T00:00:00Z") .activeUntil("2025-12-31T23:59:59Z")) .statement(new index_1.StatementBuilder() .deny(["delete"]) .on(["project/production/*"]))); console.log("✓ Created policy using complex builder:"); console.log(` Policy ID: ${complexBuilderPolicy.id}`); console.log(` Statements: ${complexBuilderPolicy.document.Statement.length}`); console.log(` Time-based statement: ${complexBuilderPolicy.document.Statement[1].StartDate ? 'Yes' : 'No'}`); console.log("\nC) Time-Based Builder Policy:"); const timeBasedPolicy = await accessControl.createPolicy(new index_1.PolicyBuilder(`time-based-${(0, uuid_1.v4)()}`) .allow(["read", "update"]) .on(["contractor-project/*"]) .when({ contractorId: "C12345" }) .activeFrom("2025-06-01T00:00:00Z") .activeUntil("2025-11-30T23:59:59Z")); console.log("✓ Created time-based policy:"); console.log(` Policy ID: ${timeBasedPolicy.id}`); console.log(` Active from: ${timeBasedPolicy.document.Statement[0].StartDate}`); console.log(` Active until: ${timeBasedPolicy.document.Statement[0].EndDate}`); console.log("\n3. COMPARISON & BENEFITS"); console.log("-".repeat(40)); console.log("\nTraditional Approach:"); console.log("✓ Familiar object-based syntax"); console.log("✓ Direct control over policy structure"); console.log("✓ Fully backward compatible"); console.log("✗ More verbose for complex policies"); console.log("✗ Less IDE support/auto-completion"); console.log("\nBuilder Pattern Approach:"); console.log("✓ Fluent, readable API"); console.log("✓ Better IDE support and auto-completion"); console.log("✓ Built-in validation"); console.log("✓ Type safety"); console.log("✓ Method chaining"); console.log("✗ New API to learn"); console.log("\n4. MIXED USAGE IN SAME APPLICATION"); console.log("-".repeat(40)); const role = await accessControl.createRole({ id: (0, uuid_1.v4)(), name: "Mixed-Usage-Role" }); const user = await accessControl.createUser({ id: (0, uuid_1.v4)(), name: "Mixed-Usage-User" }); await accessControl.assignRoleToUser(user.id, role.id); await accessControl.attachPolicyToRole(traditionalPolicy.id, role.id); await accessControl.attachPolicyToRole(simpleBuilderPolicy.id, role.id); await accessControl.attachPolicyToRole(complexBuilderPolicy.id, role.id); console.log("✓ Successfully attached policies from both approaches to the same role:"); console.log(` Role ID: ${role.id}`); console.log(" Attached policies:"); console.log(` - Traditional: ${traditionalPolicy.id}`); console.log(` - Simple Builder: ${simpleBuilderPolicy.id}`); console.log(` - Complex Builder: ${complexBuilderPolicy.id}`); console.log("\n5. VALIDATION EXAMPLE"); console.log("-".repeat(40)); try { new index_1.PolicyBuilder(`invalid-${(0, uuid_1.v4)()}`) .allow(["read", "write"]) .build(); } catch (error) { console.log("✓ Builder validation caught invalid policy:"); console.log(` Error: ${error.message}`); console.log(` Details: ${(_a = error.details) === null || _a === void 0 ? void 0 : _a.join(', ')}`); } console.log("\n=".repeat(60)); console.log("Example completed successfully!"); console.log("Both approaches work seamlessly together! 🎉"); console.log("=".repeat(60)); } catch (error) { console.error("Error in example:", error); } } run(); //# sourceMappingURL=builder-pattern.js.map