Commits

Hector Garcia  committed aceb1b3

Added sqlite db file from example project to .hgignore. Updated docs with usage file.

  • Participants
  • Parent commits 29e0116

Comments (0)

Files changed (4)

 syntax: glob
 *.pyc
+example/db/dev.db
 

File docs/overview.rst

+===========
 django-rbac
 ===========
 
-Introduction
-=========
-
 First of all, I would like to show some drawbacks of Django's current permission system:
 
 * Permissions are tied directly to the ``User`` model from ``django.contrib.auth``, so you cannot use any other existing model in your application.
 
 I you are interested, you can read the `introduced formal model`_ by F. Ferraiolo and D. R. Kuhn.
 
-.. _#11010: http://code.djangoproject.com/ticket/11010
-.. _ACL: http://en.wikipedia.org/wiki/Access_control_list
+.. _11010: http://code.djangoproject.com/ticket/11010
 .. _RBAC: http://csrc.nist.gov/groups/SNS/rbac/
 .. _introduced formal model: http://csrc.nist.gov/groups/SNS/rbac/documents/Role_Based_Access_Control-1992.html
 
 Dependencies
-==========
+============
 
 Be sure you have ``django.contrib.contenttypes`` installed in you project.
 
 Installation
-========
+============
 
-Mercurial checkout
-------------------
+Currently only installation from latest development code is available. Once the code is mature enough I will upload it to PyPi_ so anyone can grab and install it using ``easy_install`` or ``pip``.
+
+.. _PyPi: http://pypi.python.org/
+
+Development
+-----------
 
 Install Mercurial_ if you don't have it yet, and clone the repository::
 
 .. _Virtualenvwrapper: http://www.doughellmann.com/projects/virtualenvwrapper/
 
 Overview
-=======
+========
 
-Permissions are constructed by the following elements:
+The following elements conform a RBAC permission in django-rbac:
 
-1. The owner: The owner of either the object being accessed or the permission rule itself -- a site user, a community administrator...
-3. The object: The element being accessed on which the permission is being checked upon -- a profile, photo album...
-3. The operation: The action requested -- display, create, delete, show birth date, send message, request friendship...
-4. The roles: Define who is the requesting user in relation to the owner or the object -- anonymous, friend, family, coworker, roommate...
+1. The **owner**: The proprietary of either the object being accessed or the permission rule itself, e.g. a site user or a community administrator.
+3. The **object**: The element being accessed on which the permission is being checked upon, e.g. a profile or photo album.
+3. The **operation**: The action requested, e.g. display, create, delete, show birth date, send message or request friendship.
+4. The **roles**: Define who are the requesting users in relation to the owner or the object, e.g anonymous, friend, family, coworker, or roommate.
 
 This is best explained with a simple example:
 
-* User Fritz wants to see Mr. Natural's profile. Thus, Fritz requests permission to access (view) the profile for Mr. Natural (the object).
-* Fritz is initially an 'anonymous' user, a role that everybody holds in the system. As Fritz and Mr. Natural are friends, the role 'friend' is appended to the role set where 'anonymous' was also included.
-* The privacy framework performs its magic to pull an answer: has Fritz permission to access this profile?
+* User *Fritz* wants to see *Mr. Natural's* profile. Thus, *Fritz* (subject) requests permission to access (**operation**) the profile (**object**) of *Mr. Natural* (**owner**).
+* *Fritz* is an 'anonymous' user (**role**), a role that everybody holds initially in the system. As *Fritz* and *Mr. Natural* are friends, the role 'friend' is appended to the **roles**. So we have a role list containing 'anonymous' and 'friend'.
+* The privacy framework performs its magic to pull an answer: has *Fritz* permission to access this profile?
     * For the 'anonymous' role, the system denies the access.
-    * For the 'friend' role the access is granted, as Mr. Natural had set access only to friends to his profile.
-* Access is granted, so Fritz can go ahead and view all the stuff.
+    * For the 'friend' role the access is granted, as *Mr. Natural* had set access only to friends to his profile.
+* Access is granted, so *Fritz* can go ahead and view all the stuff.
 
