GeezerVison is showing github.com — src,permission: make ERR_ACCESS_DENIED more descriptive · nodejs/node@a154352
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: src/permission/permission.cc +23-8Lines changed: 23 additions & 8 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -59,15 +59,15 @@ static void Has(const FunctionCallbackInfo<Value>& args) { | 59 | 59 |
| 60 | 60 | } // namespace | 61 | 61 |
| 62 | | -#define V(Name, label, _) \ | | 62 | +#define V(Name, label, _, __) \ | 63 | 63 | if (perm == PermissionScope::k##Name) return #Name; | 64 | 64 | const char* Permission::PermissionToString(const PermissionScope perm) { | 65 | 65 | PERMISSIONS(V) | 66 | 66 | return nullptr; | 67 | 67 | } | 68 | 68 | #undef V | 69 | 69 |
| 70 | | -#define V(Name, label, _) \ | | 70 | +#define V(Name, label, _, __) \ | 71 | 71 | if (perm == label) return PermissionScope::k##Name; | 72 | 72 | PermissionScope Permission::StringToPermission(const std::string& perm) { | 73 | 73 | PERMISSIONS(V) | @@ -84,32 +84,47 @@ Permission::Permission() : enabled_(false) { | 84 | 84 | std::shared_ptr<PermissionBase> inspector = | 85 | 85 | std::make_shared<InspectorPermission>(); | 86 | 86 | std::shared_ptr<PermissionBase> wasi = std::make_shared<WASIPermission>(); | 87 | | -#define V(Name, _, __) \ | | 87 | +#define V(Name, _, __, ___) \ | 88 | 88 | nodes_.insert(std::make_pair(PermissionScope::k##Name, fs)); | 89 | 89 | FILESYSTEM_PERMISSIONS(V) | 90 | 90 | #undef V | 91 | | -#define V(Name, _, __) \ | | 91 | +#define V(Name, _, __, ___) \ | 92 | 92 | nodes_.insert(std::make_pair(PermissionScope::k##Name, child_p)); | 93 | 93 | CHILD_PROCESS_PERMISSIONS(V) | 94 | 94 | #undef V | 95 | | -#define V(Name, _, __) \ | | 95 | +#define V(Name, _, __, ___) \ | 96 | 96 | nodes_.insert(std::make_pair(PermissionScope::k##Name, worker_t)); | 97 | 97 | WORKER_THREADS_PERMISSIONS(V) | 98 | 98 | #undef V | 99 | | -#define V(Name, _, __) \ | | 99 | +#define V(Name, _, __, ___) \ | 100 | 100 | nodes_.insert(std::make_pair(PermissionScope::k##Name, inspector)); | 101 | 101 | INSPECTOR_PERMISSIONS(V) | 102 | 102 | #undef V | 103 | | -#define V(Name, _, __) \ | | 103 | +#define V(Name, _, __, ___) \ | 104 | 104 | nodes_.insert(std::make_pair(PermissionScope::k##Name, wasi)); | 105 | 105 | WASI_PERMISSIONS(V) | 106 | 106 | #undef V | 107 | 107 | } | 108 | 108 |
| | 109 | +const char* GetErrorFlagSuggestion(node::permission::PermissionScope perm) { | | 110 | + switch (perm) { | | 111 | +#define V(Name, _, __, Flag) \ | | 112 | + case node::permission::PermissionScope::k##Name: \ | | 113 | + return Flag[0] != '\0' ? "Use " Flag " to manage permissions." : ""; | | 114 | + PERMISSIONS(V) | | 115 | +#undef V | | 116 | + default: | | 117 | + return ""; | | 118 | + } | | 119 | +} | | 120 | + | 109 | 121 | MaybeLocal<Value> CreateAccessDeniedError(Environment* env, | 110 | 122 | PermissionScope perm, | 111 | 123 | const std::string_view& res) { | 112 | | - Local<Object> err = ERR_ACCESS_DENIED(env->isolate()); | | 124 | + const char* suggestion = GetErrorFlagSuggestion(perm); | | 125 | + Local<Object> err = ERR_ACCESS_DENIED( | | 126 | + env->isolate(), "Access to this API has been restricted. %s", suggestion); | | 127 | + | 113 | 128 | Local<Value> perm_string; | 114 | 129 | Local<Value> resource_string; | 115 | 130 | std::string_view perm_str = Permission::PermissionToString(perm); | |
Collapse file Copy file name to clipboardExpand all lines: src/permission/permission_base.h +9-8Lines changed: 9 additions & 8 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -15,18 +15,19 @@ class Environment; | 15 | 15 | namespace permission { | 16 | 16 |
| 17 | 17 | #define FILESYSTEM_PERMISSIONS(V) \ | 18 | | - V(FileSystem, "fs", PermissionsRoot) \ | 19 | | - V(FileSystemRead, "fs.read", FileSystem) \ | 20 | | - V(FileSystemWrite, "fs.write", FileSystem) | | 18 | + V(FileSystem, "fs", PermissionsRoot, "") \ | | 19 | + V(FileSystemRead, "fs.read", FileSystem, "--allow-fs-read") \ | | 20 | + V(FileSystemWrite, "fs.write", FileSystem, "--allow-fs-write") | 21 | 21 |
| 22 | | -#define CHILD_PROCESS_PERMISSIONS(V) V(ChildProcess, "child", PermissionsRoot) | | 22 | +#define CHILD_PROCESS_PERMISSIONS(V) \ | | 23 | + V(ChildProcess, "child", PermissionsRoot, "--allow-child-process") | 23 | 24 |
| 24 | | -#define WASI_PERMISSIONS(V) V(WASI, "wasi", PermissionsRoot) | | 25 | +#define WASI_PERMISSIONS(V) V(WASI, "wasi", PermissionsRoot, "--allow-wasi") | 25 | 26 |
| 26 | 27 | #define WORKER_THREADS_PERMISSIONS(V) \ | 27 | | - V(WorkerThreads, "worker", PermissionsRoot) | | 28 | + V(WorkerThreads, "worker", PermissionsRoot, "--allow-worker") | 28 | 29 |
| 29 | | -#define INSPECTOR_PERMISSIONS(V) V(Inspector, "inspector", PermissionsRoot) | | 30 | +#define INSPECTOR_PERMISSIONS(V) V(Inspector, "inspector", PermissionsRoot, "") | 30 | 31 |
| 31 | 32 | #define PERMISSIONS(V) \ | 32 | 33 | FILESYSTEM_PERMISSIONS(V) \ | @@ -35,7 +36,7 @@ namespace permission { | 35 | 36 | WORKER_THREADS_PERMISSIONS(V) \ | 36 | 37 | INSPECTOR_PERMISSIONS(V) | 37 | 38 |
| 38 | | -#define V(name, _, __) k##name, | | 39 | +#define V(name, _, __, ___) k##name, | 39 | 40 | enum class PermissionScope { | 40 | 41 | kPermissionsRoot = -1, | 41 | 42 | PERMISSIONS(V) kPermissionsCount | |
Collapse file Copy file name to clipboardExpand all lines: test/fixtures/permission/fs-read.js +10Lines changed: 10 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -14,6 +14,16 @@ const blockedFolder = process.env.BLOCKEDFOLDER; | 14 | 14 | const allowedFolder = process.env.ALLOWEDFOLDER; | 15 | 15 | const regularFile = __filename; | 16 | 16 |
| | 17 | +// Guarantee the error message suggest the --allow-fs-read | | 18 | +{ | | 19 | + fs.readFile(blockedFile, common.expectsError({ | | 20 | + message: 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', | | 21 | + code: 'ERR_ACCESS_DENIED', | | 22 | + permission: 'FileSystemRead', | | 23 | + resource: path.toNamespacedPath(blockedFile), | | 24 | + })); | | 25 | +} | | 26 | + | 17 | 27 | // fs.readFile | 18 | 28 | { | 19 | 29 | fs.readFile(blockedFile, common.expectsError({ | |
Collapse file Copy file name to clipboardExpand all lines: test/fixtures/permission/fs-write.js +9Lines changed: 9 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -25,6 +25,15 @@ const relativeProtectedFolder = process.env.RELATIVEBLOCKEDFOLDER; | 25 | 25 | assert.ok(!process.permission.has('fs.write', blockedFile)); | 26 | 26 | } | 27 | 27 |
| | 28 | +// Guarantee the error message suggest the --allow-fs-write | | 29 | +{ | | 30 | + fs.writeFile(blockedFile, 'example', common.expectsError({ | | 31 | + message: 'Access to this API has been restricted. Use --allow-fs-write to manage permissions.', | | 32 | + code: 'ERR_ACCESS_DENIED', | | 33 | + permission: 'FileSystemWrite', | | 34 | + })); | | 35 | +} | | 36 | + | 28 | 37 | // fs.writeFile | 29 | 38 | { | 30 | 39 | assert.throws(() => { | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-permission-child-process-cli.js +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -26,6 +26,7 @@ if (process.argv[2] === 'child') { | 26 | 26 | assert.throws(() => { | 27 | 27 | childProcess.spawn(process.execPath, ['--version']); | 28 | 28 | }, common.expectsError({ | | 29 | + message: 'Access to this API has been restricted. Use --allow-child-process to manage permissions.', | 29 | 30 | code: 'ERR_ACCESS_DENIED', | 30 | 31 | permission: 'ChildProcess', | 31 | 32 | })); | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-permission-inspector.js +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -22,6 +22,7 @@ if (!common.hasCrypto) | 22 | 22 | const session = new Session(); | 23 | 23 | session.connect(); | 24 | 24 | }, common.expectsError({ | | 25 | + message: 'Access to this API has been restricted. ', | 25 | 26 | code: 'ERR_ACCESS_DENIED', | 26 | 27 | permission: 'Inspector', | 27 | 28 | })); | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-permission-wasi.js +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -13,6 +13,7 @@ const { WASI } = require('wasi'); | 13 | 13 | preopens: { '/': '/' }, | 14 | 14 | }); | 15 | 15 | }, common.expectsError({ | | 16 | + message: 'Access to this API has been restricted. Use --allow-wasi to manage permissions.', | 16 | 17 | code: 'ERR_ACCESS_DENIED', | 17 | 18 | permission: 'WASI', | 18 | 19 | })); | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-permission-worker-threads-cli.js +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -22,6 +22,7 @@ if (isMainThread) { | 22 | 22 | assert.throws(() => { | 23 | 23 | new Worker(__filename); | 24 | 24 | }, common.expectsError({ | | 25 | + message: 'Access to this API has been restricted. Use --allow-worker to manage permissions.', | 25 | 26 | code: 'ERR_ACCESS_DENIED', | 26 | 27 | permission: 'WorkerThreads', | 27 | 28 | })); | |
|