18874: Merge branch 'main' into 18874-merge-wb2
[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         in_batches(of: 15).
16         destroy_all
17       Collection.
18         where('is_trashed = false and trash_at < statement_timestamp()').
19         in_batches(of: 15).
20         update_all('is_trashed = true')
21
22       # Sweep trashed projects and their contents (as well as role
23       # groups that were trashed before #18340 when that was
24       # disallowed)
25       Group.
26         where('delete_at is not null and delete_at < statement_timestamp()').each do |project|
27           delete_project_and_contents(project.uuid)
28       end
29       Group.
30         where('is_trashed = false and trash_at < statement_timestamp()').
31         update_all('is_trashed = true')
32
33       # Sweep expired tokens
34       ActiveRecord::Base.connection.execute("DELETE from api_client_authorizations where expires_at <= statement_timestamp()")
35     end
36     head :no_content
37   end
38
39   protected
40
41   def delete_project_and_contents(p_uuid)
42     p = Group.find_by_uuid(p_uuid)
43     if !p
44       raise "can't sweep group '#{p_uuid}', it may not exist"
45     end
46     # First delete sub projects
47     Group.where({group_class: 'project', owner_uuid: p_uuid}).each do |sub_project|
48       delete_project_and_contents(sub_project.uuid)
49     end
50     # Next, iterate over all tables which have owner_uuid fields, with some
51     # exceptions, and delete records owned by this project
52     skipped_classes = ['Group', 'User']
53     ActiveRecord::Base.descendants.reject(&:abstract_class?).each do |klass|
54       if !skipped_classes.include?(klass.name) && klass.columns.collect(&:name).include?('owner_uuid')
55         klass.where({owner_uuid: p_uuid}).in_batches(of: 15).destroy_all
56       end
57     end
58     # Finally delete the project itself
59     p.destroy
60   end
61 end