Forum OpenACS Development: copying permissions
This is easy to achieve, as I have a folder with templates under which the folder structure I need to copy begins (e.g. /templates/project and /templates/project/folder1 /templates/project/folder2 aso.). Once I create a new project, I just call content_folder__copy and be done with it.
Yet.... it does copy the folder structure, but sadly assumes, that I want to inherit the permissions from the new destination folder. Furthermore it assumes, I don't want to keep the permissions set in the template folders.
Sadly, that's not true, so I wrote a procedure to copy a folder (fs::copy_folder) which allows me to copy the permissions as well as the notifications from the template folder (as I also have a group which should get notifications for uploads to a certain folder).
Writing this I realized, there is no procedure to copy permissions from one object to another. So I wrote this as well (permission::copy)
Before I post my code (later on), did I overlook something? Could I have done this easier?
ad_proc permission::copy { -from_object_id -to_object_id -clean_inheritance:boolean -overwrite:boolean } { @author Malte Sussdorff (mailto:malte.sussdorff@cognovis.de) Copy the permissions from one object to another. @param from_object_id Source object_id for the permissions @param to_object_id Destination object_id which will get the new permissions @param clean_inheritance Clean the inheritance of the destination object_id. Useful for items / folders which would usually inherit from the pare\ nt_object_id regardless of what the permissions are on the object itself @param overwrite Overwrite existing permissions. In this case we would first clean up the permissions for this item } { if {$overwrite_p} { # Clean the permissions set object_id $to_object_id db_foreach select_permissions {} { permission::revoke -object_id $object_id -party_id $grantee_id -privilege $privilege } } if {$clean_inheritance_p} { # Unset inheritance permission::set_not_inherit -object_id $to_object_id } set object_id $from_object_id db_foreach select_permissions {} { permission::grant -object_id $to_object_id -party_id $grantee_id -privilege $privilege } } <fullquery name="permission::copy.select_permissions"> <querytext> select grantee_id,privilege from acs_permissions where object_id = :object_id </querytext> </fullquery>
ad_proc fs::copy_folder { -source_folder_id -destination_folder_id } { @author Malte Sussdorff (mailto:malte.sussdorff@cognovis.de) @creation-date 2010-09-24 Copies the folder to another parent folder Makes sure to copy the permissions as well @param destination_folder_id Folder ID of the destination folder below which the folder will be copied @param source_folder_id Folder ID of the folder to be copied } { set user_id [ad_conn user_id] set peer_addr [ad_conn peeraddr] # Make sure we have write permission on the destination folder permission::require_permission \ -party_id $user_id \ -object_id $destination_folder_id \ -privilege "write" permission::require_permission \ -party_id $user_id \ -object_id $source_folder_id \ -privilege "read" # Make sure both are actually folders if {![content::folder::is_folder -item_id $source_folder_id] || ![content::folder::is_folder -item_id $destination_folder_id]} { return 0 } set new_parent_folder_id [db_string copy_folder {}] db_foreach folder_compare { select source.item_id as old_folder_id, target.item_id as new_folder_id, security_inherit_p from (select children.item_id, children.name, security_inherit_p from cr_items children, cr_items parent, acs_objects o where children.tree_sortkey between parent.tree_sortkey and tree_right(parent.tree_sortkey) and parent.tree_sortkey <> children.tree_sortkey and parent.item_id = :source_folder_id and children.item_id = o.object_id order by children.tree_sortkey) source, (select children.item_id, children.name from cr_items children, cr_items parent where children.tree_sortkey between parent.tree_sortkey and tree_right(parent.tree_sortkey) and parent.tree_sortkey <> children.tree_sortkey and parent.item_id = :new_parent_folder_id order by children.tree_sortkey) target where source.name = target.name } { if {$security_inherit_p eq "t"} { permission::copy -from_object_id $old_folder_id -to_object_id $new_folder_id -overwrite } else { permission::copy -from_object_id $old_folder_id -to_object_id $new_folder_id -overwrite -clean_inheritance } } if {[permission::inherit_p -object_id $source_folder_id]} { permission::copy -from_object_id [content::item::get_parent_folder -item_id $source_folder_id] -to_object_id $new_parent_folder_id -clean_inheritance -overwrite } else { permission::copy -from_object_id $source_folder_id -to_object_id $new_parent_folder_id -clean_inheritance -overwrite } }