Merge branch 'master' into 9998-unsigned_manifest
[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     #auth_was = Thread.current[:api_client_authorization]
128     user_was = Thread.current[:user]
129     Thread.current[:user] = user
130     #Thread.current[:api_client_authorization] = ApiClientAuthorization.
131     #  where('user_id=? and scopes is null', user.id).
132     #  order('expires_at desc').
133     #  first
134     begin
135       yield
136     ensure
137       Thread.current[:user] = user_was
138       #Thread.current[:api_client_authorization] = auth_was
139     end
140   end
141
142   def anonymous_group
143     $anonymous_group = check_cache $anonymous_group do
144       act_as_system_user do
145         ActiveRecord::Base.transaction do
146           Group.where(uuid: anonymous_group_uuid).
147             first_or_create!(group_class: "role",
148                              name: "Anonymous users",
149                              description: "Anonymous users")
150         end
151       end
152     end
153   end
154
155   def anonymous_group_read_permission
156     $anonymous_group_read_permission =
157         check_cache $anonymous_group_read_permission do
158       act_as_system_user do
159         Link.where(tail_uuid: all_users_group.uuid,
160                    head_uuid: anonymous_group.uuid,
161                    link_class: "permission",
162                    name: "can_read").first_or_create!
163       end
164     end
165   end
166
167   def anonymous_user
168     $anonymous_user = check_cache $anonymous_user do
169       act_as_system_user do
170         User.where(uuid: anonymous_user_uuid).
171           first_or_create!(is_active: false,
172                            is_admin: false,
173                            email: 'anonymous',
174                            first_name: 'Anonymous',
175                            last_name: '') do |u|
176           u.save!
177           Link.where(tail_uuid: anonymous_user_uuid,
178                      head_uuid: anonymous_group.uuid,
179                      link_class: 'permission',
180                      name: 'can_read').
181             first_or_create!
182         end
183       end
184     end
185   end
186
187   def empty_collection_uuid
188     'd41d8cd98f00b204e9800998ecf8427e+0'
189   end
190
191   def empty_collection
192     $empty_collection = check_cache $empty_collection do
193       act_as_system_user do
194         ActiveRecord::Base.transaction do
195           Collection.
196             where(portable_data_hash: empty_collection_uuid).
197             first_or_create!(manifest_text: '', owner_uuid: anonymous_group.uuid)
198         end
199       end
200     end
201   end
202
203   private
204
205   # If the given value is nil, or the cache has been cleared since it
206   # was set, yield. Otherwise, return the given value.
207   def check_cache value
208     if not Rails.env.test? and
209         ActionController::Base.cache_store.is_a? ActiveSupport::Cache::FileStore and
210         not File.owned? ActionController::Base.cache_store.cache_path
211       # If we don't own the cache dir, we're probably
212       # crunch-dispatch. Whoever we are, using this cache is likely to
213       # either fail or screw up the cache for someone else. So we'll
214       # just assume the $globals are OK to live forever.
215       #
216       # The reason for making the globals expire with the cache in the
217       # first place is to avoid leaking state between test cases: in
218       # production, we don't expect the database seeds to ever go away
219       # even when the cache is cleared, so there's no particular
220       # reason to expire our global variables.
221     else
222       Rails.cache.fetch "CurrentApiClient.$globals" do
223         value = nil
224         true
225       end
226     end
227     return value unless value.nil?
228     yield
229   end
230 end