Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <peter.amstutz@curii.com>
validate :ensure_filesystem_compatible_name
before_create :assign_name
validate :ensure_filesystem_compatible_name
before_create :assign_name
- after_create :update_permissions
+ after_create :after_ownership_change
after_create :update_trash
after_create :update_trash
- after_update :update_permissions, :if => :owner_uuid_changed?
- after_update :update_trash
-
- after_destroy :clear_permissions_and_trash
+ before_update :before_ownership_change
+ after_update :after_ownership_change
+ after_update :update_trash
+ before_destroy :clear_permissions_and_trash
api_accessible :user, extend: :common do |t|
t.add :name
api_accessible :user, extend: :common do |t|
t.add :name
- def update_permissions
- User.update_permissions self.owner_uuid, self.uuid, 3
+ def before_ownership_change
+ if owner_uuid_changed? and !self.owner_uuid_was.nil?
+ MaterializedPermission.where(user_uuid: owner_uuid_was, target_uuid: uuid).delete_all
+ User.update_permissions self.owner_uuid, self.uuid, 0
+ end
+ end
+
+ def after_ownership_change
+ if owner_uuid_changed?
+ User.update_permissions self.owner_uuid, self.uuid, 3
+ end
end
def clear_permissions_and_trash
end
def clear_permissions_and_trash
- User.update_permissions self.owner_uuid, self.uuid, 0
+ MaterializedPermission.where(target_uuid: uuid).delete_all
ActiveRecord::Base.connection.exec_query %{
delete from trashed_groups where group_uuid=$1
}, "Group.clear_trash", [[nil, self.uuid]]
ActiveRecord::Base.connection.exec_query %{
delete from trashed_groups where group_uuid=$1
}, "Group.clear_trash", [[nil, self.uuid]]
before_update :permission_to_attach_to_objects
after_update :update_permissions
after_create :update_permissions
before_update :permission_to_attach_to_objects
after_update :update_permissions
after_create :update_permissions
+ before_destroy :clear_permissions
after_destroy :clear_permissions
api_accessible :user, extend: :common do |t|
after_destroy :clear_permissions
api_accessible :user, extend: :common do |t|
def clear_permissions
if self.link_class == 'permission'
def clear_permissions
if self.link_class == 'permission'
- User.update_permissions tail_uuid, head_uuid, 0
+ User.update_permissions tail_uuid, head_uuid, 0, false
+ end
+ end
+
+ def check_permissions
+ if self.link_class == 'permission'
+ User.update_permissions tail_uuid, head_uuid, 0, true
user.username.nil? and user.username_changed?
}
before_update :setup_on_activate
user.username.nil? and user.username_changed?
}
before_update :setup_on_activate
before_create :check_auto_admin
before_create :set_initial_username, :if => Proc.new { |user|
user.username.nil? and user.email
}
before_create :check_auto_admin
before_create :set_initial_username, :if => Proc.new { |user|
user.username.nil? and user.email
}
- after_create :update_permissions
+ after_create :after_ownership_change
after_create :setup_on_activate
after_create :add_system_group_permission_link
after_create :auto_setup_new_user, :if => Proc.new { |user|
after_create :setup_on_activate
after_create :add_system_group_permission_link
after_create :auto_setup_new_user, :if => Proc.new { |user|
(user.uuid != anonymous_user_uuid)
}
after_create :send_admin_notifications
(user.uuid != anonymous_user_uuid)
}
after_create :send_admin_notifications
- after_update :update_permissions, :if => :owner_uuid_changed?
+
+ before_update :before_ownership_change
+ after_update :after_ownership_change
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?)
}
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?)
}
+ after_destroy :clear_permissions
has_many :authorized_keys, :foreign_key => :authorized_user_uuid, :primary_key => :uuid
has_many :repositories, foreign_key: :owner_uuid, primary_key: :uuid
has_many :authorized_keys, :foreign_key => :authorized_user_uuid, :primary_key => :uuid
has_many :repositories, foreign_key: :owner_uuid, primary_key: :uuid
+ def before_ownership_change
+ if owner_uuid_changed? and !self.owner_uuid_was.nil?
+ MaterializedPermission.where(user_uuid: owner_uuid_was, target_uuid: uuid).delete_all
+ User.update_permissions self.owner_uuid_was, self.uuid, 0, false
+ end
+ end
+
+ def after_ownership_change
# puts "Update permissions for #{uuid}"
# User.printdump %{
# select * from materialized_permissions where user_uuid='#{uuid}'
# }
# puts "Update permissions for #{uuid}"
# User.printdump %{
# select * from materialized_permissions where user_uuid='#{uuid}'
# }
+ puts "-1- #{uuid_changed?} and #{uuid} and #{uuid_was}"
+ puts "-2- #{owner_uuid_changed?} and #{owner_uuid} and #{owner_uuid_was}"
+
+ unless owner_uuid_changed?
+ return
+ end
+
+# if !uuid_was.nil? and uuid_changed?
+# puts "Cleaning house #{uuid_was}"
+# ActiveRecord::Base.connection.exec_query %{
+# update #{PERMISSION_VIEW} set user_uuid=$1 where user_uuid = $2
+# },
+# 'Change user uuid',
+# [[nil, uuid],
+# [nil, uuid_was]]
+# ActiveRecord::Base.connection.exec_query %{
+# update #{PERMISSION_VIEW} set target_uuid=$1 where target_uuid = $2
+# },
+# 'Change user uuid',
+# [[nil, uuid],
+# [nil, uuid_was]]
+# end
+
User.update_permissions self.owner_uuid, self.uuid, 3
# puts "post-update"
User.update_permissions self.owner_uuid, self.uuid, 3
# puts "post-update"
+ def clear_permissions
+ MaterializedPermission.where("user_uuid = ? or target_uuid = ?", uuid, uuid).delete_all
+ end
+
def self.printdump qr
q1 = ActiveRecord::Base.connection.exec_query qr
q1.each do |r|
def self.printdump qr
q1 = ActiveRecord::Base.connection.exec_query qr
q1.each do |r|
- def self.update_permissions perm_origin_uuid, starting_uuid, perm_level
+ def self.update_permissions perm_origin_uuid, starting_uuid, perm_level, check=true
# Update a subset of the permission graph
# perm_level is the inherited permission
# perm_level is a number from 0-3
# Update a subset of the permission graph
# perm_level is the inherited permission
# perm_level is a number from 0-3
should_traverse_owned(ps.target_uuid, ps.val)
from edges, lateral search_permission_graph(edges.head_uuid, edges.val) as ps
where (not (edges.tail_uuid = '#{perm_origin_uuid}' and
should_traverse_owned(ps.target_uuid, ps.val)
from edges, lateral search_permission_graph(edges.head_uuid, edges.val) as ps
where (not (edges.tail_uuid = '#{perm_origin_uuid}' and
- edges.head_uuid = '#{starting_uuid}' and
- edges.val = #{perm_level})) and
+ edges.head_uuid = '#{starting_uuid}')) and
edges.tail_uuid not in (select target_uuid from perm_from_start) and
edges.head_uuid in (select target_uuid from perm_from_start)),
edges.tail_uuid not in (select target_uuid from perm_from_start) and
edges.head_uuid in (select target_uuid from perm_from_start)),
user_identity_perms(perm_origin_uuid, target_uuid, val, traverse_owned) as (
select users.uuid as perm_origin_uuid, ps.target_uuid, ps.val, ps.traverse_owned
from users, lateral search_permission_graph(users.uuid, 3) as ps
user_identity_perms(perm_origin_uuid, target_uuid, val, traverse_owned) as (
select users.uuid as perm_origin_uuid, ps.target_uuid, ps.val, ps.traverse_owned
from users, lateral search_permission_graph(users.uuid, 3) as ps
- where users.owner_uuid not in (select target_uuid from partial_perms where traverse_owned) and
+ where (users.owner_uuid not in (select target_uuid from partial_perms) or
+ users.owner_uuid = users.uuid) and
users.uuid in (select target_uuid from partial_perms)
),
users.uuid in (select target_uuid from partial_perms)
),
ActiveRecord::Base.connection.exec_query %{
delete from materialized_permissions where
target_uuid in (select target_uuid from #{temptable_perms}) and
ActiveRecord::Base.connection.exec_query %{
delete from materialized_permissions where
target_uuid in (select target_uuid from #{temptable_perms}) and
- (user_uuid not in (select user_uuid from #{temptable_perms} where target_uuid=materialized_permissions.target_uuid)
- or user_uuid in (select user_uuid from #{temptable_perms} where target_uuid=materialized_permissions.target_uuid and perm_level=0))
+ not exists (select 1 from #{temptable_perms}
+ where target_uuid=materialized_permissions.target_uuid and
+ user_uuid=materialized_permissions.user_uuid and
+ val>0)
}
ActiveRecord::Base.connection.exec_query %{
insert into materialized_permissions (user_uuid, target_uuid, perm_level, traverse_owned)
}
ActiveRecord::Base.connection.exec_query %{
insert into materialized_permissions (user_uuid, target_uuid, perm_level, traverse_owned)
- select user_uuid, target_uuid, val as perm_level, traverse_owned from #{temptable_perms}
+ select user_uuid, target_uuid, val as perm_level, traverse_owned from #{temptable_perms} where val>0
on conflict (user_uuid, target_uuid) do update set perm_level=EXCLUDED.perm_level, traverse_owned=EXCLUDED.traverse_owned;
}
# for testing only - make a copy of the table and compare it to the one generated
# using a full permission recompute
on conflict (user_uuid, target_uuid) do update set perm_level=EXCLUDED.perm_level, traverse_owned=EXCLUDED.traverse_owned;
}
# for testing only - make a copy of the table and compare it to the one generated
# using a full permission recompute
-# puts "dump--"
-# User.printdump %{
-# select * from users
-# }
-# User.printdump %{
-# select * from groups
-# }
-# User.printdump %{
-# select * from search_permission_graph('zzzzz-tpzed-000000000000000', 3)
-# }
-# puts "--"
-
+# puts "dump--"
+# User.printdump %{
+# select owner_uuid, uuid from users order by uuid
+# }
+# User.printdump %{
+# select * from groups
+# }
+# User.printdump %{
+#select * from search_permission_graph('zzzzz-tpzed-000000000000000', 3)
+# }
+# puts "--"
- q1 = ActiveRecord::Base.connection.exec_query %{
+ if check
+ q1 = ActiveRecord::Base.connection.exec_query %{
select user_uuid, target_uuid, perm_level, traverse_owned from materialized_permissions
order by user_uuid, target_uuid
}
select user_uuid, target_uuid, perm_level, traverse_owned from materialized_permissions
order by user_uuid, target_uuid
}
- q2 = ActiveRecord::Base.connection.exec_query %{
+ q2 = ActiveRecord::Base.connection.exec_query %{
select users.uuid as user_uuid, g.target_uuid, g.val as perm_level, g.traverse_owned
from users, lateral search_permission_graph(users.uuid, 3) as g where g.val > 0
order by users.uuid, target_uuid
}
select users.uuid as user_uuid, g.target_uuid, g.val as perm_level, g.traverse_owned
from users, lateral search_permission_graph(users.uuid, 3) as g where g.val > 0
order by users.uuid, target_uuid
}
- if q1.count != q2.count
- puts "Didn't match incremental+: #{q1.count} != full refresh-: #{q2.count}"
- end
+ if q1.count != q2.count
+ puts "Didn't match incremental+: #{q1.count} != full refresh-: #{q2.count}"
+ end
- if q1.count > q2.count
- q1.each_with_index do |r, i|
- if r != q2[i]
- puts "+#{r}\n-#{q2[i]}"
- raise "Didn't match"
+ if q1.count > q2.count
+ q1.each_with_index do |r, i|
+ if r != q2[i]
+ puts "+#{r}\n-#{q2[i]}"
+ raise "Didn't match"
+ end
- end
- else
- q2.each_with_index do |r, i|
- if r != q1[i]
- puts "+#{q1[i]}\n-#{r}"
- raise "Didn't match"
+ else
+ q2.each_with_index do |r, i|
+ if r != q1[i]
+ puts "+#{q1[i]}\n-#{r}"
+ raise "Didn't match"
+ end
self.uuid = new_uuid
save!(validate: false)
change_all_uuid_refs(old_uuid: old_uuid, new_uuid: new_uuid)
self.uuid = new_uuid
save!(validate: false)
change_all_uuid_refs(old_uuid: old_uuid, new_uuid: new_uuid)
+ ActiveRecord::Base.connection.exec_query %{
+update #{PERMISSION_VIEW} set user_uuid=$1 where user_uuid = $2
+},
+ 'Change user uuid',
+ [[nil, new_uuid],
+ [nil, old_uuid]]
+ ActiveRecord::Base.connection.exec_query %{
+update #{PERMISSION_VIEW} set target_uuid=$1 where target_uuid = $2
+},
+ 'Change target uuid',
+ [[nil, new_uuid],
+ [nil, old_uuid]]
should_traverse_owned(ps.target_uuid, ps.val)
from edges, lateral search_permission_graph(edges.head_uuid, edges.val) as ps
where (not (edges.tail_uuid = perm_origin_uuid and
should_traverse_owned(ps.target_uuid, ps.val)
from edges, lateral search_permission_graph(edges.head_uuid, edges.val) as ps
where (not (edges.tail_uuid = perm_origin_uuid and
- edges.head_uuid = starting_uuid and
- edges.val = starting_perm)) and
+ edges.head_uuid = starting_uuid)) and
edges.tail_uuid not in (select target_uuid from perm_from_start) and
edges.head_uuid in (select target_uuid from perm_from_start)),
edges.tail_uuid not in (select target_uuid from perm_from_start) and
edges.head_uuid in (select target_uuid from perm_from_start)),
user_identity_perms(perm_origin_uuid, target_uuid, val, traverse_owned) as (
select users.uuid as perm_origin_uuid, ps.target_uuid, ps.val, ps.traverse_owned
from users, lateral search_permission_graph(users.uuid, 3) as ps
user_identity_perms(perm_origin_uuid, target_uuid, val, traverse_owned) as (
select users.uuid as perm_origin_uuid, ps.target_uuid, ps.val, ps.traverse_owned
from users, lateral search_permission_graph(users.uuid, 3) as ps
- where users.owner_uuid not in (select target_uuid from partial_perms where traverse_owned) and
+ where (users.owner_uuid not in (select target_uuid from partial_perms) or
+ users.owner_uuid = users.uuid) and
users.uuid in (select target_uuid from partial_perms)
),
users.uuid in (select target_uuid from partial_perms)
),
uuid: zzzzz-j7d0g-48foin4vonvc2at
owner_uuid: zzzzz-tpzed-000000000000000
name: Administrators of a subset of users
uuid: zzzzz-j7d0g-48foin4vonvc2at
owner_uuid: zzzzz-tpzed-000000000000000
name: Administrators of a subset of users
aproject:
uuid: zzzzz-j7d0g-v955i6s2oi1cbso
aproject:
uuid: zzzzz-j7d0g-v955i6s2oi1cbso
uuid: zzzzz-j7d0g-ptt1ou6a9lxrv07
owner_uuid: zzzzz-tpzed-d9tiejq69daie8f
name: Active user has can_manage
uuid: zzzzz-j7d0g-ptt1ou6a9lxrv07
owner_uuid: zzzzz-tpzed-d9tiejq69daie8f
name: Active user has can_manage
# Group for testing granting permission between users who share a group.
group_for_sharing_tests:
# Group for testing granting permission between users who share a group.
group_for_sharing_tests:
trash_at: 2001-01-01T00:00:00Z
delete_at: 2038-03-01T00:00:00Z
is_trashed: false
trash_at: 2001-01-01T00:00:00Z
delete_at: 2038-03-01T00:00:00Z
is_trashed: false
- modified_at: 2001-01-01T00:00:00Z
\ No newline at end of file
+ modified_at: 2001-01-01T00:00:00Z
"new #{o_class} should really be in DB")
old_uuid = o.uuid
new_uuid = o.uuid.sub(/..........$/, rand(2**256).to_s(36)[0..9])
"new #{o_class} should really be in DB")
old_uuid = o.uuid
new_uuid = o.uuid.sub(/..........$/, rand(2**256).to_s(36)[0..9])
- assert(o.update_attributes(uuid: new_uuid),
- "should change #{o_class} uuid from #{old_uuid} to #{new_uuid}")
+ puts "//Changing//"
+ if o.respond_to? :update_uuid
+ o.update_uuid(new_uuid: new_uuid)
+ else
+ assert(o.update_attributes(uuid: new_uuid),
+ "should change #{o_class} uuid from #{old_uuid} to #{new_uuid}")
+ end
assert_equal(false, o_class.where(uuid: old_uuid).any?,
"#{old_uuid} should disappear when renamed to #{new_uuid}")
end
assert_equal(false, o_class.where(uuid: old_uuid).any?,
"#{old_uuid} should disappear when renamed to #{new_uuid}")
end
"setting owner to self should work")
old_uuid = o.uuid
new_uuid = o.uuid.sub(/..........$/, rand(2**256).to_s(36)[0..9])
"setting owner to self should work")
old_uuid = o.uuid
new_uuid = o.uuid.sub(/..........$/, rand(2**256).to_s(36)[0..9])
- assert(o.update_attributes(uuid: new_uuid),
- "should change uuid of User that owns self")
+ o.update_uuid(new_uuid: new_uuid)
+ o = User.find_by_uuid(new_uuid)
assert_equal(false, User.where(uuid: old_uuid).any?,
"#{old_uuid} should not be in DB after deleting")
assert_equal(true, User.where(uuid: new_uuid).any?,
assert_equal(false, User.where(uuid: old_uuid).any?,
"#{old_uuid} should not be in DB after deleting")
assert_equal(true, User.where(uuid: new_uuid).any?,
if auto_admin_first_user_config
# This test requires no admin users exist (except for the system user)
if auto_admin_first_user_config
# This test requires no admin users exist (except for the system user)
+ act_as_system_user do
+ users(:admin).update_attributes!(is_admin: false)
+ end
+ # need to manually call clear_permissions because we used 'delete' instead of 'destory'
+ # we use delete here because 'destroy' will throw an error
+ #users(:admin).clear_permissions
@all_users = User.where("uuid not like '%-000000000000000'").where(:is_admin => true)
assert_equal 0, @all_users.count, "No admin users should exist (except for the system user)"
end
@all_users = User.where("uuid not like '%-000000000000000'").where(:is_admin => true)
assert_equal 0, @all_users.count, "No admin users should exist (except for the system user)"
end