collection_permissions.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "collection_permissions.hpp"
  2. #include "logging/logger.hpp"
  3. namespace smartbotic::runner {
  4. // System collections that are always protected - no workflow access allowed
  5. const std::unordered_set<std::string> CollectionPermissions::SYSTEM_COLLECTIONS = {
  6. "users",
  7. "sessions",
  8. "api_keys",
  9. "credentials",
  10. "collection_permissions"
  11. };
  12. std::string collectionAccessToString(CollectionAccess access) {
  13. switch (access) {
  14. case CollectionAccess::None: return "none";
  15. case CollectionAccess::ReadOnly: return "read-only";
  16. case CollectionAccess::ReadWrite: return "read-write";
  17. default: return "none";
  18. }
  19. }
  20. CollectionAccess collectionAccessFromString(const std::string& str) {
  21. if (str == "read-only") return CollectionAccess::ReadOnly;
  22. if (str == "read-write") return CollectionAccess::ReadWrite;
  23. return CollectionAccess::None;
  24. }
  25. CollectionPermissions::CollectionPermissions(storage::StorageClient& storage)
  26. : storage_(storage) {
  27. }
  28. void CollectionPermissions::loadPermissions() {
  29. std::lock_guard<std::mutex> lock(mutex_);
  30. permissions_.clear();
  31. // Set default permissions for known collections
  32. // These can be overridden by database settings
  33. permissions_["workflows"] = CollectionAccess::ReadWrite;
  34. permissions_["workflow_groups"] = CollectionAccess::ReadWrite;
  35. permissions_["executions"] = CollectionAccess::ReadOnly;
  36. permissions_["runners"] = CollectionAccess::ReadOnly;
  37. permissions_["nodes"] = CollectionAccess::ReadOnly;
  38. // Load permissions from database
  39. auto result = storage_.get("collection_permissions", "settings");
  40. if (result.ok()) {
  41. const auto& data = result.value();
  42. // Load default access
  43. if (data.contains("defaultAccess")) {
  44. default_access_ = collectionAccessFromString(data["defaultAccess"].get<std::string>());
  45. }
  46. // Load per-collection permissions
  47. if (data.contains("permissions") && data["permissions"].is_object()) {
  48. for (auto& [collection, config] : data["permissions"].items()) {
  49. if (config.is_object() && config.contains("access")) {
  50. auto access = collectionAccessFromString(config["access"].get<std::string>());
  51. permissions_[collection] = access;
  52. }
  53. }
  54. }
  55. LOG_INFO("Loaded collection permissions for {} collections", permissions_.size());
  56. } else {
  57. LOG_INFO("No collection permissions found in database, using defaults");
  58. }
  59. }
  60. bool CollectionPermissions::canRead(const std::string& collection) const {
  61. // System collections are never accessible
  62. if (isSystemCollection(collection)) {
  63. return false;
  64. }
  65. std::lock_guard<std::mutex> lock(mutex_);
  66. auto it = permissions_.find(collection);
  67. if (it != permissions_.end()) {
  68. return it->second == CollectionAccess::ReadOnly ||
  69. it->second == CollectionAccess::ReadWrite;
  70. }
  71. // Use default access for unlisted collections
  72. return default_access_ == CollectionAccess::ReadOnly ||
  73. default_access_ == CollectionAccess::ReadWrite;
  74. }
  75. bool CollectionPermissions::canWrite(const std::string& collection) const {
  76. // System collections are never accessible
  77. if (isSystemCollection(collection)) {
  78. return false;
  79. }
  80. std::lock_guard<std::mutex> lock(mutex_);
  81. auto it = permissions_.find(collection);
  82. if (it != permissions_.end()) {
  83. return it->second == CollectionAccess::ReadWrite;
  84. }
  85. // Use default access for unlisted collections
  86. return default_access_ == CollectionAccess::ReadWrite;
  87. }
  88. CollectionAccess CollectionPermissions::getAccess(const std::string& collection) const {
  89. // System collections are never accessible
  90. if (isSystemCollection(collection)) {
  91. return CollectionAccess::None;
  92. }
  93. std::lock_guard<std::mutex> lock(mutex_);
  94. auto it = permissions_.find(collection);
  95. if (it != permissions_.end()) {
  96. return it->second;
  97. }
  98. return default_access_;
  99. }
  100. bool CollectionPermissions::isSystemCollection(const std::string& collection) const {
  101. return SYSTEM_COLLECTIONS.contains(collection);
  102. }
  103. std::unordered_map<std::string, CollectionAccess> CollectionPermissions::getPermissions() const {
  104. std::lock_guard<std::mutex> lock(mutex_);
  105. return permissions_;
  106. }
  107. CollectionAccess CollectionPermissions::getDefaultAccess() const {
  108. std::lock_guard<std::mutex> lock(mutex_);
  109. return default_access_;
  110. }
  111. void CollectionPermissions::setPermission(const std::string& collection, CollectionAccess access) {
  112. std::lock_guard<std::mutex> lock(mutex_);
  113. permissions_[collection] = access;
  114. }
  115. void CollectionPermissions::setDefaultAccess(CollectionAccess access) {
  116. std::lock_guard<std::mutex> lock(mutex_);
  117. default_access_ = access;
  118. }
  119. } // namespace smartbotic::runner