17755: Merge branch 'main' into 17755-add-singularity-to-compute-image
[arvados.git] / services / api / test / functional / arvados / v1 / api_client_authorizations_controller_test.rb
index 5da9145a81e052b3ef5a471f672c7568399e428b..bf407afcd7e06ed8cd55438e6f85883ae198aa49 100644 (file)
@@ -1,3 +1,7 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 require 'test_helper'
 
 class Arvados::V1::ApiClientAuthorizationsControllerTest < ActionController::TestCase
@@ -9,7 +13,7 @@ class Arvados::V1::ApiClientAuthorizationsControllerTest < ActionController::Tes
 
   test "should not get index with expired auth" do
     authorize_with :expired
-    get :index, format: :json
+    get :index, params: {format: :json}
     assert_response 401
   end
 
@@ -21,30 +25,32 @@ class Arvados::V1::ApiClientAuthorizationsControllerTest < ActionController::Tes
 
   test "create system auth" do
     authorize_with :admin_trustedclient
-    post :create_system_auth, scopes: '["test"]'
+    post :create_system_auth, params: {scopes: '["test"]'}
     assert_response :success
     assert_not_nil JSON.parse(@response.body)['uuid']
   end
 
   test "prohibit create system auth with token from non-trusted client" do
     authorize_with :admin
-    post :create_system_auth, scopes: '["test"]'
+    post :create_system_auth, params: {scopes: '["test"]'}
     assert_response 403
   end
 
   test "prohibit create system auth by non-admin" do
     authorize_with :active
-    post :create_system_auth, scopes: '["test"]'
+    post :create_system_auth, params: {scopes: '["test"]'}
     assert_response 403
   end
 
-  def assert_found_tokens(auth, search_params, *expected_tokens)
+  def assert_found_tokens(auth, search_params, expected)
     authorize_with auth
-    expected_tokens.map! { |name| api_client_authorizations(name).api_token }
-    get :index, search_params
+    expected_tokens = expected.map do |name|
+      api_client_authorizations(name).api_token
+    end
+    get :index, params: search_params
     assert_response :success
     got_tokens = JSON.parse(@response.body)['items']
-      .map { |auth| auth['api_token'] }
+      .map { |a| a['api_token'] }
     assert_equal(expected_tokens.sort, got_tokens.sort,
                  "wrong results for #{search_params.inspect}")
   end
@@ -52,62 +58,149 @@ class Arvados::V1::ApiClientAuthorizationsControllerTest < ActionController::Tes
   # Three-tuples with auth to use, scopes to find, and expected tokens.
   # Make two tests for each tuple, one searching with where and the other
   # with filter.
-  [[:admin_trustedclient, [], :admin_noscope],
-   [:active_trustedclient, ["GET /arvados/v1/users"], :active_userlist],
+  [[:admin_trustedclient, [], [:admin_noscope]],
+   [:active_trustedclient, ["GET /arvados/v1/users"], [:active_userlist]],
    [:active_trustedclient,
     ["POST /arvados/v1/api_client_authorizations",
      "GET /arvados/v1/api_client_authorizations"],
-    :active_apitokens],
-  ].each do |auth, scopes, *expected|
+    [:active_apitokens]],
+  ].each do |auth, scopes, expected|
     test "#{auth.to_s} can find auths where scopes=#{scopes.inspect}" do
-      assert_found_tokens(auth, {where: {scopes: scopes}}, *expected)
+      assert_found_tokens(auth, {where: {scopes: scopes}}, expected)
     end
 
     test "#{auth.to_s} can find auths filtered with scopes=#{scopes.inspect}" do
-      assert_found_tokens(auth, {filters: [['scopes', '=', scopes]]}, *expected)
+      assert_found_tokens(auth, {filters: [['scopes', '=', scopes]]}, expected)
+    end
+
+    test "#{auth.to_s} offset works with filter scopes=#{scopes.inspect}" do
+      assert_found_tokens(auth, {
+                            offset: expected.length,
+                            filters: [['scopes', '=', scopes]]
+                          }, [])
     end
   end
 
-  [
-    [:admin, :admin, 200],
-    [:admin, :active, 403],
-    [:admin, :admin_vm, 403], # this belongs to the user of current session, but we can't get it by uuid
-    [:admin_trustedclient, :active, 200],
-  ].each do |user, token, status|
-    test "as user #{user} get #{token} token and expect #{status}" do
-      authorize_with user
-      get :show, {id: api_client_authorizations(token).uuid}
-      assert_response status
+  [:admin, :active].each do |token|
+    test "using '#{token}', get token details via 'current'" do
+      authorize_with token
+      get :current
+      assert_response 200
+      assert_equal json_response['scopes'], ['all']
     end
   end
 
