| 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 ==== |