membership_origin_validator.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #![warn(missing_docs)]
  2. use sp_std::marker::PhantomData;
  3. use common::origin::ActorOriginValidator;
  4. use frame_system::ensure_signed;
  5. /// Member of the Joystream organization
  6. pub type MemberId<T> = <T as membership::Trait>::MemberId;
  7. /// Default membership actor origin validator.
  8. pub struct MembershipOriginValidator<T> {
  9. marker: PhantomData<T>,
  10. }
  11. impl<T: membership::Trait>
  12. ActorOriginValidator<
  13. <T as frame_system::Trait>::Origin,
  14. MemberId<T>,
  15. <T as frame_system::Trait>::AccountId,
  16. > for MembershipOriginValidator<T>
  17. {
  18. /// Check for valid combination of origin and actor_id. Actor_id should be valid member_id of
  19. /// the membership module
  20. fn ensure_actor_origin(
  21. origin: <T as frame_system::Trait>::Origin,
  22. actor_id: MemberId<T>,
  23. ) -> Result<<T as frame_system::Trait>::AccountId, &'static str> {
  24. // check valid signed account_id
  25. let account_id = ensure_signed(origin)?;
  26. // check whether actor_id belongs to the registered member
  27. let profile_result = <membership::Module<T>>::ensure_membership(actor_id);
  28. if let Ok(profile) = profile_result {
  29. // whether the account_id belongs to the actor
  30. if profile.controller_account == account_id {
  31. return Ok(account_id);
  32. } else {
  33. return Err("Membership validation failed: given account doesn't match with profile accounts");
  34. }
  35. }
  36. Err("Membership validation failed: cannot find a profile for a member")
  37. }
  38. }
  39. #[cfg(test)]
  40. mod tests {
  41. use super::MembershipOriginValidator;
  42. use crate::Runtime;
  43. use common::origin::ActorOriginValidator;
  44. use frame_system::RawOrigin;
  45. use sp_runtime::AccountId32;
  46. type Membership = membership::Module<Runtime>;
  47. fn initial_test_ext() -> sp_io::TestExternalities {
  48. let t = frame_system::GenesisConfig::default()
  49. .build_storage::<Runtime>()
  50. .unwrap();
  51. t.into()
  52. }
  53. #[test]
  54. fn membership_origin_validator_fails_with_unregistered_member() {
  55. initial_test_ext().execute_with(|| {
  56. let origin = RawOrigin::Signed(AccountId32::default());
  57. let member_id = 1;
  58. let error = "Membership validation failed: cannot find a profile for a member";
  59. let validation_result =
  60. MembershipOriginValidator::<Runtime>::ensure_actor_origin(origin.into(), member_id);
  61. assert_eq!(validation_result, Err(error));
  62. });
  63. }
  64. #[test]
  65. fn membership_origin_validator_succeeds() {
  66. initial_test_ext().execute_with(|| {
  67. let account_id = AccountId32::default();
  68. let origin = RawOrigin::Signed(account_id.clone());
  69. let authority_account_id = AccountId32::default();
  70. Membership::set_screening_authority(
  71. RawOrigin::Root.into(),
  72. authority_account_id.clone(),
  73. )
  74. .unwrap();
  75. Membership::add_screened_member(
  76. RawOrigin::Signed(authority_account_id).into(),
  77. account_id.clone(),
  78. Some(b"handle".to_vec()),
  79. None,
  80. None,
  81. None,
  82. )
  83. .unwrap();
  84. let member_id = 0; // newly created member_id
  85. let validation_result =
  86. MembershipOriginValidator::<Runtime>::ensure_actor_origin(origin.into(), member_id);
  87. assert_eq!(validation_result, Ok(account_id));
  88. });
  89. }
  90. #[test]
  91. fn membership_origin_validator_fails_with_incompatible_account_id_and_member_id() {
  92. initial_test_ext().execute_with(|| {
  93. let account_id = AccountId32::default();
  94. let error =
  95. "Membership validation failed: given account doesn't match with profile accounts";
  96. let authority_account_id = AccountId32::default();
  97. Membership::set_screening_authority(
  98. RawOrigin::Root.into(),
  99. authority_account_id.clone(),
  100. )
  101. .unwrap();
  102. Membership::add_screened_member(
  103. RawOrigin::Signed(authority_account_id).into(),
  104. account_id,
  105. Some(b"handle".to_vec()),
  106. None,
  107. None,
  108. None,
  109. )
  110. .unwrap();
  111. let member_id = 0; // newly created member_id
  112. let invalid_account_id: [u8; 32] = [2; 32];
  113. let validation_result = MembershipOriginValidator::<Runtime>::ensure_actor_origin(
  114. RawOrigin::Signed(invalid_account_id.into()).into(),
  115. member_id,
  116. );
  117. assert_eq!(validation_result, Err(error));
  118. });
  119. }
  120. }