Index: openacs-4/packages/acs-kernel/sql/postgresql/acs-permissions-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/sql/postgresql/acs-permissions-create.sql,v diff -u -N -r1.35 -r1.36 --- openacs-4/packages/acs-kernel/sql/postgresql/acs-permissions-create.sql 7 Jul 2011 10:46:02 -0000 1.35 +++ openacs-4/packages/acs-kernel/sql/postgresql/acs-permissions-create.sql 2 Apr 2013 11:05:17 -0000 1.36 @@ -578,14 +578,88 @@ DECLARE exists_p boolean; BEGIN - return exists (select 1 - from acs_permissions p, party_approved_member_map m, - acs_object_context_index c, acs_privilege_descendant_map h - where p.object_id = c.ancestor_id - and h.descendant = permission_p__privilege - and c.object_id = permission_p__object_id - and m.member_id = permission_p__party_id - and p.privilege = h.privilege - and p.grantee_id = m.party_id); + return exists (With RECURSIVE object_context(object_id, context_id) AS ( + + select permission_p__object_id, permission_p__object_id + from acs_objects + where object_id = permission_p__object_id + + union all + + select ao.object_id, + case when (ao.security_inherit_p = 'f' or ao.context_id is null) + then acs__magic_object_id('security_context_root') else ao.context_id end + from object_context oc, acs_objects ao + where ao.object_id = oc.context_id + and ao.object_id != acs__magic_object_id('security_context_root') + + ), privilege_ancestors(privilege, child_privilege) AS ( + + select permission_p__privilege, permission_p__privilege + + union all + + select aph.privilege, aph.child_privilege + from privilege_ancestors pa join acs_privilege_hierarchy aph + on aph.child_privilege = pa.privilege + + ) select + 1 + from + acs_permissions p + join party_approved_member_map pap on pap.party_id = p.grantee_id + join privilege_ancestors pa on pa.privilege = p.privilege + join object_context oc on p.object_id = oc.context_id + where pap.member_id = permission_p__party_id + ); END; $$ LANGUAGE plpgsql stable; + + +-- for tsearch + +select define_function_args('acs_permission__permission_p_recursive_array','a_objects,a_party_id,a_privilege'); + +CREATE OR REPLACE FUNCTION acs_permission__permission_p_recursive_array( + permission_p__objects integer[], + permission_p__party_id integer, + permission_p__privilege varchar +) RETURNS table (object_id integer, orig_object_id integer) as $$ +BEGIN + return query With RECURSIVE object_context(object_id, context_id, orig_object_id) AS ( + + select unnest(permission_p__objects), unnest(permission_p__objects), unnest(permission_p__objects) + + union all + + select ao.object_id, + case when (ao.security_inherit_p = 'f' or ao.context_id is null) + then acs__magic_object_id('security_context_root') else ao.context_id END, + oc.orig_object_id + from object_context oc, acs_objects ao + where ao.object_id = oc.context_id + and ao.object_id != acs__magic_object_id('security_context_root') + + ), privilege_ancestors(privilege, child_privilege) AS ( + + select permission_p__privilege, permission_p__privilege + from acs_privilege_hierarchy + where privilege = permission_p__privilege + + union all + + select aph.privilege, aph.child_privilege + from privilege_ancestors pa join acs_privilege_hierarchy aph + on aph.child_privilege = pa.privilege + + ) select + p.object_id, oc.orig_object_id + from + acs_permissions p + join party_approved_member_map pap on pap.party_id = p.grantee_id + join privilege_ancestors pa on pa.privilege = p.privilege + join object_context oc on p.object_id = oc.context_id + where pap.member_id = permission_p__party_id + ; +END; +$$ LANGUAGE plpgsql stable;