Merge branch 'main' into 15397-remove-obsolete-apis
[arvados.git] / services / api / lib / current_api_client.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 module CurrentApiClient
6   def current_user
7     Thread.current[:user]
8   end
9
10   def current_api_client
11     Thread.current[:api_client]
12   end
13
14   def current_api_client_authorization
15     Thread.current[:api_client_authorization]
16   end
17
18   def current_api_base
19     Thread.current[:api_url_base]
20   end
21
22   # Where is the client connecting from?
23   def current_api_client_ip_address
24     Thread.current[:api_client_ip_address]
25   end
26
27   def system_user_uuid
28     [Rails.configuration.ClusterID,
29      User.uuid_prefix,
30      '000000000000000'].join('-')
31   end
32
33   def system_group_uuid
34     [Rails.configuration.ClusterID,
35      Group.uuid_prefix,
36      '000000000000000'].join('-')
37   end
38
39   def anonymous_group_uuid
40     [Rails.configuration.ClusterID,
41      Group.uuid_prefix,
42      'anonymouspublic'].join('-')
43   end
44
45   def anonymous_user_uuid
46     [Rails.configuration.ClusterID,
47      User.uuid_prefix,
48      'anonymouspublic'].join('-')
49   end
50
51   def public_project_uuid
52     [Rails.configuration.ClusterID,
53      Group.uuid_prefix,
54      'publicfavorites'].join('-')
55   end
56
57   def system_user
58     real_current_user = Thread.current[:user]
59     begin
60       Thread.current[:user] = User.new(is_admin: true,
61                                        is_active: true,
62                                        uuid: system_user_uuid)
63       $system_user = check_cache($system_user) do
64         User.where(uuid: system_user_uuid).
65           first_or_create!(is_active: true,
66                            is_admin: true,
67                            email: 'root',
68                            first_name: 'root',
69                            last_name: '')
70       end
71     ensure
72       Thread.current[:user] = real_current_user
73     end
74   end
75
76   def system_group
77     $system_group = check_cache($system_group) do
78       act_as_system_user do
79         ActiveRecord::Base.transaction do
80           Group.where(uuid: system_group_uuid).
81             first_or_create!(name: "System group",
82                              description: "System group",
83                              group_class: "role") do |g|
84             g.save!
85             User.all.collect(&:uuid).each do |user_uuid|
86               Link.create!(link_class: 'permission',
87                            name: 'can_manage',
88                            tail_uuid: system_group_uuid,
89                            head_uuid: user_uuid)
90             end
91           end
92         end
93       end
94     end
95   end
96
97   def all_users_group_uuid
98     [Rails.configuration.ClusterID,
99      Group.uuid_prefix,
100      'fffffffffffffff'].join('-')
101   end
102
103   def all_users_group
104     $all_users_group = check_cache($all_users_group) do
105       act_as_system_user do
106         ActiveRecord::Base.transaction do
107           Group.where(uuid: all_users_group_uuid).
108             first_or_create!(name: "All users",
109                              description: "All users",
110                              group_class: "role")
111         end
112       end
113     end
114   end
115
116   def act_as_system_user
117     if block_given?
118       act_as_user system_user do
119         yield
120       end
121     else
122       Thread.current[:user] = system_user
123     end
124   end
125
126   def act_as_user user
127     user_was = Thread.current[:user]
128     Thread.current[:user] = user
129     begin
130       yield
131     ensure
132       Thread.current[:user] = user_was
133       if user_was
134         user_was.forget_cached_group_perms
135       end
136     end
137   end
138
139   def anonymous_group
140     $anonymous_group = check_cache($anonymous_group) do
141       act_as_system_user do
142         ActiveRecord::Base.transaction do
143           Group.where(uuid: anonymous_group_uuid).
144             first_or_create!(group_class: "role",
145                              name: "Anonymous users",
146                              description: "Anonymous users")
147         end
148       end
149     end
150   end
151
152   def anonymous_group_read_permission
153     $anonymous_group_read_permission = check_cache($anonymous_group_read_permission) do
154       act_as_system_user do
155         Link.where(tail_uuid: all_users_group.uuid,
156                    head_uuid: anonymous_group.uuid,
157                    link_class: "permission",
158                    name: "can_read").first_or_create!
159       end
160     end
161   end
162
163   def anonymous_user
164     $anonymous_user = check_cache($anonymous_user) do
165       act_as_system_user do
166         User.where(uuid: anonymous_user_uuid).
167           first_or_create!(is_active: false,
168                            is_admin: false,
169                            email: 'anonymous',
170                            first_name: 'Anonymous',
171                            last_name: '') do |u|
172           u.save!
173           Link.where(tail_uuid: anonymous_user_uuid,
174                      head_uuid: anonymous_group.uuid,
175                      link_class: 'permission',
176                      name: 'can_read').
177             first_or_create!
178         end
179       end
180     end
181   end
182
183   def public_project_group
184     $public_project_group = check_cache($public_project_group) do
185       act_as_system_user do
186         ActiveRecord::Base.transaction do
187           Group.where(uuid: public_project_uuid).
188             first_or_create!(group_class: "project",
189                              name: "Public favorites",
190                              description: "Public favorites")
191         end
192       end
193     end
194   end
195
196   def public_project_read_permission
197     $public_project_group_read_permission = check_cache($public_project_group_read_permission) do
198       act_as_system_user do
199         Link.where(tail_uuid: anonymous_group.uuid,
200                    head_uuid: public_project_group.uuid,
201                    link_class: "permission",
202                    name: "can_read").first_or_create!
203       end
204     end
205   end
206
207   def anonymous_user_token_api_client
208     $anonymous_user_token_api_client = check_cache($anonymous_user_token_api_client) do
209       act_as_system_user do
210         ActiveRecord::Base.transaction do
211           ApiClient.find_or_create_by!(is_trusted: false, url_prefix: "", name: "AnonymousUserToken")
212         end
213       end
214     end
215   end
216
217   def system_root_token_api_client
218     $system_root_token_api_client = check_cache($system_root_token_api_client) do
219       act_as_system_user do
220         ActiveRecord::Base.transaction do
221           ApiClient.find_or_create_by!(is_trusted: true, url_prefix: "", name: "SystemRootToken")
222         end
223       end
224     end
225   end
226
227   def empty_collection_pdh
228     'd41d8cd98f00b204e9800998ecf8427e+0'
229   end
230
231   def empty_collection
232     $empty_collection = check_cache($empty_collection) do
233       act_as_system_user do
234         ActiveRecord::Base.transaction do
235           Collection.
236             where(portable_data_hash: empty_collection_pdh).
237             first_or_create(manifest_text: '', owner_uuid: system_user.uuid, name: "empty collection") do |c|
238             c.save!
239             Link.where(tail_uuid: anonymous_group.uuid,
240                        head_uuid: c.uuid,
241                        link_class: 'permission',
242                        name: 'can_read').
243                   first_or_create!
244             c
245           end
246         end
247       end
248     end
249   end
250
251   # Purge the module globals if necessary. If the cached value is
252   # non-nil and the globals weren't purged, return the cached
253   # value. Otherwise, call the block.
254   #
255   # Purge is only done in test mode.
256   def check_cache(cached)
257     if Rails.env != 'test'
258       return (cached || yield)
259     end
260     t = Rails.cache.fetch "CurrentApiClient.$system_globals_reset" do
261       Time.now.to_f
262     end
263     if t != $system_globals_reset
264       reset_system_globals(t)
265       yield
266     else
267       cached || yield
268     end
269   end
270
271   def reset_system_globals(t)
272     $system_globals_reset = t
273     $system_user = nil
274     $system_group = nil
275     $all_users_group = nil
276     $anonymous_group = nil
277     $anonymous_group_read_permission = nil
278     $anonymous_user = nil
279     $public_project_group = nil
280     $public_project_group_read_permission = nil
281     $anonymous_user_token_api_client = nil
282     $system_root_token_api_client = nil
283     $empty_collection = nil
284   end
285   module_function :reset_system_globals
286 end
287
288 CurrentApiClient.reset_system_globals(0)