13996: More config migrations, refactor some code into config_loader.rb
[arvados.git] / services / api / app / models / api_client_authorization.rb
index b158faa272635d1cce630faf58bea0fc307fa128..db99c0bc17d263016e994e336cb1fda7b069f682 100644 (file)
@@ -87,22 +87,42 @@ class ApiClientAuthorization < ArvadosModel
   end
 
   def self.remote_host(uuid_prefix:)
-    Rails.configuration.remote_hosts[uuid_prefix] ||
-      (Rails.configuration.remote_hosts_via_dns &&
+    Rails.configuration.RemoteClusters[uuid_prefix]["Host"] ||
+      (Rails.configuration.RemoteClusters["*"]["Proxy"] &&
        uuid_prefix+".arvadosapi.com")
   end
 
-  def self.validate(token:, remote:)
+  def self.validate(token:, remote: nil)
     return nil if !token
-    remote ||= Rails.configuration.uuid_prefix
+    remote ||= Rails.configuration.ClusterID
 
     case token[0..2]
     when 'v2/'
-      _, uuid, secret = token.split('/')
+      _, uuid, secret, optional = token.split('/')
       unless uuid.andand.length == 27 && secret.andand.length.andand > 0
         return nil
       end
 
+      if !optional.nil?
+        # if "optional" is a container uuid, check that it
+        # matches expections.
+        c = Container.where(uuid: optional).first
+        if !c.nil?
+          if !c.auth_uuid.nil? and c.auth_uuid != uuid
+            # token doesn't match the container's token
+            return nil
+          end
+          if !c.runtime_token.nil? and "v2/#{uuid}/#{secret}" != c.runtime_token
+            # token doesn't match the container's token
+            return nil
+          end
+          if ![Container::Locked, Container::Running].include?(c.state)
+            # container isn't locked or running, token shouldn't be used
+            return nil
+          end
+        end
+      end
+
       auth = ApiClientAuthorization.
              includes(:user, :api_client).
              where('uuid=? and (expires_at is null or expires_at > CURRENT_TIMESTAMP)', uuid).
@@ -114,7 +134,7 @@ class ApiClientAuthorization < ArvadosModel
       end
 
       uuid_prefix = uuid[0..4]
-      if uuid_prefix == Rails.configuration.uuid_prefix
+      if uuid_prefix == Rails.configuration.ClusterID
         # If the token were valid, we would have validated it above
         return nil
       elsif uuid_prefix.length != 5
@@ -133,12 +153,18 @@ class ApiClientAuthorization < ArvadosModel
       # [re]validate it.
       begin
         clnt = HTTPClient.new
-        if Rails.configuration.sso_insecure
+        if Rails.configuration.TLS["Insecure"]
           clnt.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
+        else
+          # Use system CA certificates
+          ["/etc/ssl/certs/ca-certificates.crt",
+           "/etc/pki/tls/certs/ca-bundle.crt"]
+            .select { |ca_path| File.readable?(ca_path) }
+            .each { |ca_path| clnt.ssl_config.add_trust_ca(ca_path) }
         end
         remote_user = SafeJSON.load(
           clnt.get_content('https://' + host + '/arvados/v1/users/current',
-                           {'remote' => Rails.configuration.uuid_prefix},
+                           {'remote' => Rails.configuration.ClusterID},
                            {'Authorization' => 'Bearer ' + token}))
       rescue => e
         Rails.logger.warn "remote authentication with token #{token.inspect} failed: #{e}"
@@ -161,7 +187,8 @@ class ApiClientAuthorization < ArvadosModel
           end
         end
 
-        if Rails.configuration.new_users_are_active
+        if Rails.configuration.Users["NewUsersAreActive"] ||
+           Rails.configuration.RemoteClusters[remote_user['uuid'][0..4]].andand["ActivateUsers"]
           # Update is_active to whatever it is at the remote end
           user.is_active = remote_user['is_active']
         elsif !remote_user['is_active']
@@ -203,6 +230,25 @@ class ApiClientAuthorization < ArvadosModel
     return nil
   end
 
+  def token
+    v2token
+  end
+
+  def v1token
+    api_token
+  end
+
+  def v2token
+    'v2/' + uuid + '/' + api_token
+  end
+
+  def salted_token(remote:)
+    if remote.nil?
+      token
+    end
+    'v2/' + uuid + '/' + OpenSSL::HMAC.hexdigest('sha1', api_token, remote)
+  end
+
   protected
 
   def permission_to_create