17778: Merge branch 'master' into 17778-doc-update
[arvados.git] / services / api / test / integration / user_sessions_test.rb
index a46a4d1bc29c0e25992f6424bb4f50b919020229..76659f3207fff6b7470e6d85ca95dcbbc936e10b 100644 (file)
@@ -1,27 +1,37 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 require 'test_helper'
 
 class UserSessionsApiTest < ActionDispatch::IntegrationTest
-  def client_url
-    'https://wb.example.com'
+  # remote prefix & return url packed into the return_to param passed around
+  # between API and SSO provider.
+  def client_url(remote: nil)
+    url = ',https://wb.example.com'
+    url = "#{remote}#{url}" unless remote.nil?
+    url
   end
 
-  def mock_auth_with(email: nil, username: nil)
+  def mock_auth_with(email: nil, username: nil, identity_url: nil, remote: nil, expected_response: :redirect)
     mock = {
-      'provider' => 'josh_id',
-      'uid' => 'https://edward.example.com',
-      'info' => {
         'identity_url' => 'https://edward.example.com',
         'name' => 'Edward Example',
         'first_name' => 'Edward',
         'last_name' => 'Example',
-      },
     }
-    mock['info']['email'] = email unless email.nil?
-    mock['info']['username'] = username unless username.nil?
-    post('/auth/josh_id/callback',
-         {return_to: client_url},
-         {'omniauth.auth' => mock})
-    assert_response :redirect, 'Did not redirect to client with token'
+    mock['email'] = email unless email.nil?
+    mock['username'] = username unless username.nil?
+    mock['identity_url'] = identity_url unless identity_url.nil?
+    post('/auth/controller/callback',
+      params: {return_to: client_url(remote: remote), :auth_info => SafeJSON.dump(mock)},
+      headers: {'Authorization' => 'Bearer ' + Rails.configuration.SystemRootToken})
+
+    errors = {
+      :redirect => 'Did not redirect to client with token',
+      400 => 'Did not return Bad Request error',
+    }
+    assert_response expected_response, errors[expected_response]
   end
 
   test 'assign username from sso' do
@@ -36,16 +46,45 @@ class UserSessionsApiTest < ActionDispatch::IntegrationTest
     assert_equal 'foo', u.username
   end
 
+  test 'existing user login' do
+    mock_auth_with(identity_url: "https://active-user.openid.local")
+    u = assigns(:user)
+    assert_equal users(:active).uuid, u.uuid
+  end
+
+  test 'user redirect_to_user_uuid' do
+    mock_auth_with(identity_url: "https://redirects-to-active-user.openid.local")
+    u = assigns(:user)
+    assert_equal users(:active).uuid, u.uuid
+  end
+
+  test 'user double redirect_to_user_uuid' do
+    mock_auth_with(identity_url: "https://double-redirects-to-active-user.openid.local")
+    u = assigns(:user)
+    assert_equal users(:active).uuid, u.uuid
+  end
+
   test 'create new user during omniauth callback' do
     mock_auth_with(email: 'edward@example.com')
-    assert_equal(0, @response.redirect_url.index(client_url),
+    assert_equal(0, @response.redirect_url.index(client_url.split(',', 2)[1]),
                  'Redirected to wrong address after succesful login: was ' +
-                 @response.redirect_url + ', expected ' + client_url + '[...]')
+                 @response.redirect_url + ', expected ' + client_url.split(',', 2)[1] + '[...]')
     assert_not_nil(@response.redirect_url.index('api_token='),
                    'Expected api_token in query string of redirect url ' +
                    @response.redirect_url)
   end
 
+  test 'issue salted token from omniauth callback with remote param' do
+    mock_auth_with(email: 'edward@example.com', remote: 'zbbbb')
+    api_client_auth = assigns(:api_client_auth)
+    assert_not_nil api_client_auth
+    assert_includes(@response.redirect_url, 'api_token=' + api_client_auth.salted_token(remote: 'zbbbb'))
+  end
+
+  test 'error out from omniauth callback with invalid remote param' do
+    mock_auth_with(email: 'edward@example.com', remote: 'invalid_cluster_id', expected_response: 400)
+  end
+
   # Test various combinations of auto_setup configuration and email
   # address provided during a new user's first session setup.
   [{result: :nope, email: nil, cfg: {auto: true, repo: true, vm: true}},
@@ -68,10 +107,11 @@ class UserSessionsApiTest < ActionDispatch::IntegrationTest
    ].each do |testcase|
     test "user auto-activate #{testcase.inspect}" do
       # Configure auto_setup behavior according to testcase[:cfg]
-      Rails.configuration.auto_setup_new_users = testcase[:cfg][:auto]
-      Rails.configuration.auto_setup_new_users_with_vm_uuid =
-        (testcase[:cfg][:vm] ? virtual_machines(:testvm).uuid : false)
-      Rails.configuration.auto_setup_new_users_with_repository =
+      Rails.configuration.Users.NewUsersAreActive = false
+      Rails.configuration.Users.AutoSetupNewUsers = testcase[:cfg][:auto]
+      Rails.configuration.Users.AutoSetupNewUsersWithVmUUID =
+        (testcase[:cfg][:vm] ? virtual_machines(:testvm).uuid : "")
+      Rails.configuration.Users.AutoSetupNewUsersWithRepository =
         testcase[:cfg][:repo]
 
       mock_auth_with(email: testcase[:email])