permissions.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. use codec::{Decode, Encode};
  2. use crate::constraint::*;
  3. use crate::credentials::*;
  4. use crate::DispatchResult;
  5. #[cfg(feature = "std")]
  6. use serde::{Deserialize, Serialize};
  7. /// Permissions for an instance of a Class in the versioned store.
  8. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  9. #[derive(Encode, Decode, Default, Eq, PartialEq, Clone, Debug)]
  10. pub struct ClassPermissions<ClassId, Credential, PropertyIndex, BlockNumber>
  11. where
  12. ClassId: Ord,
  13. Credential: Ord + Clone,
  14. PropertyIndex: Ord,
  15. {
  16. // concrete permissions
  17. /// Permissions that are applied to entities of this class, define who in addition to
  18. /// root origin can update entities of this class.
  19. pub entity_permissions: EntityPermissions<Credential>,
  20. /// Wether new entities of this class be created or not. Is not enforced for root origin.
  21. pub entities_can_be_created: bool,
  22. /// Who can add new schemas in the versioned store for this class
  23. pub add_schemas: CredentialSet<Credential>,
  24. /// Who can create new entities in the versioned store of this class
  25. pub create_entities: CredentialSet<Credential>,
  26. /// The type of constraint on referencing the class from other entities.
  27. pub reference_constraint: ReferenceConstraint<ClassId, PropertyIndex>,
  28. /// Who (in addition to root origin) can update all concrete permissions.
  29. /// The admins can only be set by the root origin, "System".
  30. pub admins: CredentialSet<Credential>,
  31. // Block where permissions were changed
  32. pub last_permissions_update: BlockNumber,
  33. }
  34. impl<ClassId, Credential, PropertyIndex, BlockNumber>
  35. ClassPermissions<ClassId, Credential, PropertyIndex, BlockNumber>
  36. where
  37. ClassId: Ord,
  38. Credential: Ord + Clone,
  39. PropertyIndex: Ord,
  40. {
  41. /// Returns Ok if access_level is root origin or credential is in admins set, Err otherwise
  42. pub fn is_admin(
  43. class_permissions: &Self,
  44. access_level: &AccessLevel<Credential>,
  45. ) -> DispatchResult {
  46. match access_level {
  47. AccessLevel::System => Ok(()),
  48. AccessLevel::Credential(credential) => {
  49. if class_permissions.admins.contains(credential) {
  50. Ok(())
  51. } else {
  52. Err("NotInAdminsSet")
  53. }
  54. }
  55. AccessLevel::Unspecified => Err("UnspecifiedActor"),
  56. AccessLevel::EntityMaintainer => Err("AccessLevel::EntityMaintainer-UsedOutOfPlace"),
  57. }
  58. }
  59. pub fn can_add_class_schema(
  60. class_permissions: &Self,
  61. access_level: &AccessLevel<Credential>,
  62. ) -> DispatchResult {
  63. match access_level {
  64. AccessLevel::System => Ok(()),
  65. AccessLevel::Credential(credential) => {
  66. if class_permissions.add_schemas.contains(credential) {
  67. Ok(())
  68. } else {
  69. Err("NotInAddSchemasSet")
  70. }
  71. }
  72. AccessLevel::Unspecified => Err("UnspecifiedActor"),
  73. AccessLevel::EntityMaintainer => Err("AccessLevel::EntityMaintainer-UsedOutOfPlace"),
  74. }
  75. }
  76. pub fn can_create_entity(
  77. class_permissions: &Self,
  78. access_level: &AccessLevel<Credential>,
  79. ) -> DispatchResult {
  80. match access_level {
  81. AccessLevel::System => Ok(()),
  82. AccessLevel::Credential(credential) => {
  83. if !class_permissions.entities_can_be_created {
  84. Err("EntitiesCannotBeCreated")
  85. } else if class_permissions.create_entities.contains(credential) {
  86. Ok(())
  87. } else {
  88. Err("NotInCreateEntitiesSet")
  89. }
  90. }
  91. AccessLevel::Unspecified => Err("UnspecifiedActor"),
  92. AccessLevel::EntityMaintainer => Err("AccessLevel::EntityMaintainer-UsedOutOfPlace"),
  93. }
  94. }
  95. pub fn can_update_entity(
  96. class_permissions: &Self,
  97. access_level: &AccessLevel<Credential>,
  98. ) -> DispatchResult {
  99. match access_level {
  100. AccessLevel::System => Ok(()),
  101. AccessLevel::Credential(credential) => {
  102. if class_permissions
  103. .entity_permissions
  104. .update
  105. .contains(credential)
  106. {
  107. Ok(())
  108. } else {
  109. Err("CredentialNotInEntityPermissionsUpdateSet")
  110. }
  111. }
  112. AccessLevel::EntityMaintainer => {
  113. if class_permissions
  114. .entity_permissions
  115. .maintainer_has_all_permissions
  116. {
  117. Ok(())
  118. } else {
  119. Err("MaintainerNotGivenAllPermissions")
  120. }
  121. }
  122. _ => Err("UnknownActor"),
  123. }
  124. }
  125. }
  126. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  127. #[derive(Encode, Decode, Clone, Debug, Eq, PartialEq)]
  128. pub struct EntityPermissions<Credential>
  129. where
  130. Credential: Ord,
  131. {
  132. // Principals permitted to update any entity of the class which this permission is associated with.
  133. pub update: CredentialSet<Credential>,
  134. /// Wether the designated maintainer (if set) of an entity has permission to update it.
  135. pub maintainer_has_all_permissions: bool,
  136. }
  137. impl<Credential: Ord> Default for EntityPermissions<Credential> {
  138. fn default() -> Self {
  139. EntityPermissions {
  140. maintainer_has_all_permissions: true,
  141. update: CredentialSet::new(),
  142. }
  143. }
  144. }