Fix 2.4.2 upgrade notes formatting refs #19330
[arvados.git] / services / api / app / controllers / sys_controller.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 class SysController < ApplicationController
6   skip_before_action :find_object_by_uuid
7   skip_before_action :render_404_if_no_object
8   before_action :admin_required
9
10   def trash_sweep
11     act_as_system_user do
12       # Sweep trashed collections
13       Collection.
14         where('delete_at is not null and delete_at < statement_timestamp()').
15         destroy_all
16       Collection.
17         where('is_trashed = false and trash_at < statement_timestamp()').
18         update_all('is_trashed = true')
19
20       # Sweep trashed projects and their contents (as well as role
21       # groups that were trashed before #18340 when that was
22       # disallowed)
23       Group.
24         where('delete_at is not null and delete_at < statement_timestamp()').each do |project|
25           delete_project_and_contents(project.uuid)
26       end
27       Group.
28         where('is_trashed = false and trash_at < statement_timestamp()').
29         update_all('is_trashed = true')
30
31       # Sweep expired tokens
32       ActiveRecord::Base.connection.execute("DELETE from api_client_authorizations where expires_at <= statement_timestamp()")
33     end
34     head :no_content
35   end
36
37   protected
38
39   def delete_project_and_contents(p_uuid)
40     p = Group.find_by_uuid(p_uuid)
41     if !p
42       raise "can't sweep group '#{p_uuid}', it may not exist"
43     end
44     # First delete sub projects
45     Group.where({group_class: 'project', owner_uuid: p_uuid}).each do |sub_project|
46       delete_project_and_contents(sub_project.uuid)
47     end
48     # Next, iterate over all tables which have owner_uuid fields, with some
49     # exceptions, and delete records owned by this project
50     skipped_classes = ['Group', 'User']
51     ActiveRecord::Base.descendants.reject(&:abstract_class?).each do |klass|
52       if !skipped_classes.include?(klass.name) && klass.columns.collect(&:name).include?('owner_uuid')
53         klass.where({owner_uuid: p_uuid}).destroy_all
54       end
55     end
56     # Finally delete the project itself
57     p.destroy
58   end
59 end