4958: Merge branch 'master' into 4958-old-browser-alert
[arvados.git] / services / api / lib / current_api_client.rb
1 module CurrentApiClient
2   def current_user
3     Thread.current[:user]
4   end
5
6   def current_api_client
7     Thread.current[:api_client]
8   end
9
10   def current_api_client_authorization
11     Thread.current[:api_client_authorization]
12   end
13
14   def current_api_base
15     Thread.current[:api_url_base]
16   end
17
18   def current_default_owner
19     # owner_uuid for newly created objects
20     ((current_api_client_authorization &&
21       current_api_client_authorization.default_owner_uuid) ||
22      (current_user && current_user.default_owner_uuid) ||
23      (current_user && current_user.uuid) ||
24      nil)
25   end
26
27   # Where is the client connecting from?
28   def current_api_client_ip_address
29     Thread.current[:api_client_ip_address]
30   end
31
32   def system_user_uuid
33     [Server::Application.config.uuid_prefix,
34      User.uuid_prefix,
35      '000000000000000'].join('-')
36   end
37
38   def system_group_uuid
39     [Server::Application.config.uuid_prefix,
40      Group.uuid_prefix,
41      '000000000000000'].join('-')
42   end
43
44   def anonymous_group_uuid
45     [Server::Application.config.uuid_prefix,
46      Group.uuid_prefix,
47      'anonymouspublic'].join('-')
48   end
49
50   def anonymous_user_uuid
51     [Server::Application.config.uuid_prefix,
52      User.uuid_prefix,
53      'anonymouspublic'].join('-')
54   end
55
56   def system_user
57     $system_user = check_cache $system_user do
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         User.where(uuid: system_user_uuid).
64           first_or_create!(is_active: true,
65                            is_admin: true,
66                            email: 'root',
67                            first_name: 'root',
68                            last_name: '')
69       ensure
70         Thread.current[:user] = real_current_user
71       end
72     end
73   end
74
75   def system_group
76     $system_group = check_cache $system_group do
77       act_as_system_user do
78         ActiveRecord::Base.transaction do
79           Group.where(uuid: system_group_uuid).
80             first_or_create!(name: "System group",
81                              description: "System group") do |g|
82             g.save!
83             User.all.collect(&:uuid).each do |user_uuid|
84               Link.create!(link_class: 'permission',
85                            name: 'can_manage',
86                            tail_kind: 'arvados#group',
87                            tail_uuid: system_group_uuid,
88                            head_kind: 'arvados#user',
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     [Server::Application.config.uuid_prefix,
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     end
134   end
135
136   def anonymous_group
137     $anonymous_group = check_cache $anonymous_group do
138       act_as_system_user do
139         ActiveRecord::Base.transaction do
140           Group.where(uuid: anonymous_group_uuid).
141             first_or_create!(group_class: "role",
142                              name: "Anonymous users",
143                              description: "Anonymous users")
144         end
145       end
146     end
147   end
148
149   def anonymous_group_read_permission
150     $anonymous_group_read_permission =
151         check_cache $anonymous_group_read_permission do
152       act_as_system_user do
153         Link.where(tail_uuid: all_users_group.uuid,
154                    head_uuid: anonymous_group.uuid,
155                    link_class: "permission",
156                    name: "can_read").first_or_create!
157       end
158     end
159   end
160
161   def anonymous_user
162     $anonymous_user = check_cache $anonymous_user do
163       act_as_system_user do
164         User.where(uuid: anonymous_user_uuid).
165           first_or_create!(is_active: false,
166                            is_admin: false,
167                            email: 'anonymous',
168                            first_name: 'Anonymous',
169                            last_name: '') do |u|
170           u.save!
171           Link.where(tail_uuid: anonymous_user_uuid,
172                      head_uuid: anonymous_group.uuid,
173                      link_class: 'permission',
174                      name: 'can_read').
175             first_or_create!
176         end
177       end
178     end
179   end
180
181   def empty_collection_uuid
182     'd41d8cd98f00b204e9800998ecf8427e+0'
183   end
184
185   def empty_collection
186     $empty_collection = check_cache $empty_collection do
187       act_as_system_user do
188         ActiveRecord::Base.transaction do
189           Collection.
190             where(portable_data_hash: empty_collection_uuid).
191             first_or_create!(manifest_text: '', owner_uuid: anonymous_group.uuid)
192         end
193       end
194     end
195   end
196
197   private
198
199   # If the given value is nil, or the cache has been cleared since it
200   # was set, yield. Otherwise, return the given value.
201   def check_cache value
202     if not Rails.env.test? and
203         ActionController::Base.cache_store.is_a? ActiveSupport::Cache::FileStore and
204         not File.owned? ActionController::Base.cache_store.cache_path
205       # If we don't own the cache dir, we're probably
206       # crunch-dispatch. Whoever we are, using this cache is likely to
207       # either fail or screw up the cache for someone else. So we'll
208       # just assume the $globals are OK to live forever.
209       #
210       # The reason for making the globals expire with the cache in the
211       # first place is to avoid leaking state between test cases: in
212       # production, we don't expect the database seeds to ever go away
213       # even when the cache is cleared, so there's no particular
214       # reason to expire our global variables.
215     else
216       Rails.cache.fetch "CurrentApiClient.$globals" do
217         value = nil
218         true
219       end
220     end
221     return value unless value.nil?
222     yield
223   end
224 end