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