avp-cli
Version:
Small CLI to help interacts with the Amazon Verified Permissions (AVP) service.
1,301 lines (1,189 loc) • 34.6 kB
JavaScript
import {
BatchIsAuthorizedCommand,
BatchIsAuthorizedWithTokenCommand,
CreateIdentitySourceCommand,
DeleteIdentitySourceCommand,
CreatePolicyCommand,
CreatePolicyStoreCommand,
CreatePolicyTemplateCommand,
DeletePolicyCommand,
DeletePolicyStoreCommand,
DeletePolicyTemplateCommand,
GetPolicyCommand,
GetPolicyStoreCommand,
GetPolicyTemplateCommand,
GetIdentitySourceCommand,
GetSchemaCommand,
IsAuthorizedCommand,
IsAuthorizedWithTokenCommand,
ListPoliciesCommand,
ListPolicyStoresCommand,
ListIdentitySourcesCommand,
ListPolicyTemplatesCommand,
PutSchemaCommand,
UpdatePolicyCommand,
UpdatePolicyStoreCommand,
UpdateIdentitySourceCommand,
UpdatePolicyTemplateCommand,
VerifiedPermissionsClient,
} from "@aws-sdk/client-verifiedpermissions";
import fs from "fs";
import path from "path";
import Table from "cli-table3";
import os from "os";
const client = new VerifiedPermissionsClient();
export const listPolicyStores = async (logOutput = true) => {
const command = new ListPolicyStoresCommand({});
try {
const response = await client.send(command);
const table = new Table({
head: ["ID", "ARN", "Description", "Created Date"],
colWidths: [24, 80, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
response.policyStores.forEach((store) => {
table.push([
store.policyStoreId,
store.arn,
store.description,
formatDate(store.createdDate),
]);
});
if (logOutput) {
console.log(table.toString());
}
return response.policyStores;
} catch (error) {
console.error(`Failed to list policy stores: ${error.message}`);
}
};
export const listIdentitySources = async (policyStoreId, logOutput = true) => {
const command = new ListIdentitySourcesCommand({ policyStoreId });
try {
const response = await client.send(command);
const table = new Table({
head: ["ID", "principalEntityType", "details", "Created Date"],
colWidths: [24, 80, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
response.identitySources.forEach((source) => {
table.push([
source.identitySourceId,
source.principalEntityType,
source.details,
source.createdDate,
]);
});
if (logOutput) {
console.log(table.toString());
}
return response.identitySources;
} catch (error) {
console.error(`Failed to list identity sources: ${error.message}`);
}
};
export const getSchema = async (policyStoreId, logOutput = true) => {
const input = { policyStoreId };
const command = new GetSchemaCommand(input);
try {
const response = await client.send(command);
if (logOutput) {
console.log(`Schema for policy store ID ${policyStoreId}:`);
console.log(response.schema);
}
return response.schema;
} catch (error) {
console.error(`Failed to get schema: ${error.message}`);
}
};
export const getPolicy = async (policyStoreId, policyId, logOutput = true) => {
const input = { policyStoreId, policyId };
const command = new GetPolicyCommand(input);
try {
const response = await client.send(command);
const table = new Table({
head: ["Policy ID", "Policy Type", "Created Date", "Last Updated Date"],
colWidths: [24, 20, 40, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
table.push([
response.policyId,
response.policyType,
formatDate(response.createdDate),
response.lastUpdatedDate,
]);
if (logOutput) {
console.log(table.toString());
}
return response;
} catch (error) {
console.error(`Failed to get policy: ${error.message}`);
}
};
export const getPolicyTemplate = async (
policyStoreId,
policyTemplateId,
logOutput = true
) => {
const input = { policyStoreId, policyTemplateId };
const command = new GetPolicyTemplateCommand(input);
try {
const response = await client.send(command);
const table = new Table({
head: ["Policy ID", "statement", "Created Date", "Last Updated Date"],
colWidths: [24, 20, 40, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
table.push([
response.policyTemplateId,
response.statement,
formatDate(response.createdDate),
response.lastUpdatedDate,
]);
if (logOutput) {
console.log(table.toString());
}
return response;
} catch (error) {
console.error(`Failed to get policy template: ${error.message}`);
}
};
export const updateStaticPolicy = async (
policyStoreId,
policyId,
policyPath,
policyDescription,
logOutput = true
) => {
const policy = fs.readFileSync(policyPath, "utf8");
const input = {
policyStoreId,
policyId,
definition: {
static: {
description: policyDescription,
statement: policy,
},
},
};
const command = new UpdatePolicyCommand(input);
try {
if (logOutput) {
console.log("Updating a policy...");
}
const response = await client.send(command);
if (logOutput) {
console.log(`Policy updated with ID: ${response.policyId}`);
}
return response.policyId;
} catch (error) {
console.error(`Failed to update policy: ${error.message}`);
}
};
export const createPolicyStore = async (
validationMode,
policyStoreDescription,
logOutput = true
) => {
const input = {
validationSettings: {
mode: validationMode,
},
description: policyStoreDescription,
};
const createCommand = new CreatePolicyStoreCommand(input);
try {
const response = await client.send(createCommand);
if (logOutput) {
console.log(`Policy store created with ID: ${response.policyStoreId}`);
}
return response.policyStoreId;
} catch (error) {
console.error(`Failed to create policy store: ${error.message}`);
}
};
export const updatePolicyStore = async (
policyStoreId,
validationMode,
policyStoreDescription,
logOutput = true
) => {
const input = {
policyStoreId,
validationSettings: {
mode: validationMode,
},
description: policyStoreDescription,
};
const createCommand = new UpdatePolicyStoreCommand(input);
try {
const response = await client.send(createCommand);
if (logOutput) {
console.log(`Policy store updated with ID: ${response.policyStoreId}`);
}
return response.policyStoreId;
} catch (error) {
console.error(`Failed to update policy store: ${error.message}`);
}
};
export const updatePolicyTemplate = async (
policyStoreId,
policyTemplateId,
statement,
description,
logOutput = true
) => {
const input = {
policyStoreId,
policyTemplateId,
statement,
description,
};
const updateCommand = new UpdatePolicyTemplateCommand(input);
try {
const response = await client.send(updateCommand);
if (logOutput) {
console.log(
`Policy template updated with ID: ${response.policyTemplateId}`
);
}
return response.policyTemplateId;
} catch (error) {
console.error(`Failed to update policy template: ${error.message}`);
}
};
export const getPolicyStore = async (policyStoreId, logOutput = true) => {
const input = { policyStoreId };
const command = new GetPolicyStoreCommand(input);
try {
const response = await client.send(command);
const table = new Table({
head: ["ID", "ARN", "Description", "Created Date"],
colWidths: [24, 80, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
table.push([
response.policyStoreId,
response.arn,
response.description,
formatDate(response.createdDate),
]);
if (logOutput) {
console.log(table.toString());
}
return response;
} catch (error) {
console.error(`Failed to get policy store: ${error.message}`);
}
};
export const getIdentitySource = async (
policyStoreId,
identitySourceId,
logOutput = true
) => {
const input = { policyStoreId, identitySourceId };
const command = new GetIdentitySourceCommand(input);
try {
const response = await client.send(command);
const table = new Table({
head: ["Policy Store", "identitySourceId", "Created Date"],
colWidths: [24, 80, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
table.push([
response.policyStoreId,
response.identitySourceId,
formatDate(response.createdDate),
]);
if (logOutput) {
console.log(table.toString());
}
return response;
} catch (error) {
console.error(`Failed to get identity source: ${error.message}`);
}
};
export const deletePolicyStore = async (policyStoreId, logOutput = true) => {
const input = { policyStoreId };
const command = new DeletePolicyStoreCommand(input);
try {
if (logOutput) {
console.log("Deleting a policy store...");
}
await client.send(command);
if (logOutput) {
console.log(`Policy store deleted with ID: ${policyStoreId}`);
}
} catch (error) {
console.error(`Failed to delete policy store: ${error.message}`);
}
};
export const putSchema = async (
policyStoreId,
pathToSchema,
logOutput = true
) => {
const schemaJson = JSON.parse(
fs.readFileSync(path.resolve(pathToSchema), "utf-8")
);
const schema = JSON.stringify(schemaJson);
const input = {
policyStoreId,
definition: {
cedarJson: schema,
},
};
const command = new PutSchemaCommand(input);
try {
if (logOutput) {
console.log("Adding schema to a policy store...");
}
const response = await client.send(command);
if (logOutput) {
console.log(
`Schema put successfully for policy store ID: ${response.policyStoreId}`
);
}
return response.policyStoreId;
} catch (error) {
console.error(`Failed to put schema: ${error.message}`);
}
};
export const createStaticPolicy = async (
policyStoreId,
policyPath,
description,
logOutput = true
) => {
const policy = fs.readFileSync(policyPath, "utf8");
const input = {
policyStoreId,
definition: {
static: {
description: description,
statement: policy,
},
},
};
const command = new CreatePolicyCommand(input);
try {
if (logOutput) {
console.log("Creating a static policy...");
}
const response = await client.send(command);
if (logOutput) {
console.log(`Static policy created with ID: ${response.policyId}`);
}
return response;
} catch (error) {
console.error(`Failed to create static policy: ${error.message}`);
}
};
export const createPolicyTemplate = async (
policyStoreId,
policyPath,
description,
logOutput = true
) => {
const policy = fs.readFileSync(policyPath, "utf8");
const params = {
policyStoreId: policyStoreId,
statement: policy,
description: description,
};
try {
const response = await client.send(new CreatePolicyTemplateCommand(params));
if (logOutput) {
console.log(`Policy template created successfully.`);
}
return response;
} catch (error) {
if (logOutput) {
console.error(
`An error occurred while creating the policy template: ${error}`
);
}
}
};
export const deletePolicy = async (
policyStoreId,
policyId,
logOutput = true
) => {
const input = { policyStoreId, policyId };
const command = new DeletePolicyCommand(input);
try {
if (logOutput) {
console.log("Deleting a policy...");
}
await client.send(command);
if (logOutput) {
console.log(`Policy deleted with ID: ${policyId}`);
}
} catch (error) {
console.error(`Failed to delete policy: ${error.message}`);
}
};
export const deletePolicyTemplate = async (
policyStoreId,
policyTemplateId,
logOutput = true
) => {
const input = { policyStoreId, policyTemplateId };
const command = new DeletePolicyTemplateCommand(input);
try {
if (logOutput) {
console.log("Deleting a policy template...");
}
await client.send(command);
if (logOutput) {
console.log(
`Policy template deleted with ID: ${policyTemplateId} from policy store id ${policyStoreId}`
);
}
} catch (error) {
console.error(`Failed to delete policy template: ${error.message}`);
}
};
export const listPolicies = async (policyStoreId, logOutput = true) => {
const input = { policyStoreId };
const command = new ListPoliciesCommand(input);
try {
const response = await client.send(command);
if (logOutput) {
const table = new Table({
head: ["Policy ID", "Policy Type", "Created Date", "Last Updated Date"],
colWidths: [24, 20, 40, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
response.policies.forEach((policy) => {
table.push([
policy.policyId,
policy.policyType,
formatDate(policy.createdDate),
policy.lastUpdatedDate,
]);
});
console.log(table.toString());
}
return response.policies;
} catch (error) {
console.error(`Failed to list policies: ${error.message}`);
}
};
export const listPolicyTemplates = async (policyStoreId, logOutput = true) => {
const input = { policyStoreId };
const command = new ListPolicyTemplatesCommand(input);
try {
const response = await client.send(command);
if (logOutput) {
const table = new Table({
head: [
"Policy Template ID",
"Description",
"Created Date",
"Last Updated Date",
],
colWidths: [24, 20, 40, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
response.policyTemplates.forEach((policyTemplate) => {
table.push([
policyTemplate.policyTemplateId,
policyTemplate.description,
formatDate(policyTemplate.createdDate),
policyTemplate.lastUpdatedDate,
]);
});
console.log(table.toString());
}
return response.policyTemplates;
} catch (error) {
console.error(`Failed to list policy templates: ${error.message}`);
}
};
const handleTemplateLinkedPoliciesScenario = async (
policyStoreId,
scenario
) => {
const policyTemplate = scenario.policyTemplate;
const createdPolicyTemplate = await createPolicyTemplate(
policyStoreId,
policyTemplate.path,
policyTemplate.description,
false
);
console.log(
`Policy template created with ID: ${createdPolicyTemplate.policyTemplateId}`
);
const policyTemplateId = createdPolicyTemplate.policyTemplateId;
const templateLinkedPolicies = [];
for (const templateLinkedPolicy of scenario.templateLinkedPolicies) {
const principal = {
entityType: templateLinkedPolicy.principal.entityType,
entityId: templateLinkedPolicy.principal.entityId,
};
const resource = {
entityType: templateLinkedPolicy.resource.entityType,
entityId: templateLinkedPolicy.resource.entityId,
};
const createdTemplateLinkedPolicy = await createTemplatePolicy(
policyStoreId,
policyTemplateId,
principal,
resource,
false
);
console.log(
`Template-linked policy created with ID: ${createdTemplateLinkedPolicy.policyId}`
);
templateLinkedPolicies.push({
...createdTemplateLinkedPolicy,
principal,
resource,
policyTemplate: policyTemplate.description,
});
}
const table = new Table({
head: [
"Template-Linked Policy ID",
"Policy Store ID",
"Created Date",
"Principal",
"Resource",
"Policy Template",
],
colWidths: [40, 40, 40, 40, 40, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
for (const policy of templateLinkedPolicies) {
table.push([
policy.policyId,
policyStoreId,
formatDate(policy.createdDate),
`${policy.principal.entityType}::${policy.principal.entityId}`,
`${policy.resource.entityType}::${policy.resource.entityId}`,
policy.policyTemplate,
]);
}
console.log(table.toString());
};
export const useScenario = async (
scenarioName,
userPoolArn = null,
appClientId = null
) => {
const scenarioPath = `./scenarios/${scenarioName}/${scenarioName}.json`;
console.log(scenarioPath);
const scenarioData = fs.readFileSync(scenarioPath, "utf-8");
const scenario = JSON.parse(scenarioData);
if (scenario) {
console.log(`Starting creating scenario: ${scenario.name}`);
console.log(`description: ${scenario.description}`);
const policyStoreId = await createPolicyStore(
scenario.validationMode,
scenario.policyStoreDescription,
false
);
console.log(`Policy store created with ID: ${policyStoreId}`);
if (policyStoreId) {
await putSchema(policyStoreId, scenario.schemaPath, false);
console.log(
`Schema put successfully for policy store ID: ${policyStoreId}`
);
if (scenarioName === "ecommercePolicyTemplateScenario") {
await handleTemplateLinkedPoliciesScenario(policyStoreId, scenario);
} else if (scenarioName === "ecommerceCognitoIntegrationScenario") {
await handleCognitoIntegrationScenario(
policyStoreId,
scenario,
userPoolArn,
appClientId
);
} else if (scenarioName === "ecommerceCognitoGroupsScenario") {
await handleCognitoGroupsScenario(
policyStoreId,
scenario,
userPoolArn,
appClientId
);
} else {
const policies = [];
for (const policy of scenario.policies) {
const createdPolicy = await createStaticPolicy(
policyStoreId,
policy.path,
policy.description,
false
);
console.log(
`Static policy created with ID: ${createdPolicy.policyId}`
);
policies.push(createdPolicy);
}
const table = new Table({
head: ["Policy ID", "Policy Store ID", "Created Date"],
colWidths: [40, 40, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
for (const policy of policies) {
table.push([
policy.policyId,
policyStoreId,
formatDate(policy.createdDate),
]);
}
console.log(table.toString());
}
console.log(
`Generating of the ${scenarioName} is finished. Open the AWS console to play around with that.`
);
console.log(generateTestMessage(scenario));
}
} else {
console.error(`Scenario ${scenarioName} not found`);
}
};
export const createTemplatePolicy = async (
policyStoreId,
policyTemplateId,
principal,
resource,
logOutput = true
) => {
const input = {
policyStoreId,
definition: {
templateLinked: {
policyTemplateId,
principal,
resource,
},
},
};
const command = new CreatePolicyCommand(input);
try {
if (logOutput) {
console.log("Creating a template-linked policy...");
}
const response = await client.send(command);
if (logOutput) {
console.log(
`Template-linked policy created with ID: ${response.policyId}`
);
}
return response;
} catch (error) {
console.error(`Failed to create template-linked policy: ${error.message}`);
}
};
export const createIdentitySource = async (
policyStoreId,
principalEntityType,
userPoolArn,
appClientId,
groupEntityType = null
) => {
const configuration = {
cognitoUserPoolConfiguration: {
userPoolArn: userPoolArn,
clientIds: [appClientId],
},
};
if (groupEntityType) {
configuration.cognitoUserPoolConfiguration["groupConfiguration"] = {
groupEntityType: groupEntityType,
};
}
const input = {
policyStoreId,
principalEntityType,
configuration: configuration,
};
const command = new CreateIdentitySourceCommand(input);
try {
console.log("Creating an identity source...");
const response = await client.send(command);
console.log(
`Identity source created with ID: ${response.identitySourceId}`
);
return response;
} catch (error) {
console.error(`Failed to create identity source: ${error.message}`);
throw error;
}
};
export const updateIdentitySource = async (
policyStoreId,
identitySourceId,
userPoolArn,
principalEntityType,
appClientId
) => {
const input = {
policyStoreId,
identitySourceId,
principalEntityType,
updateConfiguration: {
cognitoUserPoolConfiguration: {
userPoolArn: userPoolArn,
clientIds: [appClientId],
},
},
};
const command = new UpdateIdentitySourceCommand(input);
try {
console.log("Updating an identity source...");
const response = await client.send(command);
console.log(
`Identity source updated with ID: ${response.identitySourceId}`
);
return response;
} catch (error) {
console.error(`Failed to update identity source: ${error.message}`);
}
};
export const deleteIdentitySource = async (
policyStoreId,
identitySourceId,
logOutput = true
) => {
const input = { policyStoreId, identitySourceId };
const command = new DeleteIdentitySourceCommand(input);
try {
if (logOutput) {
console.log("Deleting a identity source...");
}
await client.send(command);
if (logOutput) {
console.log(
`Identity source deleted with ID: ${identitySourceId} from policy store id ${policyStoreId}`
);
}
} catch (error) {
console.error(`Failed to delete identity source: ${error.message}`);
}
};
export const IsAuthorized = async (testFilePath) => {
const fileContent = fs.readFileSync(testFilePath, "utf8");
const input = JSON.parse(fileContent);
if (input.policyStoreId === "your-policy-store-id") {
console.error(
"Please set the 'policyStoreId' in your JSON file before proceeding."
);
return;
}
const command = new IsAuthorizedCommand(input);
try {
console.log("Making authorization decision...");
const response = await client.send(command);
handleAuthorizationResponse(
response,
input.policyStoreId,
input.principal,
input.action,
input.resource,
input.context
);
return response;
} catch (error) {
console.error(`Failed to make authorization decision: ${error.message}`);
}
};
export const batchIsAuthorized = async (batchTestFilePath) => {
const fileContent = fs.readFileSync(batchTestFilePath, "utf8");
const input = JSON.parse(fileContent);
if (input.policyStoreId === "your-policy-store-id") {
console.error(
"Please set the 'policyStoreId' in your JSON file before proceeding."
);
return;
}
// batch authorization allows to process up to 30 authorization decisions for a single principal or resource in a single API call.
if (input.requests && input.requests.length > 30) {
console.error(
"Batch request limit exceeded. Only up to 30 requests are allowed."
);
return;
}
const command = new BatchIsAuthorizedCommand(input);
try {
console.log("Making batch authorization decision...");
const response = await client.send(command);
handleBatchAuthorizationResponse(response, input.policyStoreId);
} catch (error) {
console.error(`Failed to make authorization decision: ${error.message}`);
}
};
export const batchIsAuthorizedWithToken = async (
batchWithTokenTestFilePath
) => {
const fileContent = fs.readFileSync(batchWithTokenTestFilePath, "utf8");
const input = JSON.parse(fileContent);
if (input.policyStoreId === "your-policy-store-id") {
console.error(
"Please set the 'policyStoreId' in your JSON file before proceeding."
);
return;
}
if (input.accessToken === "ACCESS_TOKEN_HERE") {
console.error("Add access token in your JSON file before proceeding.");
return;
}
// batch authorization with token allows to process up to 30 authorization decisions for a single principal or resource in a single API call.
if (input.requests && input.requests.length > 30) {
console.error(
"Batch request limit exceeded. Only up to 30 requests are allowed."
);
return;
}
const command = new BatchIsAuthorizedWithTokenCommand(input);
try {
console.log("Making batch with token authorization decision...");
const response = await client.send(command);
handleBatchAuthorizationWithTokenResponse(response, input);
} catch (error) {
console.error(`Failed to make authorization decision: ${error.message}`);
}
};
export const isAuthorizedWithToken = async (testFilePath) => {
const fileContent = fs.readFileSync(testFilePath, "utf8");
const input = JSON.parse(fileContent);
if (input.policyStoreId === "your-policy-store-id") {
console.error(
"Please set the 'policyStoreId' in your JSON file before proceeding."
);
return;
}
if (input.accessToken === "ACCESS_TOKEN_HERE") {
console.error("Add access token in your JSON file before proceeding.");
return;
}
const command = new IsAuthorizedWithTokenCommand(input);
try {
const response = await client.send(command);
handleAuthorizationWithTokenResponse(
response,
input.policyStoreId,
input.action,
input.resource,
input.context
);
return response;
} catch (error) {
console.error(`Failed to make authorization decision: ${error.message}`);
}
};
export const handleCognitoIntegrationScenario = async (
policyStoreId,
scenario,
userPoolArn,
appClientId
) => {
try {
await createIdentitySource(
policyStoreId,
scenario.principalEntityType,
userPoolArn,
appClientId
);
const policies = [];
for (const policy of scenario.policies) {
const createdPolicy = await createStaticPolicy(
policyStoreId,
policy.path,
policy.description,
false
);
console.log(`Static policy created with ID: ${createdPolicy.policyId}`);
policies.push(createdPolicy);
}
const table = new Table({
head: ["Policy ID", "Policy Store ID", "Created Date"],
colWidths: [40, 40, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
for (const policy of policies) {
table.push([
policy.policyId,
policyStoreId,
formatDate(policy.createdDate),
]);
}
console.log(table.toString());
console.log(
`Generating of the ${scenario.scenarioName} is finished. Open the AWS console to play around with that.`
);
console.log(generateTestMessage(scenario));
} catch (error) {
console.error(`Scenario execution failed: ${error.message}`);
}
};
export const handleCognitoGroupsScenario = async (
policyStoreId,
scenario,
userPoolArn,
appClientId
) => {
try {
await createIdentitySource(
policyStoreId,
scenario.principalEntityType,
userPoolArn,
appClientId,
scenario.groupEntityType
);
const policies = [];
for (const policy of scenario.policies) {
try {
const userPoolId = extractUserPoolIdFromArn(userPoolArn);
const policyTemplateContent = fs.readFileSync(policy.path, "utf8");
const policyContent = policyTemplateContent.replace(
"<user-pool-goes-here>",
userPoolId
);
// Write the interpolated policy content to a temporary file
const policyFilePath = await writePolicyToFile(policyContent);
const createdPolicy = await createStaticPolicy(
policyStoreId,
policyFilePath,
policy.description,
true
);
// Policy has been created; we can now clean up the temporary file
await fs.promises.unlink(policyFilePath);
if (createdPolicy.policyId) {
policies.push(createdPolicy);
}
} catch (error) {
console.error("An error occurred:", error);
}
}
const table = new Table({
head: ["Policy ID", "Policy Store ID", "Created Date"],
colWidths: [40, 40, 40],
wordWrap: true,
wrapOnWordBoundary: false,
});
for (const policy of policies) {
table.push([
policy.policyId,
policyStoreId,
formatDate(policy.createdDate),
]);
}
console.log(table.toString());
console.log(
`Generating of the ${scenario.scenarioName} is finished. Open the AWS console to play around with that.`
);
console.log(generateTestMessage(scenario));
} catch (error) {
console.error(`Scenario execution failed: ${error.message}`);
}
};
const handleAuthorizationResponse = (
response,
policyStoreId,
principal,
action,
resource,
context
) => {
const table = new Table({
head: [
"Decision",
"Determining Policies",
"Errors",
"Policy Store ID",
"Principal",
"Action",
"Resource",
"Context",
],
colWidths: [10, 30, 20, 30, 30, 30, 30, 30],
wordWrap: true,
wrapOnWordBoundary: false,
});
const determiningPolicies = response.determiningPolicies
.map((policy) => policy.policyId)
.join(", ");
const errors = response.errors
.map((error) => error.errorDescription)
.join(", ");
table.push([
response.decision,
determiningPolicies,
errors,
policyStoreId,
`${principal.entityType}::${principal.entityId}`,
`${action.actionType}::${action.actionId}`,
`${resource.entityType}::${resource.entityId}`,
JSON.stringify(context.contextMap),
]);
console.log(table.toString());
};
const handleAuthorizationWithTokenResponse = (
response,
policyStoreId,
action,
resource,
context
) => {
const table = new Table({
head: [
"Decision",
"Determining Policies",
"Errors",
"Policy Store ID",
"Principal",
"Action",
"Resource",
"Context",
],
colWidths: [10, 30, 20, 30, 30, 30, 30, 30],
wordWrap: true,
wrapOnWordBoundary: false,
});
const determiningPolicies = response.determiningPolicies
.map((policy) => policy.policyId)
.join(", ");
const errors = response.errors
.map((error) => error.errorDescription)
.join(", ");
table.push([
response.decision,
determiningPolicies,
errors,
policyStoreId,
`${response.principal.entityType}::${response.principal.entityId}`,
`${action.actionType}::${action.actionId}`,
`${resource.entityType}::${resource.entityId}`,
JSON.stringify(context.contextMap),
]);
console.log(table.toString());
};
const handleBatchAuthorizationResponse = (response, policyStoreId) => {
const table = new Table({
head: [
"Decision",
"Determining Policies",
"Errors",
"Policy Store ID",
"Principal",
"Action",
"Resource",
],
colWidths: [10, 30, 20, 30, 30, 30, 30, 30],
wordWrap: true,
wrapOnWordBoundary: false,
});
response.results.forEach((result) => {
const determiningPolicies = result.determiningPolicies
.map((policy) => policy.policyId)
.join(", ");
const errors = result.errors
.map((error) => error.errorDescription)
.join(", ");
const request = result.request;
const principal = `${request.principal.entityType}::${request.principal.entityId}`;
const action = `${request.action.actionType}::${request.action.actionId}`;
const resource = `${request.resource.entityType}::${request.resource.entityId}`;
table.push([
result.decision,
determiningPolicies,
errors,
policyStoreId,
principal,
action,
resource,
]);
});
console.log(table.toString());
};
const handleBatchAuthorizationWithTokenResponse = (response, input) => {
const table = new Table({
head: [
"Decision",
"Determining Policies",
"Errors",
"Policy Store ID",
"Principal",
"Action",
"Resource",
"Context",
],
colWidths: [10, 30, 20, 30, 30, 30, 30, 30],
wordWrap: true,
wrapOnWordBoundary: false,
});
response.results.forEach((singleResult) => {
const determiningPolicies = singleResult.determiningPolicies
? singleResult.determiningPolicies
.map((policy) => policy.policyId)
.join(", ")
: "";
const errors = singleResult.errors
? singleResult.errors.map((error) => error.errorDescription).join(", ")
: "";
console.log("SingleResult: ", singleResult);
table.push([
singleResult.decision,
determiningPolicies,
errors,
input.policyStoreId,
`${response.principal.entityType}::${response.principal.entityId}`,
`${singleResult.request.action.actionType}::${singleResult.request.action.actionId}`,
`${singleResult.request.resource.entityType}::${singleResult.request.resource.entityId}`,
JSON.stringify(
singleResult.request.context
? singleResult.request.context.contextMap
: {}
),
]);
});
console.log(table.toString());
};
const generateTestMessage = (scenario) => {
let message = "\nConsider testing it with our prepared test scenarios:\n";
message +=
"Either use `Test Scenario` in main CLI to select the specific test scenario, or use below path as argument to `IsAuthorized` from the manual approach option of the CLI:\n Remember to update the policy-store-id within files.\n";
for (const test of scenario.tests) {
message += `- ${test.path} (${test.description}) ${test.type}\n`;
}
return message;
};
const formatDate = (dateString) => {
const date = new Date(dateString);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(
2,
"0"
)}-${String(date.getDate()).padStart(2, "0")} ${String(
date.getHours()
).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
};
function extractUserPoolIdFromArn(userPoolArn) {
const arnParts = userPoolArn.split(":");
const userPoolId =
arnParts.length > 1 ? arnParts[arnParts.length - 1].split("/")[1] : null;
if (!userPoolId) {
throw new Error("Invalid ARN format. Unable to extract User Pool ID.");
}
return userPoolId;
}
async function writePolicyToFile(policyContent) {
const tempDir = os.tmpdir();
const tempFilePath = path.join(tempDir, `policy-${Date.now()}.cedar`);
await fs.promises.writeFile(tempFilePath, policyContent);
return tempFilePath;
}