Changes between Version 19 and Version 20 of BluePrintAuthorization


Ignore:
Timestamp:
06/19/10 14:43:31 (14 years ago)
Author:
Fran Boon
Comment:

shn_has_permission()

Legend:

Unmodified
Added
Removed
Modified
  • BluePrintAuthorization

    v19 v20  
    2222        writable = None,    # All Authenticated users can edit resources which aren't specially protected
    2323        module_type = 2,    # Used to locate the module in the default menu
    24         resource_readable = Storage(
    25             apikey = 1,     # This resource is only visible to Administrators
     24        resources = Storage(
     25            apikey = {
     26                    read : 1,     # This resource is only visible to Administrators
     27                },
     28            layer_js = {
     29                    create : deployment_settings.auth.roles["AdvancedJS"],    # This resource requires the 'AdvancedJS' role to create (or admin)
     30                    delete : deployment_settings.auth.roles["AdvancedJS"],    # This resource requires the 'AdvancedJS' role to delete (or admin)
     31                    update : deployment_settings.auth.roles["AdvancedJS"],    # This resource requires the 'AdvancedJS' role to update (or admin)
     32                }
    2633        ),
    27         resource_writable = Storage(
    28             layer_js = deployment_settings.auth.roles["AdvancedJS"],    # This resource requires the 'AdvancedJS' role to edit (or admin)
    29         )
    3034    ),
    3135    ...
     
    4347  * Need a new method: open by default & restricted manually
    4448   * Needs to be a DAL-level method since not all accesses go via S3XRC.
    45    * Use an {{{auth_permission}}} table similar to Web2Py 'full' just for tables?
    46    * Set within {{{000_config.py}}}, along with module permissions? (see above example)
     49   * Option1: Use an {{{auth_permission}}} table similar to Web2Py 'full' just for tables?
     50   * Option2: Set within {{{000_config.py}}}, along with module permissions? (see above example)
     51    * Means less DAL calls
     52   * Option3: Have an onaccept which auto-populates the reader_id/writer_id fields in records?
     53    * Means that no additional auth check at table-level needed
     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}}}
    4757
    4858 * A Developer needs to be able to restrict access to a record
     
    5565{{{
    5666def shn_accessible_query(table):
    57     """ Modified version of current function from models/01_crud.py """
     67    """
     68    Return a filter of those records which are readable by the currently logged-in user
     69    - deleted records are filtered
     70    - records to which they don't have permissions are filtered
     71    (Modified version of current function from models/01_crud.py)
     72    """
    5873
    5974    deleted = (table.deleted == None)
     
    8297    return query
    8398
    84 def user_function:
     99def user_function():
     100    ...
    85101    table = db[tablename]
    86102    available = shn_accessible_query(table)
    87103    query = available & query
     104    ...
    88105}}}
    89106    * Advantages:
     
    93110    * Advantage: Might have better performance than complex DB string?
    94111    * Disadvantage: More records pulled from DB than necessary
    95   * writer_id checked with a new API function (called from shn_update(), but also available for other functions)
     112  * writer_id checked within a modified {{{shn_has_permission()}}} (called from shn_update(), etc, but also available for other functions)
     113{{{
     114def shn_has_permission(name, tablename, record_id = 0):
     115    """
     116        S3 framework function to define whether a user can access a record in manner "name"
     117    """
     118
     119    try:
     120        user_id = auth.user.id
     121        _memberships = db.auth_membership
     122        memberships = db(_memberships.user_id == user_id).select(_memberships.group_id)
     123    except:
     124        memberships = None
     125   
     126    roles = []
     127    for membership in memberships:
     128        roles.append(membership.group_id)
     129
     130    # Check if table is restricted
     131    table = db[tablename]
     132    if 1 in roles:
     133        # Admins see all tables
     134        authorised = True
     135    else:   
     136        # Option 1
     137        #restriction = db(table[name].like('%|%d|%' % role)).select()
     138        # Option 2
     139        module, resource = tablename.split("_", 1)
     140        try:
     141            restriction = deployment_settings_modules["module"].resources["resource"]["name"]
     142        except:
     143            restriction = None
     144       
     145        if restriction:
     146            if restriction in roles:
     147                authorised = True
     148            else:
     149                authorised = False
     150        else:
     151            # No restriction
     152            authorised = True
     153        # Option 3
     154        # - not necessary!
     155
     156    if record_id and authorised:
     157        # Check if record is deleted
     158        record = db(table.id == record_id).select(table.deleted, table.reader_id, table.writer_id, limitby=(0, 1)).first()
     159        if record.deleted:
     160            authorised = False
     161        elif 1 in roles:
     162            authorised = True
     163        else:
     164            if name == "read":
     165                if not table.reader_id:
     166                    authorised = True
     167                else:
     168                    authorised = False
     169                    restrictions = re.split("\|", table.reader_id)[1:-1]
     170                    # Assume we generally have fewer restrictions than roles
     171                    for restriction in restrictions:
     172                        if restriction in roles:
     173                            authorised = True
     174                   
     175            elif name in ["delete", "update"]:
     176                if not table.writer_id:
     177                    authorised = True
     178                else:
     179                    authorised = False
     180                    restrictions = re.split("\|", table.writer_id)[1:-1]
     181                    # Assume we generally have fewer restrictions than roles
     182                    for restriction in restrictions:
     183                        if restriction in roles:
     184                            authorised = True
     185
     186            else:
     187                # Something went wrong
     188                session.error = str(T("Invalid mode sent to")) + " shn_has_permission(): " + name
     189                redirect(URL(r=request, f="index"))
     190
     191return authorised
     192}}}
     193   * Disadvantage: Slow
    96194  * UI to manage the fields.
    97195   * We expect relatively few groups per instance, so can use the checkboxes widget?