UNPKG

3.72 kBJavaScriptView Raw
1'use strict';
2
3const {
4 getProfile
5} = require('./profile');
6const { red } = require('colors');
7
8function throwProcessedException(ex, policyName) {
9
10 if (ex.code === 'Forbidden.RAM') {
11 console.error(`\n${ex.message}`);
12 throw new Error(`\nMaybe you need grant ${policyName} policy to the sub-account or use the primary account.\nIf you don’t want use the ${policyName} policy or primary account, you can also specify the Role property for Service.`);
13 }
14 throw ex;
15}
16
17async function throwProcessedPopPermissionError(ex, action) {
18 if (!ex.code || !ex.url || (ex.code !== 'NoPermission' && ex.code !== 'Forbidden.RAM' && !ex.code.includes('Forbbiden'))) { // NAS 返回的权限错误码是 Forbbiden.ram
19 throw ex;
20 }
21 const productRegex = new RegExp(/https?:\/\/([a-zA-Z]*).(.*)aliyuncs.com/);
22 const productRegexRes = productRegex.exec(ex.url);
23 if (!productRegexRes) {
24 throw ex;
25 }
26 const product = productRegexRes[1];
27 action = `${product}:${action}`;
28 let resource = '*';
29 if (ex.data && ex.data.Message) {
30 const regex = new RegExp(/Resource: (.*) Action: (.*)/);
31 const res = regex.exec(ex.data.Message);
32 if (res) {
33 resource = res[1];
34 action = res[2];
35 }
36 }
37 const policyName = generatePolicyName(action);
38 printPermissionTip(policyName, action, resource);
39 throw ex;
40}
41
42async function throwProcessedFCPermissionError(ex, ...resourceArr) {
43 if (!ex.code || ex.code !== 'AccessDenied' || !ex.message) {
44 throw ex;
45 }
46 const regex = new RegExp(/the caller is not authorized to perform '(.*)' on resource '(.*)'/);
47 const res = regex.exec(ex.message);
48 if (!res) {
49 throw ex;
50 }
51 const profile = await getProfile();
52 const action = res[1];
53 const resource = res[2];
54 const policyName = generatePolicyName(action, profile.defaultRegion, ...resourceArr);
55 printPermissionTip(policyName, action, resource);
56 throw ex;
57}
58
59async function throwProcessedSLSPermissionError(ex) {
60 if (!ex.code || ex.code !== 'Unauthorized' || !ex.message) {
61 throw ex;
62 }
63 const regex = new RegExp(/action: (.*), resource: (.*)/);
64 const res = regex.exec(ex.message);
65 if (!res) {
66 throw ex;
67 }
68 const action = res[1];
69 const resource = res[2];
70 const policyName = generatePolicyName(action);
71 printPermissionTip(policyName, action, resource);
72 throw ex;
73}
74
75function printPermissionTip(policyName, action, resource) {
76 const policy = {
77 'Version': '1',
78 'Statement': [
79 {
80 'Effect': 'Allow',
81 'Action': [
82 action
83 ],
84 'Resource': [
85 resource
86 ]
87 }
88 ]
89 };
90 console.error(red(`\nYou can run the following commands to grant permission '${action}' on '${resource}' `));
91 console.error(red('Via the link: https://shell.aliyun.com/ or aliyun cli'));
92 console.error(red('(Note: aliyun cli tool needs to be configured with credentials that have related RAM permissions, such as primary account\'s AK)'));
93 console.error(red('\n1. Create Policy'));
94 console.error(red(`aliyun ram CreatePolicy --PolicyName ${policyName} --PolicyDocument "${JSON.stringify(policy).replace(/"/g, '\\"')}"`));
95 console.error(red('\n2. Attach Policy To User'));
96 console.error(red(`aliyun ram AttachPolicyToUser --PolicyName ${policyName} --PolicyType "Custom" --UserName "YOUR_USER_NAME"\n`));
97}
98
99function generatePolicyName(action, ...resourceArr) {
100 const resource = resourceArr && resourceArr.length ? resourceArr.join('-') : Math.random().toString(36).slice(-8);
101 return `fun-generated-${action.replace(/:/g, '-')}-${resource}`;
102}
103
104module.exports = {
105 throwProcessedException,
106 throwProcessedPopPermissionError,
107 throwProcessedFCPermissionError,
108 throwProcessedSLSPermissionError
109};
\No newline at end of file