33#include " env-inl.h"
44#include " memory_tracker-inl.h"
55#include " node.h"
6+ #include " node_diagnostics_channel.h"
67#include " node_errors.h"
78#include " node_external_reference.h"
89#include " node_file.h"
@@ -27,6 +28,27 @@ namespace permission {
2728
2829namespace {
2930
31+ constexpr std::string_view GetDiagnosticsChannelName (PermissionScope scope) {
32+ switch (scope) {
33+ case PermissionScope::kFileSystem :
34+ case PermissionScope::kFileSystemRead :
35+ case PermissionScope::kFileSystemWrite :
36+ return " node:permission-model:fs" ;
37+ case PermissionScope::kChildProcess :
38+ return " node:permission-model:child" ;
39+ case PermissionScope::kWorkerThreads :
40+ return " node:permission-model:worker" ;
41+ case PermissionScope::kInspector :
42+ return " node:permission-model:inspector" ;
43+ case PermissionScope::kWASI :
44+ return " node:permission-model:wasi" ;
45+ case PermissionScope::kAddon :
46+ return " node:permission-model:addon" ;
47+ default :
48+ return {};
49+ }
50+ }
51+
3052// permission.has('fs.in', '/tmp/')
3153// permission.has('fs.in')
3254static void Has (const FunctionCallbackInfo<Value>& args) {
@@ -70,7 +92,7 @@ PermissionScope Permission::StringToPermission(const std::string& perm) {
7092}
7193#undef V
7294
73- Permission::Permission () : enabled_(false ) {
95+ Permission::Permission () : enabled_(false ), warning_only_( false ) {
7496 std::shared_ptr<PermissionBase> fs = std::make_shared<FSPermission>();
7597 std::shared_ptr<PermissionBase> child_p =
7698 std::make_shared<ChildProcessPermission>();
@@ -170,6 +192,74 @@ void Permission::EnablePermissions() {
170192 }
171193}
172194
195+ void Permission::EnableWarningOnly () {
196+ if (!warning_only_) {
197+ warning_only_ = true ;
198+ }
199+ }
200+
201+ bool Permission::is_scope_granted (Environment* env,
202+ const PermissionScope permission,
203+ const std::string_view& res) const {
204+ auto perm_node = nodes_.find (permission);
205+ bool result = false ;
206+ if (perm_node != nodes_.end ()) {
207+ result = perm_node->second ->is_granted (env, permission, res);
208+ }
209+
210+ if (!result && !publishing_) {
211+ auto channel_name = GetDiagnosticsChannelName (permission);
212+ if (!channel_name.empty ()) {
213+ auto ch = GetOrCreateChannel (env, permission);
214+ if (ch && ch->HasSubscribers ()) {
215+ publishing_ = true ;
216+ v8::Isolate* isolate = env->isolate ();
217+ v8::HandleScope handle_scope (isolate);
218+ v8::Local<v8::Context> context = env->context ();
219+ v8::Local<v8::Object> msg =
220+ v8::Object::New (isolate, v8::Null (isolate), nullptr , nullptr , 0 );
221+ const char * perm_str = PermissionToString (permission);
222+ msg->Set (context,
223+ FIXED_ONE_BYTE_STRING (isolate, " permission" ),
224+ v8::String::NewFromUtf8 (isolate, perm_str).ToLocalChecked ())
225+ .Check ();
226+ msg->Set (context,
227+ FIXED_ONE_BYTE_STRING (isolate, " resource" ),
228+ v8::String::NewFromUtf8 (isolate,
229+ res.data (),
230+ v8::NewStringType::kNormal ,
231+ static_cast <int >(res.size ()))
232+ .ToLocalChecked ())
233+ .Check ();
234+ ch->Publish (env, msg);
235+ publishing_ = false ;
236+ }
237+ }
238+ }
239+
240+ return result;
241+ }
242+
243+ BaseObjectPtr<diagnostics_channel::Channel> Permission::GetOrCreateChannel (
244+ Environment* env, PermissionScope scope) const {
245+ auto it = channels_.find (scope);
246+ if (it != channels_.end ()) {
247+ // Promote weak ref to strong for the duration of this call.
248+ BaseObjectPtr<diagnostics_channel::Channel> ptr (it->second .get ());
249+ if (ptr) return ptr;
250+ channels_.erase (it);
251+ }
252+ auto channel_name = GetDiagnosticsChannelName (scope);
253+ diagnostics_channel::Channel* ch =
254+ diagnostics_channel::Channel::Get (env, channel_name.data ());
255+ if (ch != nullptr ) {
256+ channels_.emplace (scope,
257+ BaseObjectWeakPtr<diagnostics_channel::Channel>(ch));
258+ return BaseObjectPtr<diagnostics_channel::Channel>(ch);
259+ }
260+ return {};
261+ }
262+
173263void Permission::Apply (Environment* env,
174264 const std::vector<std::string>& allow,
175265 PermissionScope scope) {
0 commit comments