Skip to content

Commit 57468fd

Browse files
authored
Merge pull request #230 from hashed-io/feature/proxy-financial/update-rbac
Feature/proxy financial/update rbac
2 parents 227260d + c8ba2d0 commit 57468fd

File tree

5 files changed

+131
-119
lines changed

5 files changed

+131
-119
lines changed

pallets/proxy-financial/src/functions.rs

Lines changed: 69 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,31 @@ impl<T: Config> Pallet<T> {
1616
// --------------------------------------------------------------------------------------------
1717

1818
pub fn do_initial_setup() -> DispatchResult{
19+
// Create a global scope for the administrator role
1920
let pallet_id = Self::pallet_id();
2021
let global_scope = pallet_id.using_encoded(blake2_256);
2122
<GlobalScope<T>>::put(global_scope);
23+
T::Rbac::create_scope(Self::pallet_id(), global_scope)?;
2224

2325
//Admin rol & permissions
2426
let administrator_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::Administrator.to_vec()].to_vec())?;
2527
T::Rbac::create_and_set_permissions(pallet_id.clone(), administrator_role_id[0], ProxyPermission::administrator_permissions())?;
2628

27-
//Developer rol & permissions
28-
let _developer_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::Developer.to_vec()].to_vec())?;
29-
//T::Rbac::create_and_set_permissions(pallet_id.clone(), developer_role_id[0], ProxyPermission::developer_permissions())?;
29+
//Builder rol & permissions
30+
let builder_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::Builder.to_vec()].to_vec())?;
31+
T::Rbac::create_and_set_permissions(pallet_id.clone(), builder_role_id[0], ProxyPermission::builder_permissions())?;
3032

3133
// Investor rol & permissions
32-
let _investor_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::Investor.to_vec()].to_vec())?;
33-
//T::Rbac::create_and_set_permissions(pallet_id.clone(), investor_role_id[0], ProxyPermission::investor_permissions())?;
34+
let investor_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::Investor.to_vec()].to_vec())?;
35+
T::Rbac::create_and_set_permissions(pallet_id.clone(), investor_role_id[0], ProxyPermission::investor_permissions())?;
3436

3537
// Issuer rol & permissions
36-
let _issuer_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::Issuer.to_vec()].to_vec())?;
37-
//T::Rbac::create_and_set_permissions(pallet_id.clone(), issuer_role_id[0], ProxyPermission::issuer_permissions())?;
38+
let issuer_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::Issuer.to_vec()].to_vec())?;
39+
T::Rbac::create_and_set_permissions(pallet_id.clone(), issuer_role_id[0], ProxyPermission::issuer_permissions())?;
3840

3941
// Regional center rol & permissions
40-
let _regional_center_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::RegionalCenter.to_vec()].to_vec())?;
41-
//T::Rbac::create_and_set_permissions(pallet_id.clone(), regional_center_role_id[0], ProxyPermission::regional_center_permissions())?;
42-
43-
// Create a global scope for the administrator role
44-
T::Rbac::create_scope(Self::pallet_id(), global_scope)?;
42+
let regional_center_role_id = T::Rbac::create_and_set_roles(pallet_id.clone(), [ProxyRole::RegionalCenter.to_vec()].to_vec())?;
43+
T::Rbac::create_and_set_permissions(pallet_id.clone(), regional_center_role_id[0], ProxyPermission::regional_center_permissions())?;
4544

