18676: simplify AnonymousUserToken configuration.
[arvados.git] / services / api / lib / current_api_client.rb
index 404de4f4c3dd89e3178dd3e2a0a6f6cabd04d06a..ee666b77ab78632f843211fc9e510f9dd11f564c 100644 (file)
@@ -1,3 +1,17 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+$system_user = nil
+$system_group = nil
+$all_users_group = nil
+$anonymous_user = nil
+$anonymous_group = nil
+$anonymous_group_read_permission = nil
+$empty_collection = nil
+$public_project_group = nil
+$public_project_group_read_permission = nil
+
 module CurrentApiClient
   def current_user
     Thread.current[:user]
@@ -30,29 +44,35 @@ module CurrentApiClient
   end
 
   def system_user_uuid
-    [Server::Application.config.uuid_prefix,
+    [Rails.configuration.ClusterID,
      User.uuid_prefix,
      '000000000000000'].join('-')
   end
 
   def system_group_uuid
-    [Server::Application.config.uuid_prefix,
+    [Rails.configuration.ClusterID,
      Group.uuid_prefix,
      '000000000000000'].join('-')
   end
 
   def anonymous_group_uuid
-    [Server::Application.config.uuid_prefix,
+    [Rails.configuration.ClusterID,
      Group.uuid_prefix,
      'anonymouspublic'].join('-')
   end
 
   def anonymous_user_uuid
-    [Server::Application.config.uuid_prefix,
+    [Rails.configuration.ClusterID,
      User.uuid_prefix,
      'anonymouspublic'].join('-')
   end
 
+  def public_project_uuid
+    [Rails.configuration.ClusterID,
+     Group.uuid_prefix,
+     'publicfavorites'].join('-')
+  end
+
   def system_user
     $system_user = check_cache $system_user do
       real_current_user = Thread.current[:user]
@@ -60,7 +80,7 @@ module CurrentApiClient
         Thread.current[:user] = User.new(is_admin: true,
                                          is_active: true,
                                          uuid: system_user_uuid)
-        User.where('uuid=?', system_user_uuid).
+        User.where(uuid: system_user_uuid).
           first_or_create!(is_active: true,
                            is_admin: true,
                            email: 'root',
@@ -78,13 +98,13 @@ module CurrentApiClient
         ActiveRecord::Base.transaction do
           Group.where(uuid: system_group_uuid).
             first_or_create!(name: "System group",
-                             description: "System group") do |g|
+                             description: "System group",
+                             group_class: "role") do |g|
+            g.save!
             User.all.collect(&:uuid).each do |user_uuid|
               Link.create!(link_class: 'permission',
                            name: 'can_manage',
-                           tail_kind: 'arvados#group',
                            tail_uuid: system_group_uuid,
-                           head_kind: 'arvados#user',
                            head_uuid: user_uuid)
             end
           end
@@ -94,7 +114,7 @@ module CurrentApiClient
   end
 
   def all_users_group_uuid
-    [Server::Application.config.uuid_prefix,
+    [Rails.configuration.ClusterID,
      Group.uuid_prefix,
      'fffffffffffffff'].join('-')
   end
@@ -129,6 +149,9 @@ module CurrentApiClient
       yield
     ensure
       Thread.current[:user] = user_was
+      if user_was
+        user_was.forget_cached_group_perms
+      end
     end
   end
 
@@ -145,26 +168,84 @@ module CurrentApiClient
     end
   end
 
+  def anonymous_group_read_permission
+    $anonymous_group_read_permission =
+        check_cache $anonymous_group_read_permission do
+      act_as_system_user do
+        Link.where(tail_uuid: all_users_group.uuid,
+                   head_uuid: anonymous_group.uuid,
+                   link_class: "permission",
+                   name: "can_read").first_or_create!
+      end
+    end
+  end
+
   def anonymous_user
     $anonymous_user = check_cache $anonymous_user do
       act_as_system_user do
-        anon = User.where('uuid=?', anonymous_user_uuid).
+        User.where(uuid: anonymous_user_uuid).
           first_or_create!(is_active: false,
                            is_admin: false,
                            email: 'anonymous',
                            first_name: 'Anonymous',
-                           last_name: '')
-        Link.where(tail_uuid: anonymous_user_uuid,
-                   head_uuid: anonymous_group_uuid,
-                   link_class: 'permission',
-                   name: 'can_read').
-          first_or_create!
-        anon
+                           last_name: '') do |u|
+          u.save!
+          Link.where(tail_uuid: anonymous_user_uuid,
+                     head_uuid: anonymous_group.uuid,
+                     link_class: 'permission',
+                     name: 'can_read').
+            first_or_create!
+        end
+      end
+    end
+  end
+
+  def public_project_group
+    $public_project_group = check_cache $public_project_group do
+      act_as_system_user do
+        ActiveRecord::Base.transaction do
+          Group.where(uuid: public_project_uuid).
+            first_or_create!(group_class: "project",
+                             name: "Public favorites",
+                             description: "Public favorites")
+        end
+      end
+    end
+  end
+
+  def public_project_read_permission
+    $public_project_group_read_permission =
+        check_cache $public_project_group_read_permission do
+      act_as_system_user do
+        Link.where(tail_uuid: anonymous_group.uuid,
+                   head_uuid: public_project_group.uuid,
+                   link_class: "permission",
+                   name: "can_read").first_or_create!
+      end
+    end
+  end
+
+  def anonymous_user_token_api_client
+    $anonymous_user_token_api_client = check_cache $anonymous_user_token_api_client do
+      act_as_system_user do
+        ActiveRecord::Base.transaction do
+          ApiClient.find_or_create_by!(is_trusted: false, url_prefix: "", name: "AnonymousUserToken")
+        end
       end
     end
   end
 
-  def empty_collection_uuid
+  def system_root_token_api_client
+    $system_root_token_api_client = check_cache $system_root_token_api_client do
+      act_as_system_user do
+        ActiveRecord::Base.transaction do
+          ApiClient.find_or_create_by!(is_trusted: true, url_prefix: "", name: "SystemRootToken")
+        end
+      end
+    end
+  end
+
+  def empty_collection_pdh
     'd41d8cd98f00b204e9800998ecf8427e+0'
   end
 
@@ -172,9 +253,17 @@ module CurrentApiClient
     $empty_collection = check_cache $empty_collection do
       act_as_system_user do
         ActiveRecord::Base.transaction do
-          $empty_collection = Collection.
-            where(portable_data_hash: empty_collection_uuid).
-            first_or_create!(manifest_text: '', owner_uuid: anonymous_group.uuid)
+          Collection.
+            where(portable_data_hash: empty_collection_pdh).
+            first_or_create(manifest_text: '', owner_uuid: system_user.uuid, name: "empty collection") do |c|
+            c.save!
+            Link.where(tail_uuid: anonymous_group.uuid,
+                       head_uuid: c.uuid,
+                       link_class: 'permission',
+                       name: 'can_read').
+                  first_or_create!
+            c
+          end
         end
       end
     end
@@ -185,9 +274,24 @@ module CurrentApiClient
   # If the given value is nil, or the cache has been cleared since it
   # was set, yield. Otherwise, return the given value.
   def check_cache value
-    Rails.cache.fetch "CurrentApiClient.$globals" do
-      value = nil
-      true
+    if not Rails.env.test? and
+        ActionController::Base.cache_store.is_a? ActiveSupport::Cache::FileStore and
+        not File.owned? ActionController::Base.cache_store.cache_path
+      # If we don't own the cache dir, we're probably
+      # crunch-dispatch. Whoever we are, using this cache is likely to
+      # either fail or screw up the cache for someone else. So we'll
+      # just assume the $globals are OK to live forever.
+      #
+      # The reason for making the globals expire with the cache in the
+      # first place is to avoid leaking state between test cases: in
+      # production, we don't expect the database seeds to ever go away
+      # even when the cache is cleared, so there's no particular
+      # reason to expire our global variables.
+    else
+      Rails.cache.fetch "CurrentApiClient.$globals" do
+        value = nil
+        true
+      end
     end
     return value unless value.nil?
     yield