Access Check
Usage
 1#pragma once
 2
 3#include <erbsland/conf/AccessCheck.hpp>
 4#include <erbsland/conf/Error.hpp>
 5
 6#include <filesystem>
 7#include <memory>
 8
 9using el::conf::AccessSources;
10using el::conf::AccessCheckResult;
11using el::conf::Error;
12using el::conf::ErrorCategory;
13
14class MyAccessCheck final : public el::conf::AccessCheck {
15public:
16    explicit MyAccessCheck(std::filesystem::path sandbox) : _sandbox{std::move(sandbox)} {};
17    ~MyAccessCheck() override = default;
18    static auto create(std::filesystem::path sandbox) -> std::shared_ptr<MyAccessCheck> {
19        return std::make_shared<MyAccessCheck>(std::move(sandbox));
20    }
21
22public:
23    auto check(const AccessSources &sources) -> AccessCheckResult override {
24        try {
25            if (sources.source == nullptr || sources.source->name() != u8"text") {}
26            auto sourcePath = std::filesystem::path{sources.source->path().toCharString()};
27            auto canonicalSource = canonical(sourcePath).string();
28            auto canonicalSandbox = canonical(_sandbox).string();
29            if (!canonicalSource.starts_with(canonicalSandbox)) {
30                return AccessCheckResult::Denied;
31            }
32            return AccessCheckResult::Granted;
33        } catch (const std::system_error &error) {
34            throw Error(ErrorCategory::Access, u8"System error", error.code());
35        }
36    }
37
38private:
39    std::filesystem::path _sandbox;
40};
Interface
- 
class AccessCheck
 The interface to access check implementations.
Subclassed by erbsland::conf::FileAccessCheck
Public Functions
- 
virtual ~AccessCheck() = default
 Default destructor.
- 
virtual AccessCheckResult check(const AccessSources &sources) = 0
 The check function is called for every source, including the initial source that is passed to the
parse()function call. You can either grant or deny access to this source. If you deny the access to the source, the parser will throw anErrorwithErrorCategory::Access.Instead of returning
AccessResult::Denied, you can also throw anErrorwithErrorCategory::Access.- Not Tested:
 This is part of
Parser
- Parameters:
 sources – The sources that are verified.
- Throws:
 Error – Alternatively, throw an
Errorwith theErrorCategory::Access.- Returns:
 Return either
AccessResult::GrantedorAccessResult::Denied.
- 
virtual ~AccessCheck() = default
 
- 
struct AccessSources
 The source identifiers to verify in the access function.
This structure names the individual source elements for the access function.
- Not Tested:
 This is part of
Parser
Public Members
- 
SourceIdentifierPtr source
 The source to verify.
- 
SourceIdentifierPtr parent
 The parent source that resolved this new source or
nullptrifsourceis the root document.
- 
SourceIdentifierPtr root
 The root document. The root document is always present.
- 
enum class erbsland::conf::AccessCheckResult : uint8_t
 The result of an access check.
- Not Tested:
 This is part of
Parser
Values:
- 
enumerator Granted
 If the access is granted.
- 
enumerator Denied
 If the access is denied.
- 
using erbsland::conf::AccessCheckPtr = std::shared_ptr<AccessCheck>
 
- 
class FileAccessCheck : public erbsland::conf::AccessCheck
 A basic file access check.
By default, the
CanonicalizePath,SameDirectory,Subdirectoriesfeatures are activated.If neither
SameDirectory,SubdirectoriesorAnyDirectoryis set, all file sources are rejected.If a file is included from a non-file source and
AnyDirectoryis not set, the source is rejected.
Public Types
- 
enum Feature
 The feature flags controlling file access restrictions.
Values:
- 
enumerator SameDirectory
 Allow included sources to be in the same directory as the including document (recommended, default).
Example: If the including document has the path `config/main.elcl` documents that are in the directory `config`, like `config/other.elcl` are accepted. If this feature is disabled, documents in the same directory as the including document are rejected.
- 
enumerator Subdirectories
 Allow included sources in subdirectories of the parent document (recommended, default).
Example: If the including document has the path `config/main.elcl` documents that are in subdirectories of `config`, like `config/sub/other.elcl` are accepted. If this feature is disabled, documents in subdirectories of the including document are rejected.
- 
enumerator AnyDirectory
 Not Recommended: Allow included sources in any directory.
Included sources can be anywhere in the filesystem and on shares. Paths can point anywhere.
- 
enumerator OnlyFileSources
 Only allow file sources and reject everything else.
If this feature is enabled, this access check only accepts file sources. Sources of any other type e.g. "text" sources are rejected. If this feature is disabled, which is the default, this check only focuses on "file" sources and grants access to any other sources. Granting non-file source is designed to allow chaining multiple checks.
- 
enumerator LimitSize
 Limit the maximum size of a file to 100MB (recommended, default).
- 
enumerator RequireSuffix
 Only allow file sources with an
.elclsuffix.If this feature is set, this access check only accepts file sources with an `.elcl` suffix.
- 
enumerator _featureCount
 
- 
enumerator SameDirectory
 
Public Functions
- 
FileAccessCheck() = default
 Default constructor.
- 
~FileAccessCheck() override = default
 Default destructor.
- 
virtual AccessCheckResult check(const AccessSources &sources) override
 The check function is called for every source, including the initial source that is passed to the
parse()function call. You can either grant or deny access to this source. If you deny the access to the source, the parser will throw anErrorwithErrorCategory::Access.Instead of returning
AccessResult::Denied, you can also throw anErrorwithErrorCategory::Access.- Not Tested:
 This is part of
Parser
- Parameters:
 sources – The sources that are verified.
- Throws:
 Error – Alternatively, throw an
Errorwith theErrorCategory::Access.- Returns:
 Return either
AccessResult::GrantedorAccessResult::Denied.
Public Static Functions
- 
static inline FileAccessCheckPtr create()
 Create a custom file access check instance.
- 
using erbsland::conf::FileAccessCheckPtr = std::shared_ptr<FileAccessCheck>