4645
Self::deposit_event(Event::ProxySetupCompleted);
4746
Ok(())
@@ -51,16 +50,7 @@ impl<T: Config> Pallet<T> {
5150
admin: T::AccountId,
5251
name: FieldName,
5352
) -> DispatchResult{
54-
let pallet_id = Self::pallet_id();
55-
let global_scope = <GlobalScope<T>>::try_get().map_err(|_| Error::<T>::GlobalScopeNotSet)?;
56-
57-
T::Rbac::assign_role_to_user(
58-
admin.clone(),
59-
pallet_id.clone(),
60-
&global_scope,
61-
ProxyRole::Administrator.id())?;
62-
63-
// create a administrator user account
53+
// create a administrator user account & register it in the rbac pallet
6454
Self::sudo_register_admin(admin.clone(), name)?;
6555

6656
Self::deposit_event(Event::AdministratorAssigned(admin));
@@ -70,16 +60,7 @@ impl<T: Config> Pallet<T> {
7060
pub fn do_sudo_remove_administrator(
7161
admin: T::AccountId,
7262
) -> DispatchResult{
73-
let pallet_id = Self::pallet_id();
74-
let global_scope = <GlobalScope<T>>::try_get().map_err(|_| Error::<T>::GlobalScopeNotSet)?;
75-
76-
T::Rbac::remove_role_from_user(
77-
admin.clone(),
78-
pallet_id.clone(),
79-
&global_scope,
80-
ProxyRole::Administrator.id())?;
81-
82-
// remove administrator user account
63+
// remove administrator user account & remove it from the rbac pallet
8364
Self::sudo_delete_admin(admin.clone())?;
8465

8566
Self::deposit_event(Event::AdministratorRemoved(admin));
@@ -118,7 +99,7 @@ impl<T: Config> Pallet<T> {
11899
), T::MaxRegistrationsAtTime>>,
119100
) -> DispatchResult {
120101
// Ensure admin permissions
121-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
102+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::CreateProject)?;
122103

123104
//Add timestamp
124105
let timestamp = Self::get_timestamp_in_milliseconds().ok_or(Error::<T>::TimestampError)?;
@@ -132,7 +113,7 @@ impl<T: Config> Pallet<T> {
132113

133114
//Create project data
134115
let project_data = ProjectData::<T> {
135-
developer: Some(BoundedVec::<T::AccountId, T::MaxDevelopersPerProject>::default()),
116+
builder: Some(BoundedVec::<T::AccountId, T::MaxBuildersPerProject>::default()),
136117
investor: Some(BoundedVec::<T::AccountId, T::MaxInvestorsPerProject>::default()),
137118
issuer: Some(BoundedVec::<T::AccountId, T::MaxIssuersPerProject>::default()),
138119
regional_center: Some(BoundedVec::<T::AccountId, T::MaxRegionalCenterPerProject>::default()),
@@ -183,8 +164,8 @@ impl<T: Config> Pallet<T> {
183164
creation_date: Option<u64>,
184165
completion_date: Option<u64>,
185166
) -> DispatchResult {
186-
//ensure admin permissions
187-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
167+
// Ensure admin permissions
168+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::EditProject)?;
188169

189170
//Ensure project exists
190171
ensure!(ProjectsInfo::<T>::contains_key(project_id), Error::<T>::ProjectNotFound);
@@ -241,8 +222,8 @@ impl<T: Config> Pallet<T> {
241222
admin: T::AccountId,
242223
project_id: [u8;32],
243224
) -> DispatchResult {
244-
//ensure admin permissions
245-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
225+
// Ensure admin permissions
226+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::DeleteProject)?;
246227

247228
//Ensure project exists & get project data
248229
let project_data = ProjectsInfo::<T>::get(project_id).ok_or(Error::<T>::ProjectNotFound)?;
@@ -283,8 +264,8 @@ impl<T: Config> Pallet<T> {
283264
AssignAction,
284265
), T::MaxRegistrationsAtTime>,
285266
) -> DispatchResult {
286-
//ensure admin permissions
287-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
267+
// Ensure admin permissions
268+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::AssignUser)?;
288269

289270
//Ensure project exists
290271
ensure!(ProjectsInfo::<T>::contains_key(project_id), Error::<T>::ProjectNotFound);
@@ -395,8 +376,8 @@ impl<T: Config> Pallet<T> {
395376
CUDAction, // 3:action
396377
), T::MaxRegistrationsAtTime>,
397378
) -> DispatchResult {
398-
//ensure admin permissions
399-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
379+
// Ensure admin permissions
380+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::RegisterUser)?;
400381

401382
for user in users{
402383
match user.3 {
@@ -591,8 +572,8 @@ impl<T: Config> Pallet<T> {
591572
Option<[u8;32]>, // 6: expenditure_id
592573
), T::MaxRegistrationsAtTime>,
593574
) -> DispatchResult {
594-
// Ensure admin permissions
595-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
575+
// Ensure admin permissions
576+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::Expenditures)?;
596577

597578
// Ensure project exists
598579
ensure!(<ProjectsInfo<T>>::contains_key(project_id), Error::<T>::ProjectNotFound);
@@ -769,7 +750,6 @@ impl<T: Config> Pallet<T> {
769750
// D R A W D O W N S
770751
// --------------------------------------------------------------------------------------------
771752
// For now drawdowns functions are private, but in the future they may be public
772-
773753
fn do_create_drawdown(
774754
project_id: [u8;32],
775755
drawdown_type: DrawdownType,
@@ -820,8 +800,8 @@ impl<T: Config> Pallet<T> {
820800
admin: T::AccountId,
821801
project_id: [u8;32],
822802
) -> DispatchResult {
823-
// Ensure admin permissions
824-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
803+
// Ensure admin permissions
804+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::Expenditures)?;
825805

826806
// Ensure project exists
827807
ensure!(ProjectsInfo::<T>::contains_key(project_id), Error::<T>::ProjectNotFound);
@@ -839,12 +819,9 @@ impl<T: Config> Pallet<T> {
839819
}
840820

841821
pub fn do_submit_drawdown(
842-
_user: T::AccountId, //TODO: remove underscore when user permissions are implemented
843822
project_id: [u8;32],
844823
drawdown_id: [u8;32],
845824
) -> DispatchResult {
846-
//TODO: Ensure builder & admin permissions
847-
848825
// Ensure project exists & is not completed
849826
Self::is_project_completed(project_id)?;
850827

@@ -891,9 +868,9 @@ impl<T: Config> Pallet<T> {
891868
project_id: [u8;32],
892869
drawdown_id: [u8;32],
893870
) -> DispatchResult {
894-
//ensure admin permissions
895-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
896-
871+
// Ensure admin permissions
872+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::Expenditures)?;
873+
897874
// Get drawdown data & ensure drawdown exists
898875
let drawdown_data = DrawdownsInfo::<T>::get(drawdown_id).ok_or(Error::<T>::DrawdownNotFound)?;
899876

@@ -949,8 +926,8 @@ impl<T: Config> Pallet<T> {
949926
transactions_feedback: Option<BoundedVec<([u8;32], FieldDescription), T::MaxRegistrationsAtTime>>,
950927
drawdown_feedback: Option<BoundedVec<FieldDescription, T::MaxBoundedVecs>>,
951928
) -> DispatchResult {
952-
//ensure admin permissions
953-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
929+
// Ensure admin permissions
930+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::Expenditures)?;
954931

955932
// Get drawdown data & ensure drawdown exists
956933
let drawdown_data = DrawdownsInfo::<T>::get(drawdown_id).ok_or(Error::<T>::DrawdownNotFound)?;
@@ -1029,7 +1006,6 @@ impl<T: Config> Pallet<T> {
10291006
// --------------------------------------------------------------------------------------------
10301007
// For now transactions functions are private, but in the future they may be public
10311008
pub fn do_execute_transactions(
1032-
_user: T::AccountId, //TODO: remove underscore when permissions are implemented
10331009
project_id: [u8;32],
10341010
drawdown_id: [u8;32],
10351011
transactions: BoundedVec<(
@@ -1040,8 +1016,6 @@ impl<T: Config> Pallet<T> {
10401016
Option<[u8;32]>, // transaction_id
10411017
), T::MaxRegistrationsAtTime>,
10421018
) -> DispatchResult {
1043-
// Check permissions here so helper private functions doesn't need to check it
1044-
// TODO: Ensure admin & builder permissions
10451019

10461020
// Ensure project exists & is not completed so helper private functions doesn't need to check it
10471021
Self::is_project_completed(project_id)?;
@@ -1220,14 +1194,15 @@ impl<T: Config> Pallet<T> {
12201194
// B U L K U P L O A D T R A N S A C T I O N S
12211195

12221196
pub fn do_up_bulk_upload(
1223-
_user: T::AccountId, //TODO: Remove underscore when permissions are implemented
1197+
user: T::AccountId, //TODO: Remove underscore when permissions are implemented
12241198
project_id: [u8;32],
12251199
drawdown_id: [u8;32],
12261200
description: FieldDescription,
12271201
total_amount: u64,
12281202
documents: Documents<T>,
12291203
) -> DispatchResult {
1230-
// TODO: Ensure builder permissions
1204+
// Ensure builder permissions
1205+
Self::is_authorized(user, &project_id, ProxyPermission::UpBulkupload)?;
12311206

12321207
// Ensure project is not completed
12331208
Self::is_project_completed(project_id)?;
@@ -1267,8 +1242,8 @@ impl<T: Config> Pallet<T> {
12671242
admin: T::AccountId,
12681243
projects: BoundedVec<([u8;32], Option<u32>, CUDAction), T::MaxRegistrationsAtTime>,
12691244
) -> DispatchResult {
1270-
// Ensure admin permissions
1271-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
1245+
// Ensure admin permissions
1246+
Self::is_authorized(admin.clone(), &Self::get_global_scope(), ProxyPermission::Expenditures)?;
12721247

12731248
// Ensure projects is not empty
12741249
ensure!(!projects.is_empty(), Error::<T>::ProjectsIsEmpty);
@@ -1374,21 +1349,21 @@ impl<T: Config> Pallet<T> {
13741349
ProxyRole::Administrator => {
13751350
return Err(Error::<T>::CannotRegisterAdminRole.into());
13761351
},
1377-
ProxyRole::Developer => {
1352+
ProxyRole::Builder => {
13781353
//TODO: Fix internal validations
13791354
//TODO: move logic to a helper function to avoid boilerplate
13801355

13811356
//Mutate project data
13821357
<ProjectsInfo<T>>::try_mutate::<_,_,DispatchError,_>(project_id, |project| {
13831358
let project = project.as_mut().ok_or(Error::<T>::ProjectNotFound)?;
1384-
match project.developer.as_mut() {
1385-
Some(developer) => {
1386-
//developer.iter().find(|&u| *u != user).ok_or(Error::<T>::UserAlreadyAssignedToProject)?;
1387-
developer.try_push(user.clone()).map_err(|_| Error::<T>::MaxDevelopersPerProjectReached)?;
1359+
match project.builder.as_mut() {
1360+
Some(builder) => {
1361+
//builder.iter().find(|&u| *u != user).ok_or(Error::<T>::UserAlreadyAssignedToProject)?;
1362+
builder.try_push(user.clone()).map_err(|_| Error::<T>::MaxBuildersPerProjectReached)?;
13881363
},
13891364
None => {
1390-
let devs = project.developer.get_or_insert(BoundedVec::<T::AccountId, T::MaxDevelopersPerProject>::default());
1391-
devs.try_push(user.clone()).map_err(|_| Error::<T>::MaxDevelopersPerProjectReached)?;
1365+
let devs = project.builder.get_or_insert(BoundedVec::<T::AccountId, T::MaxBuildersPerProject>::default());
1366+
devs.try_push(user.clone()).map_err(|_| Error::<T>::MaxBuildersPerProjectReached)?;
13921367
}
13931368
}
13941369
Ok(())
@@ -1460,16 +1435,16 @@ impl<T: Config> Pallet<T> {
14601435
ProxyRole::Administrator => {
14611436
return Err(Error::<T>::CannotRemoveAdminRole.into());
14621437
},
1463-
ProxyRole::Developer => {
1438+
ProxyRole::Builder => {
14641439
//TODO: Fix internal validations
14651440
//TODO: move logic to a helper function to avoid boilerplate
14661441
//Mutate project data
14671442
<ProjectsInfo<T>>::try_mutate::<_,_,DispatchError,_>(project_id, |project| {
14681443
let project = project.as_mut().ok_or(Error::<T>::ProjectNotFound)?;
1469-
match project.developer.as_mut() {
1470-
Some(developer) => {
1471-
//developer.clone().iter().find(|&u| *u == user).ok_or(Error::<T>::UserNotAssignedToProject)?;
1472-
developer.retain(|u| *u != user);
1444+
match project.builder.as_mut() {
1445+
Some(builder) => {
1446+
//builder.clone().iter().find(|&u| *u == user).ok_or(Error::<T>::UserNotAssignedToProject)?;
1447+
builder.retain(|u| *u != user);
14731448
},
14741449
None => {
14751450
return Err(Error::<T>::UserNotAssignedToProject.into());
@@ -1606,7 +1581,6 @@ impl<T: Config> Pallet<T> {
16061581
}
16071582
}
16081583

1609-
#[allow(dead_code)]
16101584
fn is_transaction_editable(
16111585
transaction_id: [u8;32],
16121586
) -> DispatchResult {
@@ -1625,9 +1599,8 @@ impl<T: Config> Pallet<T> {
16251599
}
16261600
}
16271601

1628-
//TODO: remove macro when used
1629-
#[allow(dead_code)]
1630-
fn is_authorized( authority: T::AccountId, project_id: &[u8;32], permission: ProxyPermission ) -> DispatchResult{
1602+
1603+
pub fn is_authorized( authority: T::AccountId, project_id: &[u8;32], permission: ProxyPermission ) -> DispatchResult{
16311604
T::Rbac::is_authorized(
16321605
authority,
16331606
Self::pallet_id(),
@@ -1636,6 +1609,7 @@ impl<T: Config> Pallet<T> {
16361609
)
16371610
}
16381611

1612+
#[allow(dead_code)]
16391613
fn is_superuser( authority: T::AccountId, scope_global: &[u8;32], rol_id: RoleId ) -> DispatchResult{
16401614
T::Rbac::has_role(
16411615
authority,
@@ -1666,6 +1640,15 @@ impl<T: Config> Pallet<T> {
16661640

16671641
//Insert user data
16681642
<UsersInfo<T>>::insert(admin.clone(), user_data);
1643+
1644+
// Add administrator to rbac pallet
1645+
T::Rbac::assign_role_to_user(
1646+
admin.clone(),
1647+
Self::pallet_id(),
1648+
&Self::get_global_scope(),
1649+
ProxyRole::Administrator.id()
1650+
)?;
1651+
16691652
Ok(())
16701653
}
16711654

@@ -1676,6 +1659,14 @@ impl<T: Config> Pallet<T> {
16761659
//Remove user from UsersInfo storage map
16771660
<UsersInfo<T>>::remove(admin.clone());
16781661

1662+
// Remove administrator to rbac pallet
1663+
T::Rbac::remove_role_from_user(
1664+
admin.clone(),
1665+
Self::pallet_id(),
1666+
&Self::get_global_scope(),
1667+
ProxyRole::Administrator.id()
1668+
)?;
1669+
16791670
Ok(())
16801671
}
16811672

0 commit comments

Comments
 (0)