FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
permissions.hpp
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <map>
12#include <cstring>
13#include <set>
14#include <ranges>
15
16#include "reserved.hpp"
17#include "../std/enum.hpp"
18#include "../std/expected.hpp"
19
31{
32
33namespace
34{
35
36namespace fs = std::filesystem;
37
38}
39
40// Permission bits
41using Bits = uint64_t;
42
43// Permissions as fields
44ENUM(Permission,ALL,HOME,MEDIA,AUDIO,WAYLAND,XORG,DBUS_USER,DBUS_SYSTEM,UDEV,USB,INPUT,GPU,NETWORK,DEV,SHM,OPTICAL);
45
46// Corresponding bit position index
47inline std::map<Permission,Bits> const permission_mask =
48{
49 {Permission::HOME, Bits{1} << 0},
50 {Permission::MEDIA, Bits{1} << 1},
51 {Permission::AUDIO, Bits{1} << 2},
52 {Permission::WAYLAND, Bits{1} << 3},
53 {Permission::XORG, Bits{1} << 4},
54 {Permission::DBUS_USER, Bits{1} << 5},
55 {Permission::DBUS_SYSTEM, Bits{1} << 6},
56 {Permission::UDEV, Bits{1} << 7},
57 {Permission::USB, Bits{1} << 8},
58 {Permission::INPUT, Bits{1} << 9},
59 {Permission::GPU, Bits{1} << 10},
60 {Permission::NETWORK, Bits{1} << 11},
61 {Permission::DEV, Bits{1} << 12},
62 {Permission::SHM, Bits{1} << 13},
63 {Permission::OPTICAL, Bits{1} << 14},
64};
65
74[[nodiscard]] inline Value<void> bit_set(Bits& bits, Permission const& permission, bool value) noexcept
75{
76 auto it = permission_mask.find(permission);
77 return_if(it == permission_mask.end(), Error("E::Permission '{}' not found", permission));
78 Bits mask = it->second;
79 if (value) { bits |= mask; }
80 else { bits &= ~mask; }
81 return {};
82}
83
90[[nodiscard]] inline std::set<std::string> to_strings(Bits const& bits) noexcept
91{
92 std::set<std::string> out;
93 for(auto&& [permission,mask] : permission_mask)
94 {
95 if(bits & mask)
96 {
97 std::string str = permission;
98 std::ranges::transform(str, str.begin(), ::tolower);
99 out.insert(str);
100 }
101 }
102 return out;
103}
104
112inline Value<void> write(fs::path const& path_file_binary, Bits const& bits) noexcept
113{
114 static_assert(sizeof(Bits) == sizeof(uint64_t), "Bits size must be 8 bytes");
115 uint64_t offset_begin = ns_reserved::FIM_RESERVED_OFFSET_PERMISSIONS_BEGIN;
116 uint64_t offset_end = ns_reserved::FIM_RESERVED_OFFSET_PERMISSIONS_END;
117 return ns_reserved::write(path_file_binary, offset_begin, offset_end, reinterpret_cast<char const*>(&bits), sizeof(bits));
118}
119
126inline Value<Bits> read(fs::path const& path_file_binary) noexcept
127{
128 static_assert(sizeof(Bits) == sizeof(uint64_t), "Bits size must be 8 bytes");
129 uint64_t offset_begin = ns_reserved::FIM_RESERVED_OFFSET_PERMISSIONS_BEGIN;
130 uint64_t size = ns_reserved::FIM_RESERVED_OFFSET_PERMISSIONS_END - offset_begin;
131 constexpr size_t const size_bits = sizeof(Bits);
132 return_if(size_bits != size, Error("E::Trying to read an exceeding number of bytes: {} vs {}", size_bits, size));
133 Bits bits;
134 Pop(ns_reserved::read(path_file_binary, offset_begin, reinterpret_cast<char*>(&bits), size_bits));
135 return bits;
136}
137
142{
143 private:
144 fs::path m_path_file_binary;
145
146 Value<void> set_permissions(Bits bits, std::set<Permission> const& permissions, bool value)
147 {
148 if(permissions.contains(Permission::NONE))
149 {
150 return Error("E::Invalid permission 'NONE'");
151 }
152 if(permissions.contains(Permission::ALL))
153 {
154 return_if(permissions.size() > 1, Error("E::Permission 'all' should not be used with others"));
155 return this->set_all(true);
156 }
157 for(Permission const& permission : permissions)
158 {
159 Pop(bit_set(bits, permission, value));
160 };
161 Pop(write(m_path_file_binary, bits));
162 return {};
163 }
164 public:
169 Permissions(fs::path const& path_file_binary)
170 : m_path_file_binary(path_file_binary)
171 {}
172
178 [[nodiscard]] inline Value<void> set_all(bool value)
179 {
180 auto permissions = permission_mask
181 | std::views::transform([](auto&& e){ return e.first; })
182 | std::views::filter([](auto&& e){ return e != Permission::ALL; })
183 | std::ranges::to<std::set<Permission>>();
184 return set_permissions(Bits{}, permissions, value);
185 }
186
192 [[nodiscard]] inline Value<void> set(std::set<Permission> const& permissions)
193 {
194 return set_permissions(Bits{}, permissions, true);
195 }
196
202 [[nodiscard]] inline Value<void> add(std::set<Permission> const& permissions)
203 {
204 return set_permissions(Pop(read(m_path_file_binary)), permissions, true);
205 }
206
212 [[nodiscard]] inline Value<void> del(std::set<Permission> const& permissions)
213 {
214 return set_permissions(Pop(read(m_path_file_binary)), permissions, false);
215 }
216
222 [[nodiscard]] inline bool contains(Permission const& permission) const noexcept
223 {
224 return_if(permission == Permission::NONE or permission == Permission::ALL, false);
225 Bits bits = read(m_path_file_binary).value_or(0);
226 auto it = permission_mask.find(permission);
227 return_if(it == permission_mask.end(), false);
228 return (bits & it->second) != 0;
229 }
230
235 [[nodiscard]] inline Value<std::set<std::string>> to_strings() const noexcept
236 {
237 return ::ns_reserved::ns_permissions::to_strings(Pop(read(m_path_file_binary)));
238 }
239};
240
241} // namespace ns_reserved::ns_permissions
242
243/* vim: set expandtab fdm=marker ts=2 sw=2 tw=100 et :*/
Value< std::set< std::string > > to_strings() const noexcept
Converts enabled permissions to string representations.
Value< void > add(std::set< Permission > const &permissions)
Adds permissions to existing configuration.
Value< void > set_all(bool value)
Sets all permissions to the specified value.
Value< void > del(std::set< Permission > const &permissions)
Removes permissions from existing configuration.
Permissions(fs::path const &path_file_binary)
Constructs a Permissions manager for the given binary.
bool contains(Permission const &permission) const noexcept
Checks if a specific permission is enabled.
Value< void > set(std::set< Permission > const &permissions)
Sets the specified permissions (replaces existing)
Custom enumeration class.
Enhanced error handling framework built on std::expected.
Permission bitfield management in reserved space.
std::set< std::string > to_strings(Bits const &bits) noexcept
Creates a set of lowercase string permission representations.
Value< void > write(fs::path const &path_file_binary, Bits const &bits) noexcept
Write the Bits struct to the given binary.
Value< Bits > read(fs::path const &path_file_binary) noexcept
Read the Bits struct from the given binary.
Value< void > bit_set(Bits &bits, Permission const &permission, bool value) noexcept
Sets a bit permission with the target value.
Value< void > write(fs::path const &path_file_binary, uint64_t offset_begin, uint64_t offset_end, const char *data, uint64_t length) noexcept
Writes data to a file in binary format.
Definition reserved.hpp:142
Value< std::streamsize > read(fs::path const &path_file_binary, uint64_t offset, char *data, uint64_t length) noexcept
Reads data from a file in binary format.
Definition reserved.hpp:172
Manages reserved space.
Enhanced expected type with integrated logging capabilities.
Definition expected.hpp:44