39 | | * A Developer needs to be able to restrict access to a '''Function''': |
40 | | * ~~Decorator function : @auth.requires_membership("Administrator")~~ |
41 | | * doesn't support OR (we could easily write our own function to do this, though) |
42 | | |
43 | | * A Developer needs to be able to restrict access to a '''Resource''': |
44 | | * REST controller can be blocked via a Decorator |
45 | | * we'd need to patch other functions, such as sync, which would be hard to maintain |
46 | | * Full security policy (native web2py) can be invoked, but this is painful (based on protected by default & granted manually) & untested within S3 recently |
47 | | * Need a new method: open by default & restricted manually |
48 | | * Option1: Use an {{{auth_permission}}} table similar to Web2Py 'full' but just for tables & with {{{group_id}}} as {{{multiple=True}}} |
49 | | * Option2: Set within {{{000_config.py}}}, along with module permissions? (see above example) |
50 | | * Means less DAL calls |
51 | | * Option3: Have an onvalidation which auto-populates the reader_id/writer_id fields in records? |
52 | | * Means that no additional auth check at table-level needed |
53 | | * If done at validation time then it means that no extra DAL calls are done when creating resources (just extra field(s) within the 1 DAL call) |
54 | | * Once new solution in-place: |
55 | | * remove security_policy from {{{s3_setting}}} table & session ({{{00_utils.py}}}) |
56 | | * modify {{{shn_action_buttons()}}} in {{{00_utils.py}}} |
57 | | |
58 | | * A Developer needs to be able to restrict access to a '''Record''': |
59 | | * Add 2 reusable {{{multiple=True}}} fields to each table which needs this: {{{reader_id}}} & {{{writer_id}}} combined as {{{permissions_id}}} |
60 | | * Full backward compatibility since they default to None |
61 | | * For List views modify {{{shn_accessible_query()}}} (called from {{{shn_list()}}} & {{{shn_search()}}}) |
62 | | * combine with the {{{deleted==True}}} check? |
63 | | * makes it easier to then replace that check with an 'inactive' field which is a date instead of a boolean, so that records can be set to expire (as well as giving us easy access to know when a record was deleted) |
64 | | * Preferred Option: Do the check alongside deleted as part of a big JOIN |
| 39 | === Function restriction === |
| 40 | * ~~Decorator function : @auth.requires_membership("Administrator")~~ |
| 41 | * doesn't support OR (we could easily write our own function to do this, though) |
| 42 | * within Controller put manual restrictions or alternate routes |
| 43 | |
| 44 | === Resource restriction === |
| 45 | * REST controller can be blocked via a Decorator |
| 46 | * we'd need to patch other functions, such as sync, which would be hard to maintain |
| 47 | * Full security policy (native web2py) can be invoked, but this is painful (based on protected by default & granted manually) & untested within S3 recently |
| 48 | * Need a new method: open by default & restricted manually |
| 49 | * Option1: Use an {{{auth_permission}}} table similar to Web2Py 'full' but just for tables & with {{{group_id}}} as {{{multiple=True}}} |
| 50 | * Option2: Set within {{{000_config.py}}}, along with module permissions? (see above example) |
| 51 | * Means less DAL calls |
| 52 | * Option3: Have an onvalidation which auto-populates the reader_id/writer_id fields in records? |
| 53 | * Means that no additional auth check at table-level needed |
| 54 | * If done at validation time then it means that no extra DAL calls are done when creating resources (just extra field(s) within the 1 DAL call) |
| 55 | * Once new solution in-place: |
| 56 | * remove security_policy from {{{s3_setting}}} table & session ({{{00_utils.py}}}) |
| 57 | * modify {{{shn_action_buttons()}}} in {{{00_utils.py}}} |
| 58 | |
| 59 | === Record restriction === |
| 60 | * Add 2 reusable {{{multiple=True}}} fields to each table which needs this: {{{reader_id}}} & {{{writer_id}}} combined as {{{permissions_id}}} |
| 61 | * Full backward compatibility since they default to None |
| 62 | * For List views modify {{{shn_accessible_query()}}} (called from {{{shn_list()}}} & {{{shn_search()}}}) |
| 63 | * combine with the {{{deleted==True}}} check? |
| 64 | * makes it easier to then replace that check with an 'inactive' field which is a date instead of a boolean, so that records can be set to expire (as well as giving us easy access to know when a record was deleted) |
| 65 | * Preferred Option: Do the check alongside deleted as part of a big JOIN |
105 | | * Advantages: |
106 | | * Combines the deleted into single API call |
107 | | * Single JOIN for optimal DB performance (Assumption needs testing) |
108 | | * Alternate Option: Do the check in Python after the initial query has returned |
109 | | * Advantage: Might have better performance than complex DB string? |
110 | | * Disadvantage: More records pulled from DB than necessary |
111 | | |
112 | | * For single records modify {{{shn_has_permission()}}} (called from {{{shn_create()}}}, {{{shn_delete()}}}, {{{shn_read()}}} & {{{shn_update()}}}, but also available for other functions) |
| 106 | * Advantages: |
| 107 | * Combines the deleted into single API call |
| 108 | * Single JOIN for optimal DB performance (Assumption needs testing) |
| 109 | * Alternate Option: Do the check in Python after the initial query has returned |
| 110 | * Advantage: Might have better performance than complex DB string? |
| 111 | * Disadvantage: More records pulled from DB than necessary |
| 112 | |
| 113 | * For single records modify {{{shn_has_permission()}}} (called from {{{shn_create()}}}, {{{shn_delete()}}}, {{{shn_read()}}} & {{{shn_update()}}}, but also available for other functions) |
210 | | * UI to manage the fields. |
211 | | * We expect relatively few groups per instance, so can use the checkboxes widget? |
212 | | * can filter out some groups? |
213 | | * Have a single checkbox for 'Restrict access' which then opens out the 2 fields. |
214 | | |
215 | | * A Developer needs to be able to restrict access to a '''Field''': |
216 | | * In model (for access by all controllers, such as sync): |
| 211 | * UI to manage the fields. |
| 212 | * We expect relatively few groups per instance, so can use the checkboxes widget? |
| 213 | * can filter out some groups? |
| 214 | * Have a single checkbox for 'Restrict access' which then opens out the 2 fields. |
| 215 | |
| 216 | === Field restriction === |
| 217 | * In model (for access by all controllers, such as sync): |
232 | | * NB If doing this then the roles checks inside {{{shn_has_permission()}}} & {{{shn_accessible_fields()}}} should be modified to read this global value instead of more DAL queries (even cached)! |
233 | | |
234 | | * A Developer should be able to restrict access to records to just those within a certain '''GIS Location''' (e.g. Country or Region): |
235 | | * Add a special role 'Geographic' which can be added to {{{writer_id}}} (& maybe {{{reader_id}}} although less use case for this) |
236 | | * Patch {{{shn_has_permission()}}} & maybe {{{shn_accessible_query()}}} to spot this special case &, if no other roles match, then do a lookup in another table (or deployment_settings dict) |
237 | | |
238 | | * A Developer should be able to restrict access to records to just those within a certain '''Organisation''': |
239 | | * This could be all members of the Organisation or just the 'Focal Point' |
240 | | * Add a special role 'Organisation' which can be added to {{{writer_id}}} (& maybe {{{reader_id}}} although less use case for this) |
241 | | * Patch {{{shn_has_permission()}}} & maybe {{{shn_accessible_query()}}} to spot this special case &, if no other roles match, then do a lookup in another table (or deployment_settings dict) |
242 | | |
243 | | * A Developer should be able to restrict access to records to just those which the person '''Created''': |
244 | | * Add a special role 'Creator' which can be added to {{{writer_id}}} (& maybe {{{reader_id}}} although less use case for this) |
245 | | * Patch {{{shn_has_permission()}}} & maybe {{{shn_accessible_query()}}} to spot this special case &, if no other roles match, then do a check between {{{auth.user.id}}} & {{{table.created_by}}} |
246 | | |
247 | | * Ideally options which a user doesn't have permission for should be hidden from them. |
248 | | * ~~Modules are hidden from Modules menu & front page~~ |
249 | | * ~~Action buttons in tables only show 'Details' for unauthenticated users, but 'Update'/'Delete' for authenticated ones~~ |
250 | | * ideally would distinguish per record if some records restricted (We already pull the data for the rows, so need to ensure SQL query includes relevant fields & that we act upon them) |
251 | | * Controller menus should be adjusted (currently done manually => harder maintenance) |
252 | | * Views should be adjusted (currently done manually => harder maintenance) |
253 | | |
254 | | === Specific Examples === |
| 233 | * NB If doing this then the roles checks inside {{{shn_has_permission()}}} & {{{shn_accessible_fields()}}} should be modified to read this global value instead of more DAL queries (even cached)! |
| 234 | |
| 235 | === Location restriction === |
| 236 | e.g. Country or Region |
| 237 | * Add a special role 'Geographic' which can be added to {{{writer_id}}} (& maybe {{{reader_id}}} although less use case for this) |
| 238 | * Patch {{{shn_has_permission()}}} (& maybe {{{shn_accessible_query()}}}) to spot this special case &, if no other roles match, then do a lookup in another table (or deployment_settings dict) |
| 239 | |
| 240 | === Organisation restriction === |
| 241 | * This could be all members of the Organisation or just the 'Focal Point' |
| 242 | * Add a special role 'Organisation' which can be added to {{{writer_id}}} (& maybe {{{reader_id}}} although less use case for this) |
| 243 | * Patch {{{shn_has_permission()}}} (& maybe {{{shn_accessible_query()}}}) to spot this special case &, if no other roles match, then do a lookup in another table (or deployment_settings dict) |
| 244 | |
| 245 | === Author restriction === |
| 246 | Only allow a user to update records which they created. |
| 247 | * Add a special role 'Creator' which can be added to {{{writer_id}}} (& maybe {{{reader_id}}} although less use case for this) |
| 248 | * Patch {{{shn_has_permission()}}} (& maybe {{{shn_accessible_query()}}}) to spot this special case &, if no other roles match, then do a check between {{{auth.user.id}}} & {{{table.created_by}}} |
| 249 | |
| 250 | === Anonymous authoring === |
| 251 | Some tables should be writable by unauthenticated users ({{{writable=|0|}}}) |
| 252 | * Need special handling for this in {{{shn_create}}}/{{{shn_update}}}? |
| 253 | * Might need to differentiate the 2 (can deposit new but not edit existing) |
| 254 | * Might want to be have new records by unauthenticated users not be visible in lists until an admin has approved them |
| 255 | |
| 256 | === Visibility of Options === |
| 257 | Ideally options which a user doesn't have permission for should be hidden from them. |
| 258 | * ~~Modules are hidden from Modules menu & front page~~ |
| 259 | * ~~Action buttons in tables only show 'Details' for unauthenticated users, but 'Update'/'Delete' for authenticated ones~~ |
| 260 | * ideally would distinguish per record if some records restricted (We already pull the data for the rows, so need to ensure SQL query includes relevant fields & that we act upon them) |
| 261 | * Controller menus should be adjusted (currently done manually => harder maintenance) |
| 262 | * Views should be adjusted (currently done manually => harder maintenance) |
| 263 | |
| 264 | ==== Specific Examples ==== |