<%= writable ? 'writable' : 'read-only' %>
</td>
<td style="word-break:break-all;">
- <code><%= writable ? repo[:push_url] : repo[:fetch_url] %></code>
+ <code><%= writable ? repo.push_url : repo.fetch_url %></code>
</td>
<td>
<% if writable == 'can_manage' %>
within '.modal-content' do
find 'label', text: 'Virtual Machine'
fill_in "email", :with => "foo@example.com"
- fill_in "repo_name", :with => "test_repo"
+ fill_in "repo_name", :with => "newtestrepo"
click_button "Submit"
wait_for_ajax
end
click_link 'Advanced'
click_link 'Metadata'
- assert page.has_text? 'Repository: test_repo'
+ assert page.has_text? 'Repository: foo/newtestrepo'
assert !(page.has_text? 'VirtualMachine:')
end
within '.modal-content' do
find 'label', text: 'Virtual Machine'
- fill_in "repo_name", :with => "test_repo"
+ fill_in "repo_name", :with => "activetestrepo"
click_button "Submit"
end
click_link 'Advanced'
click_link 'Metadata'
- assert page.has_text? 'Repository: test_repo'
+ assert page.has_text? 'Repository: active/activetestrepo'
assert !(page.has_text? 'VirtualMachine:')
# Click on Setup button again and this time also choose a VM
click_link 'Setup Active User'
within '.modal-content' do
- fill_in "repo_name", :with => "second_test_repo"
+ fill_in "repo_name", :with => "activetestrepo2"
select("testvm.shell", :from => 'vm_uuid')
click_button "Submit"
end
click_link 'Advanced'
click_link 'Metadata'
- assert page.has_text? 'Repository: second_test_repo'
+ assert page.has_text? 'Repository: active/activetestrepo2'
assert page.has_text? 'VirtualMachine: testvm.shell'
end
click_link 'Advanced'
click_link 'Metadata'
- assert !(page.has_text? 'Repository: test_repo')
- assert !(page.has_text? 'Repository: second_test_repo')
- assert !(page.has_text? 'VirtualMachine: testvm.shell')
+ assert page.has_no_text? 'Repository: active/'
+ assert page.has_no_text? 'VirtualMachine: testvm.shell'
# setup user again and verify links present
click_link 'Admin'
click_link 'Setup Active User'
within '.modal-content' do
- fill_in "repo_name", :with => "second_test_repo"
+ fill_in "repo_name", :with => "activetestrepo"
select("testvm.shell", :from => 'vm_uuid')
click_button "Submit"
end
click_link 'Advanced'
click_link 'Metadata'
- assert page.has_text? 'Repository: second_test_repo'
+ assert page.has_text? 'Repository: active/activetestrepo'
assert page.has_text? 'VirtualMachine: testvm.shell'
end
"name":"My md5 pipeline",
"components":{
"do_hash":{
- "repository":"$USER",
+ "repository":"$USER/$USER",
"script":"hash.py",
"script_version":"master",
"runtime_constraints":{
{
"job": {
"script": "hash.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": {
"input": "c1bad4b39ca5a924e481008009d94e32+210"
{
"job": {
"script": "hash.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "d00220fb38d4b85ca8fc28a8151702a2b9d1dec5",
"script_parameters": {
"input": "c1bad4b39ca5a924e481008009d94e32+210"
{
"job": {
"script": "hash.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": {
"input": "c1bad4b39ca5a924e481008009d94e32+210"
{
"job": {
"script": "hash.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": {
"input": "c1bad4b39ca5a924e481008009d94e32+210"
}
},
"filters": [["script", "=", "hash.py"],
- ["repository", "=", "<b>you</b>"],
+ ["repository", "=", "<b>you</b>/<b>you</b>"],
["script_version", "in git", "earlier_version_tag"],
["script_version", "not in git", "blacklisted_version_tag"]],
"find_or_create": true
}
</pre></notextile>
-Run the script "crunch_scripts/monte-carlo.py" in the repository "you" using the current "master" commit. Because it is marked as "nondeterministic", this job will not be considered as a suitable candidate for future job submissions that use the "find_or_create" feature.
+Run the script "crunch_scripts/monte-carlo.py" in the repository "you/you" using the current "master" commit. Because it is marked as "nondeterministic", this job will not be considered as a suitable candidate for future job submissions that use the "find_or_create" feature.
<notextile><pre>
{
"job": {
"script": "monte-carlo.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"nondeterministic": true,
"script_parameters": {
"components": {
"do_hash": {
"script": "hash.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": {
"input": {
},
"filter": {
"script": "0-filter.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": {
"input": {
"components": {
"cat_in_the_hat": {
"script": "cat.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": { }
},
"thing1": {
"script": "thing1.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": {
"input": {
},
"thing2": {
"script": "thing2.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": {
"input": {
"components": {
"thing1": {
"script": "thing1.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": { }
},
"thing2": {
"script": "thing2.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": { }
},
"cleanup": {
"script": "cleanup.py",
- "repository": "<b>you</b>",
+ "repository": "<b>you</b>/<b>you</b>",
"script_version": "master",
"script_parameters": {
"mess1": {
table(table table-bordered table-condensed).
|_. Attribute|_. Type|_. Description|_. Example|
-|name|string|||
-|fetch_url|string|||
-|push_url|string|||
+|name|string|The name of the repository on disk. Repository names must begin with a letter and contain only alphanumerics. Unless the repository is owned by the system user, the name must begin with the owner's username, then be separated from the base repository name with @/@. You may not create a repository that is owned by a user without a username.|@username/project1@|
+|fetch_url|string|The git remote's fetch URL for the repository. Read-only.||
+|push_url|string|The git remote's push URL for the repository. Read-only.||
<pre><code>~/$USER/crunch_scripts$ <span class="userinput">cat >~/the_job <<EOF
{
"script": "concurrent-hash.py",
- "repository": "$USER",
+ "repository": "$USER/$USER",
"script_version": "master",
"script_parameters":
{
~$ <span class="userinput">git config --global user.email $USER@example.com</span></code></pre>
</notextile>
-On the Arvados Workbench, navigate to "Code repositories":https://{{site.arvados_workbench_host}}/repositories. You should see a repository with your user name listed in the *name* column. Next to *name* is the column *push_url*. Copy the *push_url* value associated with your repository. This should look like <notextile><code>git@git.{{ site.arvados_api_host }}:$USER.git</code></notextile>.
+On the Arvados Workbench, navigate to "Code repositories":https://{{site.arvados_workbench_host}}/repositories. You should see a repository with your user name listed in the *name* column. Next to *name* is the column *push_url*. Copy the *push_url* value associated with your repository. This should look like <notextile><code>git@git.{{ site.arvados_api_host }}:$USER/$USER.git</code></notextile>.
Next, on the Arvados virtual machine, clone your Git repository:
<notextile>
<pre><code>~$ <span class="userinput">cd $HOME</span> # (or wherever you want to install)
-~$ <span class="userinput">git clone git@git.{{ site.arvados_api_host }}:$USER.git</span>
+~$ <span class="userinput">git clone git@git.{{ site.arvados_api_host }}:$USER/$USER.git</span>
Cloning into '$USER'...</code></pre>
</notextile>
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 682 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
-To git@git.qr1hi.arvadosapi.com:$USER.git
+To git@git.qr1hi.arvadosapi.com:$USER/$USER.git
* [new branch] master -> master</code></pre>
</notextile>
end
end
+ # It's not always possible to know the user's username when submitting
+ # this request. If it included a plain repository name, expand that to a
+ # user-owned name now.
+ if params[:repo_name].nil?
+ full_repo_name = nil
+ else
+ full_repo_name = "#{@object.username}/#{params[:repo_name]}"
+ end
if object_found
- @response = @object.setup_repo_vm_links params[:repo_name],
+ if params[:repo_name].andand.include?("/")
+ repo_name = params[:repo_name]
+ elsif @object.username.nil?
+ raise ArgumentError.
+ new("can't setup a user without a username with a repository")
+ else
+ repo_name = full_repo_name
+ end
+ @response = @object.setup_repo_vm_links repo_name,
params[:vm_uuid], params[:openid_prefix]
else
@response = User.setup @object, params[:openid_prefix],
- params[:repo_name], params[:vm_uuid]
+ full_repo_name, params[:vm_uuid]
end
# setup succeeded. send email to user
protected
- def self.repositories
- return @repositories if @repositories
-
- @repositories = {}
- @gitdirbase = Rails.configuration.git_repositories_dir
- Dir.foreach @gitdirbase do |repo|
- next if repo.match /^\./
- git_dir = File.join(@gitdirbase,
- repo.match(/\.git$/) ? repo : File.join(repo, '.git'))
- next if git_dir == Rails.configuration.git_internal_dir
- repo_name = repo.sub(/\.git$/, '')
- @repositories[repo_name] = {git_dir: git_dir}
- end
-
- @repositories
- end
+ def self.repositories
+ return @repositories if @repositories
+
+ @repositories = {}
+ Repository.find_each do |repo|
+ if git_dir = repo.server_path
+ @repositories[repo.name] = {git_dir: git_dir}
+ end
+ end
+
+ @repositories
+ end
end
include KindAndEtag
include CommonApiTemplate
+ # Order is important here. We must validate the owner before we can
+ # validate the name.
+ validate :valid_owner
+ validate :name_format, :if => Proc.new { |r| r.errors[:owner_uuid].empty? }
+ validates(:name, uniqueness: true, allow_nil: false)
+
api_accessible :user, extend: :common do |t|
t.add :name
t.add :fetch_url
t.add :push_url
end
+ def self.attributes_required_columns
+ super.merge({"push_url" => ["name"], "fetch_url" => ["name"]})
+ end
+
def push_url
- super || self.name && "git@git.#{Rails.configuration.uuid_prefix}.arvadosapi.com:#{self.name}.git"
+ "git@git.%s.arvadosapi.com:%s.git" % [Rails.configuration.uuid_prefix, name]
end
def fetch_url
- super || push_url
+ push_url
end
- protected
-
- def permission_to_create
- current_user and current_user.is_admin
+ def server_path
+ # Find where the repository is stored on the API server's filesystem,
+ # and return that path, or nil if not found.
+ # This method is only for the API server's internal use, and should not
+ # be exposed through the public API. Following our current gitolite
+ # setup, it searches for repositories stored by UUID, then name; and it
+ # prefers bare repositories over checkouts.
+ [["%s.git"], ["%s", ".git"]].each do |repo_base, *join_args|
+ [:uuid, :name].each do |path_attr|
+ git_dir = File.join(Rails.configuration.git_repositories_dir,
+ repo_base % send(path_attr), *join_args)
+ return git_dir if File.exist?(git_dir)
+ end
+ end
+ nil
end
+ protected
+
def permission_to_update
return false if not current_user
return true if current_user.is_admin
return super if changed_attributes.keys - ['modified_at', 'updated_at'] == []
false
end
+
+ def owner
+ User.find_by_uuid(owner_uuid)
+ end
+
+ def valid_owner
+ if owner.nil? or (owner.username.nil? and (owner.uuid != system_user_uuid))
+ errors.add(:owner_uuid, "must refer to a user with a username")
+ false
+ end
+ end
+
+ def name_format
+ if owner.uuid == system_user_uuid
+ prefix_match = ""
+ errmsg_start = "must be"
+ else
+ prefix_match = Regexp.escape(owner.username + "/")
+ errmsg_start = "must be the owner's username, then '/', then"
+ end
+ if not /^#{prefix_match}[A-Za-z][A-Za-z0-9]*$/.match(name)
+ errors.add(:name,
+ "#{errmsg_start} a letter followed by alphanumerics")
+ false
+ end
+ end
end
allow_nil: true)
before_update :prevent_privilege_escalation
before_update :prevent_inactive_admin
+ before_update :verify_repositories_empty, :if => Proc.new { |user|
+ user.username.nil? and user.username_changed?
+ }
before_create :check_auto_admin
before_create :set_initial_username, :if => Proc.new { |user|
user.username.nil? and user.email
}
after_create :send_admin_notifications
after_update :send_profile_created_notification
+ after_update :sync_repository_names, :if => Proc.new { |user|
+ (user.uuid != system_user_uuid) and
+ user.username_changed? and
+ (not user.username_was.nil?)
+ }
has_many :authorized_keys, :foreign_key => :authorized_user_uuid, :primary_key => :uuid
+ has_many :repositories, foreign_key: :owner_uuid, primary_key: :uuid
api_accessible :user, extend: :common do |t|
t.add :email
return
end
- repo = Repository.where(name: repo_name).first_or_create!
+ repo = Repository.where(owner_uuid: uuid, name: repo_name).first_or_create!
logger.info { "repo uuid: " + repo[:uuid] }
repo_perm = Link.where(tail_uuid: uuid, head_uuid: repo.uuid,
link_class: "permission",
if username
create_vm_login_permission_link(Rails.configuration.auto_setup_new_users_with_vm_uuid,
username)
+ repo_name = "#{username}/#{username}"
if Rails.configuration.auto_setup_new_users_with_repository and
- Repository.where(name: username).first.nil?
- repo = Repository.create!(name: username)
+ Repository.where(name: repo_name).first.nil?
+ repo = Repository.create!(name: repo_name, owner_uuid: uuid)
Link.create!(tail_uuid: uuid, head_uuid: repo.uuid,
link_class: "permission", name: "can_manage")
end
end
end
+ def verify_repositories_empty
+ unless repositories.first.nil?
+ errors.add(:username, "can't be unset when the user owns repositories")
+ false
+ end
+ end
+
+ def sync_repository_names
+ old_name_re = /^#{Regexp.escape(username_was)}\//
+ name_sub = "#{username}/"
+ repositories.find_each do |repo|
+ repo.name = repo.name.sub(old_name_re, name_sub)
+ repo.save!
+ end
+ end
end
--- /dev/null
+require 'has_uuid'
+require 'kind_and_etag'
+
+class BackwardCompatibilityForUserRepositories < ActiveRecord::Migration
+ include CurrentApiClient
+
+ class ArvadosModel < ActiveRecord::Base
+ self.abstract_class = true
+ extend HasUuid::ClassMethods
+ include CurrentApiClient
+ include KindAndEtag
+ before_create do |record|
+ record.uuid ||= record.class.generate_uuid
+ record.owner_uuid ||= system_user_uuid
+ end
+ serialize :properties, Hash
+
+ def self.to_s
+ # Clean up the name of the stub model class so we generate correct UUIDs.
+ super.rpartition("::").last
+ end
+ end
+
+ class Log < ArvadosModel
+ def self.log_for(thing, age="old")
+ { "#{age}_etag" => thing.etag,
+ "#{age}_attributes" => thing.attributes,
+ }
+ end
+
+ def self.log_create(thing)
+ new_log("create", thing, log_for(thing, "new"))
+ end
+
+ def self.log_update(thing, start_state)
+ new_log("update", thing, start_state.merge(log_for(thing, "new")))
+ end
+
+ def self.log_destroy(thing)
+ new_log("destroy", thing, log_for(thing, "old"))
+ end
+
+ private
+
+ def self.new_log(event_type, thing, properties)
+ create!(event_type: event_type,
+ event_at: Time.now,
+ object_uuid: thing.uuid,
+ object_owner_uuid: thing.owner_uuid,
+ properties: properties)
+ end
+ end
+
+ class Link < ArvadosModel
+ end
+
+ class Repository < ArvadosModel
+ end
+
+ def up
+ remove_index :repositories, name: "repositories_search_index"
+ add_index(:repositories, %w(uuid owner_uuid modified_by_client_uuid
+ modified_by_user_uuid name),
+ name: "repositories_search_index")
+ remove_column :repositories, :fetch_url
+ remove_column :repositories, :push_url
+
+ [Link, Log, Repository].each { |m| m.reset_column_information }
+ Repository.where("owner_uuid != ?", system_user_uuid).find_each do |repo|
+ link_attrs = {
+ tail_uuid: repo.owner_uuid,
+ link_class: "permission", name: "can_manage", head_uuid: repo.uuid,
+ }
+ if Link.where(link_attrs).first.nil?
+ manage_link = Link.create!(link_attrs)
+ Log.log_create(manage_link)
+ end
+ start_log = Log.log_for(repo)
+ repo.owner_uuid = system_user_uuid
+ repo.save!
+ Log.log_update(repo, start_log)
+ end
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration.
+ new("can't restore prior fetch and push URLs")
+ end
+end
modified_by_user_uuid character varying(255),
modified_at timestamp without time zone,
name character varying(255),
- fetch_url character varying(255),
- push_url character varying(255),
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
-- Name: repositories_search_index; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
-CREATE INDEX repositories_search_index ON repositories USING btree (uuid, owner_uuid, modified_by_client_uuid, modified_by_user_uuid, name, fetch_url, push_url);
+CREATE INDEX repositories_search_index ON repositories USING btree (uuid, owner_uuid, modified_by_client_uuid, modified_by_user_uuid, name);
--
INSERT INTO schema_migrations (version) VALUES ('20150312151136');
-INSERT INTO schema_migrations (version) VALUES ('20150317132720');
\ No newline at end of file
+INSERT INTO schema_migrations (version) VALUES ('20150317132720');
+
+INSERT INTO schema_migrations (version) VALUES ('20150324152204');
\ No newline at end of file
end
@repo_root = Rails.configuration.git_repositories_dir
+ @arvados_repo_path = Repository.where(name: "arvados").first.server_path
@authorizations = {}
@did_recently = {}
@fetched_commits = {}
@authorizations[job.uuid]
end
- def get_commit(repo_name, commit_hash)
+ def get_commit(src_repo, commit_hash)
# @fetched_commits[V]==true if we know commit V exists in the
# arvados_internal git repository.
if !@fetched_commits[commit_hash]
- src_repo = File.join(@repo_root, "#{repo_name}.git")
- if not File.exists? src_repo
- src_repo = File.join(@repo_root, repo_name, '.git')
- if not File.exists? src_repo
- fail_job job, "No #{repo_name}.git or #{repo_name}/.git at #{@repo_root}"
- return nil
- end
- end
-
# check if the commit needs to be fetched or not
commit_rev = stdout_s(git_cmd("rev-list", "-n1", commit_hash),
err: "/dev/null")
"GEM_PATH=#{ENV['GEM_PATH']}")
end
+ repo = Repository.where(name: job.repository).first
+ if repo.nil? or repo.server_path.nil?
+ fail_job "Repository #{job.repository} not found under #{@repo_root}"
+ next
+ end
+
ready = (get_authorization(job) and
- get_commit(job.repository, job.script_version) and
+ get_commit(repo.server_path, job.script_version) and
tag_commit(job.script_version, job.uuid))
if ready and job.arvados_sdk_version
- ready = (get_commit("arvados", job.arvados_sdk_version) and
+ ready = (get_commit(@arvados_repo_path, job.arvados_sdk_version) and
tag_commit(job.arvados_sdk_version, "#{job.uuid}-arvados-sdk"))
end
next unless ready
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
+system_user:
+ api_client: untrusted
+ user: system_user
+ api_token: systemusertesttoken1234567890aoeuidhtnsqjkxbmwvzpy
+ expires_at: 2038-01-01 00:00:00
+
admin:
api_client: untrusted
user: admin
cancelled_by_user_uuid: ~
cancelled_by_client_uuid: ~
script: hash
- repository: foo
+ repository: active/foo
script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250
script_parameters:
input: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45
finished_at: <%= 2.minute.ago.to_s(:db) %>
running: false
success: true
- repository: foo
+ repository: active/foo
output: ea10d51bcf88862dbcc36eb292017dfd+45
priority: 0
log: d41d8cd98f00b204e9800998ecf8427e+0
finished_at: <%= 2.minute.ago.to_s(:db) %>
running: true
success: ~
- repository: foo
+ repository: active/foo
output: ea10d51bcf88862dbcc36eb292017dfd+45
priority: 0
log: d41d8cd98f00b204e9800998ecf8427e+0
uuid: zzzzz-8i9sb-cjs4pklxxjykqqq
created_at: <%= 14.minute.ago.to_s(:db) %>
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
- repository: foo
+ repository: active/foo
script: hash
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
script_parameters:
uuid: zzzzz-8i9sb-k6emstgk4kw4yhi
created_at: <%= 14.minute.ago.to_s(:db) %>
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
- repository: foo
+ repository: active/foo
script: hash
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
script_parameters:
uuid: zzzzz-8i9sb-eoo0321or2dw2jg
created_at: <%= 14.minute.ago.to_s(:db) %>
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
- repository: foo
+ repository: active/foo
script: hash
script_version: 31ce37fe365b3dc204300a3e4c396ad333ed0556
script_parameters:
uuid: zzzzz-8i9sb-cjs4pklxxjykppp
created_at: <%= 14.minute.ago.to_s(:db) %>
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
- repository: foo
+ repository: active/foo
script: hash
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
script_parameters:
uuid: zzzzz-8i9sb-cjs4pklxxjykyyy
created_at: <%= 14.minute.ago.to_s(:db) %>
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
- repository: foo
+ repository: active/foo
script: hash2
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
script_parameters:
created_at: 2014-10-15 12:00:00
owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
log: ~
- repository: foo
+ repository: active/foo
script: hash
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
state: Complete
graph_stage1:
uuid: zzzzz-8i9sb-graphstage10000
owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
- repository: foo
+ repository: active/foo
script: hash
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
state: Complete
graph_stage2:
uuid: zzzzz-8i9sb-graphstage20000
owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
- repository: foo
+ repository: active/foo
script: hash2
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
state: Complete
graph_stage3:
uuid: zzzzz-8i9sb-graphstage30000
owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
- repository: foo
+ repository: active/foo
script: hash2
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
state: Complete
cancelled_by_user_uuid: ~
cancelled_by_client_uuid: ~
script: hash
- repository: foo
+ repository: active/foo
script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250
supplied_script_version: master
script_parameters:
uuid: zzzzz-8i9sb-n7omg50bvt0m1nf
owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0
modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
- repository: foo
+ repository: active/foo
script: running_job_script
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
state: Running
uuid: zzzzz-8i9sb-jyq01m7in1jlofj
owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0
modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
- repository: foo
+ repository: active/foo
script: completed_job_script
script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577
state: Complete
crunch_dispatch_test:
uuid: zzzzz-s0uqq-382brsig8rp3665
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user
- name: crunch_dispatch_test
+ name: active/crunchdispatchtest
created_at: 2015-01-01T00:00:00.123456Z
modified_at: 2015-01-01T00:00:00.123456Z
foo:
uuid: zzzzz-s0uqq-382brsig8rp3666
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user
- name: foo
+ name: active/foo
created_at: 2015-01-01T00:00:00.123456Z
modified_at: 2015-01-01T00:00:00.123456Z
repository2:
uuid: zzzzz-s0uqq-382brsig8rp3667
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user
- name: foo2
+ name: active/foo2
created_at: 2015-01-01T00:00:00.123456Z
modified_at: 2015-01-01T00:00:00.123456Z
repository3:
uuid: zzzzz-s0uqq-38orljkqpyo1j61
owner_uuid: zzzzz-tpzed-d9tiejq69daie8f # admin user
- name: foo3
+ name: admin/foo3
created_at: 2015-01-01T00:00:00.123456Z
modified_at: 2015-01-01T00:00:00.123456Z
repository4:
uuid: zzzzz-s0uqq-38oru8hnk57ht34
owner_uuid: zzzzz-tpzed-d9tiejq69daie8f # admin user
- name: foo4
- created_at: 2015-01-01T00:00:00.123456Z
- modified_at: 2015-01-01T00:00:00.123456Z
-
-auto_setup_repository:
- uuid: zzzzz-s0uqq-382brabc8rp3667
- owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user
- name: auto_setup_repo
+ name: admin/foo4
created_at: 2015-01-01T00:00:00.123456Z
modified_at: 2015-01-01T00:00:00.123456Z
identity_url: https://inactive-user.openid.local
is_active: false
is_admin: false
+ username: inactiveuser
prefs: {}
inactive_but_signed_user_agreement:
assert_includes(a, '077ba2ad3ea24a929091a9e6ce545c93199b8e57')
#test "test_branch2" do
- a = Commit.find_commit_range(users(:active), 'foo', nil, 'b1', nil)
+ a = Commit.find_commit_range(users(:active), 'active/foo', nil, 'b1', nil)
assert_equal ['1de84a854e2b440dc53bf42f8548afa4c17da332'], a
#test "test_branch3" do
- a = Commit.find_commit_range(users(:active), 'foo', nil, 'HEAD', nil)
+ a = Commit.find_commit_range(users(:active), 'active/foo', nil, 'HEAD', nil)
assert_equal ['1de84a854e2b440dc53bf42f8548afa4c17da332'], a
#test "test_single_revision_repo" do
- a = Commit.find_commit_range(users(:active), "foo", nil, '31ce37fe365b3dc204300a3e4c396ad333ed0556', nil)
+ a = Commit.find_commit_range(users(:active), "active/foo", nil, '31ce37fe365b3dc204300a3e4c396ad333ed0556', nil)
assert_equal ['31ce37fe365b3dc204300a3e4c396ad333ed0556'], a
- a = Commit.find_commit_range(users(:active), "bar", nil, '31ce37fe365b3dc204300a3e4c396ad333ed0556', nil)
+ a = Commit.find_commit_range(users(:active), "arvados", nil, '31ce37fe365b3dc204300a3e4c396ad333ed0556', nil)
assert_equal nil, a
#test "test_multi_revision" do
no_reuse: false,
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "tag1",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
no_reuse: true,
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
no_reuse: false,
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '2'
script: "hash",
minimum_script_version: "tag1",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
no_reuse: false,
script: "hash",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
no_reuse: false,
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '2'
no_reuse: false,
script: "hash",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '2'
no_reuse: false,
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
no_reuse: false,
script: "hash2",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
no_reuse: false,
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
script: "hash",
minimum_script_version: "31ce37fe365b3dc204300a3e4c396ad333ed0556",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
exclude_script_versions: ["tag1"],
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
job: {
script: "hash",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
end
BASE_FILTERS = {
- 'repository' => ['=', 'foo'],
+ 'repository' => ['=', 'active/foo'],
'script' => ['=', 'hash'],
'script_version' => ['in git', 'master'],
'docker_image_locator' => ['=', nil],
job: {
script: "hash",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
job: {
script: "hash",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1'
end
test "find Job with script version range" do
- get :index, filters: [["repository", "=", "foo"],
+ get :index, filters: [["repository", "=", "active/foo"],
["script", "=", "hash"],
["script_version", "in git", "tag1"]]
assert_response :success
end
test "find Job with script version range exclusions" do
- get :index, filters: [["repository", "=", "foo"],
+ get :index, filters: [["repository", "=", "active/foo"],
["script", "=", "hash"],
["script_version", "not in git", "tag1"]]
assert_response :success
params[:job] = {
script: "hash",
script_version: "4fe459abe02d9b365932b8f5dc419439ab4e2577",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {
input: 'fa7aeb5140e2848d39b416daeef4ffc5+45',
an_integer: '1',
post :create, job: {
script: "hash",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
script_parameters: {}
}
assert_response :success
script: "hash",
script_version: "master",
script_parameters: {},
- repository: "foo",
+ repository: "active/foo",
started_at: Time.now,
finished_at: Time.now,
running: false,
"response public_key does not match fixture #{u}.")
end
end
+
+ test "default index includes fetch_url" do
+ authorize_with :active
+ get(:index)
+ assert_response :success
+ assert_includes(json_response["items"].map { |r| r["fetch_url"] },
+ "git@git.zzzzz.arvadosapi.com:active/foo.git")
+ end
+
+ test "can select push_url in index" do
+ authorize_with :active
+ get(:index, {select: ["uuid", "push_url"]})
+ assert_response :success
+ assert_includes(json_response["items"].map { |r| r["push_url"] },
+ "git@git.zzzzz.arvadosapi.com:active/foo.git")
+ end
end
test "create user with user, vm and repo as input" do
authorize_with :admin
- repo_name = 'test_repo'
+ repo_name = 'usertestrepo'
post :setup, {
repo_name: repo_name,
created['uuid'], created['email'], 'arvados#user', false, 'User'
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- repo_name, created['uuid'], 'arvados#repository', true, 'Repository'
+ "foo/#{repo_name}", created['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
post :setup, {
uuid: 'bogus_uuid',
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
vm_uuid: @vm_uuid
}
response_body = JSON.parse(@response.body)
post :setup, {
user: {uuid: 'bogus_uuid'},
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
vm_uuid: @vm_uuid,
openid_prefix: 'https://www.google.com/accounts/o8/id'
}
authorize_with :admin
post :setup, {
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
vm_uuid: @vm_uuid,
openid_prefix: 'https://www.google.com/accounts/o8/id'
}
post :setup, {
user: {},
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
vm_uuid: @vm_uuid,
openid_prefix: 'https://www.google.com/accounts/o8/id'
}
post :setup, {
uuid: users(:inactive).uuid,
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
vm_uuid: @vm_uuid
}
# expect repo and vm links
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- 'test_repo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
+ 'inactiveuser/usertestrepo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
@vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
authorize_with :admin
post :setup, {
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
user: {email: 'foo@example.com'},
openid_prefix: 'https://www.google.com/accounts/o8/id'
}
authorize_with :admin
post :setup, {
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
vm_uuid: 'no_such_vm',
user: {email: 'foo@example.com'},
openid_prefix: 'https://www.google.com/accounts/o8/id'
authorize_with :admin
post :setup, {
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
openid_prefix: 'https://www.google.com/accounts/o8/id',
vm_uuid: @vm_uuid,
user: {email: 'foo@example.com'}
'All users', response_object['uuid'], 'arvados#group', true, 'Group'
verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
- 'test_repo', response_object['uuid'], 'arvados#repository', true, 'Repository'
+ 'foo/usertestrepo', response_object['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
post :setup, {
openid_prefix: 'https://www.google.com/accounts/o8/id',
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
vm_uuid: @vm_uuid,
user: {
first_name: 'test_first_name',
post :setup, {
openid_prefix: 'https://www.google.com/accounts/o8/id',
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
user: {
email: inactive_user['email']
}
authorize_with :admin
post :setup, {
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
openid_prefix: 'http://www.example.com/account',
user: {
first_name: "in_create_test_first_name",
created['uuid'], created['email'], 'arvados#user', false, 'User'
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- 'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
+ 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
authorize_with :admin
post :setup, {
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
user: {
first_name: "in_create_test_first_name",
last_name: "test_last_name",
email: "foo@example.com"
},
vm_uuid: @vm_uuid,
- repo_name: 'test_repo',
+ repo_name: 'usertestrepo',
openid_prefix: 'https://www.google.com/accounts/o8/id'
}
created['uuid'], created['email'], 'arvados#user', false, 'User'
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- 'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
+ 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
# invoke setup with a repository
post :setup, {
- repo_name: 'new_repo',
+ repo_name: 'usertestrepo',
uuid: active_user['uuid']
}
'All users', created['uuid'], 'arvados#group', true, 'Group'
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- 'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
+ 'active/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
test "setup active user with vm and no repo" do
authorize_with :admin
active_user = users(:active)
+ repos_query = Repository.where(owner_uuid: active_user.uuid)
+ repo_link_query = Link.where(tail_uuid: active_user.uuid,
+ link_class: "permission", name: "can_manage")
+ repos_count = repos_query.count
+ repo_link_count = repo_link_query.count
# invoke setup with a repository
post :setup, {
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
- verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
- 'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
+ assert_equal(repos_count, repos_query.count)
+ assert_equal(repo_link_count, repo_link_query.count)
verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
@vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
format: "json",
job: {
script: "log",
- repository: "crunch_dispatch_test",
+ repository: "active/crunchdispatchtest",
script_version: "f35f99b7d32bac257f5989df02b9f12ee1a9b0d6",
script_parameters: "{}"
}
human: {properties: {eye_color: 'gray'}},
job: {
- repository: 'foo',
+ repository: 'active/foo',
runtime_constraints: {docker_image: 'arvados/apitestfixture'},
script: 'hash',
script_version: 'master',
include UsersTestHelper
test "setup user multiple times" do
- repo_name = 'test_repo'
+ repo_name = 'usertestrepo'
post "/arvados/v1/users/setup", {
repo_name: repo_name,
created['uuid'], created['email'], 'arvados#user', false, 'arvados#user'
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- repo_name, created['uuid'], 'arvados#repository', true, 'Repository'
+ 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
# arvados#user, repo link and link add user to 'All users' group
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- repo_name, created['uuid'], 'arvados#repository', true, 'Repository'
+ 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
- verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
- 'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
-
verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
# invoke setup with a repository
post "/arvados/v1/users/setup", {
openid_prefix: 'http://www.example.com/account',
- repo_name: 'new_repo',
+ repo_name: 'newusertestrepo',
uuid: created['uuid']
}, auth(:admin)
'All users', created['uuid'], 'arvados#group', true, 'Group'
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- 'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
+ 'foo/newusertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
- # since no repo name in input, we won't get any; even though user has one
- verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
- 'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
-
verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
virtual_machines(:testvm).uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
end
test "setup and unsetup user" do
post "/arvados/v1/users/setup", {
- repo_name: 'test_repo',
+ repo_name: 'newusertestrepo',
vm_uuid: virtual_machines(:testvm).uuid,
user: {email: 'foo@example.com'},
openid_prefix: 'https://www.google.com/accounts/o8/id'
'All users', created['uuid'], 'arvados#group', true, 'Group'
verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
- 'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
+ 'foo/newusertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
virtual_machines(:testvm).uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
restore_configuration
end
+ def assert_not_allowed
+ # Provide a block that calls a Rails boolean "true or false" success value,
+ # like model.save or model.destroy. This method will test that it either
+ # returns false, or raises a Permission Denied exception.
+ begin
+ refute(yield)
+ rescue ArvadosModel::PermissionDeniedError
+ end
+ end
+
def restore_configuration
# Restore configuration settings changed during tests
$application_config.each do |k,v|
{
script: "hash",
script_version: "master",
- repository: "foo",
+ repository: "active/foo",
}.merge(merge_me)
end
ob.update_attributes!(owner_uuid: groups(:aproject).uuid)
end
end
-
- test "active user cannot write admin's repo" do
- set_user_from_auth :active
- assert_raises ArvadosModel::PermissionDeniedError, "pwned" do
- repositories(:repository3).update_attributes(name: "kilroy")
- end
- end
-
- test "active user cannot change repo name via can_manage permission" do
- set_user_from_auth :active
- assert_raises ArvadosModel::PermissionDeniedError, "pwned" do
- repositories(:foo).update_attributes(name: "arvados")
- end
- end
end
require 'test_helper'
+require 'helpers/git_test_helper'
class RepositoryTest < ActiveSupport::TestCase
+ include GitTestHelper
+
+ def new_repo(owner_key, attrs={})
+ set_user_from_auth owner_key
+ owner = users(owner_key)
+ Repository.new({owner_uuid: owner.uuid}.merge(attrs))
+ end
+
+ def changed_repo(repo_key, changes)
+ repo = repositories(repo_key)
+ changes.each_pair { |attr, value| repo.send("#{attr}=".to_sym, value) }
+ repo
+ end
+
+ def default_git_url(repo_name, user_name=nil)
+ if user_name
+ "git@git.%s.arvadosapi.com:%s/%s.git" %
+ [Rails.configuration.uuid_prefix, user_name, repo_name]
+ else
+ "git@git.%s.arvadosapi.com:%s.git" %
+ [Rails.configuration.uuid_prefix, repo_name]
+ end
+ end
+
+ def assert_server_path(path_tail, repo_sym)
+ assert_equal(File.join(Rails.configuration.git_repositories_dir, path_tail),
+ repositories(repo_sym).server_path)
+ end
+
+ ### name validation
+
+ {active: "active/", admin: "admin/", system_user: ""}.
+ each_pair do |user_sym, name_prefix|
+ %w(a aa a0 aA Aa AA A0).each do |name|
+ test "'#{name_prefix}#{name}' is a valid name for #{user_sym} repo" do
+ repo = new_repo(user_sym, name: name_prefix + name)
+ assert(repo.valid?)
+ end
+ end
+
+ test "name is required for #{user_sym} repo" do
+ refute(new_repo(user_sym).valid?)
+ end
+
+ test "repo name beginning with numeral is invalid for #{user_sym}" do
+ repo = new_repo(user_sym, name: "#{name_prefix}0a")
+ refute(repo.valid?)
+ end
+
+ "\\.-_/!@#$%^&*()[]{}".each_char do |bad_char|
+ test "name containing #{bad_char.inspect} is invalid for #{user_sym}" do
+ repo = new_repo(user_sym, name: "#{name_prefix}bad#{bad_char}reponame")
+ refute(repo.valid?)
+ end
+ end
+ end
+
+ test "admin can create valid repo for other user with correct name prefix" do
+ owner = users(:active)
+ repo = new_repo(:admin, name: "#{owner.username}/validnametest",
+ owner_uuid: owner.uuid)
+ assert(repo.valid?)
+ end
+
+ test "admin can create valid system repo without name prefix" do
+ repo = new_repo(:admin, name: "validnametest",
+ owner_uuid: users(:system_user).uuid)
+ assert(repo.valid?)
+ end
+
+ test "repo name prefix must match owner_uuid username" do
+ repo = new_repo(:admin, name: "admin/badusernametest",
+ owner_uuid: users(:active).uuid)
+ refute(repo.valid?)
+ end
+
+ test "repo name prefix must be empty for system repo" do
+ repo = new_repo(:admin, name: "root/badprefixtest",
+ owner_uuid: users(:system_user).uuid)
+ refute(repo.valid?)
+ end
+
+ ### owner validation
+
+ test "name must be unique per user" do
+ repo = new_repo(:active, name: repositories(:foo).name)
+ refute(repo.valid?)
+ end
+
+ test "name can be duplicated across users" do
+ repo = new_repo(:active, name: "active/#{repositories(:arvados).name}")
+ assert(repo.valid?)
+ end
+
+ test "repository cannot be owned by a group" do
+ set_user_from_auth :active
+ repo = Repository.new(owner_uuid: groups(:all_users).uuid,
+ name: "ownedbygroup")
+ refute(repo.valid?)
+ refute_empty(repo.errors[:owner_uuid] || [])
+ end
+
+ ### URL generation
+
+ test "fetch_url" do
+ repo = new_repo(:active, name: "active/fetchtest")
+ assert_equal(default_git_url("fetchtest", "active"), repo.fetch_url)
+ end
+
+ test "fetch_url owned by system user" do
+ set_user_from_auth :admin
+ repo = Repository.new(owner_uuid: users(:system_user).uuid,
+ name: "fetchtest")
+ assert_equal(default_git_url("fetchtest"), repo.fetch_url)
+ end
+
+ test "push_url" do
+ repo = new_repo(:active, name: "active/pushtest")
+ assert_equal(default_git_url("pushtest", "active"), repo.push_url)
+ end
+
+ test "push_url owned by system user" do
+ set_user_from_auth :admin
+ repo = Repository.new(owner_uuid: users(:system_user).uuid,
+ name: "pushtest")
+ assert_equal(default_git_url("pushtest"), repo.push_url)
+ end
+
+ ### Path generation
+
+ test "disk path stored by UUID" do
+ assert_server_path("zzzzz-s0uqq-382brsig8rp3666/.git", :foo)
+ end
+
+ test "disk path stored by name" do
+ assert_server_path("arvados/.git", :arvados)
+ end
+
+ test "disk path for repository not on disk" do
+ assert_nil(Repository.new.server_path)
+ end
+
+ ### Repository creation
+
+ test "non-admin can create a repository for themselves" do
+ repo = new_repo(:active, name: "active/newtestrepo")
+ assert(repo.save)
+ end
+
+ test "non-admin can't create a repository for another visible user" do
+ repo = new_repo(:active, name: "repoforanon",
+ owner_uuid: users(:anonymous).uuid)
+ assert_not_allowed { repo.save }
+ end
+
+ test "admin can create a repository for themselves" do
+ repo = new_repo(:admin, name: "admin/newtestrepo")
+ assert(repo.save)
+ end
+
+ test "admin can create a repository for others" do
+ repo = new_repo(:admin, name: "active/repoforactive",
+ owner_uuid: users(:active).uuid)
+ assert(repo.save)
+ end
+
+ test "admin can create a system repository" do
+ repo = new_repo(:admin, name: "repoforsystem",
+ owner_uuid: users(:system_user).uuid)
+ assert(repo.save)
+ end
+
+ ### Repository destruction
+
+ test "non-admin can destroy their own repository" do
+ set_user_from_auth :active
+ assert(repositories(:foo).destroy)
+ end
+
+ test "non-admin can't destroy others' repository" do
+ set_user_from_auth :active
+ assert_not_allowed { repositories(:repository3).destroy }
+ end
+
+ test "non-admin can't destroy system repository" do
+ set_user_from_auth :active
+ assert_not_allowed { repositories(:arvados).destroy }
+ end
+
+ test "admin can destroy their own repository" do
+ set_user_from_auth :admin
+ assert(repositories(:repository3).destroy)
+ end
+
+ test "admin can destroy others' repository" do
+ set_user_from_auth :admin
+ assert(repositories(:foo).destroy)
+ end
+
+ test "admin can destroy system repository" do
+ set_user_from_auth :admin
+ assert(repositories(:arvados).destroy)
+ end
+
+ ### Changing ownership
+
+ test "non-admin can't make their repository a system repository" do
+ set_user_from_auth :active
+ repo = changed_repo(:foo, owner_uuid: users(:system_user).uuid)
+ assert_not_allowed { repo.save }
+ end
+
+ test "admin can give their repository to someone else" do
+ set_user_from_auth :admin
+ repo = changed_repo(:repository3, owner_uuid: users(:active).uuid,
+ name: "active/foo3")
+ assert(repo.save)
+ end
+
+ test "admin can make their repository a system repository" do
+ set_user_from_auth :admin
+ repo = changed_repo(:repository3, owner_uuid: users(:system_user).uuid,
+ name: "foo3")
+ assert(repo.save)
+ end
+
test 'write permission allows changing modified_at' do
act_as_user users(:active) do
r = repositories(:foo)
end
test "non-admin can't update username" do
- set_user_from_auth :active_trustedclient
- user = User.find_by_uuid(users(:active).uuid)
+ set_user_from_auth :rominiadmin
+ user = User.find_by_uuid(users(:rominiadmin).uuid)
user.username = "selfupdate"
- begin
- refute(user.save)
- rescue ArvadosModel::PermissionDeniedError
- # That works too.
- end
+ assert_not_allowed { user.save }
end
def check_admin_username_change(fixture_name)
check_new_username_setting("_", nil)
end
+ test "updating username updates repository names" do
+ set_user_from_auth :admin
+ user = users(:active)
+ user.username = "newtestname"
+ assert(user.save, "username update failed")
+ {foo: "newtestname/foo", repository2: "newtestname/foo2"}.
+ each_pair do |repo_sym, expect_name|
+ assert_equal(expect_name, repositories(repo_sym).name)
+ end
+ end
+
+ test "admin can clear username when user owns no repositories" do
+ set_user_from_auth :admin
+ user = users(:spectator)
+ user.username = nil
+ assert(user.save)
+ assert_nil(user.username)
+ end
+
+ test "admin can't clear username when user owns repositories" do
+ set_user_from_auth :admin
+ user = users(:active)
+ start_username = user.username
+ user.username = nil
+ assert_not_allowed { user.save }
+ refute_empty(user.errors[:username])
+ end
+
+ test "failed username update doesn't change repository names" do
+ set_user_from_auth :admin
+ user = users(:active)
+ user.username = users(:fuse).username
+ assert_not_allowed { user.save }
+ assert_equal("active/foo", repositories(:foo).name)
+ end
+
[[false, 'foo@example.com', true, nil],
[false, 'bar@example.com', nil, true],
[true, 'foo@example.com', true, nil],
test "create new user as non-admin user" do
set_user_from_auth :active
-
- begin
- user = User.new
- user.save
- rescue ArvadosModel::PermissionDeniedError => e
- end
- assert (e.message.include? 'PermissionDeniedError'),
- 'Expected PermissionDeniedError'
+ assert_not_allowed { User.new.save }
end
test "setup new user" do
vm = VirtualMachine.create
- response = User.setup user, openid_prefix, 'test_repo', vm.uuid
+ response = User.setup user, openid_prefix, 'foo/testrepo', vm.uuid
resp_user = find_obj_in_resp response, 'User'
verify_user resp_user, email
verify_link resp_link, 'permission', 'can_login', email, bad_uuid
- response = User.setup user, openid_prefix, 'test_repo', vm.uuid
+ response = User.setup user, openid_prefix, 'foo/testrepo', vm.uuid
resp_user = find_obj_in_resp response, 'User'
verify_user resp_user, email
verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
# invoke setup again with repo_name
- response = User.setup user, openid_prefix, 'test_repo'
+ response = User.setup user, openid_prefix, 'foo/testrepo'
resp_user = find_obj_in_resp response, 'User', nil
verify_user resp_user, email
assert_equal user.uuid, resp_user[:uuid], 'expected uuid not found'
# invoke setup again with a vm_uuid
vm = VirtualMachine.create
- response = User.setup user, openid_prefix, 'test_repo', vm.uuid
+ response = User.setup user, openid_prefix, 'foo/testrepo', vm.uuid
resp_user = find_obj_in_resp response, 'User', nil
verify_user resp_user, email
can_setup = (Rails.configuration.auto_setup_new_users and
(not expect_username.nil?))
- prior_repo = Repository.where(name: expect_username).first
+ expect_repo_name = "#{expect_username}/#{expect_username}"
+ prior_repo = Repository.where(name: expect_repo_name).first
user = User.new
user.first_name = "first_name_for_newly_created_user"
user.uuid, user.email, "permission", "can_login")
# Check for repository.
if named_repo = (prior_repo or
- Repository.where(name: expect_username).first)
+ Repository.where(name: expect_repo_name).first)
verify_link_exists((can_setup and prior_repo.nil? and
Rails.configuration.auto_setup_new_users_with_repository),
named_repo.uuid, user.uuid, "permission", "can_manage")