1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
7 class UserSessionsApiTest < ActionDispatch::IntegrationTest
8 # remote prefix & return url packed into the return_to param passed around
9 # between API and SSO provider.
10 def client_url(remote: nil)
11 url = ',https://wb.example.com'
12 url = "#{remote}#{url}" unless remote.nil?
16 def mock_auth_with(email: nil, username: nil, identity_url: nil, remote: nil, expected_response: :redirect)
18 'identity_url' => 'https://edward.example.com',
19 'name' => 'Edward Example',
20 'first_name' => 'Edward',
21 'last_name' => 'Example',
23 mock['email'] = email unless email.nil?
24 mock['username'] = username unless username.nil?
25 mock['identity_url'] = identity_url unless identity_url.nil?
26 post('/auth/controller/callback',
27 params: {return_to: client_url(remote: remote), :auth_info => SafeJSON.dump(mock)},
28 headers: {'Authorization' => 'Bearer ' + Rails.configuration.SystemRootToken})
31 :redirect => 'Did not redirect to client with token',
32 400 => 'Did not return Bad Request error',
34 assert_response expected_response, errors[expected_response]
37 test 'assign username from sso' do
38 mock_auth_with(email: 'foo@example.com', username: 'bar')
40 assert_equal 'bar', u.username
43 test 'no assign username from sso' do
44 mock_auth_with(email: 'foo@example.com')
46 assert_equal 'foo', u.username
49 test 'existing user login' do
50 mock_auth_with(identity_url: "https://active-user.openid.local")
52 assert_equal users(:active).uuid, u.uuid
55 test 'user redirect_to_user_uuid' do
56 mock_auth_with(identity_url: "https://redirects-to-active-user.openid.local")
58 assert_equal users(:active).uuid, u.uuid
61 test 'user double redirect_to_user_uuid' do
62 mock_auth_with(identity_url: "https://double-redirects-to-active-user.openid.local")
64 assert_equal users(:active).uuid, u.uuid
67 test 'create new user during omniauth callback' do
68 mock_auth_with(email: 'edward@example.com')
69 assert_equal(0, @response.redirect_url.index(client_url.split(',', 2)[1]),
70 'Redirected to wrong address after succesful login: was ' +
71 @response.redirect_url + ', expected ' + client_url.split(',', 2)[1] + '[...]')
72 assert_not_nil(@response.redirect_url.index('api_token='),
73 'Expected api_token in query string of redirect url ' +
74 @response.redirect_url)
77 test 'issue salted token from omniauth callback with remote param' do
78 mock_auth_with(email: 'edward@example.com', remote: 'zbbbb')
79 api_client_auth = assigns(:api_client_auth)
80 assert_not_nil api_client_auth
81 assert_includes(@response.redirect_url, 'api_token=' + api_client_auth.salted_token(remote: 'zbbbb'))
84 test 'error out from omniauth callback with invalid remote param' do
85 mock_auth_with(email: 'edward@example.com', remote: 'invalid_cluster_id', expected_response: 400)
88 # Test various combinations of auto_setup configuration and email
89 # address provided during a new user's first session setup.
90 [{result: :nope, email: nil, cfg: {auto: true, repo: true, vm: true}},
91 {result: :yup, email: nil, cfg: {auto: true}},
92 {result: :nope, email: '@example.com', cfg: {auto: true, repo: true, vm: true}},
93 {result: :yup, email: '@example.com', cfg: {auto: true}},
94 {result: :nope, email: 'root@', cfg: {auto: true, repo: true, vm: true}},
95 {result: :nope, email: 'root@', cfg: {auto: true, repo: true}},
96 {result: :nope, email: 'root@', cfg: {auto: true, vm: true}},
97 {result: :yup, email: 'root@', cfg: {auto: true}},
98 {result: :nope, email: 'gitolite@', cfg: {auto: true, repo: true}},
99 {result: :nope, email: '*_*@', cfg: {auto: true, vm: true}},
100 {result: :yup, email: 'toor@', cfg: {auto: true, vm: true, repo: true}},
101 {result: :yup, email: 'foo@', cfg: {auto: true, vm: true},
103 {result: :yup, email: 'foo@', cfg: {auto: true, repo: true},
105 {result: :yup, email: 'auto_setup_vm_login@', cfg: {auto: true, repo: true},
106 uniqprefix: 'auto_setup_vm_login'},
108 test "user auto-activate #{testcase.inspect}" do
109 # Configure auto_setup behavior according to testcase[:cfg]
110 Rails.configuration.Users.NewUsersAreActive = false
111 Rails.configuration.Users.AutoSetupNewUsers = testcase[:cfg][:auto]
112 Rails.configuration.Users.AutoSetupNewUsersWithVmUUID =
113 (testcase[:cfg][:vm] ? virtual_machines(:testvm).uuid : "")
114 Rails.configuration.Users.AutoSetupNewUsersWithRepository =
115 testcase[:cfg][:repo]
117 mock_auth_with(email: testcase[:email])
119 vm_links = Link.where('link_class=? and tail_uuid=? and head_uuid like ?',
120 'permission', u.uuid,
121 '%-' + VirtualMachine.uuid_prefix + '-%')
122 repo_links = Link.where('link_class=? and tail_uuid=? and head_uuid like ?',
123 'permission', u.uuid,
124 '%-' + Repository.uuid_prefix + '-%')
125 repos = Repository.where('uuid in (?)', repo_links.collect(&:head_uuid))
128 assert_equal false, u.is_invited, "should not have been set up"
129 assert_empty vm_links, "should not have VM login permission"
130 assert_empty repo_links, "should not have repo permission"
132 assert_equal true, u.is_invited
133 if testcase[:cfg][:vm]
134 assert_equal 1, vm_links.count, "wrong number of VM perm links"
136 assert_empty vm_links, "should not have VM login permission"
138 if testcase[:cfg][:repo]
139 assert_equal 1, repo_links.count, "wrong number of repo perm links"
140 assert_equal 1, repos.count, "wrong number of repos"
141 assert_equal 'can_manage', repo_links.first.name, "wrong perm type"
143 assert_empty repo_links, "should not have repo permission"
146 if (prefix = testcase[:uniqprefix])
147 # This email address conflicts with a test fixture. Make sure
148 # every VM login and repository name got digits added to make
150 (repos.collect(&:name) +
151 vm_links.collect { |link| link.properties['username'] }
153 r = name.match(/^(.{#{prefix.length}})(\d+)$/)
154 assert_not_nil r, "#{name.inspect} does not match {prefix}\\d+"
155 assert_equal(prefix, r[1],
156 "#{name.inspect} was not {#{prefix.inspect} plus digits}")