REVOKE_PERM = 0
CAN_MANAGE_PERM = 3
-def update_permissions perm_origin_uuid, starting_uuid, perm_level
+def update_permissions perm_origin_uuid, starting_uuid, perm_level, edge_id=nil
+ return if Thread.current[:suppress_update_permissions]
+
#
# Update a subset of the permission table affected by adding or
# removing a particular permission relationship (ownership or a
# see db/migrate/20200501150153_permission_table.rb for details on
# how the permissions are computed.
+ if edge_id.nil?
+ # For changes of ownership, edge_id is starting_uuid. In turns
+ # out most invocations of update_permissions are for changes of
+ # ownership, so make this parameter optional to reduce
+ # clutter.
+ # For permission links, the uuid of the link object will be passed in for edge_id.
+ edge_id = starting_uuid
+ end
+
ActiveRecord::Base.transaction do
# "Conflicts with the ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE
temptable_perms = "temp_perms_#{rand(2**64).to_s(10)}"
ActiveRecord::Base.connection.exec_query %{
create temporary table #{temptable_perms} on commit drop
-as select * from compute_permission_subgraph($1, $2, $3)
+as select * from compute_permission_subgraph($1, $2, $3, $4)
},
'update_permissions.select',
[[nil, perm_origin_uuid],
[nil, starting_uuid],
- [nil, perm_level]]
+ [nil, perm_level],
+ [nil, edge_id]]
ActiveRecord::Base.connection.exec_query "SET LOCAL enable_mergejoin to true;"
def check_permissions_against_full_refresh
# No-op except when running tests
- return unless Rails.env == 'test' and !Thread.current[:no_check_permissions_against_full_refresh]
+ return unless Rails.env == 'test' and !Thread.current[:no_check_permissions_against_full_refresh] and !Thread.current[:suppress_update_permissions]
# For checking correctness of the incremental permission updates.
# Check contents of the current 'materialized_permission' table
#{PERM_QUERY_TEMPLATE % {:base_case => %{
select uuid, uuid, 3, true, true from users
},
-:override => ''
+:edge_perm => 'edges.val'
} }) as pq order by origin_uuid, target_uuid
}, "check_permissions_against_full_refresh.full_recompute"
end
end
+def batch_update_permissions
+ check_perm_was = Thread.current[:suppress_update_permissions]
+ Thread.current[:suppress_update_permissions] = true
+ begin
+ yield
+ ensure
+ Thread.current[:suppress_update_permissions] = check_perm_was
+ refresh_permissions
+ end
+end
+
# Used to account for permissions that a user gains by having
# can_manage on another user.
#