11cb0ef41Sopenharmony_ci#ifndef SRC_PERMISSION_FS_PERMISSION_H_ 21cb0ef41Sopenharmony_ci#define SRC_PERMISSION_FS_PERMISSION_H_ 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ci#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci#include "v8.h" 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <unordered_map> 91cb0ef41Sopenharmony_ci#include "permission/permission_base.h" 101cb0ef41Sopenharmony_ci#include "util.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cinamespace node { 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_cinamespace permission { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciclass FSPermission final : public PermissionBase { 171cb0ef41Sopenharmony_ci public: 181cb0ef41Sopenharmony_ci void Apply(const std::string& allow, PermissionScope scope) override; 191cb0ef41Sopenharmony_ci bool is_granted(PermissionScope perm, const std::string_view& param) override; 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci struct RadixTree { 221cb0ef41Sopenharmony_ci struct Node { 231cb0ef41Sopenharmony_ci std::string prefix; 241cb0ef41Sopenharmony_ci std::unordered_map<char, Node*> children; 251cb0ef41Sopenharmony_ci Node* wildcard_child; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci explicit Node(const std::string& pre) 281cb0ef41Sopenharmony_ci : prefix(pre), wildcard_child(nullptr) {} 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci Node() : wildcard_child(nullptr) {} 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci Node* CreateChild(std::string prefix) { 331cb0ef41Sopenharmony_ci char label = prefix[0]; 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci Node* child = children[label]; 361cb0ef41Sopenharmony_ci if (child == nullptr) { 371cb0ef41Sopenharmony_ci children[label] = new Node(prefix); 381cb0ef41Sopenharmony_ci return children[label]; 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci // swap prefix 421cb0ef41Sopenharmony_ci unsigned int i = 0; 431cb0ef41Sopenharmony_ci unsigned int prefix_len = prefix.length(); 441cb0ef41Sopenharmony_ci for (; i < child->prefix.length(); ++i) { 451cb0ef41Sopenharmony_ci if (i > prefix_len || prefix[i] != child->prefix[i]) { 461cb0ef41Sopenharmony_ci std::string parent_prefix = child->prefix.substr(0, i); 471cb0ef41Sopenharmony_ci std::string child_prefix = child->prefix.substr(i); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci child->prefix = child_prefix; 501cb0ef41Sopenharmony_ci Node* split_child = new Node(parent_prefix); 511cb0ef41Sopenharmony_ci split_child->children[child_prefix[0]] = child; 521cb0ef41Sopenharmony_ci children[parent_prefix[0]] = split_child; 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci return split_child->CreateChild(prefix.substr(i)); 551cb0ef41Sopenharmony_ci } 561cb0ef41Sopenharmony_ci } 571cb0ef41Sopenharmony_ci return child->CreateChild(prefix.substr(i)); 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci Node* CreateWildcardChild() { 611cb0ef41Sopenharmony_ci if (wildcard_child != nullptr) { 621cb0ef41Sopenharmony_ci return wildcard_child; 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci wildcard_child = new Node(); 651cb0ef41Sopenharmony_ci return wildcard_child; 661cb0ef41Sopenharmony_ci } 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci Node* NextNode(const std::string& path, unsigned int idx) { 691cb0ef41Sopenharmony_ci if (idx >= path.length()) { 701cb0ef41Sopenharmony_ci return nullptr; 711cb0ef41Sopenharmony_ci } 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci auto it = children.find(path[idx]); 741cb0ef41Sopenharmony_ci if (it == children.end()) { 751cb0ef41Sopenharmony_ci return nullptr; 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci auto child = it->second; 781cb0ef41Sopenharmony_ci // match prefix 791cb0ef41Sopenharmony_ci unsigned int prefix_len = child->prefix.length(); 801cb0ef41Sopenharmony_ci for (unsigned int i = 0; i < path.length(); ++i) { 811cb0ef41Sopenharmony_ci if (i >= prefix_len || child->prefix[i] == '*') { 821cb0ef41Sopenharmony_ci return child; 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci // Handle optional trailing 861cb0ef41Sopenharmony_ci // path = /home/subdirectory 871cb0ef41Sopenharmony_ci // child = subdirectory/* 881cb0ef41Sopenharmony_ci if (idx >= path.length() && 891cb0ef41Sopenharmony_ci child->prefix[i] == node::kPathSeparator) { 901cb0ef41Sopenharmony_ci continue; 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci if (path[idx++] != child->prefix[i]) { 941cb0ef41Sopenharmony_ci return nullptr; 951cb0ef41Sopenharmony_ci } 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci return child; 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci // A node can be a *end* node and have children 1011cb0ef41Sopenharmony_ci // E.g: */slower*, */slown* are inserted: 1021cb0ef41Sopenharmony_ci // /slow 1031cb0ef41Sopenharmony_ci // ---> er 1041cb0ef41Sopenharmony_ci // ---> n 1051cb0ef41Sopenharmony_ci // If */slow* is inserted right after, it will create an 1061cb0ef41Sopenharmony_ci // empty node 1071cb0ef41Sopenharmony_ci // /slow 1081cb0ef41Sopenharmony_ci // ---> '\000' ASCII (0) || \0 1091cb0ef41Sopenharmony_ci // ---> er 1101cb0ef41Sopenharmony_ci // ---> n 1111cb0ef41Sopenharmony_ci bool IsEndNode() { 1121cb0ef41Sopenharmony_ci if (children.size() == 0) { 1131cb0ef41Sopenharmony_ci return true; 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci return children['\0'] != nullptr; 1161cb0ef41Sopenharmony_ci } 1171cb0ef41Sopenharmony_ci }; 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci RadixTree(); 1201cb0ef41Sopenharmony_ci ~RadixTree(); 1211cb0ef41Sopenharmony_ci void Insert(const std::string& s); 1221cb0ef41Sopenharmony_ci bool Lookup(const std::string_view& s) { return Lookup(s, false); } 1231cb0ef41Sopenharmony_ci bool Lookup(const std::string_view& s, bool when_empty_return); 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci private: 1261cb0ef41Sopenharmony_ci Node* root_node_; 1271cb0ef41Sopenharmony_ci }; 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci private: 1301cb0ef41Sopenharmony_ci void GrantAccess(PermissionScope scope, const std::string& param); 1311cb0ef41Sopenharmony_ci // fs granted on startup 1321cb0ef41Sopenharmony_ci RadixTree granted_in_fs_; 1331cb0ef41Sopenharmony_ci RadixTree granted_out_fs_; 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci bool deny_all_in_ = true; 1361cb0ef41Sopenharmony_ci bool deny_all_out_ = true; 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci bool allow_all_in_ = false; 1391cb0ef41Sopenharmony_ci bool allow_all_out_ = false; 1401cb0ef41Sopenharmony_ci}; 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci} // namespace permission 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci} // namespace node 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 1471cb0ef41Sopenharmony_ci#endif // SRC_PERMISSION_FS_PERMISSION_H_ 148