dc40f158eeaef6fb4fb21cc7d3d8dad04c28f917
[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 $system_user = nil
6 $system_group = nil
7 $all_users_group = nil
8 $anonymous_user = nil
9 $anonymous_group = nil
10 $anonymous_group_read_permission = nil
11 $empty_collection = nil
12 $public_project_group = nil
13 $public_project_group_read_permission = nil
14
15 module CurrentApiClient
16   def current_user
17     Thread.current[:user]
18   end
19
20   def current_api_client
21     Thread.current[:api_client]
22   end
23
24   def current_api_client_authorization
25     Thread.current[:api_client_authorization]
26   end
27
28   def current_api_base
29     Thread.current[:api_url_base]
30   end
31
32   def current_default_owner
33     # owner_uuid for newly created objects
34     ((current_api_client_authorization &&
35       current_api_client_authorization.default_owner_uuid) ||
36      (current_user && current_user.default_owner_uuid) ||
37      (current_user && current_user.uuid) ||
38      nil)
39   end
40
41   # Where is the client connecting from?
42   def current_api_client_ip_address
43     Thread.current[:api_client_ip_address]
44   end
45
46   def system_user_uuid
47     [Rails.configuration.ClusterID,
48      User.uuid_prefix,
49      '000000000000000'].join('-')
50   end
51
52   def system_group_uuid
53     [Rails.configuration.ClusterID,
54      Group.uuid_prefix,
55      '000000000000000'].join('-')
56   end
57
58   def anonymous_group_uuid
59     [Rails.configuration.ClusterID,
60      Group.uuid_prefix,
61      'anonymouspublic'].join('-')
62   end
63
64   def anonymous_user_uuid
65     [Rails.configuration.ClusterID,
66      User.uuid_prefix,
67      'anonymouspublic'].join('-')
68   end
69
70   def public_project_uuid
71     [Rails.configuration.ClusterID,
72      Group.uuid_prefix,
73      'publicfavorites'].join('-')
74   end
75
76   def system_user
77     $system_user = check_cache $system_user do
78       real_current_user = Thread.current[:user]
79       begin
80         Thread.current[:user] = User.new(is_admin: true,
81                                          is_active: true,
82                                          uuid: system_user_uuid)
83         User.where(uuid: system_user_uuid).
84           first_or_create!(is_active: true,
85                            is_admin: true,
86                            email: 'root',
87                            first_name: 'root',
88                            last_name: '')
89       ensure
90         Thread.current[:user] = real_current_user
91       end
92     end
93   end
94
95   def system_group
96     $system_group = check_cache $system_group do
97       act_as_system_user do
98         ActiveRecord::Base.transaction do
99           Group.where(uuid: system_group_uuid).
100             first_or_create!(name: "System group",
101                              description: "System group",
102                              group_class: "role") do |g|
103             g.save!
104             User.all.collect(&:uuid).each do |user_uuid|
105               Link.create!(link_class: 'permission',
106                            name: 'can_manage',
107                            tail_uuid: system_group_uuid,
108                            head_uuid: user_uuid)
109             end
110           end
111         end
112       end
113     end
114   end
115
116   def all_users_group_uuid
117     [Rails.configuration.ClusterID,
118      Group.uuid_prefix,
119      'fffffffffffffff'].join('-')
120   end
121
122   def all_users_group
123     $all_users_group = check_cache $all_users_group do
124       act_as_system_user do
125         ActiveRecord::Base.transaction do
126           Group.where(uuid: all_users_group_uuid).
127             first_or_create!(name: "All users",
128                              description: "All users",
129                              group_class: "role")
130         end
131       end
132     end
133   end
134
135   def act_as_system_user
136     if block_given?
137       act_as_user system_user do
138         yield
139       end
140     else
141       Thread.current[:user] = system_user
142     end
143   end
144
145   def act_as_user user
146     user_was = Thread.current[:user]
147     Thread.current[:user] = user
148     begin
149       yield
150     ensure
151       Thread.current[:user] = user_was
152     end
153   end
154
155   def anonymous_group
156     $anonymous_group = check_cache $anonymous_group do
157       act_as_system_user do
158         ActiveRecord::Base.transaction do
159           Group.where(uuid: anonymous_group_uuid).
160             first_or_create!(group_class: "role",
161                              name: "Anonymous users",
162                              description: "Anonymous users")
163         end
164       end
165     end
166   end
167
168   def anonymous_group_read_permission
169     $anonymous_group_read_permission =
170         check_cache $anonymous_group_read_permission do
171       act_as_system_user do
172         Link.where(tail_uuid: all_users_group.uuid,
173                    head_uuid: anonymous_group.uuid,
174                    link_class: "permission",
175                    name: "can_read").first_or_create!
176       end
177     end
178   end
179
180   def anonymous_user
181     $anonymous_user = check_cache $anonymous_user do
182       act_as_system_user do
183         User.where(uuid: anonymous_user_uuid).
184           first_or_create!(is_active: false,
185                            is_admin: false,
186                            email: 'anonymous',
187                            first_name: 'Anonymous',
188                            last_name: '') do |u|
189           u.save!
190           Link.where(tail_uuid: anonymous_user_uuid,
191                      head_uuid: anonymous_group.uuid,
192                      link_class: 'permission',
193                      name: 'can_read').
194             first_or_create!
195         end
196       end
197     end
198   end
199
200   def public_project_group
201     $public_project_group = check_cache $public_project_group do
202       act_as_system_user do
203         ActiveRecord::Base.transaction do
204           Group.where(uuid: public_project_uuid).
205             first_or_create!(group_class: "project",
206                              name: "Public favorites",
207                              description: "Public favorites")
208         end
209       end
210     end
211   end
212
213   def public_project_read_permission
214     $public_project_group_read_permission =
215         check_cache $public_project_group_read_permission do
216       act_as_system_user do
217         Link.where(tail_uuid: anonymous_group.uuid,
218                    head_uuid: public_project_group.uuid,
219                    link_class: "permission",
220                    name: "can_read").first_or_create!
221       end
222     end
223   end
224
225   def system_root_token_api_client
226     $system_root_token_api_client = check_cache $system_root_token_api_client do
227       act_as_system_user do
228         ActiveRecord::Base.transaction do
229           ApiClient.find_or_create_by!(is_trusted: true, url_prefix: "", name: "SystemRootToken")
230         end
231       end
232     end
233   end
234
235   def empty_collection_pdh
236     'd41d8cd98f00b204e9800998ecf8427e+0'
237   end
238
239   def empty_collection
240     $empty_collection = check_cache $empty_collection do
241       act_as_system_user do
242         ActiveRecord::Base.transaction do
243           Collection.
244             where(portable_data_hash: empty_collection_pdh).
245             first_or_create(manifest_text: '', owner_uuid: system_user.uuid, name: "empty collection") do |c|
246             c.save!
247             Link.where(tail_uuid: anonymous_group.uuid,
248                        head_uuid: c.uuid,
249                        link_class: 'permission',
250                        name: 'can_read').
251                   first_or_create!
252             c
253           end
254         end
255       end
256     end
257   end
258
259   private
260
261   # If the given value is nil, or the cache has been cleared since it
262   # was set, yield. Otherwise, return the given value.
263   def check_cache value
264     if not Rails.env.test? and
265         ActionController::Base.cache_store.is_a? ActiveSupport::Cache::FileStore and
266         not File.owned? ActionController::Base.cache_store.cache_path
267       # If we don't own the cache dir, we're probably
268       # crunch-dispatch. Whoever we are, using this cache is likely to
269       # either fail or screw up the cache for someone else. So we'll
270       # just assume the $globals are OK to live forever.
271       #
272       # The reason for making the globals expire with the cache in the
273       # first place is to avoid leaking state between test cases: in
274       # production, we don't expect the database seeds to ever go away
275       # even when the cache is cleared, so there's no particular
276       # reason to expire our global variables.
277     else
278       Rails.cache.fetch "CurrentApiClient.$globals" do
279         value = nil
280         true
281       end
282     end
283     return value unless value.nil?
284     yield
285   end
286 end