summaryrefslogtreecommitdiff
path: root/include/fud_permissions.hpp
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2024-10-02 08:30:08 -0500
committerDominick Allen <djallen@librehumanitas.org>2024-10-02 08:30:08 -0500
commit2cdb2cac44a07fa5db72408f62427a64f32c1d90 (patch)
tree0795220193a293a0297fe16fc257507c41e78760 /include/fud_permissions.hpp
parent3a18a6dcab45467e779e91c7b346aa3b148e8b9c (diff)
Add permissions model for files.
Diffstat (limited to 'include/fud_permissions.hpp')
-rw-r--r--include/fud_permissions.hpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/include/fud_permissions.hpp b/include/fud_permissions.hpp
new file mode 100644
index 0000000..66eec0c
--- /dev/null
+++ b/include/fud_permissions.hpp
@@ -0,0 +1,191 @@
+/*
+ * libfud
+ * Copyright 2024 Dominick Allen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FUD_PERMISSIONS_HPP
+#define FUD_PERMISSIONS_HPP
+
+#include <climits>
+#include <cstdint>
+#include <sys/stat.h>
+#include <type_traits>
+
+namespace fud {
+
+static_assert(CHAR_BIT == 8, "Assume that uint8_t has 8 bits");
+static_assert(sizeof(uint8_t) == 1, "Assume that uint8_t is 1 byte");
+
+enum class PermissionType : uint8_t
+{
+ None = 0x00,
+ Exec = 0x01,
+ Write = 0x02,
+ Read = 0x04
+};
+
+struct PermissionField {
+ explicit constexpr PermissionField(PermissionType permissionType) :
+ m_permissions{static_cast<uint8_t>(permissionType)}
+ {
+ }
+
+ constexpr PermissionField(PermissionType lhs, PermissionType rhs)
+ {
+ m_permissions = static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs);
+ }
+
+ constexpr PermissionField(PermissionType lhs, PermissionField rhs)
+ {
+ m_permissions = static_cast<uint8_t>(lhs) | rhs.m_permissions;
+ }
+
+ constexpr PermissionField(PermissionField lhs, PermissionType rhs)
+ {
+ m_permissions = lhs.m_permissions | static_cast<uint8_t>(rhs);
+ }
+
+ constexpr PermissionField(PermissionField lhs, PermissionField rhs)
+ {
+ m_permissions = lhs.m_permissions | rhs.m_permissions;
+ }
+
+ constexpr uint16_t operator()()
+ {
+ return m_permissions;
+ }
+
+ uint8_t m_permissions{};
+};
+
+enum class PermissionSpecialType : uint8_t
+{
+ None = 0x00,
+ Sticky = 0x01,
+ SetGroupId = 0x02,
+ SetUserId = 0x04
+};
+
+struct PermissionSpecial {
+ explicit constexpr PermissionSpecial(PermissionSpecialType permissionType) :
+ m_permissions{static_cast<uint8_t>(permissionType)}
+ {
+ }
+
+ constexpr PermissionSpecial(PermissionSpecialType lhs, PermissionSpecialType rhs)
+ {
+ m_permissions = static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs);
+ }
+
+ constexpr PermissionSpecial(PermissionSpecialType lhs, PermissionSpecial rhs)
+ {
+ m_permissions = static_cast<uint8_t>(lhs) | rhs.m_permissions;
+ }
+
+ constexpr PermissionSpecial(PermissionSpecial lhs, PermissionSpecialType rhs)
+ {
+ m_permissions = lhs.m_permissions | static_cast<uint8_t>(rhs);
+ }
+
+ constexpr PermissionSpecial(PermissionSpecial lhs, PermissionSpecial rhs)
+ {
+ m_permissions = lhs.m_permissions | rhs.m_permissions;
+ }
+
+ constexpr uint16_t operator()()
+ {
+ return m_permissions;
+ }
+
+ uint8_t m_permissions{0};
+};
+
+class Permissions {
+ public:
+ static constexpr uint8_t GroupShift = 3;
+ static constexpr uint8_t UserShift = GroupShift + 3;
+ static constexpr uint8_t SpecialShift = UserShift + 3;
+
+ constexpr Permissions(PermissionField user, PermissionField group, PermissionField others)
+ {
+ m_permissions = user() << UserShift | group() << GroupShift | others();
+ }
+
+ template <typename U, typename G, typename O>
+ constexpr Permissions(U user, G group, O others)
+ {
+ m_permissions = PermissionField{user}() << UserShift | PermissionField{group}() << GroupShift |
+ PermissionField{others}();
+ }
+
+ constexpr Permissions(
+ PermissionField user,
+ PermissionField group,
+ PermissionField others,
+ PermissionSpecial special)
+ {
+ m_permissions = special() << SpecialShift | user() << UserShift | group() << GroupShift | others();
+ }
+
+ template <typename U, typename G, typename O, typename S>
+ constexpr Permissions(
+ PermissionField user,
+ PermissionField group,
+ PermissionField others,
+ PermissionSpecial special)
+ {
+ m_permissions = special() << SpecialShift | PermissionField{user}() << UserShift |
+ PermissionField{group}() << GroupShift | PermissionField{others}();
+ }
+
+ constexpr int32_t operator()()
+ {
+ return m_permissions;
+ }
+
+ constexpr mode_t mode()
+ {
+ return static_cast<mode_t>(m_permissions);
+ }
+
+ private:
+ int32_t m_permissions{0};
+};
+
+constexpr PermissionField operator|(PermissionType lhs, PermissionType rhs)
+{
+ return PermissionField{lhs, rhs};
+}
+
+constexpr PermissionField operator|(PermissionType lhs, PermissionField rhs)
+{
+ return PermissionField{lhs, rhs};
+}
+
+constexpr PermissionField operator|(PermissionField lhs, PermissionType rhs)
+{
+ return PermissionField{lhs, rhs};
+}
+
+constexpr PermissionField operator|(PermissionField lhs, PermissionField rhs)
+{
+ return PermissionField{lhs, rhs};
+}
+
+constexpr PermissionField PermReadWrite = PermissionType::Read | PermissionType::Write;
+
+} // namespace fud
+
+#endif