-A permission can be assigned to a either a single object ("per-object permission" category, also known as "granular permissions" or "row level permissions") or to all objects of the same model class. For this reason, django-rbac implements two classes respectively: ``RBACPermission`` and ``RBACGenericPermission``. The example above falls into the first "per-object permission" category.
+Permissions can be assigned to either a single object ("per-object permission" category, also known as "granular permissions" or "row level permissions") like in the example above, or to all objects of the same model class. For this reason, django-rbac implements two classes respectively: ``RBACPermission`` and ``RBACGenericPermission``.
 
 How it works
+============
+
+Asking for permission in django-rbac is a 2-step process:
+
+1. Get the roles: The user that tries to perform the operation over an object or model does so within a context given between him and the owner or the object/model itself. You have to provide a python list of ``RBACRole`` objects to the function that will later check authorization.
+2. Call the ``get_permission`` method from one of the two RBAC permission objects (``RBACPermission.objects.get_permission`` or ``RBACGenericPermission,objects.get_permission``). The method will return ``True`` or ``False`` if the operation is authorized or not.
+
+You are totally responsible of executing step 1. The ways that roles can be assigned to users are endless, particular to each application or project, so django-rbac cannot provide any generic method to accomplish this task. Jump to the subsection "Writing functions to get roles" in the "Roles" section for more information.
+
+Operations
 ==========
 
-First it is essential for you to know that in django-rbac, asking for permission is a 2-step process:
-
-1. Get the roles: The user that tries to perform the operation over an object or model does so within a context given between him and the owner or the object/model itself. You have to provide a python list of ``RBACRole`` objects to the function that will check authorization (point 2 in this list!)
-2. Call ``rbac_permission`` function: It will perform the checking to answer if the operation is authorized or not.
-
-You are totally responsible of executing step 1. The ways that roles can be assigned to users and endless, particular to each application or project, so django-rbac cannot plan in advance any way of doing it generic. The resulting role list is then passed to the ``rbac_permission`` along with the object or model owner, the object or model itself, and the operation. More on this in the following sections.
-
-Operations
-========
-
-The ``RBACOperation`` model define functions that can be done in the system, e.g. 'display_profile', 'send_message', 'request_friendship', or 'show_email'. You can define what you want, just try to stick to a common syntax convention and short names for your own sake, because these strings will be used later on to request authorizations over permissions in your code.
+The ``RBACOperation`` model defines operations that can be done in the system, e.g. 'display_profile', 'send_message', 'request_friendship', or 'show_email'. You can define what you want, just try to stick to a common syntax convention and short names for your own sake.
 
 Roles
-====
+=====
 
-Originally a role is a job function within the context of an organization, but it can also be seen like a relationship between the requesting user (subject) and the owner. Users trying to perform operations over bjects can do so in multiple fashions. For example, someone asks for permission to see, let's say, a photo album from another user. Such requesting user can be friend or family of the album owner, a member of a photography community, or maybe an anonymous folk with a deep interest in other's pics. Thus, 'anonymous', 'friend', 'community_member' or 'family' would be roles that users can belong to.
+Originally a role is a job function within the context of an organization, but it can also be seen like a relationship between the requesting user (subject) and the owner. Users trying to perform operations over objects can do so in multiple fashions. For example, someone asks for permission to see, let's say, a photo album from another user. Such requesting user can be friend or family of the album owner, a member of a photography community, or maybe an anonymous folk with a deep interest in other's pics. Thus, 'anonymous', 'friend', 'community_member' or 'family' would be names of ``RBACRole`` roles that users can belong to.
 
 Writing functions to get roles
------------------------------
+------------------------------
 
-Sometimes you need to provide your app some programming logic to know which roles is the requesting user going to play. A common case is the ``request.user`` in a Django view. See this example extracted from the project that comes with the django-rbac package in the ``example`` folder::
+You need to provide your app some programming logic to know which roles is the requesting user going to play. A common case is the ``request.user`` in a Django view. See this example extracted from the project that comes with the django-rbac package in the ``example`` folder::
 
     from rbac.models import RBACRole
-   
+    
     def get_user_roles(user, target_user):
         roles = []
         # These two functions below would validate the relationship between the two users.
         return roles
 
 Permissions
-=========
+===========
 
