@@ -1514,6 +1514,82 @@ complex permission schemes. An `example in upgrading.html
1514
1514
<upgrading.html#enhancement-to-check-command-for-permissions>`_
1515
1515
shows the use of ``ctx``.
1516
1516
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
+
1517
1593
**properties**
1518
1594
A sequence of property names that are the only properties to apply the
1519
1595
new Permission to (eg. ``... klass='user', properties=('name',
@@ -1565,16 +1641,6 @@ shows the use of ``ctx``.
1565
1641
1566
1642
**Invalid properties for file: ['summary']
1567
1643
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
-
1578
1644
1579
1645
Example Scenarios
1580
1646
~~~~~~~~~~~~~~~~~
0 commit comments