Permissions

Introduction

See Pyramid article regarding security.

The default Pyramid security pattern consists of

  • principals: list of role-like string ids given to an authenticated user based on his/her username and groups
  • permissions: mapped to principals using __acl__ attribute on Resources. Each principal can be allowed or denied a specific permission.
  • permission: attribute on the view definition asking what permissions the user should have to access the Views

Resource is based on traversing. For URL dispatched views websauna.system.core.root.Root is used. All admin views traverse through websauna.system.admin.admin.Admin admin root resource.

Making travesable hierarchies protected

By default, view permission is set on pyramid.security.Everyone` principal by websauna.system.core.root.Root. This tells that all traversable resources are public unless otherwise declared. This mechanism is used by Sitemap subsystem to automatically enumerate publicly traversable site content.

To make your traversable hierarchies private override the default view ACL from root:

from websauna.system.core.traversal import Resource


class MyContent(Resource):

    __acl__ = [
        # Allow to be viewed by admin group only
        (Allow, 'group:admin', 'view'),

        # Disable access to public users
        (Deny, Everyone, 'view'),  # Declared in websauna.system.core.root.Root
    ]

More information

  • websauna.tests.test_admin.test_admin_permissions()

Default roles and permissions

Websauna comes with some out of the box permissions.

Access control list definitions

For usage of __acl__ attribute see

The default traversable root object (/) is websauna.system.core.root.Root. It defines the following permissions

  • authenticated pseudopermission to limit views to authenticated users only viw permission="authenticated. Non-authenticated users get HTTP 403 Forbidden as generated by websauna.system.core.views.forbidden.
  • shell that is primarily used by notebook to determine if the user can open context sensitive shell
  • view that tells that all traversable resources are public by default. This is used by Sitemap to automatically find public traversable end points.

The admin interface resource is defined websauna.system.admin.admin.Admin.

Permission aware views

TODO

  • How to define a custom permission
  • How to apply this on a view

Authenticated only views

To make sure the user is logged in when accessing the view use pseudo permission authenticated. Example:

from websauna.system.core.route import simple_route

@simple_route("/affiliate", renderer="views/affiliate.html", permission="authenticated")
def affiliate_program(request):
    # Only authenticated users can ge to this line of code
    pass

Manually checking a permission

You can check if your user has a certain permission inside your view:

def my_view(request):
    if request.has_permission("add"):
        # The principals this user has were given "add" permission through __acl__
        pass

Checking permissions in templates

Use pyramid.request.Request.has_permission() to check if the user has the named permission in the current context.

Example: checking if a user has a permission on certain resources inside admin:

{% block panel_buttons %}

    {% if request.has_permission('view', context) %}
        <a id="btn-panel-list-{{ model_admin.id }}" class="btn btn-default btn-admin-list" href="{{ model_admin|model_url('listing') }}">
            List
        </a>
    {% endif %}


    {% if request.has_permission('add', context) %}
        <a id="btn-panel-add-{{ model_admin.id }}" class="btn btn-default btn-admin-list" href="{{ model_admin|model_url('add') }}">
            Add
        </a>
    {% endif %}
{% endblock %}

Example: check if a user has permission to view admin:

{% if request.admin %}
   {% if request.has_permission('view', context=request.admin) %}
      <li>
        <a href="{{'admin_home'|route_url}}">
           Admin
        </a>
      </li>
  {% endif %}
{% endif %}