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