I take slight offense with the word manually here ;)
It does not matter what software you use or if you write it yourself from scratch - any solution will require you to define your conditions if you need them. r3 has one of the simplest solutions I´ve come across, when it comes to complex permission systems. Many systems will require you to re-define these on every view, be it lists, forms, etc. Easy to forget and a lot of work to update. Even when writing them from scratch, you will need to implement complex access permissions and apply them everywhere it´s needed - helper functions or access methods are then often used, pretty much the same way r3 does it by offering a central place to define the access.
Policies in r3 enable you to define these restrictions in a single location, applied everywhere automatically and enforcing it wherever you deal with data. They work with the same syntax and the same DB access, you can use everywhere else in r3.
rfernandez There is no pre.-build filtering system
That is literally what r3 policies do. It´s a pre-built system that is automatically applied everywhere where it´s relevant. The only "unique" thing about it, is that it does not serve you a pre-defined structure of things (like hierarchies, such as departments and other organizational structures) that might or might not work with the structure and requirements of your application. You are free in defining access based on any chosen structure (ie. relationships in your app) - which can model your organization, regulatory requirements, best-use dates of your products, countries of origin of supplier provided material, and anything else.
rfernandez I willl appreciate a lot if you point me to any of the standard application/part of the application in which I can see how to get the userid an other user attributes, and how to use them in the ad-hoc Policy function to allow it to filter the records in everyt attempt to access the target table.
Please have a look at any of our standard applications in the repository that use policies. Examples are REI3 Tasks, REI3 Tickets, REI3 Password Safe, REI3 Kanbans. It works by using instance functions that tell you, who is currently logged in, if they have specific roles and so on. The rest is SELECT statements.
Here is an example from the app REI3 Kanbans. It uses a backend function from REI3 Organizations to get the contact ID of the currently logged in user (you can look at that function too). This of course works when your app builds on REI3 Organizations. As you have your own user relation, you would use the instance function instance.get_user_id() to get the ID of the currently logged in user - it must match with the user ID on your user relation. The rest is just SELECTs looking up the record IDs of everything the current user may access (or not if blacklist policy) based on your defined access rules (may access if in department, if substitute of owner, if part of team that is managing that record, ...).
$BODY$
DECLARE
_contact_id INTEGER;
BEGIN
_contact_id := {lsw_organizations}.[get_contact_id_by_user]();
IF _contact_id IS NULL THEN
RETURN ARRAY[]::INTEGER[];
END IF;
RETURN ARRAY(
SELECT k.(lsw_kanbans.kanban.id)
FROM {lsw_kanbans}.[kanban] AS k
JOIN {lsw_organizations}.[contact] AS c ON c.(lsw_organizations.contact.id) = k.(lsw_kanbans.kanban.owner)
WHERE k.(lsw_kanbans.kanban.owner) = _contact_id
OR (
k.(lsw_kanbans.kanban.share_department) AND
c.(lsw_organizations.contact.department) = (
SELECT (lsw_organizations.contact.department)
FROM {lsw_organizations}.[contact]
WHERE (lsw_organizations.contact.id) = _contact_id
)
)
OR EXISTS (
SELECT 1
FROM {lsw_kanbans}.[kanban_team_share]
WHERE (lsw_kanbans.kanban_team_share.kanban) = k.(lsw_kanbans.kanban.id)
AND (lsw_kanbans.kanban_team_share.team) IN (
SELECT (lsw_organizations.team_contact.team)
FROM {lsw_organizations}.[team_contact]
WHERE (lsw_organizations.team_contact.contact) = _contact_id
)
)
);
END;
$BODY$