%PDF- %PDF-
| Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/permission/ |
| Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/permission/fs_permission.h |
#ifndef SRC_PERMISSION_FS_PERMISSION_H_
#define SRC_PERMISSION_FS_PERMISSION_H_
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "v8.h"
#include <unordered_map>
#include "permission/permission_base.h"
#include "util.h"
namespace node {
namespace permission {
class FSPermission final : public PermissionBase {
public:
void Apply(Environment* env,
const std::vector<std::string>& allow,
PermissionScope scope) override;
bool is_granted(PermissionScope perm,
const std::string_view& param) const override;
struct RadixTree {
struct Node {
std::string prefix;
std::unordered_map<char, Node*> children;
Node* wildcard_child;
bool is_leaf;
explicit Node(const std::string& pre)
: prefix(pre), wildcard_child(nullptr), is_leaf(false) {}
Node() : wildcard_child(nullptr), is_leaf(false) {}
Node* CreateChild(const std::string& path_prefix) {
if (path_prefix.empty() && !is_leaf) {
is_leaf = true;
return this;
}
CHECK(!path_prefix.empty());
char label = path_prefix[0];
Node* child = children[label];
if (child == nullptr) {
children[label] = new Node(path_prefix);
return children[label];
}
// swap prefix
size_t i = 0;
size_t prefix_len = path_prefix.length();
for (; i < child->prefix.length(); ++i) {
if (i > prefix_len || path_prefix[i] != child->prefix[i]) {
std::string parent_prefix = child->prefix.substr(0, i);
std::string child_prefix = child->prefix.substr(i);
child->prefix = child_prefix;
Node* split_child = new Node(parent_prefix);
split_child->children[child_prefix[0]] = child;
children[parent_prefix[0]] = split_child;
return split_child->CreateChild(path_prefix.substr(i));
}
}
child->is_leaf = true;
return child->CreateChild(path_prefix.substr(i));
}
Node* CreateWildcardChild() {
if (wildcard_child != nullptr) {
return wildcard_child;
}
wildcard_child = new Node();
return wildcard_child;
}
Node* NextNode(const std::string& path, size_t idx) const {
if (idx >= path.length()) {
return nullptr;
}
// wildcard node takes precedence
if (children.size() > 1) {
auto it = children.find('*');
if (it != children.end()) {
return it->second;
}
}
auto it = children.find(path[idx]);
if (it == children.end()) {
return nullptr;
}
auto child = it->second;
// match prefix
size_t prefix_len = child->prefix.length();
for (size_t i = 0; i < path.length(); ++i) {
if (i >= prefix_len || child->prefix[i] == '*') {
return child;
}
// Handle optional trailing
// path = /home/subdirectory
// child = subdirectory/*
if (idx >= path.length() &&
child->prefix[i] == node::kPathSeparator) {
continue;
}
if (path[idx++] != child->prefix[i]) {
return nullptr;
}
}
return child;
}
// A node can be a *end* node and have children
// E.g: */slower*, */slown* are inserted:
// /slow
// ---> er
// ---> n
// If */slow* is inserted right after, it will create an
// empty node
// /slow
// ---> '\000' ASCII (0) || \0
// ---> er
// ---> n
bool IsEndNode() const {
if (children.size() == 0) {
return true;
}
return is_leaf;
}
};
RadixTree();
~RadixTree();
void Insert(const std::string& s);
bool Lookup(const std::string_view& s) const { return Lookup(s, false); }
bool Lookup(const std::string_view& s, bool when_empty_return) const;
private:
Node* root_node_;
};
private:
void GrantAccess(PermissionScope scope, const std::string& param);
// fs granted on startup
RadixTree granted_in_fs_;
RadixTree granted_out_fs_;
bool deny_all_in_ = true;
bool deny_all_out_ = true;
bool allow_all_in_ = false;
bool allow_all_out_ = false;
};
} // namespace permission
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif // SRC_PERMISSION_FS_PERMISSION_H_