X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/27f3423ab974547d8ff666e7d9f9af7aec933765..ddff0f5816f8100154c9ae0a95147b2061097da3:/services/api/lib/fix_roles_projects.rb diff --git a/services/api/lib/fix_roles_projects.rb b/services/api/lib/fix_roles_projects.rb index dafef61aa9..79fea45901 100644 --- a/services/api/lib/fix_roles_projects.rb +++ b/services/api/lib/fix_roles_projects.rb @@ -2,61 +2,76 @@ # # SPDX-License-Identifier: AGPL-3.0 -def fix_roles_projects - # This migration is not reversible. However, the behavior it - # enforces is backwards-compatible, and most of the time there - # shouldn't be anything to do at all. - act_as_system_user do - ActiveRecord::Base.transaction do - q = ActiveRecord::Base.connection.exec_query %{ -select uuid from groups limit 1 -} +require 'update_permissions' - # 1) any group not group_class != project becomes a 'role' (both empty and invalid groups) - ActiveRecord::Base.connection.exec_query %{ -UPDATE groups set group_class='role' where group_class != 'project' or group_class is null - } +include CurrentApiClient - Group.where(group_class: "role").each do |g| - if g.owner_uuid != system_user_uuid - # 2) Ownership of a role becomes a can_manage link - Link.create!(link_class: 'permission', - name: 'can_manage', - tail_uuid: g.owner_uuid, - head_uuid: g.uuid) +def fix_roles_projects + batch_update_permissions do + # This migration is not reversible. However, the behavior it + # enforces is backwards-compatible, and most of the time there + # shouldn't be anything to do at all. + act_as_system_user do + ActiveRecord::Base.transaction do + Group.where("(group_class != 'project' and group_class != 'filter') or group_class is null").each do |g| + # 1) any group not group_class != project and != filter becomes a 'role' (both empty and invalid groups) + old_owner = g.owner_uuid g.owner_uuid = system_user_uuid + g.group_class = 'role' g.save_with_unique_name! + + if old_owner != system_user_uuid + # 2) Ownership of a role becomes a can_manage link + Link.new(link_class: 'permission', + name: 'can_manage', + tail_uuid: old_owner, + head_uuid: g.uuid). + save!(validate: false) + end end - # 3) If a role owns anything, give it to system user and it - # becomes a can_manage link ActiveRecord::Base.descendants.reject(&:abstract_class?).each do |klass| next if [ApiClientAuthorization, AuthorizedKey, - Log].include?(klass) + Log, + Group].include?(klass) next if !klass.columns.collect(&:name).include?('owner_uuid') - klass.where(owner_uuid: g.uuid).each do |owned| - Link.create!(link_class: 'permission', - name: 'can_manage', - tail_uuid: g.uuid, - head_uuid: owned.uuid) + # 3) If a role owns anything, give it to system user and it + # becomes a can_manage link + klass.joins("join groups on groups.uuid=#{klass.table_name}.owner_uuid and groups.group_class='role'").each do |owned| + Link.new(link_class: 'permission', + name: 'can_manage', + tail_uuid: owned.owner_uuid, + head_uuid: owned.uuid). + save!(validate: false) owned.owner_uuid = system_user_uuid owned.save_with_unique_name! end end - end - # 4) Projects can't have outgoing permission links. Just delete them. - q = ActiveRecord::Base.connection.exec_query %{ + Group.joins("join groups as g2 on g2.uuid=groups.owner_uuid and g2.group_class='role'").each do |owned| + Link.new(link_class: 'permission', + name: 'can_manage', + tail_uuid: owned.owner_uuid, + head_uuid: owned.uuid). + save!(validate: false) + owned.owner_uuid = system_user_uuid + owned.save_with_unique_name! + end + + # 4) Projects can't have outgoing permission links. Just + # print a warning and delete them. + q = ActiveRecord::Base.connection.exec_query %{ select links.uuid from links, groups where groups.uuid = links.tail_uuid and links.link_class = 'permission' and groups.group_class = 'project' } - q.each do |lu| - ln = Link.find_by_uuid(lu['uuid']) - puts "Projects cannot have outgoing permission links, '#{ln.name}' link from #{ln.tail_uuid} to #{ln.head_uuid} will be removed" - Rails.logger.warn "Destroying invalid permission link from project #{ln.tail_uuid} to #{ln.head_uuid}" - ln.destroy! + q.each do |lu| + ln = Link.find_by_uuid(lu['uuid']) + puts "WARNING: Projects cannot have outgoing permission links, removing '#{ln.name}' link #{ln.uuid} from #{ln.tail_uuid} to #{ln.head_uuid}" + Rails.logger.warn "Projects cannot have outgoing permission links, removing '#{ln.name}' link #{ln.uuid} from #{ln.tail_uuid} to #{ln.head_uuid}" + ln.destroy! + end end end end