Merge pull request #5194 from artoscinote/ma_SCI_8131

Prevent removing/changing role for last user with user manage permission on protocol [SCI-8131]
This commit is contained in:
Alex Kriuchykhin 2023-03-24 13:58:57 +01:00 committed by GitHub
commit 678d51692e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 2 deletions

View file

@ -37,6 +37,14 @@ module AccessPermissions
user_id: permitted_update_params[:user_id],
team: current_team
)
# prevent role change if it would result in no users having the user management permission
new_user_role = UserRole.find(permitted_update_params[:user_role_id])
if !new_user_role.has_permission?(ProjectPermissions::USERS_MANAGE) &&
@user_assignment.last_with_permission?(ProjectPermissions::USERS_MANAGE)
raise ActiveRecord::RecordInvalid
end
@user_assignment.update!(permitted_update_params)
log_activity(:change_user_role_on_project, @user_assignment)
@ -103,6 +111,9 @@ module AccessPermissions
user = @project.assigned_users.find(params[:user_id])
user_assignment = @project.user_assignments.find_by(user: user, team: current_team)
# prevent deletion of last user that can manage users
raise ActiveRecord::RecordInvalid if user_assignment.last_with_permission?(ProjectPermissions::USERS_MANAGE)
if @project.visible?
user_assignment.update!(
user_role: @project.default_public_user_role,

View file

@ -35,6 +35,14 @@ module AccessPermissions
user_id: permitted_update_params[:user_id],
team: current_team
)
# prevent role change if it would result in no users having the user management permission
new_user_role = UserRole.find(permitted_update_params[:user_role_id])
if !new_user_role.has_permission?(ProtocolPermissions::USERS_MANAGE) &&
@user_assignment.last_with_permission?(ProtocolPermissions::USERS_MANAGE)
raise ActiveRecord::RecordInvalid
end
@user_assignment.update!(permitted_update_params)
log_activity(:protocol_template_access_changed, @user_assignment)
@ -88,6 +96,9 @@ module AccessPermissions
user = @protocol.assigned_users.find(params[:user_id])
user_assignment = @protocol.user_assignments.find_by(user: user, team: current_team)
# prevent deletion of last user that can manage users
raise ActiveRecord::RecordInvalid if user_assignment.last_with_permission?(ProtocolPermissions::USERS_MANAGE)
Protocol.transaction do
if @protocol.visible?
user_assignment.update!(

View file

@ -24,6 +24,15 @@ class UserAssignment < ApplicationRecord
assignable_owners.count == 1 && user_role.owner?
end
def last_with_permission?(permission)
return false if user_role.permissions.exclude?(permission)
assignable.user_assignments.joins(:user_role)
.where.not(user: user)
.where('? = ANY(user_roles.permissions)', permission)
.none?
end
private
def call_user_assignment_changed_hook

View file

@ -61,6 +61,10 @@ class UserRole < ApplicationRecord
predefined.find_by(name: UserRole.public_send('viewer_role').name)
end
def has_permission?(permission)
permissions.include?(permission)
end
def owner?
predefined? && name == I18n.t('user_roles.predefined.owner')
end

View file

@ -101,8 +101,7 @@ Canaid::Permissions.register_for(Protocol) do
end
can :manage_protocol_users do |user, protocol|
protocol.permission_granted?(user, ProtocolPermissions::USERS_MANAGE) ||
protocol.team.permission_granted?(user, TeamPermissions::MANAGE)
protocol.permission_granted?(user, ProtocolPermissions::USERS_MANAGE)
end
# protocol in repository: restore