Skip to content

Commit 7a8ec97

Browse files
committed
Modify flow for projects_assign_user extrinsic in order to accept an array of users to assign all of them at a time
1 parent ef74524 commit 7a8ec97

File tree

2 files changed

+67
-74
lines changed

2 files changed

+67
-74
lines changed

pallets/proxy/src/functions.rs

Lines changed: 63 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,8 @@ impl<T: Config> Pallet<T> {
309309

310310
pub fn do_assign_user(
311311
admin: T::AccountId,
312-
user: T::AccountId,
313312
project_id: [u8;32],
314-
role: ProxyRole,
313+
users: BoundedVec<(T::AccountId, ProxyRole), T::MaxResgistrationsAtTime>,
315314
) -> DispatchResult {
316315
//ensure admin permissions
317316
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
@@ -322,43 +321,38 @@ impl<T: Config> Pallet<T> {
322321
// Ensure project is not completed
323322
Self::is_project_completed(project_id)?;
324323

325-
//Ensure user is registered
326-
ensure!(<UsersInfo<T>>::contains_key(user.clone()), Error::<T>::UserNotRegistered);
324+
for user in users{
325+
// Basic validations prior to assign user
326+
Self::check_user_role(user.0.clone(), user.1)?;
327327

328-
//Ensure user is not already assigned to the project
329-
ensure!(!<UsersByProject<T>>::get(project_id).contains(&user.clone()), Error::<T>::UserAlreadyAssignedToProject);
330-
ensure!(!<ProjectsByUser<T>>::get(user.clone()).contains(&project_id), Error::<T>::UserAlreadyAssignedToProject);
328+
//Ensure user is not already assigned to the project
329+
ensure!(!<UsersByProject<T>>::get(project_id).contains(&user.0), Error::<T>::UserAlreadyAssignedToProject);
330+
ensure!(!<ProjectsByUser<T>>::get(user.0.clone()).contains(&project_id), Error::<T>::UserAlreadyAssignedToProject);
331331

332-
// Ensure user is not assigened to the selected scope (project_id) with the selected role
333-
ensure!(!T::Rbac::has_role(user.clone(), Self::pallet_id(), &project_id, [role.id()].to_vec()).is_ok(), Error::<T>::UserAlreadyHasRole);
332+
// Ensure user is not assigened to the selected scope (project_id) with the selected role
333+
ensure!(!T::Rbac::has_role(user.0.clone(), Self::pallet_id(), &project_id, [user.1.id()].to_vec()).is_ok(), Error::<T>::UserAlreadyAssignedToProject);
334334

335-
// Update project data depending on the role assigned
336-
Self::add_project_role(project_id, user.clone(), role)?;
335+
// Update project data depending on the role assigned
336+
Self::add_project_role(project_id, user.0.clone(), user.1)?;
337337

338-
339-
//HERE
340-
//Update user data depending on the role assigned
341-
//Self::add_user_role(user.clone(), role)?;
342-
343-
//TOREVIEW: this storage map will be removed?
344-
// Insert project to ProjectsByUser storagemap
345-
<ProjectsByUser<T>>::try_mutate::<_,_,DispatchError,_>(user.clone(), |projects| {
346-
projects.try_push(project_id).map_err(|_| Error::<T>::MaxProjectsPerUserReached)?;
347-
Ok(())
348-
})?;
338+
// Insert project to ProjectsByUser storagemap
339+
<ProjectsByUser<T>>::try_mutate::<_,_,DispatchError,_>(user.0.clone(), |projects| {
340+
projects.try_push(project_id).map_err(|_| Error::<T>::MaxProjectsPerUserReached)?;
341+
Ok(())
342+
})?;
349343

350-
//TOREVIEW: this storage map will be removed?
351-
// Insert user to UsersByProject storagemap
352-
<UsersByProject<T>>::try_mutate::<_,_,DispatchError,_>(project_id, |users| {
353-
users.try_push(user.clone()).map_err(|_| Error::<T>::MaxUsersPerProjectReached)?;
354-
Ok(())
355-
})?;
344+
// Insert user to UsersByProject storagemap
345+
<UsersByProject<T>>::try_mutate::<_,_,DispatchError,_>(project_id, |users| {
346+
users.try_push(user.0.clone()).map_err(|_| Error::<T>::MaxUsersPerProjectReached)?;
347+
Ok(())
348+
})?;
356349

357-
// Insert user into scope rbac pallet
358-
T::Rbac::assign_role_to_user(user.clone(), Self::pallet_id(), &project_id, role.id())?;
350+
// Insert user into scope rbac pallet
351+
T::Rbac::assign_role_to_user(user.0.clone(), Self::pallet_id(), &project_id, user.1.id())?;
352+
}
359353

360354
//Event
361-
Self::deposit_event(Event::UserAssignedToProject(user, project_id));
355+
Self::deposit_event(Event::UserAssignedToProject);
362356
Ok(())
363357
}
364358

@@ -499,6 +493,19 @@ impl<T: Config> Pallet<T> {
499493

500494
// B U D G E T E X P E N D I T U R E
501495
// --------------------------------------------------------------------------------------------
496+
/// Create a new budget expenditure
497+
///
498+
/// # Arguments
499+
///
500+
/// * `admin` - The admin user that creates the budget expenditure
501+
/// * `project_id` - The project id where the budget expenditure will be created
502+
///
503+
/// Then we add the budget expenditure data
504+
/// * `name` - The name of the budget expenditure
505+
/// * `type` - The type of the budget expenditure
506+
/// * `budget amount` - The amount of the budget expenditure
507+
/// * `naics code` - The naics code of the budget expenditure
508+
/// * `jobs_multiplier` - The jobs multiplier of the budget expenditure
502509
pub fn do_create_expenditure(
503510
admin: T::AccountId,
504511
project_id: [u8;32],
@@ -579,9 +586,8 @@ impl<T: Config> Pallet<T> {
579586
},
580587
None => {
581588
Self::do_create_budget(admin.clone(), expenditure_id, 0, project_id)?;
582-
},
583-
}
584-
589+
},
590+
}
585591
}
586592

