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,29 @@ 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::kNet :
42+ return " node:permission-model:net" ;
43+ case PermissionScope::kInspector :
44+ return " node:permission-model:inspector" ;
45+ case PermissionScope::kWASI :
46+ return " node:permission-model:wasi" ;
47+ case PermissionScope::kAddon :
48+ return " node:permission-model:addon" ;
49+ default :
50+ return {};
51+ }
52+ }
53+
3054// permission.has('fs.in', '/tmp/')
3155// permission.has('fs.in')
3256static void Has (const FunctionCallbackInfo<Value>& args) {
@@ -70,7 +94,7 @@ PermissionScope Permission::StringToPermission(const std::string& perm) {
7094}
7195#undef V
7296
73- Permission::Permission () : enabled_(false ) {
97+ Permission::Permission () : enabled_(false ), warning_only_( false ) {
7498 std::shared_ptr<PermissionBase> fs = std::make_shared<FSPermission>();
7599 std::shared_ptr<PermissionBase> child_p =
76100 std::make_shared<ChildProcessPermission>();
@@ -175,6 +199,73 @@ void Permission::EnablePermissions() {
175199 }
176200}
177201
202+ void Permission::EnableWarningOnly () {
203+ if (!warning_only_) {
204+ warning_only_ = true ;
205+ }
206+ }
207+
208+ bool Permission::is_scope_granted (Environment* env,
209+ const PermissionScope permission,
210+ const std::string_view& res) const {
211+ auto perm_node = nodes_.find (permission);
212+ bool result = false ;
213+ if (perm_node != nodes_.end ()) {
214+ result = perm_node->second ->is_granted (env, permission, res);
215+ }
216+
217+ if (!result && !publishing_) {
218+ auto channel_name = GetDiagnosticsChannelName (permission);
219+ if (!channel_name.empty ()) {
220+ auto ch = GetOrCreateChannel (env, permission);
221+ if (ch && ch->HasSubscribers ()) {
222+ publishing_ = true ;
223+ v8::Isolate* isolate = env->isolate ();
224+ v8::HandleScope handle_scope (isolate);
225+ v8::Local<v8::Context> context = env->context ();
226+ v8::Local<v8::Object> msg = v8::Object::New (isolate, v8::Null (isolate), nullptr , nullptr , 0 );
227+ const char * perm_str = PermissionToString (permission);
228+ msg->Set (context,
229+ FIXED_ONE_BYTE_STRING (isolate, " permission" ),
230+ v8::String::NewFromUtf8 (isolate, perm_str).ToLocalChecked ())
231+ .Check ();
232+ msg->Set (context,
233+ FIXED_ONE_BYTE_STRING (isolate, " resource" ),
234+ v8::String::NewFromUtf8 (isolate,
235+ res.data (),
236+ v8::NewStringType::kNormal ,
237+ static_cast <int >(res.size ()))
238+ .ToLocalChecked ())
239+ .Check ();
240+ ch->Publish (env, msg);
241+ publishing_ = false ;
242+ }
243+ }
244+ }
245+
246+ return result;
247+ }
248+
249+ BaseObjectPtr<diagnostics_channel::Channel>
250+ Permission::GetOrCreateChannel (
251+ Environment* env, PermissionScope scope) const {
252+ auto it = channels_.find (scope);
253+ if (it != channels_.end ()) {
254+ // Promote weak ref to strong for the duration of this call.
255+ BaseObjectPtr<diagnostics_channel::Channel> ptr (it->second .get ());
256+ if (ptr) return ptr;
257+ channels_.erase (it);
258+ }
259+ auto channel_name = GetDiagnosticsChannelName (scope);
260+ diagnostics_channel::Channel* ch =
261+ diagnostics_channel::Channel::Get (env, channel_name.data ());
262+ if (ch != nullptr ) {
263+ channels_.emplace (scope, BaseObjectWeakPtr<diagnostics_channel::Channel>(ch));
264+ return BaseObjectPtr<diagnostics_channel::Channel>(ch);
265+ }
266+ return {};
267+ }
268+
178269void Permission::Apply (Environment* env,
179270 const std::vector<std::string>& allow,
180271 PermissionScope scope) {
0 commit comments