16736: Enhances tests about login issued tokens.
[arvados.git] / services / api / test / functional / user_sessions_controller_test.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 require 'test_helper'
6
7 class UserSessionsControllerTest < ActionController::TestCase
8
9   test "redirect to joshid" do
10     api_client_page = 'http://client.example.com/home'
11     get :login, params: {return_to: api_client_page}
12     assert_response :redirect
13     assert_equal("http://test.host/auth/joshid?return_to=%2Chttp%3A%2F%2Fclient.example.com%2Fhome", @response.redirect_url)
14     assert_nil assigns(:api_client)
15   end
16
17   test "send token when user is already logged in" do
18     authorize_with :inactive
19     api_client_page = 'http://client.example.com/home'
20     get :login, params: {return_to: api_client_page}
21     assert_response :redirect
22     assert_equal(0, @response.redirect_url.index(api_client_page + '?'),
23                  'Redirect url ' + @response.redirect_url +
24                  ' should start with ' + api_client_page + '?')
25     assert_not_nil assigns(:api_client)
26   end
27
28   test "login creates token without expiration by default" do
29     assert_equal Rails.configuration.Login.TokenLifetime, 0
30     authorize_with :inactive
31     api_client_page = 'http://client.example.com/home'
32     get :login, params: {return_to: api_client_page}
33     assert_response :redirect
34     assert_not_nil assigns(:api_client)
35     assert_nil assigns(:api_client_auth).expires_at
36   end
37
38   test "login creates token with configured lifetime" do
39     token_lifetime = 1.hour
40     Rails.configuration.Login.TokenLifetime = token_lifetime
41     authorize_with :inactive
42     api_client_page = 'http://client.example.com/home'
43     get :login, params: {return_to: api_client_page}
44     assert_response :redirect
45     assert_not_nil assigns(:api_client)
46     api_client_auth = assigns(:api_client_auth)
47     assert_in_delta(api_client_auth.expires_at,
48                     api_client_auth.updated_at + token_lifetime,
49                     1.second)
50   end
51
52   [[0, 1.hour, 1.hour],
53   [1.hour, 2.hour, 1.hour],
54   [2.hour, 1.hour, 1.hour],
55   [2.hour, nil, 2.hour],
56   ].each do |config_lifetime, request_lifetime, expect_lifetime|
57     test "login with TokenLifetime=#{config_lifetime} and request has expires_at=#{ request_lifetime.nil? ? "nil" : request_lifetime }" do
58       Rails.configuration.Login.TokenLifetime = config_lifetime
59       expected_expiration_time =  Time.now() + expect_lifetime
60       authorize_with :inactive
61       @request.headers['Authorization'] = 'Bearer '+Rails.configuration.SystemRootToken
62       if request_lifetime.nil?
63         get :create, params: {provider: 'controller', auth_info: {email: "foo@bar.com"}, return_to: ',https://app.example'}
64       else
65         get :create, params: {provider: 'controller', auth_info: {email: "foo@bar.com", expires_at: Time.now() + request_lifetime}, return_to: ',https://app.example'}
66       end
67       assert_response :redirect
68       api_client_auth = assigns(:api_client_auth)
69       assert_not_nil api_client_auth
70       assert_not_nil assigns(:api_client)
71       assert_in_delta(api_client_auth.expires_at,
72                       expected_expiration_time,
73                       1.second)
74     end
75   end
76
77   test "login with remote param returns a salted token" do
78     authorize_with :inactive
79     api_client_page = 'http://client.example.com/home'
80     remote_prefix = 'zbbbb'
81     get :login, params: {return_to: api_client_page, remote: remote_prefix}
82     assert_response :redirect
83     api_client_auth = assigns(:api_client_auth)
84     assert_not_nil api_client_auth
85     assert_includes(@response.redirect_url, 'api_token='+api_client_auth.salted_token(remote: remote_prefix))
86   end
87
88   test "login with malformed remote param returns an error" do
89     authorize_with :inactive
90     api_client_page = 'http://client.example.com/home'
91     remote_prefix = 'invalid_cluster_id'
92     get :login, params: {return_to: api_client_page, remote: remote_prefix}
93     assert_response 400
94   end
95
96   test "login to LoginCluster" do
97     Rails.configuration.Login.LoginCluster = 'zbbbb'
98     Rails.configuration.RemoteClusters['zbbbb'] = ConfigLoader.to_OrderedOptions({'Host' => 'zbbbb.example.com'})
99     api_client_page = 'http://client.example.com/home'
100     get :login, params: {return_to: api_client_page}
101     assert_response :redirect
102     assert_equal("https://zbbbb.example.com/login?return_to=http%3A%2F%2Fclient.example.com%2Fhome", @response.redirect_url)
103     assert_nil assigns(:api_client)
104   end
105
106   test "don't go into redirect loop if LoginCluster is self" do
107     Rails.configuration.Login.LoginCluster = 'zzzzz'
108     api_client_page = 'http://client.example.com/home'
109     get :login, params: {return_to: api_client_page}
110     assert_response :redirect
111     assert_equal("http://test.host/auth/joshid?return_to=%2Chttp%3A%2F%2Fclient.example.com%2Fhome", @response.redirect_url)
112     assert_nil assigns(:api_client)
113   end
114
115   test "controller cannot create session without SystemRootToken" do
116     get :create, params: {provider: 'controller', auth_info: {email: "foo@bar.com"}, return_to: ',https://app.example'}
117     assert_response 401
118   end
119
120   test "controller cannot create session with wrong SystemRootToken" do
121     @request.headers['Authorization'] = 'Bearer blah'
122     get :create, params: {provider: 'controller', auth_info: {email: "foo@bar.com"}, return_to: ',https://app.example'}
123     assert_response 401
124   end
125
126   test "controller can create session using SystemRootToken" do
127     @request.headers['Authorization'] = 'Bearer '+Rails.configuration.SystemRootToken
128     get :create, params: {provider: 'controller', auth_info: {email: "foo@bar.com"}, return_to: ',https://app.example'}
129     assert_response :redirect
130     api_client_auth = assigns(:api_client_auth)
131     assert_not_nil api_client_auth
132     assert_includes(@response.redirect_url, 'api_token='+api_client_auth.token)
133   end
134 end