@@ -58,56 +58,72 @@ defmodule EpochtalkServer.Models.RolePermission do
5858 def insert ( [ % { } | _ ] = roles_permissions ) ,
5959 do: Repo . insert_all ( RolePermission , roles_permissions )
6060
61- ## for admin api use, modifying permissions for a role
61+ @ doc """
62+ For admin api use.
63+
64+ Updates the `modified` value of `RolePermission`s for a `Role`
65+ and updates the `Role`'s permissions and priority restrictions
66+
67+ If a permission is not included in `new_permissions`, it will be set to
68+ `false`. `new_permissions` may be an empty list - in which case, all
69+ permissions will be set to `false`.
70+
71+ Any permissions in `new_permissions` which are not valid will be ignored.
72+ """
73+ @ spec modify_by_role ( role :: Role . t ( ) ) :: { :ok , :success }
6274 def modify_by_role (
6375 % Role {
6476 id: role_id ,
6577 permissions: new_permissions ,
6678 priority_restrictions: priority_restrictions
6779 } = _new_role
6880 ) do
69- # if a permission is false, they're not included in the permissions
70- # if they're all false, permissions can be empty
71- old_role_permissions =
72- from ( rp in RolePermission ,
73- where: rp . role_id == ^ role_id
74- )
75- |> Repo . all ( )
76-
77- new_permissions = new_permissions |> Iteraptor . to_flatmap ( )
78-
79- # change a permission if it's different
80- new_role_permissions =
81- Enum . reduce ( old_role_permissions , [ ] , fn % {
82- permission_path: permission_path ,
83- value: old_value
84- } = _old_role_permission ,
85- acc ->
86- # check new value for permission_path
87- # if value is not there, set it to false
88- new_value = new_permissions [ permission_path ] || false
89- # if new value is different
90- new_role_permission =
91- if old_value != new_value do
92- # set modified true
93- % { role_id: role_id , permission_path: permission_path , modified: true }
94- # if new value is same, set modified false
95- else
96- % { role_id: role_id , permission_path: permission_path , modified: false }
97- end
98-
99- [ new_role_permission | acc ]
100- end )
101-
102- # update role permissions for this role
103- upsert_modified ( new_role_permissions )
104-
105- # update role's permissions
106- permissions = RolePermission . permissions_map_by_role_id ( role_id )
107- Role . set_permissions ( role_id , permissions )
108-
109- # update role's priority_restrictions
110- Role . set_priority_restrictions ( role_id , priority_restrictions )
81+ if is_map ( new_permissions ) do
82+ # get current set of role permissions
83+ current_role_permissions =
84+ from ( rp in RolePermission ,
85+ where: rp . role_id == ^ role_id
86+ )
87+ |> Repo . all ( )
88+
89+ # flat map the new permissions into permissions paths
90+ new_permissions_paths = new_permissions |> Iteraptor . to_flatmap ( )
91+
92+ # calculate updated role permissions based on default values
93+ new_role_permissions =
94+ Enum . reduce ( current_role_permissions , [ ] , fn % {
95+ permission_path: permission_path ,
96+ value: default_value
97+ } = _current_role_permission ,
98+ acc ->
99+ # get new value for permission_path if it exists
100+ # otherwise, set it to false
101+ new_value = new_permissions_paths [ permission_path ] || false
102+
103+ new_role_permission =
104+ if default_value != new_value do
105+ # if new value is different from default value, set modified true
106+ % { role_id: role_id , permission_path: permission_path , modified: true }
107+ else
108+ # if new value is same as default value, set modified false
109+ % { role_id: role_id , permission_path: permission_path , modified: false }
110+ end
111+
112+ [ new_role_permission | acc ]
113+ end )
114+
115+ # update role permissions for this role
116+ upsert_modified ( new_role_permissions )
117+
118+ # update role's permissions
119+ permissions = RolePermission . permissions_map_by_role_id ( role_id )
120+ Role . set_permissions ( role_id , permissions )
121+ end
122+
123+ if is_list ( priority_restrictions ) do
124+ # update role's priority_restrictions
125+ Role . set_priority_restrictions ( role_id , priority_restrictions )
126+ end
111127
112128 # return success
113129 { :ok , :success }
0 commit comments