UNPKG

rbac-engine

Version:

Role-based access control engine with policy-based permissions

351 lines 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DynamoDBRepository = void 0; const client_dynamodb_1 = require("@aws-sdk/client-dynamodb"); const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb"); class DynamoDBRepository { constructor(client) { this.client = client; this.docClient = lib_dynamodb_1.DynamoDBDocumentClient.from(client); this.tableName = process.env.TABLE_NAME || 'Access-Control'; } async setupTables() { try { await this.client.send(new client_dynamodb_1.DescribeTableCommand({ TableName: this.tableName })); console.log("Table already exists"); } catch (err) { if (err.name === "ResourceNotFoundException") { const params = { TableName: this.tableName, KeySchema: [ { AttributeName: "PK", KeyType: "HASH" }, { AttributeName: "SK", KeyType: "RANGE" } ], AttributeDefinitions: [ { AttributeName: "PK", AttributeType: "S" }, { AttributeName: "SK", AttributeType: "S" } ], BillingMode: "PAY_PER_REQUEST" }; await this.client.send(new client_dynamodb_1.CreateTableCommand(params)); console.log("Table created"); } else { throw new Error(`Something went wrong: ${err}`); } } } async createUser(user) { const item = { PK: `USER#${user.id}`, SK: `USER#${user.id}`, type: "USER", name: user.name, roles: user.roles || [], policies: user.policies || [] }; await this.docClient.send(new lib_dynamodb_1.PutCommand({ TableName: this.tableName, Item: item })); return user; } async getUser(userId) { try { const result = await this.docClient.send(new lib_dynamodb_1.GetCommand({ TableName: this.tableName, Key: { PK: `USER#${userId}`, SK: `USER#${userId}` }, })); if (!result.Item) { throw new Error(`User not found: ${userId}`); } return { id: userId, name: result.Item.name, roles: result.Item.roles, policies: result.Item.policies }; } catch (err) { throw new Error(`Something went wrong: ${err}`); } } async createRole(role) { const item = { PK: `ROLE#${role.id}`, SK: `ROLE#${role.id}`, type: "ROLE", name: role.name, policies: role.policies || [] }; await this.docClient.send(new lib_dynamodb_1.PutCommand({ TableName: this.tableName, Item: item })); return role; } async getRole(roleId) { try { const result = await this.docClient.send(new lib_dynamodb_1.GetCommand({ TableName: this.tableName, Key: { PK: `ROLE#${roleId}`, SK: `ROLE#${roleId}` }, })); if (!result.Item) { throw new Error(`Role not found: ${roleId}`); } return { id: roleId, name: result.Item.name, policies: result.Item.policies }; } catch (err) { throw new Error(`Something went wrong: ${err}`); } } async assignRoleToUser(userId, roleId) { const user = await this.getUser(userId); if (!user.roles) { user.roles = []; } const roles = new Set(user.roles); roles.add(roleId); const updatedRoles = Array.from(roles); await this.docClient.send(new lib_dynamodb_1.UpdateCommand({ TableName: this.tableName, Key: { PK: `USER#${userId}`, SK: `USER#${userId}` }, UpdateExpression: "SET #rolesAttr = :roles", ExpressionAttributeNames: { "#rolesAttr": "roles" }, ExpressionAttributeValues: { ":roles": updatedRoles } })); return user; } async createPolicy(policy) { const item = { PK: `POLICY#${policy.id}`, SK: `POLICY#${policy.id}`, type: "POLICY", document: policy.document }; await this.docClient.send(new lib_dynamodb_1.PutCommand({ TableName: this.tableName, Item: item })); return policy; } async attachPolicyToRole(policyId, roleId) { const role = await this.getRole(roleId); if (!role.policies) { role.policies = []; } const policies = new Set(role.policies); policies.add(policyId); const updatedPolicies = Array.from(policies); await this.docClient.send(new lib_dynamodb_1.UpdateCommand({ TableName: this.tableName, Key: { PK: `ROLE#${roleId}`, SK: `ROLE#${roleId}` }, UpdateExpression: "SET #policiesAttr = :policies", ExpressionAttributeNames: { "#policiesAttr": "policies" }, ExpressionAttributeValues: { ":policies": updatedPolicies } })); } async getUserPolicies(userId) { const user = await this.getUser(userId); const policies = []; if (user.policies) { for (const policyId of user.policies) { const policy = await this.getPolicy(policyId); policies.push(policy); } } return policies; } async getRolePolicies(roleId) { const role = await this.getRole(roleId); const policies = []; if (role.policies) { for (const policyId of role.policies) { const policy = await this.getPolicy(policyId); policies.push(policy); } } return policies; } async updateRole(role) { const item = { PK: `ROLE#${role.id}`, SK: `ROLE#${role.id}`, type: "ROLE", name: role.name, policies: role.policies || [] }; await this.docClient.send(new lib_dynamodb_1.PutCommand({ TableName: this.tableName, Item: item })); return role; } async updatePolicy(policy) { const item = { PK: `POLICY#${policy.id}`, SK: `POLICY#${policy.id}`, type: "POLICY", document: policy.document }; await this.docClient.send(new lib_dynamodb_1.PutCommand({ TableName: this.tableName, Item: item })); return policy; } async deletePolicy(policyId) { await this.docClient.send(new lib_dynamodb_1.DeleteCommand({ TableName: this.tableName, Key: { PK: `POLICY#${policyId}`, SK: `POLICY#${policyId}` } })); } async deleteRole(roleId) { await this.docClient.send(new lib_dynamodb_1.DeleteCommand({ TableName: this.tableName, Key: { PK: `ROLE#${roleId}`, SK: `ROLE#${roleId}` } })); } async detachPolicyFromUser(policyId, userId) { const user = await this.getUser(userId); if (!user.policies) { return; } const policies = user.policies.filter(p => p !== policyId); await this.docClient.send(new lib_dynamodb_1.UpdateCommand({ TableName: this.tableName, Key: { PK: `USER#${userId}`, SK: `USER#${userId}` }, UpdateExpression: "SET #policiesAttr = :policies", ExpressionAttributeNames: { "#policiesAttr": "policies" }, ExpressionAttributeValues: { ":policies": policies }, })); } async detachPolicyFromRole(policyId, roleId) { const role = await this.getRole(roleId); if (!role.policies) { return; } const policies = role.policies.filter(p => p !== policyId); await this.docClient.send(new lib_dynamodb_1.UpdateCommand({ TableName: this.tableName, Key: { PK: `ROLE#${roleId}`, SK: `ROLE#${roleId}` }, UpdateExpression: "SET #policiesAttr = :policies", ExpressionAttributeNames: { "#policiesAttr": "policies" }, ExpressionAttributeValues: { ":policies": policies }, })); } async removeRoleFromUser(userId, roleId) { const user = await this.getUser(userId); if (!user.roles) { return; } const roles = user.roles.filter(r => r !== roleId); await this.docClient.send(new lib_dynamodb_1.UpdateCommand({ TableName: this.tableName, Key: { PK: `USER#${userId}`, SK: `USER#${userId}` }, UpdateExpression: "SET #rolesAttr = :roles", ExpressionAttributeNames: { "#rolesAttr": "roles" }, ExpressionAttributeValues: { ":roles": roles }, })); } async attachPolicyToUser(policyId, userId) { const user = await this.getUser(userId); if (!user.policies) { user.policies = []; } const policies = new Set(user.policies); policies.add(policyId); const updatedPolicies = Array.from(policies); await this.docClient.send(new lib_dynamodb_1.UpdateCommand({ TableName: this.tableName, Key: { PK: `USER#${userId}`, SK: `USER#${userId}` }, UpdateExpression: "SET #policiesAttr = :policies", ExpressionAttributeNames: { "#policiesAttr": "policies" }, ExpressionAttributeValues: { ":policies": updatedPolicies } })); } async getPolicy(policyId) { try { const result = await this.docClient.send(new lib_dynamodb_1.GetCommand({ TableName: this.tableName, Key: { PK: `POLICY#${policyId}`, SK: `POLICY#${policyId}` }, })); if (!result.Item) { throw new Error(`Policy not found: ${policyId}`); } return { id: policyId, document: result.Item.document }; } catch (err) { throw new Error(`Something went wrong: ${err}`); } } } exports.DynamoDBRepository = DynamoDBRepository; //# sourceMappingURL=dynamodb-repo.js.map