Permission in merengue are strongly based on wonderful django-permissions application.
Main change (but important) is not using GenericForeignKey for granting permissions to objects. We prefer use a ForeignKey to BaseContent for performance reasons. Besides, in merengue all managed content are BaseContent instances.
Permissions are granted to roles (and only to roles) in order to allow something to users or groups which have these roles.
Roles are used to grant permissions. Typical roles are Reader, Manager or Editor.
Local roles are roles which are assigned to users and groups for a specific content objects.
A builtin permission will appears in the manage permission view of every content.
The builtin permissions in merengue are:
You can access to the permissions configuration clicking groups, users, roles or permissions in the main admin page in “User Management” portlet.
To create a role, first you should click in “Roles” in the main admin page or go to the url http://localhost:8000/admin/perms/role/, then you click in “Add role” button. You fill the form with a name and mark the permissions for this role.
Finally, you must go a users admin page clicking “Users” in the main admin page or go to the url http://localhost:8000/admin/auth/user/, choose a user, add previously created role and save the form.
This step is same as above, except that the user is assigned in the group admin view. You must go a groups admin page clicking “Groups” in the main admin page or go to the url http://localhost:8000/admin/auth/group/, choose a group, add previously created role and save the form.
To guarantee a permission to all contents, you must assign a permission to a role. For example, if you want give edit permission for all contents to “editor” role, you must be assign the “edit” permission in role admin page.
To see the permissions in a content, you have to go content admin page and click in “Permissions” button. Note this button is only shown if content type is basecontent.
The content permission admin page show a table with permissions and roles availables. The best way to change the permission in an object is changing the permissions for the content state, in the workflow system (see permissions and workflows), because if the content state changes, the permissions you define in this form are cleared and reset to the permissions defined for the new state.
To create a local role for a content, you have to go content admin page and click in “Permissions” button. With the form shown in the image, you can assign a local role a user or a group for current content. For example, you want that a user or a group has “editor” role only for “welcome” page. You just have to fill the user or group and role fields and click in “create” button. The user and group fields will be autocompleted.
When you’ve created local roles, you can modify assigning new roles.
There is a admin view to edit all builtin and global permissions for each role. To access to this view, you have to click on “Permissions” in the main admin page or go to the url http://localhost:8000/admin/perms/objectpermission/
Permissions in Merengue can be inherited if the ACQUIRE_SECTION_ROLES setting is defined as True. If so, every user who is accessing to an object will acquire the roles of the content’ section. So, if you set the Reviewer local role to an user in a section, he will be also Reviewer in all the section contents (news items, documents, events, etc.). Of course he will acquire also all the permissions of the Reviewer role.
Usually, the permissions in the content are defined by its workflow. So, a content in draft status with the basic workflow workflow will have the permissions defined in the draft status inside the workflow admin view.
This is an important fact because you have to think about workflow and statuses and not thinking about the content itself.
So if for example you want to change the content permission to be visible only for the Reviewer role, the best task to do is create a new visible by reviewer status, define the permission for this status and create the transitions to make sure you can pass your content to this transition. So, doing that you will gain that if you have the same need in another content, you only have to put the content in this status.
>>> from merengue.perms.utils import register_permission >>> register_permission('Vote', 'vote') <Permission: Vote (vote)> >>> from merengue.perms.utils import register_permission >>> register_permission('Vote', 'vote')
You can create a custom permission available only for some models (inherited from BaseContent):
>>> from merengue.section.models import Document >>> from plugins.news.models import NewsItem >>> register_permission('My permission', 'myperm', for_models=[Document, NewsItem]) <Permission: My permission (myperm)>
>>> staff_user = User.objects.create(username='roque') >>> plain_user = User.objects.create(username='other') >>> from merengue.perms.utils import register_role >>> editor = register_role('Editor') >>> editor.add_principal(staff_user) # add user to role 'Editor'
>>> from merengue.base.models import BaseContent >>> content = BaseContent.objects.create(slug='mycontent', name_en='My content') >>> from merengue.perms.utils import grant_permission >>> grant_permission(editor, 'vote', content)
>>> grant_permission(editor, 'vote')
>>> from merengue.perms.utils import has_permission >>> has_permission(content, staff_user, 'vote') True
>>> from merengue.perms.utils import remove_permission >>> remove_permission(editor, 'vote', content)
>>> remove_permission(editor, 'vote')
You can assign a role to an user or a group, globally (for all contents) or locally (to one content).
>>> othercontent = BaseContent.objects.create(slug='othercontent', name_en='Other content') >>> grant_permission(editor, 'vote', othercontent) # like "content" >>> from merengue.perms.utils import add_local_role >>> add_local_role(othercontent, plain_user, editor) # plain_user will be editor only in othercontent >>> has_permission(content, plain_user, 'vote') False >>> has_permission(othercontent, plain_user, 'vote') True # because is local editor for that content >>> has_permission(othercontent, staff_user, 'vote') True # because is a global editor (for all contents)
You can create permissions for your plugins defining the function get_perms in the config.py file. These permissions can be globals or related to models and content types.
To define specific permissions, for example, to edit news:
from merengue.pluggable import Plugin from plugins.news.models import NewsItem class PluginConfig(Plugin): def get_perms(self): return ( ('edit_newsitem', _('Edit news items'), [NewsItem, ]),)
To define global permissions to vote any such content:
from merengue.pluggable import Plugin class PluginConfig(Plugin): def get_perms(self): return ( ('vote', _('Vote content')),)