-  [
-    [:admin, :admin, 200],
-    [:admin, :active, 403],
-    [:admin, :admin_vm, 403], # this belongs to the user of current session, but we can't list it by uuid
-    [:admin_trustedclient, :active, 200],
-  ].each do |user, token, status|
-    test "as user #{user} list #{token} token using uuid and expect #{status}" do
+  [# anyone can look up the token they're currently using
+   [:admin, :admin, 200, 200, 1],
+   [:active, :active, 200, 200, 1],
+   # cannot look up other tokens (even for same user) if not trustedclient
+   [:admin, :active, 403, 403],
+   [:admin, :admin_vm, 403, 403],
+   [:active, :admin, 403, 403],
+   # cannot look up other tokens for other users, regardless of trustedclient
+   [:admin_trustedclient, :active, 404, 200, 0],
+   [:active_trustedclient, :admin, 404, 200, 0],
+  ].each do |user, token, expect_get_response, expect_list_response, expect_list_items|
+    test "using '#{user}', get '#{token}' by uuid" do
       authorize_with user
-      get :index, {
-        filters: [['uuid','=',api_client_authorizations(token).uuid]]
+      get :show, params: {
+        id: api_client_authorizations(token).uuid,
       }
-      assert_response status
+      assert_response expect_get_response
+    end
+
+    test "using '#{user}', update '#{token}' by uuid" do
+      authorize_with user
+      put :update, params: {
+        id: api_client_authorizations(token).uuid,
+        api_client_authorization: {},
+      }
+      assert_response expect_get_response
     end
-  end
 
-  [
-    [:admin, :admin, 200],
-    [:admin, :active, 403],
-    [:admin, :admin_vm, 200], # this belongs to the user of current session, and can be listed by token
-    [:admin_trustedclient, :active, 200],
-  ].each do |user, token, status|
-    test "as user #{user} list #{token} token using token and expect #{status}" do
+    test "using '#{user}', delete '#{token}' by uuid" do
       authorize_with user
-      get :index, {
-        filters: [['api_token','=',api_client_authorizations(token).api_token]]
+      post :destroy, params: {
+        id: api_client_authorizations(token).uuid,
       }
-      assert_response status
+      assert_response expect_get_response
     end
+
+    test "using '#{user}', list '#{token}' by uuid" do
+      authorize_with user
+      get :index, params: {
+        filters: [['uuid','=',api_client_authorizations(token).uuid]],
+      }
+      assert_response expect_list_response
+      if expect_list_items
+        assert_equal assigns(:objects).length, expect_list_items
+        assert_equal json_response['items_available'], expect_list_items
+      end
+    end
+
+    if expect_list_items
+      test "using '#{user}', list '#{token}' by uuid with offset" do
+        authorize_with user
+        get :index, params: {
+          filters: [['uuid','=',api_client_authorizations(token).uuid]],
+          offset: expect_list_items,
+        }
+        assert_response expect_list_response
+        assert_equal json_response['items_available'], expect_list_items
+        assert_equal json_response['items'].length, 0
+      end
+    end
+
+    test "using '#{user}', list '#{token}' by token" do
+      authorize_with user
+      get :index, params: {
+        filters: [['api_token','=',api_client_authorizations(token).api_token]],
+      }
+      assert_response expect_list_response
+      if expect_list_items
+        assert_equal assigns(:objects).length, expect_list_items
+        assert_equal json_response['items_available'], expect_list_items
+      end
+    end
+  end
+
+  test "scoped token cannot change its own scopes" do
+    authorize_with :admin_vm
+    put :update, params: {
+      id: api_client_authorizations(:admin_vm).uuid,
+      api_client_authorization: {scopes: ['all']},
+    }
+    assert_response 403
+  end
+
+  test "token cannot change its own uuid" do
+    authorize_with :admin
+    put :update, params: {
+      id: api_client_authorizations(:admin).uuid,
+      api_client_authorization: {uuid: 'zzzzz-gj3su-zzzzzzzzzzzzzzz'},
+    }
+    assert_response 403
+  end
+
+  test "get current token" do
+    authorize_with :active
+    get :current
+    assert_response :success
+    assert_equal(json_response['api_token'],
+                 api_client_authorizations(:active).api_token)
+  end
+
+  test "get current token using SystemRootToken" do
+    Rails.configuration.SystemRootToken = "xyzzy-systemroottoken"
+    authorize_with_token Rails.configuration.SystemRootToken
+    get :current
+    assert_response :success
+    assert_equal(Rails.configuration.SystemRootToken, json_response['api_token'])
+    assert_not_empty(json_response['uuid'])
+  end
+
+  test "get current token, no auth" do
+    get :current
+    assert_response 401
   end
 end