| 3 | |
| 4 | S3Anonymize is a tool to remove sensitive information from a record (and related records) based on configurable rules. |
| 5 | |
| 6 | == Overview == |
| 7 | |
| 8 | S3Anonymize removes information from a record (and related records) based on rules. It is primarily intended for person data, but can be re-used for any type of record. |
| 9 | |
| 10 | == Configuring Rules == |
| 11 | |
| 12 | Rules are configured using {{{s3db.configure}}} for the target table. The rules format looks like this: |
| 13 | |
| 14 | {{{#!py |
| 15 | s3db.configure("pr_person", |
| 16 | anonymize = {# A name and title for the rule set: |
| 17 | "name": "default", |
| 18 | "title": "Names, IDs, Reference Numbers, Contact Information, Addresses", |
| 19 | |
| 20 | # Rules how to clean up fields in the master record: |
| 21 | "fields": {"first_name": ("set", "-"), # Set field to this value |
| 22 | "last_name": ("set", "-"), |
| 23 | "pe_label": anonymous_id, # Callable returning a new field value |
| 24 | "date_of_birth": obscure_dob, |
| 25 | "comments": "remove", # Set field value to None |
| 26 | }, |
| 27 | |
| 28 | # Rules for related records: |
| 29 | "cascade": [("dvr_case", {"key": "person_id", # Foreign key in the related table |
| 30 | "match": "id", # Match this key of the parent table |
| 31 | |
| 32 | # Field rules for the related table |
| 33 | "fields": {"comments": "remove", |
| 34 | }, |
| 35 | }), |
| 36 | |
| 37 | ("pr_contact", {"key": "pe_id", |
| 38 | "match": "pe_id", |
| 39 | "fields": {"contact_description": "remove", |
| 40 | "value": ("set", ""), |
| 41 | "comments": "remove", |
| 42 | }, |
| 43 | |
| 44 | "delete": True, # Delete the related records after cleanup (default False) |
| 45 | }), |
| 46 | ], |
| 47 | }, |
| 48 | ) |
| 49 | }}} |
| 50 | |
| 51 | - in cascading rules, the {{{key}}}+{{{match}}} properties can be replaced by a {{{lookup}}} property to configure a callable with the signature {{{lookup(table, rows, tablename)}}} that returns a set of relevant record IDs in the related table |
| 52 | |
| 53 | - standard field rules are: |
| 54 | - {{{"remove"}}} sets the field value to None |
| 55 | - {{{"reset"}}} sets the field value to the field default |
| 56 | - {{{("set", value)}}} sets the field value to the specified value |
| 57 | - field rules can also be callables with the signature {{{rule(master_id, field, current_value)}}} that return the new value for the field |
| 58 | - field rules must produce valid records (i.e. the resulting value must pass database constraints and validators) |
| 59 | - after applying field rules, S3Anonymize will execute {{{update_super}}} and {{{onaccept}}} like any other CRUD method |
| 60 | - records in related tables will additionally be deleted if {{{"delete": True}}} is specified (which makes sense if the field rules remove all useful information from those records anyway) |
| 61 | - if cascading records are to be deleted, this will ''additionally'' execute {{{ondelete}}} (as last step) |
| 62 | |
| 63 | Instead of a single set of rules, it is possible to configure multiple rule sets as list: |
| 64 | {{{ |
| 65 | s3db.configure("pr_person", |
| 66 | anonymize = [{...first rule set...}, {...second rule set...}], |
| 67 | ) |
| 68 | }}} |
| 69 | |
| 70 | ...each with its own {{{name}}} and {{{title}}}. These rule sets will later be selectable in the GUI, so that the user can choose to only remove some, but not other data from the record (see screenshot below). |
| 71 | |
| 72 | == GUI and REST Method == |
| 73 | |
| 74 | === S3AnonymizeWidget === |
| 75 | |
| 76 | To embed S3Anonymize in the GUI, it comes with a special widget class S3AnonymizeWidget and a UI script (s3.ui.anonymize.js). |
| 77 | |
| 78 | S3AnonymizeWidget produces an action button/link (with a hidden dialog) that can be embedded in the record view (e.g. in postp in place of the delete-button): |
| 79 | {{{ |
| 80 | def postp(r, output): |
| 81 | |
| 82 | if r.record and not r.component and r.method in (None, "update", "read") and isinstance(output, dict): |
| 83 | |
| 84 | buttons = output.get("buttons") or {} |
| 85 | |
| 86 | from s3 import S3AnonymizeWidget |
| 87 | buttons["delete_btn"] = S3AnonymizeWidget.widget(r, _class="action-btn anonymize-btn") |
| 88 | |
| 89 | output["buttons"] = buttons |
| 90 | |
| 91 | return output |
| 92 | }}} |
| 93 | |
| 94 | The {{{_class}}} parameter can be used to control the appearance of the link. The {{{widget}}} function will automatically embed the UI dialog and script, and authorize the link. |
| 95 | |
| 96 | Clicking on the link brings up a dialog like this: |
| 97 | |
| 98 | |
| 99 | == Back-end Function == |