@@ -1514,6 +1514,82 @@ complex permission schemes. An `example in upgrading.html
15141514<upgrading.html#enhancement-to-check-command-for-permissions>`_
15151515shows the use of ``ctx``.
15161516
1517+ **filter
1518+ A function to be executed on the results of a ``filter`` call of the
1519+ schema ``Class`` before displaying the results in an ``index``
1520+ template. Calling a ``filter`` method on all results is usually faster
1521+ than calling a ``check`` method (see previous paragraph) on *each
1522+ individual result*. The ``filter`` method has the signature::
1523+
1524+ filter(db, userid, klass)
1525+
1526+ where ``db`` is the database handle, ``userid`` is the user attempting
1527+ access and ``klass`` is the ``Class`` in the schema.
1528+ The ``filter`` function must return a list of dictionaries of
1529+ parameters of the `Class.filter`` call. Results found during a query
1530+ executed by an index template are passed through the filter calls
1531+ computed by the ``filter`` function. An empty list of filter
1532+ parameters indicates no access. Note that defining a ``filter``
1533+ function also needs the definition of a ``check`` function for
1534+ checking individual items for visibility. A ``check`` function is
1535+ manufactured automatically from a ``filter`` function in no ``check``
1536+ function is defined.
1537+
1538+ Note that the filter option is not supported for the Search
1539+ permission. Since the filter function is called *after* the search was
1540+ already performed a filter function does not make any sense.
1541+
1542+ An example ``filter`` function for the ``view_query`` check function
1543+ in the query checks above would look like::
1544+
1545+ def filter_query(db, userid, klass):
1546+ return [{'filterspec': {'private_for': ['-1', userid]}}]
1547+
1548+ This would be called by the framework for all queries found when
1549+ displaying queries. It filters for all queries where the
1550+ ``private_for`` field is the userid or empty. This matches the
1551+ definition of the ``view_query`` function above where permission is
1552+ granted if the ``private_for`` field indicates the query is owned by
1553+ the user, or the ``private_for`` field is empty indicating that the
1554+ query is public. If we want to modify the check to also allow acess if
1555+ the user is the ``creator`` of a query we would change the filter
1556+ function to::
1557+
1558+ def filter_query(db, userid, klass):
1559+ f1 = {'filterspec': {'private_for': ['-1', userid]}}
1560+ f2 = {'filterspec': {'creator': userid}}
1561+ return [f1, f2]
1562+
1563+ This is an example where we need multiple filter calls to model an
1564+ "or" condition, the user has access if either the ``private_for``
1565+ check passes *or* the user is the creator of the query.
1566+
1567+ Now consider an example where we have a class ``organisation`` and the
1568+ ``issue`` class has a ``Link`` to ``organisation`` as has the ``user``
1569+ class. Users may only see issues that belong to their own
1570+ ``organisation``. A ``check`` function for this would be::
1571+
1572+ def view_issue(db, userid, itemid):
1573+ user = db.user.getnode(userid)
1574+ if not user.organisation:
1575+ return False
1576+ issue = db.issue.getnode(itemid)
1577+ if user.organisation == issue.organisation:
1578+ return True
1579+
1580+ The corresponding ``filter`` function::
1581+
1582+ def filter_issue(db, userid, klass):
1583+ user = db.user.getnode(userid)
1584+ if not user.organisation:
1585+ return []
1586+ return [{'filterspec': {'organisation': user.organisation}}]
1587+
1588+ This filters for all issues where the organisation is the same as the
1589+ organisation of the user. Note how the filter fails early returning an
1590+ empty list (meaning "no access") if the user happens to not have an
1591+ organisation.
1592+
15171593**properties**
15181594 A sequence of property names that are the only properties to apply the
15191595 new Permission to (eg. ``... klass='user', properties=('name',
@@ -1565,16 +1641,6 @@ shows the use of ``ctx``.
15651641
15661642 **Invalid properties for file: ['summary']
15671643
1568- **filter
1569- A function that complements a check function: It is used when
1570- searching for viewable items. The filter function allows to filter in
1571- SQL (for an SQL backend) rather than calling the check function for
1572- each item after a query. It must return a list of dictionaries
1573- containing parameters for the hyperdb.Class.filter method. An empty
1574- list indicates no access. The signature of the filter function is::
1575-
1576- def filter(db, userid, klass):
1577-
15781644
15791645Example Scenarios
15801646~~~~~~~~~~~~~~~~~
0 commit comments