21304: Check for nil from set_initial_username
[arvados.git] / services / api / lib / create_superuser_token.rb
index 7ee951e362c566ba99bced5339026a242a304f8b..7a18d970582786e860a0378717340e5e6ba3f3f1 100755 (executable)
@@ -1,33 +1,60 @@
-module CreateSuperUserToken
-  # Install the supplied string (or a randomly generated token, if none
-  # is given) as an API token that authenticates to the system user
-  # account.
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+# Install the supplied string (or a randomly generated token, if none
+# is given) as an API token that authenticates to the system user account.
 
+module CreateSuperUserToken
   require File.dirname(__FILE__) + '/../config/boot'
   require File.dirname(__FILE__) + '/../config/environment'
 
   include ApplicationHelper
-  act_as_system_user
-
-  def create_superuser_token supplied_token
-    if supplied_token
-      api_client_auth = ApiClientAuthorization.
-        where(api_token: supplied_token).
-        first
-      if api_client_auth && !api_client_auth.user.uuid.match(/-000000000000000$/)
-        raise ActiveRecord::RecordNotUnique("Token already exists but is not a superuser token.")
+
+  def create_superuser_token supplied_token=nil
+    act_as_system_user do
+      # If token is supplied, verify that it indeed is a superuser token
+      if supplied_token
+        api_client_auth = ApiClientAuthorization.
+          where(api_token: supplied_token).
+          first
+        if !api_client_auth
+          # fall through to create a token
+        elsif !api_client_auth.user.uuid.match(/-000000000000000$/)
+          raise "Token exists but is not a superuser token."
+        elsif api_client_auth.scopes != ['all']
+          raise "Token exists but has limited scope #{api_client_auth.scopes.inspect}."
+        end
       end
-    end
 
-    if !api_client_auth
-      api_client_auth = ApiClientAuthorization.
-        new(user: system_user,
-            api_client_id: 0,
-            created_by_ip_address: '::1',
-            api_token: supplied_token)
-      api_client_auth.save!
-    end
+      # need to create a token
+      if !api_client_auth
+        # Get (or create) trusted api client
+        apiClient =  ApiClient.
+          find_or_create_by(url_prefix: "ssh://root@localhost/",
+                            is_trusted: true)
+
+        # Check if there is an unexpired superuser token corresponding to this api client
+        api_client_auth =
+          ApiClientAuthorization.
+          where(user_id: system_user.id).
+          where(api_client_id: apiClient.id).
+          where_serialized(:scopes, ['all']).
+          where('(expires_at IS NULL OR expires_at > CURRENT_TIMESTAMP)').
+          first
 
-    puts api_client_auth.api_token
+        # none exist; create one with the supplied token
+        if !api_client_auth
+          api_client_auth = ApiClientAuthorization.
+            new(user: system_user,
+              api_client_id: apiClient.id,
+              created_by_ip_address: '::1',
+              api_token: supplied_token)
+          api_client_auth.save!
+        end
+      end
+
+      "v2/" + api_client_auth.uuid + "/" + api_client_auth.api_token
+    end
   end
 end