587593
Self::deposit_event(Event::ExpenditureCreated);
@@ -1304,43 +1310,30 @@ impl<T: Config> Pallet<T> {
13041310
}
13051311

13061312

1307-
//HERE
1308-
// fn add_user_role(
1309-
// user: T::AccountId,
1310-
// role: ProxyRole,
1311-
// ) -> DispatchResult {
1312-
// // Get user account data
1313-
// let user_data = UsersInfo::<T>::get(user.clone()).ok_or(Error::<T>::UserNotRegistered)?;
1313+
/// This functions performs the following checks:
1314+
///
1315+
/// 1. Checks if the user is registered in the system
1316+
/// 2. Checks if the user has the required role from UsersInfo storage
1317+
/// 3. Checks if the user is trying to assign an admin role
1318+
fn check_user_role(
1319+
user: T::AccountId,
1320+
role: ProxyRole,
1321+
) -> DispatchResult {
1322+
// Ensure user is registered & get user data
1323+
let user_data = UsersInfo::<T>::get(user.clone()).ok_or(Error::<T>::UserNotRegistered)?;
13141324

1315-
// // Check if user already has a role
1316-
// match user_data.role {
1317-
// Some(user_role) => {
1318-
// //TODO: Ccheck what role is the user trying to add
1319-
// if user_role == role {
1320-
// return Ok(())
1321-
// } else {
1322-
// return Err(Error::<T>::UserCannotHaveMoreThanOneRole.into());
1323-
// }
1324-
// },
1325-
// None => {
1326-
// match role {
1327-
// ProxyRole::Administrator => {
1328-
// return Err(Error::<T>::CannotAddAdminRole.into());
1329-
// },
1330-
// _ => {
1331-
// // Update user data
1332-
// <UsersInfo<T>>::try_mutate::<_,_,DispatchError,_>(user.clone(), |user_data| {
1333-
// let user_data = user_data.as_mut().ok_or(Error::<T>::UserNotRegistered)?;
1334-
// user_data.role = Some(role);
1335-
// Ok(())
1336-
// })?;
1337-
// //TOREVIEW: Remove ? operator and final Ok(())
1338-
// Ok(())
1339-
// },
1340-
// }
1341-
// }
1342-
// }
1343-
// }
1325+
// Check if the user role trying to be assigned matchs the actual user role from UsersInfo storage
1326+
if user_data.role != role {
1327+
return Err(Error::<T>::UserCannotHaveMoreThanOneRole.into());
1328+
}
1329+
1330+
// Can't assign an admin to a project, admins exists globally
1331+
if role == ProxyRole::Administrator {
1332+
return Err(Error::<T>::CannotAddAdminRole.into());
1333+
}
1334+
1335+
Ok(())
1336+
}
13441337

13451338

13461339
//HERE

pallets/proxy/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ pub mod pallet {
297297
/// Administator removed
298298
AdministratorRemoved(T::AccountId),
299299
/// User assigned to project
300-
UserAssignedToProject(T::AccountId, [u8;32]),
300+
UserAssignedToProject,
301301
/// User removed from project
302302
UserUnassignedFromProject(T::AccountId, [u8;32]),
303303
/// User info updated
@@ -560,17 +560,17 @@ pub mod pallet {
560560
Self::do_delete_project(who, project_id)
561561
}
562562

563+
// Users: (user, role)
563564
#[transactional]
564565
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
565566
pub fn projects_assign_user(
566567
origin: OriginFor<T>,
567-
user: T::AccountId,
568568
project_id: [u8;32],
569-
role: ProxyRole,
569+
users: BoundedVec<(T::AccountId, ProxyRole), T::MaxResgistrationsAtTime>,
570570
) -> DispatchResult {
571571
let who = ensure_signed(origin)?; // origin need to be an admin
572572

573-
Self::do_assign_user(who, user, project_id, role)
573+
Self::do_assign_user(who, project_id, users)
574574
}
575575

576576
#[transactional]

0 commit comments

Comments
 (0)