#include "smartbotic/webserver/permissions.hpp" namespace smartbotic::permissions { auto BuildWorkspacePermission(std::string_view workspace_id, std::string_view action) -> std::string { std::string result; result.reserve(10 + workspace_id.size() + action.size()); result.append("workspace:"); result.append(workspace_id); result.append(":"); result.append(action); return result; } auto BuildCollectionPermission(std::string_view workspace_id, std::string_view collection, std::string_view action) -> std::string { std::string result; result.reserve(12 + workspace_id.size() + collection.size() + action.size()); result.append("collection:"); result.append(workspace_id); result.append(":"); result.append(collection); result.append(":"); result.append(action); return result; } auto BuildPagePermission(std::string_view workspace_id, std::string_view action) -> std::string { std::string result; result.reserve(6 + workspace_id.size() + action.size()); result.append("page:"); result.append(workspace_id); result.append(":"); result.append(action); return result; } auto BuildFieldPermission(std::string_view workspace_id, std::string_view collection, std::string_view field, std::string_view action) -> std::string { std::string result; result.reserve(8 + workspace_id.size() + collection.size() + field.size() + action.size()); result.append("field:"); result.append(workspace_id); result.append(":"); result.append(collection); result.append(":"); result.append(field); result.append(":"); result.append(action); return result; } auto ParsePermission(std::string_view permission) -> std::vector { std::vector parts; std::string part; for (char c : permission) { if (c == ':') { parts.push_back(std::move(part)); part.clear(); } else { part += c; } } if (!part.empty()) { parts.push_back(std::move(part)); } return parts; } auto MatchesPermission(std::string_view required, std::string_view granted) -> bool { // Wildcard "*" matches everything if (granted == kWildcard) { return true; } // Exact match if (required == granted) { return true; } // Parse both permissions into parts auto required_parts = ParsePermission(required); auto granted_parts = ParsePermission(granted); // If granted has fewer parts, it can't match if (granted_parts.size() < required_parts.size()) { // Unless the last part is a wildcard that covers the rest // e.g., "system:*" should match "system:users:read" if (granted_parts.empty()) { return false; } if (granted_parts.back() != "*") { return false; } // Check if the prefix matches for (size_t i = 0; i < granted_parts.size() - 1; ++i) { if (granted_parts[i] != "*" && granted_parts[i] != required_parts[i]) { return false; } } return true; } // Compare part by part for (size_t i = 0; i < required_parts.size(); ++i) { if (i >= granted_parts.size()) { return false; } // Wildcard in granted matches any value in required if (granted_parts[i] == "*") { continue; } if (granted_parts[i] != required_parts[i]) { return false; } } return true; } auto GetAllSystemPermissions() -> std::vector { return { // Authentication kLoginAllow, kLoginDeny, // User management kUsersRead, kUsersCreate, kUsersUpdate, kUsersDelete, // Group management kGroupsRead, kGroupsCreate, kGroupsUpdate, kGroupsDelete, // System group management kSystemGroupsRead, kSystemGroupsCreate, kSystemGroupsUpdate, kSystemGroupsDelete, // Workspace management kWorkspacesRead, kWorkspacesCreate, kWorkspacesUpdate, kWorkspacesDelete, // Collection management kCollectionsRead, kCollectionsCreate, kCollectionsUpdate, kCollectionsDelete, // API key management kApiKeysRead, kApiKeysCreate, kApiKeysUpdate, kApiKeysDelete, // Membership management kMembershipsRead, kMembershipsCreate, kMembershipsUpdate, kMembershipsDelete, // View management kViewsRead, kViewsCreate, kViewsUpdate, kViewsDelete, // Page management kPagesRead, kPagesCreate, kPagesUpdate, kPagesDelete, // LLM Provider management kLlmProvidersRead, kLlmProvidersCreate, kLlmProvidersUpdate, kLlmProvidersDelete, // LLM Chat access kLlmChat, // Archive management kArchivesRead, kArchivesRestore, kArchivesDelete, kArchivesExport, }; } auto GetAllCollectionActions() -> std::vector { return { "read_all", "read_own", "write_all", "write_own", "create", "delete_all", "delete_own", "manage", }; } auto GetAllFieldActions() -> std::vector { return { "read", "write", }; } auto GetAllPageActions() -> std::vector { return { "create", "read_all", "read_own", "write_all", "write_own", "delete_all", "delete_own", "share", }; } } // namespace smartbotic::permissions