Flexible Role-based Access Control¶
Business logic sometimes dictates that a provider has minimal access the billing profile of a customer and sometimes a provider must be able to update the credit card associated to a customer while on a phone call with that customer.
In order to support multiple usage patterns and security constraints, authorization is not embeded into the djaodjin-saas logic but rather implemented as URL decorators. It is the responsability of the developper to associate decorators to URLs as dictated by the business requirements.
The security framework defines a generic RoleDescription
whose purpose
is to define a role a User
has on an Organization
(see
grant and request roles).
A organization-agnostic manager role always exists and helps with bootstrapping the security policies. In most setups a second role, for example, a contributor role is implemented. Typically manager have full access to an Organization while contributor are restricted to read-only permissions.
Examples¶
Let’s say you want to give POST access to contributors on the refund API, you would write the following in your urls.py:
from urldecorators import url
from saas.api.charges import ChargeRefundAPIView
urlpatterns = [
url(r'^billing/charges/(?P<charge>[a-zA-Z0-9_\-\+\.]+)/refund/',
ChargeRefundAPIView.as_view(),
name='saas_api_charge_refund',
decorators=['saas.decorators.requires_provider_weak']),
]
The previous example uses django-urldecorators and a
saas.decorators.requires_provider_weak decorator
.
The saas.urls
module has been split in “common” set of functionalities
such that in many cases you can decorate each include() with an appropriate
decorator instead of each URL one by one. (ex: testsite/urls.py)
A blog post on Django Rest Framework, AngularJS and permissions might also be a useful read.
Decorators Available¶
The access control logic is best configured in the site URLConf through extensions like django-urldecorators. This is not only more flexible but also make security audits a lot easier.
- saas.decorators.requires_agreement(function=None, agreement='terms-of-use', redirect_field_name='next')¶
Decorator for views that checks that the user has signed a particular legal agreement, redirecting to the agreement signature or log-in page if necessary.
- saas.decorators.requires_direct(function=None, roledescription=None, redirect_field_name='next')¶
Decorator for views that checks that the authenticated
request.user
is a directroledescription
(ex: contributor) or manager for theOrganization
associated to the request.Managers can issue all types of requests (GET, POST, etc.). while
roledescription
(ex: contributors) are restricted to GET requests.
- saas.decorators.requires_paid_subscription(function=None, organization_kwarg_slug='profile', plan_kwarg_slug='subscribed_plan', redirect_field_name='next', strength=1, roledescription=None)¶
Decorator that checks a specified subscription is paid. It redirects to an appropriate page when this is not the case:
Payment page when no charge is associated to the subscription,
Update Credit Card page when
charge.status
isfailed
,Waiting page when
charge.status
isin-progress
.
- saas.decorators.requires_provider(function=None, roledescription=None, redirect_field_name='next')¶
Decorator for views that checks that the request authenticated
User
is aroledescription
(ex: contributor) or manager for theOrganization
associated to the request itself or aroledescription
(or manager) to a provider for theOrganization
associated to the request.Managers can issue all types of requests (GET, POST, etc.). while
roledescription
(ex: contributors) are restricted to GET requests.
- saas.decorators.requires_self_provider(function=None, roledescription=None, redirect_field_name='next')¶
Decorator for views that checks that the request authenticated
User
is the user associated to the URL. Authenticated users that can also access the URL through this decorator areroledescription
(ex: contributors) or managers for anyOrganization
associated with the user served by the URL (the accessed user is a directroledescription
or manager of the organization) and transitively contributors (or managers) for any provider to one of these direct organizations.Managers can issue all types of requests (GET, POST, etc.). while
roledescription
(ex: contributors) are restricted to GET requests.
Design Note
We used to decorate the saas views with the “appropriate” decorators, except in many projects appropriate had a different meaning. It turns out that the access control logic is better left to be configured in the site URLConf through extensions like django-urldecorators. This is not only more flexible but also make security audits a lot easier.