rbac-engine
Version:
Role-based access control engine with policy-based permissions
145 lines • 7.27 kB
JavaScript
;
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