<% render_pipeline_jobs.each do |pj| %>
<tr>
<td>
- <% job_status = render(partial: 'job_status_label',
+ <% job_status = render(partial: 'job_status_label',
locals: { :j => pj[:job], :title => pj[:name] }) %>
<% if pj[:job].andand[:uuid] %>
<%= link_to(job_status, job_url(id: pj[:job][:uuid])) %>
</td><td>
<%= pj[:progress_bar] %>
</td><td>
- <%= render(partial: 'job_status_label',
+ <%= render(partial: 'job_status_label',
locals: { :j => pj[:job] }) %>
</td><td>
<%= link_to_if_arvados_object pj[:output] %>
<% content_for :tab_line_buttons do %>
<%= form_tag @object, :method => :put do |f| %>
-
+
<%= hidden_field @object.class.to_s.underscore.singularize.to_sym, :active, :value => false %>
<%= button_tag "Stop pipeline", {class: 'btn btn-primary pull-right', id: "run-pipeline-button"} %>
<% content_for :tab_line_buttons do %>
<%= form_tag @object, :method => :put do |f| %>
-
+
<%= hidden_field @object.class.to_s.underscore.singularize.to_sym, :active, :value => true %>
<%= button_tag "Run pipeline", {class: 'btn btn-primary pull-right', id: "run-pipeline-button"} %>
<% end %>
<%= render partial: 'pipeline_templates/show_components_template', locals: {:template => template, :obj => @object} %>
-
+
<% end %>
$ <code class="userinput">sudo gem install arvados-cli-*.gem</code>
</pre>
</notextile>
-
* The component is listed with a human-readable name (@"do_hash"@ in this example)
* @"script"@ specifies the name of the script to run. The script is searched for in the "crunch_scripts/" subdirectory of the @git@ checkout specified by @"script_version"@.
* @"repository"@ is the git repository to search for the script version. You can access a list of available @git@ repositories on the Arvados workbench under "Compute %(rarr)→% Code repositories":https://{{site.arvados_workbench_host}}//repositories .
-* @"script_version"@ specifies the version of the script that you wish to run. This can be in the form of an explicit @git@ revision hash, a tag, or a branch (in which case it will take the HEAD of the specified branch). Arvados logs the script version that was used in the run, enabling you to go back and re-run any past job with the guarantee that the exact same code will be used as was used in the previous run.
+* @"script_version"@ specifies the version of the script that you wish to run. This can be in the form of an explicit @git@ revision hash, a tag, or a branch (in which case it will take the HEAD of the specified branch). Arvados logs the script version that was used in the run, enabling you to go back and re-run any past job with the guarantee that the exact same code will be used as was used in the previous run.
* @"script_parameters"@ describes the parameters for the script. In this example, there is one parameter called @input@ which is @required@ and is a @Collection@.
* @"output_is_persistent"@ indicates whether the output of the job is considered valuable. If this value is false (or not given), the output will be treated as intermediate data and eventually deleted to reclaim disk space.
if (c[:job][:running] or
not (c[:job][:finished_at] or c[:job][:cancelled_at]))
# Job is running so update copy of job record
- c[:job] = JobCache.get(c[:job][:uuid])
+ c[:job] = JobCache.get(c[:job][:uuid])
end
if c[:job][:success]
end
end
end
-
+
if ended == @components.length or failed > 0
@instance[:active] = false
@instance[:success] = (succeeded == @components.length)
skip_before_filter :render_404_if_no_object, :only => :queue
def create
- [:repository, :script, :script_version, :script_parameters].each do |r|
+ [:repository, :script, :script_version, :script_parameters].each do |r|
if !resource_attrs[r]
return render json: {
:error => "#{r} attribute must be specified"
- }, status: :unprocessable_entity
+ }, status: :unprocessable_entity
end
end
Job.readable_by(current_user).where(script: resource_attrs[:script],
script_version: r).
each do |j|
- if j.nondeterministic != true and
- j.success != false and
+ if j.nondeterministic != true and
+ j.success != false and
j.script_parameters == resource_attrs[:script_parameters]
# Record the first job in the list
if !@object
skip_before_filter :render_404_if_no_object, only:
[:activate, :event_stream, :current, :system, :setup]
before_filter :admin_required, only: [:setup, :unsetup]
-
+
def current
@object = current_user
show
end
end
end
-
+
def event_stream
channel = current_user.andand.uuid
if current_user.andand.is_admin
end
return [oid_login_perm] + user.setup_repo_vm_links(repo_name, vm_uuid)
- end
+ end
# create links
def setup_repo_vm_links(repo_name, vm_uuid)
group_perm = create_user_group_link
return [repo_perm, vm_login_perm, group_perm, self].compact
- end
+ end
# delete user signatures, login, repo, and vm perms, and mark as inactive
def unsetup
# mark the user as inactive
self.is_active = false
self.save!
- end
+ end
protected
link_class: 'permission',
name: 'can_write')
if repo_perms.any?
- logger.warn "User already has repository access " +
+ logger.warn "User already has repository access " +
repo_perms.collect { |p| p[:uuid] }.inspect
return repo_perms.first
end
# create login permission for the given vm_uuid, if it does not already exist
def create_vm_login_permission_link(vm_uuid, repo_name)
begin
-
+
# vm uuid is optional
- if vm_uuid
+ if vm_uuid
vm = VirtualMachine.where(uuid: vm_uuid).first
if not vm
raise "No vm found for #{vm_uuid}"
end
else
- return
+ return
end
logger.info { "vm uuid: " + vm[:uuid] }
link_class: 'permission',
name: 'can_read')
logger.info { "group permission: " + group_perm[:uuid] }
- else
+ else
group_perm = group_perms.first
end
end
log.level = (ENV['DEBUG'] || opts.debug) ? Logger::DEBUG : Logger::WARN
-
+
if ARGV.count != 3
Trollop::die "required arguments are missing"
end
found_user = arv.user.get(uuid: user_arg)
rescue Arvados::TransactionFailedError
found = arv.user.list(where: {email: user_arg})[:items]
-
- if found.count == 0
+
+ if found.count == 0
if !user_arg.match(/\w\@\w+\.\w+/)
abort "About to create new user, but #{user_arg.inspect} " +
"does not look like an email address. Stop."
repo_name: repo_name,
openid_prefix: 'https://www.google.com/accounts/o8/id',
user: {
- uuid: "this_is_agreeable",
+ uuid: "this_is_agreeable",
first_name: "in_create_test_first_name",
last_name: "test_last_name",
email: "foo@example.com"
assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
assert_equal 'this_is_agreeable', created['uuid']
assert_not_nil created['email'], 'expected non-nil email'
- assert_nil created['identity_url'], 'expected no identity_url'
+ assert_nil created['identity_url'], 'expected no identity_url'
# arvados#user, repo link and link add user to 'All users' group
verify_num_links @all_links_at_start, 3
get :current
assert_response :success
inactive_user = JSON.parse(@response.body)
-
+
authorize_with :admin
post :setup, {
assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
assert_equal inactive_user['uuid'], resp_obj['uuid']
- assert_equal inactive_user['email'], resp_obj['email'],
+ assert_equal inactive_user['email'], resp_obj['email'],
'expecting inactive user email'
# expect repo and vm links
get :current
assert_response :success
inactive_user = JSON.parse(@response.body)
-
+
authorize_with :admin
post :setup, {
assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
assert_equal inactive_user['uuid'], resp_obj['uuid']
- assert_equal inactive_user['email'], resp_obj['email'],
+ assert_equal inactive_user['email'], resp_obj['email'],
'expecting inactive user email'
end
get :current
assert_response :success
inactive_user = JSON.parse(@response.body)
-
+
authorize_with :admin
post :setup, {
assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
assert_equal inactive_user['uuid'], resp_obj['uuid']
- assert_equal inactive_user['email'], resp_obj['email'],
+ assert_equal inactive_user['email'], resp_obj['email'],
'expecting inactive user email'
end
response_body = JSON.parse(@response.body)
response_errors = response_body['errors']
assert_not_nil response_errors, 'Expected error in response'
- assert (response_errors.first.include? "No vm found for no_such_vm"),
+ assert (response_errors.first.include? "No vm found for no_such_vm"),
'Expected RuntimeError: No vm found for no_such_vm'
end
openid_prefix: 'https://www.google.com/accounts/o8/id'
}
- assert_response :success
+ assert_response :success
response_items = JSON.parse(@response.body)['items']
response_object = find_obj_in_resp response_items, 'User', nil
assert_not_nil response_object['uuid'], 'expected uuid for new user'
response_object = find_obj_in_resp response_items, 'User', nil
assert_not_nil response_object['uuid'], 'expected uuid for new user'
assert_equal response_object['email'], 'foo@example.com', 'expected given email'
- assert_equal 'test_first_name', response_object['first_name'],
+ assert_equal 'test_first_name', response_object['first_name'],
'expecting first name'
# four extra links; login link, group link, repo link and vm link
assert_response :success
response_items = JSON.parse(@response.body)['items']
response_object2 = find_obj_in_resp response_items, 'User', nil
- assert_not_equal response_object['uuid'], response_object2['uuid'],
+ assert_not_equal response_object['uuid'], response_object2['uuid'],
'expected same uuid as first create operation'
assert_equal response_object['email'], 'foo@example.com', 'expected given email'
assert_equal 'in_create_test_first_name', created['first_name']
assert_not_nil created['uuid'], 'expected uuid for new user'
assert_not_nil created['email'], 'expected non-nil email'
- assert_nil created['identity_url'], 'expected no identity_url'
+ assert_nil created['identity_url'], 'expected no identity_url'
# verify links
# 3 new links: arvados#user, repo, and 'All users' group.
assert_equal 'in_create_test_first_name', created['first_name']
assert_not_nil created['uuid'], 'expected uuid for new user'
assert_not_nil created['email'], 'expected non-nil email'
- assert_nil created['identity_url'], 'expected no identity_url'
+ assert_nil created['identity_url'], 'expected no identity_url'
# expect 4 new links: arvados#user, repo, vm and 'All users' group link
verify_num_links @all_links_at_start, 4
verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
'All users', created['uuid'], 'arvados#group', true, 'Group'
- verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
+ verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
@vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
end
response_body = JSON.parse(@response.body)
response_errors = response_body['errors']
assert_not_nil response_errors, 'Expected error in response'
- assert (response_errors.first.include? 'PermissionDenied'),
+ assert (response_errors.first.include? 'PermissionDenied'),
'Expected PermissionDeniedError'
end
response_body = JSON.parse(@response.body)
response_errors = response_body['errors']
assert_not_nil response_errors, 'Expected error in response'
- assert (response_errors.first.include? 'Forbidden'),
+ assert (response_errors.first.include? 'Forbidden'),
'Expected Forbidden error'
end
created2 = JSON.parse(@response.body)
assert_not_nil created2['uuid'], 'expected uuid for the newly created user'
assert_equal created['uuid'], created2['uuid'], 'expected uuid not found'
-
+
verify_link_existence created['uuid'], created['email'], false, false, false, false
end
link = find_obj_in_resp response_items, 'Link', link_object_name
- if !expect_link
+ if !expect_link
assert_nil link, "Expected no link for #{link_object_name}"
return
end
end
assert_equal link['link_class'], link_class,
"did not find expected link_class for #{link_object_name}"
-
+
assert_equal link['name'], link_name,
"did not find expected link_name for #{link_object_name}"
-
+
assert_equal link['tail_uuid'], tail_uuid,
"did not find expected tail_uuid for #{link_object_name}"
-
+
assert_equal link['head_kind'], head_kind,
"did not find expected head_kind for #{link_object_name}"
-
+
assert_equal link['head_uuid'], head_uuid,
"did not find expected head_uuid for #{link_object_name}"
end
signed_uuids = Link.where(link_class: 'signature',
tail_kind: 'arvados#user',
tail_uuid: uuid)
-
+
if expect_signatures
assert signed_uuids.any?, "expected singnatures"
else
require 'test_helper'
class UserTest < ActiveSupport::TestCase
- # test "the truth" do
- # assert true
- # end
+
+ # The fixture services/api/test/fixtures/users.yml serves as the input for this test case
+ setup do
+ @all_users = User.find(:all)
+
+ @all_users.each do |user|
+ if user.is_admin && user.is_active
+ @admin_user = user
+ elsif user.is_active && !user.is_admin
+ @active_user = user
+ elsif !user.is_active && !user.is_invited
+ @uninvited_user = user
+ end
+ end
+ end
+
+ test "check non-admin active user properties" do
+ assert !@active_user.is_admin, 'is_admin should not be set for a non-admin user'
+ assert @active_user.is_active, 'user should be active'
+ assert @active_user.is_invited, 'is_invited should be set'
+ assert_not_nil @active_user.prefs, "user's preferences should be non-null, but may be size zero"
+ assert (@active_user.can? :read=>"#{@active_user.uuid}"), "user should be able to read own object"
+ assert (@active_user.can? :write=>"#{@active_user.uuid}"), "user should be able to write own object"
+ assert (@active_user.can? :manage=>"#{@active_user.uuid}"), "user should be able to manage own object"
+
+ assert @active_user.groups_i_can(:read).size > 0, "active user should be able read at least one group"
+
+ # non-admin user cannot manage or write other user objects
+ assert !(@active_user.can? :read=>"#{@uninvited_user.uuid}")
+ assert !(@active_user.can? :write=>"#{@uninvited_user.uuid}")
+ assert !(@active_user.can? :manage=>"#{@uninvited_user.uuid}")
+ end
+
+ test "check admin user properties" do
+ assert @admin_user.is_admin, 'is_admin should be set for admin user'
+ assert @admin_user.is_active, 'admin user cannot be inactive'
+ assert @admin_user.is_invited, 'is_invited should be set'
+ assert_not_nil @admin_user.uuid.size, "user's uuid should be non-null"
+ assert_not_nil @admin_user.prefs, "user's preferences should be non-null, but may be size zero"
+ assert @admin_user.identity_url.size > 0, "user's identity url is expected"
+ assert @admin_user.can? :read=>"#{@admin_user.uuid}"
+ assert @admin_user.can? :write=>"#{@admin_user.uuid}"
+ assert @admin_user.can? :manage=>"#{@admin_user.uuid}"
+
+ assert @admin_user.groups_i_can(:read).size > 0, "admin active user should be able read at least one group"
+ assert @admin_user.groups_i_can(:write).size > 0, "admin active user should be able write to at least one group"
+ assert @admin_user.groups_i_can(:manage).size > 0, "admin active user should be able manage at least one group"
+
+ # admin user can also write or manage other users
+ assert @admin_user.can? :read=>"#{@uninvited_user.uuid}"
+ assert @admin_user.can? :write=>"#{@uninvited_user.uuid}"
+ assert @admin_user.can? :manage=>"#{@uninvited_user.uuid}"
+ end
+
+ test "check inactive and uninvited user properties" do
+ assert !@uninvited_user.is_admin, 'is_admin should not be set for a non-admin user'
+ assert !@uninvited_user.is_active, 'user should be inactive'
+ assert !@uninvited_user.is_invited, 'is_invited should not be set'
+ assert @uninvited_user.can? :read=>"#{@uninvited_user.uuid}"
+ assert @uninvited_user.can? :write=>"#{@uninvited_user.uuid}"
+ assert @uninvited_user.can? :manage=>"#{@uninvited_user.uuid}"
+
+ assert @uninvited_user.groups_i_can(:read).size == 0, "inactive and uninvited user should not be able read any groups"
+ assert @uninvited_user.groups_i_can(:write).size == 0, "inactive and uninvited user should not be able write to any groups"
+ assert @uninvited_user.groups_i_can(:manage).size == 0, "inactive and uninvited user should not be able manage any groups"
+ end
+
+ test "find user method checks" do
+ User.find(:all).each do |user|
+ assert_not_nil user.uuid, "non-null uuid expected for " + user.full_name
+ end
+
+ user = users(:active) # get the active user
+
+ found_user = User.find(user.id) # find a user by the row id
+
+ assert_equal found_user.full_name, user.first_name + ' ' + user.last_name
+ assert_equal found_user.identity_url, user.identity_url
+ end
+
+ test "create new user" do
+ Thread.current[:user] = @admin_user # set admin user as the current user
+
+ user = User.new
+ user.first_name = "first_name_for_newly_created_user"
+ user.save
+
+ # verify there is one extra user in the db now
+ assert (User.find(:all).size == @all_users.size+1)
+
+ user = User.find(user.id) # get the user back
+ assert_equal(user.first_name, 'first_name_for_newly_created_user')
+ assert_not_nil user.uuid, 'uuid should be set for newly created user'
+ assert_nil user.email, 'email should be null for newly created user, because it was not passed in'
+ assert_nil user.identity_url, 'identity_url should be null for newly created user, because it was not passed in'
+
+ user.first_name = 'first_name_for_newly_created_user_updated'
+ user.save
+ user = User.find(user.id) # get the user back
+ assert_equal(user.first_name, 'first_name_for_newly_created_user_updated')
+ end
+
+ test "update existing user" do
+ Thread.current[:user] = @active_user # set active user as current user
+ @active_user.first_name = "first_name_changed"
+ @active_user.save
+
+ @active_user = User.find(@active_user.id) # get the user back
+ assert_equal(@active_user.first_name, 'first_name_changed')
+
+ # admin user also should be able to update the "active" user info
+ Thread.current[:user] = @admin_user # set admin user as current user
+ @active_user.first_name = "first_name_changed_by_admin_for_active_user"
+ @active_user.save
+
+ @active_user = User.find(@active_user.id) # get the user back
+ assert_equal(@active_user.first_name, 'first_name_changed_by_admin_for_active_user')
+ end
+
+ test "delete a user and verify" do
+ active_user_uuid = @active_user.uuid
+
+ Thread.current[:user] = @admin_user
+ @active_user.delete
+
+ found_deleted_user = false
+ User.find(:all).each do |user|
+ if user.uuid == active_user_uuid
+ found_deleted_user = true
+ break
+ end
+ end
+ assert !found_deleted_user, "found deleted user: "+active_user_uuid
+
+ end
+
+ test "create new user as non-admin user" do
+ Thread.current[:user] = @active_user
+
+ begin
+ user = User.new
+ user.save
+ rescue ArvadosModel::PermissionDeniedError => e
+ end
+ assert (e.message.include? 'PermissionDeniedError'),
+ 'Expected PermissionDeniedError'
+ end
+
+ test "setup new user" do
+ Thread.current[:user] = @admin_user
+
+ email = 'foo@example.com'
+ openid_prefix = 'http://openid/prefix'
+
+ user = User.new
+ user.email = email
+ user.uuid = 'abcdefghijklmnop'
+
+ vm = VirtualMachine.create
+
+ response = User.setup user, openid_prefix, 'test_repo', vm.uuid
+
+ resp_user = find_obj_in_resp response, 'User'
+ verify_user resp_user, email
+
+ oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
+ verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
+ resp_user[:uuid]
+ assert_equal openid_prefix, oid_login_perm[:properties][:identity_url_prefix],
+ 'expected identity_url_prefix not found for oid_login_perm'
+
+ group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
+ verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
+
+ repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
+ verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
+
+ vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
+ verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
+ end
+
+ test "setup new user in multiple steps" do
+ Thread.current[:user] = @admin_user
+
+ email = 'foo@example.com'
+ openid_prefix = 'http://openid/prefix'
+
+ user = User.new
+ user.email = email
+ user.uuid = 'abcdefghijklmnop'
+
+ response = User.setup user, openid_prefix
+
+ resp_user = find_obj_in_resp response, 'User'
+ verify_user resp_user, email
+
+ oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
+ verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
+ resp_user[:uuid]
+ assert_equal openid_prefix, oid_login_perm[:properties][:identity_url_prefix],
+ 'expected identity_url_prefix not found for oid_login_perm'
+
+ group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
+ 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'
+ 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'
+
+ group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
+ verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
+
+ repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
+ verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
+
+ # invoke setup again with a vm_uuid
+ vm = VirtualMachine.create
+
+ response = User.setup user, openid_prefix, 'test_repo', vm.uuid
+
+ 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'
+
+ group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
+ verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
+
+ repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
+ verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
+
+ vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
+ verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
+ end
+
+ def find_obj_in_resp (response, object_type, head_kind=nil)
+ return_obj = nil
+ response.each { |x|
+ if x.class.name == object_type
+ if head_kind
+ if x.head_kind == head_kind
+ return_obj = x
+ break
+ end
+ else
+ return_obj = x
+ break
+ end
+ end
+ }
+ return return_obj
+ end
+
+ def verify_user (resp_user, email)
+ assert_not_nil resp_user, 'expected user object'
+ assert_not_nil resp_user['uuid'], 'expected user object'
+ assert_equal email, resp_user['email'], 'expected email not found'
+
+ end
+
+ def verify_link (link_object, link_class, link_name, tail_uuid, head_uuid)
+ assert_not_nil link_object, 'expected link for #{link_class} #{link_name}'
+ assert_not_nil link_object[:uuid],
+ 'expected non-nil uuid for link for #{link_class} #{link_name}'
+ assert_equal link_class, link_object[:link_class],
+ 'expected link_class not found for #{link_class} #{link_name}'
+ assert_equal link_name, link_object[:name],
+ 'expected link_name not found for #{link_class} #{link_name}'
+ assert_equal tail_uuid, link_object[:tail_uuid],
+ 'expected tail_uuid not found for #{link_class} #{link_name}'
+ if head_uuid
+ assert_equal head_uuid, link_object[:head_uuid],
+ 'expected head_uuid not found for #{link_class} #{link_name}'
+ end
+ end
+
end