#
# SPDX-License-Identifier: AGPL-3.0
+include CurrentApiClient
+
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 %{
+ 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
+ q = ActiveRecord::Base.connection.exec_query %{
select uuid from groups limit 1
}
- # 1) any group not group_class != project becomes a 'role' (both empty and invalid groups)
- ActiveRecord::Base.connection.exec_query %{
+ # 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
}
- Group.where(group_class: "role").each do |g|
- if g.owner_uuid != system_user_uuid
+ Group.where("group_class='role' and owner_uuid != '#{system_user_uuid}'").each do |g|
# 2) Ownership of a role becomes a can_manage link
Link.create!(link_class: 'permission',
name: 'can_manage',
g.save_with_unique_name!
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|
+ # 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.create!(link_class: 'permission',
name: 'can_manage',
- tail_uuid: g.uuid,
+ tail_uuid: owned.owner_uuid,
head_uuid: owned.uuid)
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.create!(link_class: 'permission',
+ name: 'can_manage',
+ tail_uuid: owned.owner_uuid,
+ head_uuid: owned.uuid)
+ 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, '#{ln.name}' link from #{ln.tail_uuid} to #{ln.head_uuid} will be removed"
+ Rails.logger.warn "Projects cannot have outgoing permission links, '#{ln.name}' link from #{ln.tail_uuid} to #{ln.head_uuid} will be removed"
+ ln.destroy!
+ end
end
end
end
CAN_MANAGE_PERM = 3
def update_permissions perm_origin_uuid, starting_uuid, perm_level, edge_id=nil
+ return if Thread.current[:suppress_update_permissions]
+
#
# Update a subset of the permission table affected by adding or
# removing a particular permission relationship (ownership or a
def check_permissions_against_full_refresh
# No-op except when running tests
- return unless Rails.env == 'test' and !Thread.current[:no_check_permissions_against_full_refresh]
+ return unless Rails.env == 'test' and !Thread.current[:no_check_permissions_against_full_refresh] and !Thread.current[:suppress_update_permissions]
# For checking correctness of the incremental permission updates.
# Check contents of the current 'materialized_permission' table
end
end
+def batch_update_permissions
+ check_perm_was = Thread.current[:suppress_update_permissions]
+ Thread.current[:suppress_update_permissions] = true
+ begin
+ yield
+ ensure
+ Thread.current[:suppress_update_permissions] = check_perm_was
+ refresh_permissions
+ end
+end
+
# Used to account for permissions that a user gains by having
# can_manage on another user.
#