gem 'google-api-client', '~> 0.6.3'
gem 'trollop'
-gem 'arvados-cli', '>= 0.1.20140328152103'
+#gem 'arvados-cli', '>= 0.1.20140328152103'
addressable (2.3.5)
andand (1.3.3)
arel (3.0.2)
- arvados (0.1.20140328152103)
- activesupport (>= 3.2.13)
- andand
- google-api-client (~> 0.6.3)
- json (>= 1.7.7)
- arvados-cli (0.1.20140328152103)
- activesupport (~> 3.2, >= 3.2.13)
- andand (~> 1.3, >= 1.3.3)
- arvados (~> 0.1.0)
- curb (~> 0.8)
- google-api-client (~> 0.6.3)
- json (~> 1.7, >= 1.7.7)
- oj (~> 2.0, >= 2.0.3)
- trollop (~> 2.0)
autoparse (0.3.3)
addressable (>= 2.3.1)
extlib (>= 0.9.15)
coffee-script-source
execjs
coffee-script-source (1.6.3)
- curb (0.8.5)
daemon_controller (1.1.7)
erubis (2.7.0)
execjs (2.0.2)
DEPENDENCIES
acts_as_api
andand
- arvados-cli (>= 0.1.20140328152103)
coffee-rails (~> 3.2.0)
google-api-client (~> 0.6.3)
jquery-rails
end
else
@offset = 0
- end
+ end
orders = []
if params[:order]
order: { type: 'string', required: false }
}
end
-
+
def client_accepts_plain_text_stream
(request.headers['Accept'].split(' ') &
['text/plain', '*/*']).count > 0
class Arvados::V1::LinksController < ApplicationController
- def index
+
+ prepend_before_filter :load_kind_params, :only => :index
+
+ def create
+ resource_attrs.delete :head_kind
+ resource_attrs.delete :tail_kind
+ super
+ end
+
+ def load_kind_params
if params[:tail_uuid]
params[:where] = Oj.load(params[:where]) if params[:where].is_a?(String)
- params[:where] ||= {}
- params[:where][:tail_uuid] = params[:tail_uuid]
+ @where ||= {}
+ @where[:tail_uuid] = params[:tail_uuid]
end
- super
+
+ if params[:where] and params[:where].is_a? Hash
+ if params[:where][:head_kind]
+ params[:filters] ||= []
+ params[:filters] << ['head_uuid', 'is_a', params[:where][:head_kind]]
+ params[:where].delete :head_kind
+ end
+ if params[:where][:tail_kind]
+ params[:filters] ||= []
+ params[:filters] << ['tail_uuid', 'is_a', params[:where][:tail_kind]]
+ params[:where].delete :tail_kind
+ end
+ end
+
end
+
end
"but is not invited"
raise ArgumentError.new "Cannot activate without being invited."
end
- act_as_system_user do
+ act_as_system_user do
required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
system_user_uuid,
'signature',
params[:repo_name], params[:vm_uuid]
end
- render json: { kind: "arvados#HashList", items: @response }
+ render json: { kind: "arvados#HashList", items: @response.as_api_response(nil) }
end
# delete user agreements, vm, repository, login links; set state to inactive
end
end
+ class Email
+ def self.kind
+ "email"
+ end
+
+ def kind
+ self.class.kind
+ end
+
+ def self.readable_by (u)
+ self
+ end
+
+ def self.where (u)
+ [{:uuid => u[:uuid]}]
+ end
+ end
+
def self.resource_class_for_uuid(uuid)
if uuid.is_a? ArvadosModel
return uuid.class
uuid.match @@UUID_REGEX do |re|
return uuid_prefixes[re[1]] if uuid_prefixes[re[1]]
end
+
+ if uuid.match /.+@.+/
+ return Email
+ end
+
nil
end
after_create :maybe_invalidate_permissions_cache
after_destroy :maybe_invalidate_permissions_cache
- attr_accessor :head
- attr_accessor :tail
-
api_accessible :user, extend: :common do |t|
t.add :tail_uuid
t.add :link_class
t.add :name
t.add :head_uuid
- t.add :head, :if => :head
- t.add :tail, :if => :tail
+ t.add :head_kind
+ t.add :tail_kind
t.add :properties
end
super
end
+ def head_kind
+ if k = ArvadosModel::resource_class_for_uuid(head_uuid)
+ k.kind
+ end
+ end
+
+ def tail_kind
+ if k = ArvadosModel::resource_class_for_uuid(tail_uuid)
+ k.kind
+ end
+ end
+
protected
def permission_to_attach_to_objects
def unsetup
# delete oid_login_perms for this user
oid_login_perms = Link.where(tail_uuid: self.email,
- head_kind: 'arvados#user',
link_class: 'permission',
name: 'can_login')
oid_login_perms.each do |perm|
# delete repo_perms for this user
repo_perms = Link.where(tail_uuid: self.uuid,
- head_kind: 'arvados#repository',
link_class: 'permission',
name: 'can_write')
repo_perms.each do |perm|
# delete vm_login_perms for this user
vm_login_perms = Link.where(tail_uuid: self.uuid,
- head_kind: 'arvados#virtualMachine',
link_class: 'permission',
name: 'can_login')
vm_login_perms.each do |perm|
end.first
group_perms = Link.where(tail_uuid: self.uuid,
head_uuid: group[:uuid],
- head_kind: 'arvados#group',
link_class: 'permission',
name: 'can_read')
group_perms.each do |perm|
# delete any signatures by this user
signed_uuids = Link.where(link_class: 'signature',
- tail_kind: 'arvados#user',
tail_uuid: self.uuid)
signed_uuids.each do |sign|
Link.delete sign
# Check oid_login_perm
oid_login_perms = Link.where(tail_uuid: self.email,
- head_kind: 'arvados#user',
link_class: 'permission',
- name: 'can_login')
+ name: 'can_login').where("head_uuid like ?", User.uuid_like_pattern)
if !oid_login_perms.any?
# create openid login permission
oid_login_perm = Link.create(link_class: 'permission',
name: 'can_login',
- tail_kind: 'email',
tail_uuid: self.email,
- head_kind: 'arvados#user',
head_uuid: self.uuid,
properties: login_perm_props
)
# Look for existing repository access for this repo
repo_perms = Link.where(tail_uuid: self.uuid,
- head_kind: 'arvados#repository',
head_uuid: repo[:uuid],
link_class: 'permission',
name: 'can_write')
repo ||= Repository.create(name: repo_name)
logger.info { "repo uuid: " + repo[:uuid] }
- repo_perm = Link.create(tail_kind: 'arvados#user',
- tail_uuid: self.uuid,
- head_kind: 'arvados#repository',
+ repo_perm = Link.create(tail_uuid: self.uuid,
head_uuid: repo[:uuid],
link_class: 'permission',
name: 'can_write')
login_perms = Link.where(tail_uuid: self.uuid,
head_uuid: vm[:uuid],
- head_kind: 'arvados#virtualMachine',
link_class: 'permission',
name: 'can_login')
end
if !perm_exists
- login_perm = Link.create(tail_kind: 'arvados#user',
- tail_uuid: self.uuid,
- head_kind: 'arvados#virtualMachine',
+ login_perm = Link.create(tail_uuid: self.uuid,
head_uuid: vm[:uuid],
link_class: 'permission',
name: 'can_login',
group_perms = Link.where(tail_uuid: self.uuid,
head_uuid: group[:uuid],
- head_kind: 'arvados#group',
link_class: 'permission',
name: 'can_read')
if !group_perms.any?
- group_perm = Link.create(tail_kind: 'arvados#user',
- tail_uuid: self.uuid,
- head_kind: 'arvados#group',
+ group_perm = Link.create(tail_uuid: self.uuid,
head_uuid: group[:uuid],
link_class: 'permission',
name: 'can_read')
act_as_system_user do
Link.create(link_class: 'permission',
name: 'can_manage',
- tail_kind: 'arvados#group',
tail_uuid: system_group_uuid,
- head_kind: 'arvados#user',
head_uuid: self.uuid)
end
end
class RemoveKindColumns < ActiveRecord::Migration
+ include CurrentApiClient
+
def up
remove_column :links, :head_kind
remove_column :links, :tail_kind
- remove_column :logs, :object_kind
end
def down
add_column :links, :head_kind, :string
add_column :links, :tail_kind, :string
- add_column :logs, :object_kind, :string
+
+ act_as_system_user do
+ Link.all.each do |l|
+ l.head_kind = ArvadosModel::resource_class_for_uuid(l.head_uuid).kind if l.head_uuid
+ l.tail_kind = ArvadosModel::resource_class_for_uuid(l.tail_uuid).kind if l.tail_uuid
+ l.save
+ end
+ end
end
end
t.boolean "running"
t.boolean "success"
t.string "output"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at"
+ t.datetime "updated_at"
t.string "priority"
t.string "is_locked_by_uuid"
t.string "log"
t.string "head_uuid"
t.text "properties"
t.datetime "updated_at"
+ t.string "head_kind"
+ t.string "tail_kind"
end
add_index "links", ["created_at"], :name => "index_links_on_created_at"
end
module ClassMethods
+ def kind
+ 'arvados#' + self.to_s.camelcase(:lower)
+ end
end
def kind
- 'arvados#' + self.class.to_s.camelcase(:lower)
+ self.class.kind
end
def etag
name: System Private
description: System-owned Group
+system_group:
+ uuid: zzzzz-j7d0g-000000000000000
+ owner_uuid: zzzzz-tpzed-000000000000000
+ name: System Private
+ description: System-owned Group
+
empty_lonely_group:
uuid: zzzzz-j7d0g-jtp06ulmvsezgyu
owner_uuid: zzzzz-tpzed-000000000000000
modified_by_user_uuid: zzzzz-tpzed-000000000000000
modified_at: 2014-01-24 20:42:26 -0800
updated_at: 2014-01-24 20:42:26 -0800
- tail_kind: arvados#user
tail_uuid: zzzzz-tpzed-xurymjxw79nv3jz
link_class: permission
name: can_read
- head_kind: arvados#collection
head_uuid: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45
properties: {}
modified_by_user_uuid: zzzzz-tpzed-000000000000000
modified_at: 2014-01-24 20:42:26 -0800
updated_at: 2014-01-24 20:42:26 -0800
- tail_kind: arvados#group
tail_uuid: zzzzz-j7d0g-22xp1wpjul508rk
link_class: permission
name: can_read
- head_kind: arvados#collection
head_uuid: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45
properties: {}
modified_by_user_uuid: zzzzz-tpzed-000000000000000
modified_at: 2014-01-24 20:42:26 -0800
updated_at: 2014-01-24 20:42:26 -0800
- tail_kind: arvados#user
tail_uuid: zzzzz-tpzed-l1s2piq4t4mps8r
link_class: permission
name: can_read
- head_kind: arvados#repository
head_uuid: zzzzz-2x53u-382brsig8rp3666
properties: {}
modified_by_user_uuid: zzzzz-tpzed-000000000000000
modified_at: 2014-04-01 13:53:33 -0400
updated_at: 2014-04-01 13:53:33 -0400
- tail_kind: arvados#user
tail_uuid: zzzzz-tpzed-2bg9x0oeydcw5hm
link_class: permission
name: can_manage
- head_kind: arvados#group
head_uuid: zzzzz-j7d0g-48foin4vonvc2at
properties: {}
modified_by_user_uuid: zzzzz-tpzed-000000000000000
modified_at: 2014-04-01 13:53:33 -0400
updated_at: 2014-04-01 13:53:33 -0400
- tail_kind: arvados#user
tail_uuid: zzzzz-tpzed-4hvxm4n25emegis
link_class: permission
name: can_read
- head_kind: arvados#group
head_uuid: zzzzz-j7d0g-48foin4vonvc2at
properties: {}
modified_by_user_uuid: zzzzz-tpzed-000000000000000
modified_at: 2014-04-01 13:56:10 -0400
updated_at: 2014-04-01 13:56:10 -0400
- tail_kind: arvados#group
tail_uuid: zzzzz-j7d0g-48foin4vonvc2at
link_class: permission
name: can_manage
- head_kind: arvados#user
head_uuid: zzzzz-tpzed-xurymjxw79nv3jz
properties: {}
assert_equal false, assigns(:object).properties.has_key?(:username)
end
end
-
+
test "head must exist" do
link = {
link_class: 'test',
assert_response 422
end
+ test "head and tail exist" do
+ link = {
+ link_class: 'test',
+ name: 'stuff',
+ head_uuid: users(:active).uuid,
+ tail_uuid: users(:spectator).uuid,
+ }
+ authorize_with :admin
+ post :create, link: link
+ assert_response :success
+ l = JSON.parse(@response.body)
+ assert 'arvados#user', l['head_kind']
+ assert 'arvados#user', l['tail_kind']
+ end
+
+ test "can supply head_kind and tail_kind without error" do
+ link = {
+ link_class: 'test',
+ name: 'stuff',
+ head_uuid: users(:active).uuid,
+ tail_uuid: users(:spectator).uuid,
+ head_kind: "arvados#user",
+ tail_kind: "arvados#user",
+ }
+ authorize_with :admin
+ post :create, link: link
+ assert_response :success
+ l = JSON.parse(@response.body)
+ assert 'arvados#user', l['head_kind']
+ assert 'arvados#user', l['tail_kind']
+ end
+
test "tail must be visible by user" do
link = {
link_class: 'test',
}
assert_response :success
found = assigns(:objects)
+ assert_not_equal 0, found.count
+ assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-f0-9]{32}\+\d+/}).count
+ end
+
+ test "test can still use where tail_kind" do
+ authorize_with :admin
+ get :index, {
+ where: { tail_kind: 'arvados#user' }
+ }
assert_response :success
found = assigns(:objects)
assert_not_equal 0, found.count
- assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-f0-9]{32}\+\d+/}).count
+ assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
+ end
+
+ test "test can still use where head_kind" do
+ authorize_with :admin
+ get :index, {
+ where: { head_kind: 'arvados#user' }
+ }
+ assert_response :success
+ found = assigns(:objects)
+ assert_not_equal 0, found.count
+ assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
end
repo_name: repo_name,
openid_prefix: 'https://www.google.com/accounts/o8/id',
user: {
- uuid: "this_is_agreeable",
+ uuid: 'zzzzz-tpzed-abcdefghijklmno',
first_name: "in_create_test_first_name",
last_name: "test_last_name",
email: "foo@example.com"
response_items = JSON.parse(@response.body)['items']
created = find_obj_in_resp response_items, 'User', nil
+
assert_equal 'in_create_test_first_name', created['first_name']
assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
- assert_equal 'this_is_agreeable', created['uuid']
+ assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
assert_not_nil created['email'], 'expected non-nil email'
assert_nil created['identity_url'], 'expected no identity_url'
vm_uuid: @vm_uuid,
openid_prefix: 'https://www.google.com/accounts/o8/id',
user: {
- uuid: "this_is_agreeable",
+ uuid: 'zzzzz-tpzed-abcdefghijklmno',
first_name: "in_create_test_first_name",
last_name: "test_last_name",
email: "foo@example.com"
created = find_obj_in_resp response_items, 'User', nil
assert_equal 'in_create_test_first_name', created['first_name']
assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
- assert_equal 'this_is_agreeable', created['uuid']
+ assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
assert_not_nil created['email'], 'expected non-nil email'
assert_nil created['identity_url'], 'expected no identity_url'
end
if object_type == 'User'
- if !x['head_kind']
+ if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
return_obj = x
break
end
else # looking for a link
- if x['head_kind'] == head_kind
+ if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
return_obj = x
break
end
assert [] != object, "expected #{class_name} with name #{head_uuid}"
head_uuid = object.first[:uuid]
end
- assert_equal link['link_class'], link_class,
+ assert_equal link_class, link['link_class'],
"did not find expected link_class for #{link_object_name}"
- assert_equal link['name'], link_name,
+ assert_equal link_name, link['name'],
"did not find expected link_name for #{link_object_name}"
- assert_equal link['tail_uuid'], tail_uuid,
+ assert_equal tail_uuid, link['tail_uuid'],
"did not find expected tail_uuid for #{link_object_name}"
- assert_equal link['head_kind'], head_kind,
+ assert_equal head_kind, link['head_kind'],
"did not find expected head_kind for #{link_object_name}"
- assert_equal link['head_uuid'], head_uuid,
+ assert_equal head_uuid, link['head_uuid'],
"did not find expected head_uuid for #{link_object_name}"
end
expect_repo_perms, expect_vm_perms, expect_group_perms, expect_signatures
# verify that all links are deleted for the user
oid_login_perms = Link.where(tail_uuid: email,
- head_kind: 'arvados#user',
link_class: 'permission',
- name: 'can_login')
+ name: 'can_login').where("head_uuid like ?", User.uuid_like_pattern)
if expect_oid_login_perms
assert oid_login_perms.any?, "expected oid_login_perms"
else
end
repo_perms = Link.where(tail_uuid: uuid,
- head_kind: 'arvados#repository',
link_class: 'permission',
- name: 'can_write')
+ name: 'can_write').where("head_uuid like ?", Repository.uuid_like_pattern)
if expect_repo_perms
assert repo_perms.any?, "expected repo_perms"
else
end
vm_login_perms = Link.where(tail_uuid: uuid,
- head_kind: 'arvados#virtualMachine',
link_class: 'permission',
- name: 'can_login')
+ name: 'can_login').where("head_uuid like ?", VirtualMachine.uuid_like_pattern)
if expect_vm_perms
assert vm_login_perms.any?, "expected vm_login_perms"
else
end.first
group_read_perms = Link.where(tail_uuid: uuid,
head_uuid: group[:uuid],
- head_kind: 'arvados#group',
link_class: 'permission',
name: 'can_read')
if expect_group_perms
end
signed_uuids = Link.where(link_class: 'signature',
- tail_kind: 'arvados#user',
tail_uuid: uuid)
if expect_signatures
email = 'foo@example.com'
openid_prefix = 'http://openid/prefix'
- user = User.new
- user.email = email
- user.uuid = 'abcdefghijklmnop'
+ user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
vm = VirtualMachine.create
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'
email = 'foo@example.com'
openid_prefix = 'http://openid/prefix'
- user = User.new
- user.email = email
- user.uuid = 'abcdefghijklmnop'
+ user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
response = User.setup user, openid_prefix
verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
end
- def find_obj_in_resp (response, object_type, head_kind=nil)
+ def find_obj_in_resp (response_items, 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
+ response_items.each { |x|
+ if !x
+ next
+ end
+
+ if object_type == 'User'
+ if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
+ return_obj = x
+ break
+ end
+ else # looking for a link
+ if ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
return_obj = x
break
end
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, "expected link for #{link_class} #{link_name}"
assert_not_nil link_object[:uuid],
- 'expected non-nil uuid for link for #{link_class} #{link_name}'
+ "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}'
+ "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}'
+ "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}'
+ "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}'
+ "expected head_uuid not found for #{link_class} #{link_name}"
end
end