-Once you have your operations and roles ready, you can start creating permissions. RBAC enables the conditions for the implementaiton of what is called the Separation of Duties (SoD), so tipically applications or projects using django-rbac will set mechanisms to delegate creating new permissions to owners. That is, the owner of an object will be who is setting the permission level to all the operations that can be done with the object. You are again responsible of providing the user an interface to accomplish this task. Classical social networks, for example, give their users a 'privacy' page with forms to change different permission settings.
+Once you have your operations and roles ready, you can start creating permissions. RBAC enables the conditions for the implementaiton of what is called the *Separation of Duties* (SoD), so tipically applications or projects using django-rbac will set mechanisms to delegate creating new permissions to owners. That is, the owner of an object will be who is setting the permission level to all the operations that can be done with the object. You are again responsible of providing the user an interface to accomplish this task. Classical social networks, for example, give their users a 'privacy' page with forms to change different permission settings.
 
-As mentioned in the Overview section, the scope of a permission can be row level (``RBACPermission``) or model class level (``RBACGenericPermission``). Both models receive:
+As mentioned in the beginning of this document, the scope of a permission can be row level (``RBACPermission``) or model class level (``RBACGenericPermission``). Both models receive:
 
-* The model instance of the permission owner, i.e. a ``User`` object.
-* An operation string from a known ``RBACOperation``, i.e. 'display_profile'
-* A list of ``RBACRole`` objects
+* The model instance of the permission owner, e.g. a ``User`` object.
+* An ``RBACOperation`` object for an operation, e.g. 'display_profile'.
+* A list of ``RBACRole`` objects, e.g. 'anonymous', 'friend' and 'coworker'.
 * The object: ``RBACPermission`` receives a model instance (for example, a ``Group`` object), while ``RBACGenericPermission`` receives a class model (for example, a ``Group`` model).
 
 Two things to keep in mind when planning your permissions:
 
-* django-rbac follows this golden rule: if a permission doesn't exist, the operation is denied. This is for convenience, because fewer permission objects need to be created.
-* Try to avoid defining permissions that contain mutually exclusive roles. For example, a permission could have 'friend' and 'anonymous user' into his list of roles. Obviously, the first allows the permission operation to everybody, while the second restricts an access only to friends.
-
-Usage in views
-===========
-
-The ``example`` folder is a Django project with a ``myapp`` app that contains a ``views.py``. Inspect the code to see how you can integrate django-rbac in your views.
-
-Usage in shell
-==========
-
-# This use case is about defining a role-based access control system for users
-# who want to restrict group memberships and profile info access.
->>> from rbac.models import RBACPermission, RBACRole
-# Create an operation to define who sees/displays what:
->>> operation = RBACOperation.objects.create(name='display')
-# Create some roles:
->>> RBACRole.objects.create(name='friend')
-<RBACRole: friend>
->>> RBACRole.objects.create(name='coworker')
-<RBACRole: coworker>
->>> RBACRole.objects.create(name='family')
-<RBACRole: family>
-# As an example of a generic permission (per-model permissions),
-# we will restrict access to all user groups only to certain roles
->>> from django.contrib.auth.models import User, Group
-# Create a user that will act as the owner:
->>> owner = User.objects.create(username='hector')
-# Add some groups to the owner:
->>> group1 = Group.objects.create(name='punks')
->>> group2 = Group.objects.create(name='rockers')
->>> owner.groups.add(group1)
->>> owner.groups.add(group2)
-# Create generic permission: hector (owner) allows his friends, coworkers
-# and family (roles) to display (operation) his groups (django Group model)
->>> from rbac.models import RBACGenericPermission
->>> roles = RBACRole.objects.all()
->>> RBACGenericPermission.objects.create_permission(owner, Group, operation, roles)
-<RBACGenericPermission: hector | group | display>
-# To check if a user in a given role context is authorized to perform the operation
-# 'display', we use the rbac_permission function from utils:
->>> from rbac.utils import rbac_permission
->>> rbac_permission(owner, Group, 'display', roles)
-True
-# Create a new role and verivy that we are not allowed if trying to access
-# with only this role in the role list:
->>> RBACRole.objects.create(name='classmate')
-<RBACRole: classmate>
-# Note below that, although we get only one role object, still we need to pass
-# it inside a queryset list
->>> roles = RBACRole.objects.filter(name='classmate')
->>> rbac_permission(owner, Group, 'display', roles)
-False
-# As an example of a per-object permission, we will restrict which roles
-# are allowed to display the owner's user details.
->>> from rbac.models import RBACPermission
-# If no permission exists for a given scenario, rbac_permission returns False,
-# following the django-rbac golden rule: if a permission doesn't exist, the operation is denied.
-# Also note that we are passing a model instance
->>> rbac_permission(owner, owner, 'display', roles)
-False
-# Create permission: hector (owner) allows only his friends (roles) to display (operation)
-# his user info (again, owner -- a django User model instance)
->>> roles = RBACRole.objects.filter(name='friend')
->>> RBACPermission.objects.create_permission(owner, owner, operation, roles)
-<RBACPermission: hector | hector | display>
->>> rbac_permission(owner, owner, 'display', roles)
-True
-
-
-
-
-
+* django-rbac follows this golden rule: *if a permission doesn't exist, the operation is denied*. This is for convenience, because fewer permission objects need to be created.
+* Try to avoid defining permissions that contain mutually exclusive roles. For example, a permission could have 'friend' and 'anonymous user' into his list of roles. The first allows the permission operation to everybody, while the second restricts an access only to friends, so both are mutually exclusive.

