525: Update the .classpath to reflect the latest trimmed down version of pom.xml
[arvados.git] / services / api / test / integration / api_client_authorizations_scopes_test.rb
1 # The v1 API uses token scopes to control access to the REST API at the path
2 # level.  This is enforced in the base ApplicationController, making it a
3 # functional test that we can run against many different controllers.
4
5 require 'test_helper'
6
7 class Arvados::V1::ApiTokensScopeTest < ActionController::IntegrationTest
8   fixtures :all
9
10   def setup
11     @token = {}
12   end
13
14   def auth_with(name)
15     @token = {api_token: api_client_authorizations(name).api_token}
16   end
17
18   def v1_url(*parts)
19     (['arvados', 'v1'] + parts).join('/')
20   end
21
22   def request_with_auth(method, path, params={})
23     send(method, path, @token.merge(params))
24   end
25
26   def get_with_auth(*args)
27     request_with_auth(:get_via_redirect, *args)
28   end
29
30   def post_with_auth(*args)
31     request_with_auth(:post_via_redirect, *args)
32   end
33
34   test "user list token can only list users" do
35     auth_with :active_userlist
36     get_with_auth v1_url('users')
37     assert_response :success
38     get_with_auth v1_url('users', '')  # Add trailing slash.
39     assert_response :success
40     get_with_auth v1_url('users', 'current')
41     assert_response 403
42     get_with_auth v1_url('virtual_machines')
43     assert_response 403
44   end
45
46   test "specimens token can see exactly owned specimens" do
47     auth_with :active_specimens
48     get_with_auth v1_url('specimens')
49     assert_response 403
50     get_with_auth v1_url('specimens', specimens(:owned_by_active_user).uuid)
51     assert_response :success
52     get_with_auth v1_url('specimens', specimens(:owned_by_spectator).uuid)
53     assert_includes(403..404, @response.status)
54   end
55
56   test "token with multiple scopes can use them all" do
57     def get_token_count
58       get_with_auth v1_url('api_client_authorizations')
59       assert_response :success
60       token_count = JSON.parse(@response.body)['items_available']
61       assert_not_nil(token_count, "could not find token count")
62       token_count
63     end
64     auth_with :active_apitokens
65     # Test the GET scope.
66     token_count = get_token_count
67     # Test the POST scope.
68     post_with_auth(v1_url('api_client_authorizations'),
69                    api_client_authorization: {user_id: users(:active).id})
70     assert_response :success
71     assert_equal(token_count + 1, get_token_count,
72                  "token count suggests POST was not accepted")
73     # Test other requests are denied.
74     get_with_auth v1_url('api_client_authorizations',
75                          api_client_authorizations(:active_apitokens).uuid)
76     assert_response 403
77   end
78
79   test "token without scope has no access" do
80     # Logs are good for this test, because logs have relatively
81     # few access controls enforced at the model level.
82     auth_with :admin_noscope
83     get_with_auth v1_url('logs')
84     assert_response 403
85     get_with_auth v1_url('logs', logs(:log1).uuid)
86     assert_response 403
87     post_with_auth(v1_url('logs'), log: {})
88     assert_response 403
89   end
90
91   test "VM login scopes work" do
92     # A system administration script makes an API token with limited scope
93     # for virtual machines to let it see logins.
94     def vm_logins_url(name)
95       v1_url('virtual_machines', virtual_machines(name).uuid, 'logins')
96     end
97     auth_with :admin_vm
98     get_with_auth vm_logins_url(:testvm)
99     assert_response :success
100     get_with_auth vm_logins_url(:testvm2)
101     assert(@response.status >= 400, "getting testvm2 logins should have failed")
102   end
103 end