Merge branch '10846-nodemanager-errors' closes #10846
[arvados.git] / services / api / test / functional / arvados / v1 / repositories_controller_test.rb
1 require 'test_helper'
2
3 class Arvados::V1::RepositoriesControllerTest < ActionController::TestCase
4   test "should get_all_logins with admin token" do
5     authorize_with :admin
6     get :get_all_permissions
7     assert_response :success
8   end
9
10   test "should get_all_logins with non-admin token" do
11     authorize_with :active
12     get :get_all_permissions
13     assert_response 403
14   end
15
16   test "get_all_permissions gives RW to repository owner" do
17     authorize_with :admin
18     get :get_all_permissions
19     assert_response :success
20     ok = false
21     json_response['repositories'].each do |repo|
22       if repo['uuid'] == repositories(:repository2).uuid
23         if repo['user_permissions'][users(:active).uuid]['can_write']
24           ok = true
25         end
26       end
27     end
28     assert_equal(true, ok,
29                  "No permission on own repo '@{repositories(:repository2).uuid}'")
30   end
31
32   test "get_all_permissions takes into account is_admin flag" do
33     authorize_with :admin
34     get :get_all_permissions
35     assert_response :success
36     json_response['repositories'].each do |repo|
37       assert_not_nil(repo['user_permissions'][users(:admin).uuid],
38                      "Admin user is not listed in perms for #{repo['uuid']}")
39       assert_equal(true,
40                    repo['user_permissions'][users(:admin).uuid]['can_write'],
41                    "Admin has no perms for #{repo['uuid']}")
42     end
43   end
44
45   test "get_all_permissions takes into account is_active flag" do
46     act_as_user users(:active) do
47       Repository.create! name: 'active/testrepo'
48     end
49     act_as_system_user do
50       u = users(:active)
51       u.is_active = false
52       u.save!
53     end
54     authorize_with :admin
55     get :get_all_permissions
56     assert_response :success
57     json_response['repositories'].each do |r|
58       r['user_permissions'].each do |user_uuid, perms|
59         refute_equal user_uuid, users(:active).uuid
60       end
61     end
62   end
63
64   test "get_all_permissions does not give any access to user without permission" do
65     viewer_uuid = users(:project_viewer).uuid
66     assert_equal(authorized_keys(:project_viewer).authorized_user_uuid,
67                  viewer_uuid,
68                  "project_viewer must have an authorized_key for this test to work")
69     authorize_with :admin
70     get :get_all_permissions
71     assert_response :success
72     readable_repos = json_response["repositories"].select do |repo|
73       repo["user_permissions"].has_key?(viewer_uuid)
74     end
75     assert_equal(["arvados"], readable_repos.map { |r| r["name"] },
76                  "project_viewer should only have permissions on public repos")
77   end
78
79   test "get_all_permissions gives gitolite R to user with read-only access" do
80     authorize_with :admin
81     get :get_all_permissions
82     assert_response :success
83     found_it = false
84     assert_equal(authorized_keys(:spectator).authorized_user_uuid,
85                  users(:spectator).uuid,
86                  "spectator must have an authorized_key for this test to work")
87     json_response['repositories'].each do |repo|
88       next unless repo['uuid'] == repositories(:foo).uuid
89       assert_equal('R',
90                    repo['user_permissions'][users(:spectator).uuid]['gitolite_permissions'],
91                    "spectator user should have just R access to #{repo['uuid']}")
92       found_it = true
93     end
94     assert_equal true, found_it, "spectator user does not have R on foo repo"
95   end
96
97   test "get_all_permissions provides admin and active user keys" do
98     authorize_with :admin
99     get :get_all_permissions
100     assert_response :success
101     [:active, :admin].each do |u|
102       assert_equal(1, json_response['user_keys'][users(u).uuid].andand.count,
103                    "expected 1 key for #{u} (#{users(u).uuid})")
104       assert_equal(json_response['user_keys'][users(u).uuid][0]['public_key'],
105                    authorized_keys(u).public_key,
106                    "response public_key does not match fixture #{u}.")
107     end
108   end
109
110   test "get_all_permissions lists all repos regardless of permissions" do
111     act_as_system_user do
112       # Create repos that could potentially be left out of the
113       # permission list by accident.
114
115       # No authorized_key, no username (this can't even be done
116       # without skipping validations)
117       r = Repository.create name: 'root/testrepo'
118       assert r.save validate: false
119
120       r = Repository.create name: 'invalid username / repo name', owner_uuid: users(:inactive).uuid
121       assert r.save validate: false
122     end
123     authorize_with :admin
124     get :get_all_permissions
125     assert_response :success
126     assert_equal(Repository.count, json_response["repositories"].size)
127   end
128
129   test "get_all_permissions lists user permissions for users with no authorized keys" do
130     authorize_with :admin
131     AuthorizedKey.destroy_all
132     get :get_all_permissions
133     assert_response :success
134     assert_equal(Repository.count, json_response["repositories"].size)
135     repos_with_perms = []
136     json_response['repositories'].each do |repo|
137       if repo['user_permissions'].any?
138         repos_with_perms << repo['uuid']
139       end
140     end
141     assert_not_empty repos_with_perms, 'permissions are missing'
142   end
143
144   # Ensure get_all_permissions correctly describes what the normal
145   # permission system would do.
146   test "get_all_permissions obeys group permissions" do
147     act_as_user system_user do
148       r = Repository.create!(name: 'admin/groupcanwrite', owner_uuid: users(:admin).uuid)
149       g = Group.create!(group_class: 'group', name: 'repo-writers')
150       u1 = users(:active)
151       u2 = users(:spectator)
152       Link.create!(tail_uuid: g.uuid, head_uuid: r.uuid, link_class: 'permission', name: 'can_manage')
153       Link.create!(tail_uuid: u1.uuid, head_uuid: g.uuid, link_class: 'permission', name: 'can_write')
154       Link.create!(tail_uuid: u2.uuid, head_uuid: g.uuid, link_class: 'permission', name: 'can_read')
155
156       r = Repository.create!(name: 'admin/groupreadonly', owner_uuid: users(:admin).uuid)
157       g = Group.create!(group_class: 'group', name: 'repo-readers')
158       u1 = users(:active)
159       u2 = users(:spectator)
160       Link.create!(tail_uuid: g.uuid, head_uuid: r.uuid, link_class: 'permission', name: 'can_read')
161       Link.create!(tail_uuid: u1.uuid, head_uuid: g.uuid, link_class: 'permission', name: 'can_write')
162       Link.create!(tail_uuid: u2.uuid, head_uuid: g.uuid, link_class: 'permission', name: 'can_read')
163     end
164     authorize_with :admin
165     get :get_all_permissions
166     assert_response :success
167     json_response['repositories'].each do |repo|
168       repo['user_permissions'].each do |user_uuid, perms|
169         u = User.find_by_uuid(user_uuid)
170         if perms['can_read']
171           assert u.can? read: repo['uuid']
172           assert_match(/R/, perms['gitolite_permissions'])
173         else
174           refute_match(/R/, perms['gitolite_permissions'])
175         end
176         if perms['can_write']
177           assert u.can? write: repo['uuid']
178           assert_match(/RW\+/, perms['gitolite_permissions'])
179         else
180           refute_match(/W/, perms['gitolite_permissions'])
181         end
182         if perms['can_manage']
183           assert u.can? manage: repo['uuid']
184           assert_match(/RW\+/, perms['gitolite_permissions'])
185         end
186       end
187     end
188   end
189
190   test "default index includes fetch_url" do
191     authorize_with :active
192     get(:index)
193     assert_response :success
194     assert_includes(json_response["items"].map { |r| r["fetch_url"] },
195                     "git@git.zzzzz.arvadosapi.com:active/foo.git")
196   end
197
198   [
199     {cfg: :git_repo_ssh_base, cfgval: "git@example.com:", match: %r"^git@example.com:"},
200     {cfg: :git_repo_ssh_base, cfgval: true, match: %r"^git@git.zzzzz.arvadosapi.com:"},
201     {cfg: :git_repo_ssh_base, cfgval: false, refute: /^git@/ },
202     {cfg: :git_repo_https_base, cfgval: "https://example.com/", match: %r"^https://example.com/"},
203     {cfg: :git_repo_https_base, cfgval: true, match: %r"^https://git.zzzzz.arvadosapi.com/"},
204     {cfg: :git_repo_https_base, cfgval: false, refute: /^http/ },
205   ].each do |expect|
206     test "set #{expect[:cfg]} to #{expect[:cfgval]}" do
207       Rails.configuration.send expect[:cfg].to_s+"=", expect[:cfgval]
208       authorize_with :active
209       get :index
210       assert_response :success
211       assert_not_empty json_response['items']
212       json_response['items'].each do |r|
213         if expect[:refute]
214           r['clone_urls'].each do |u|
215             refute_match expect[:refute], u
216           end
217         else
218           assert((r['clone_urls'].any? do |u|
219                     expect[:match].match u
220                   end),
221                  "no match for #{expect[:match]} in #{r['clone_urls'].inspect}")
222         end
223       end
224     end
225   end
226
227   test "select push_url in index" do
228     authorize_with :active
229     get(:index, {select: ["uuid", "push_url"]})
230     assert_response :success
231     assert_includes(json_response["items"].map { |r| r["push_url"] },
232                     "git@git.zzzzz.arvadosapi.com:active/foo.git")
233   end
234
235   test "select clone_urls in index" do
236     authorize_with :active
237     get(:index, {select: ["uuid", "clone_urls"]})
238     assert_response :success
239     assert_includes(json_response["items"].map { |r| r["clone_urls"] }.flatten,
240                     "git@git.zzzzz.arvadosapi.com:active/foo.git")
241   end
242 end