File docs/usage.rst

+=====
+Usage
+=====
+
+Remember! You have to run Django ``syncdb`` commad to create all the tables and everything else on the SQLite database::
+
+    python manage.py syncdb
+
+Usage in views
+==============
+
+The ``example`` folder is a Django project with a ``myapp`` app that contains a ``views.py``. Inspect this file to see how you can integrate django-rbac in your views. Run your development server and access the view at /myapp/ to test. Play around changing the code to see how it works.
+
+Usage in shell
+==============
+::
+    # This use case is about defining a role-based access control system for users
+    # who want to restrict group memberships and profile info access.
+    >>> from rbac.models import RBACPermission, RBACRole
+    # Create an operation to define who sees/displays what:
+    >>> operation = RBACOperation.objects.create(name='display')
+    # Create some roles:
+    >>> RBACRole.objects.create(name='friend')
+    <RBACRole: friend>
+    >>> RBACRole.objects.create(name='coworker')
+    <RBACRole: coworker>
+    >>> RBACRole.objects.create(name='family')
+    <RBACRole: family>
+    # As an example of a generic permission (per-model permissions),
+    # we will restrict access to all user groups only to certain roles
+    >>> from django.contrib.auth.models import User, Group
+    # Create a user that will act as the owner:
+    >>> owner = User.objects.create(username='hector')
+    # Add some groups to the owner:
+    >>> group1 = Group.objects.create(name='punks')
+    >>> group2 = Group.objects.create(name='rockers')
+    >>> owner.groups.add(group1)
+    >>> owner.groups.add(group2)
+    # Create generic permission: hector (owner) allows his friends, coworkers
+    # and family (roles) to display (operation) his groups (django Group model)
+    >>> from rbac.models import RBACGenericPermission
+    >>> roles = RBACRole.objects.all()
+    >>> RBACGenericPermission.objects.create_permission(owner, Group, operation, roles)
+    <RBACGenericPermission: hector | group | display>
+    # To check if a user in a given role context is authorized to perform the operation
+    # 'display', we use the rbac_permission function from utils:
+    >>> from rbac.utils import rbac_permission
+    >>> rbac_permission(owner, Group, 'display', roles)
+    True
+    # Create a new role and verivy that we are not allowed if trying to access
+    # with only this role in the role list:
+    >>> RBACRole.objects.create(name='classmate')
+    <RBACRole: classmate>
+    # Note below that, although we get only one role object, still we need to pass
+    # it inside a queryset list. Also, the second parameter must be a model class
+    >>> roles = RBACRole.objects.filter(name='classmate')
+    >>> rbac_permission(owner, Group, 'display', roles)
+    False
+    # As an example of a per-object permission, we will restrict which roles
+    # are allowed to display the owner's user details.
+    >>> from rbac.models import RBACPermission
+    # If no permission exists for a given scenario, rbac_permission returns False,
+    # following the django-rbac golden rule: if a permission doesn't exist, the operation is denied.
+    # Also note that we are passing a model instance 
+    >>> rbac_permission(owner, owner, 'display', roles)
+    False
+    # Create permission: hector (owner) allows only his friends (roles) to display (operation)
+    # his user info (again, owner -- a django User model instance)
+    >>> roles = RBACRole.objects.filter(name='friend')
+    >>> RBACPermission.objects.create_permission(owner, owner, operation, roles)
+    <RBACPermission: hector | hector | display>
+    >>> rbac_permission(owner, owner, 'display', roles)
+    True

File example/db/dev.db

Binary file removed.