Portal roles in code#
This page lists the classes, functions and signal receivers that declare, install, protect and read the four portal roles: PortalRole, PortalRoles, PortalRolePermissionBackend, the receivers that guard the role groups, the administration site that admits role holders, and TeamView. It does not list what each role may do, which is in Portal roles, or why access is divided this way, which is in How access to a record is decided and ADR 0019. To sign in as each role while you develop, see Development accounts.
PortalRole#
PortalRole is a NamedTuple in fairdm.portal_roles. It describes one role.
Field |
Type |
Default |
What it holds |
|---|---|---|---|
|
|
None, required |
The stored name of the role’s |
|
|
None, required |
The display label, translated |
|
|
|
The permissions the role holds, each as |
PortalRoles#
PortalRoles carries the declarations and the methods that read and install them.
Attribute |
Type |
What it is |
|---|---|---|
|
|
Name |
|
|
Name |
|
|
Name |
|
|
Name |
|
|
The four roles in declaration order, which every method follows |
Method |
Returns |
What it does |
|---|---|---|
|
|
The stored names of the four roles, in declaration order |
|
|
The names of the roles that hold at least one permission. Holding any of these gives access to the administration interface. Holding only |
|
|
True when the user is authenticated, active and in the group named |
|
|
Installs the four roles. Creates each role that is missing and sets each role’s permissions to exactly its declaration. Restores a permission removed by hand and removes one added by hand. Never changes who is in a role |
reconcile() skips a declared permission that has no database row yet, because the apps that define it may not have migrated. A later run picks it up.
from fairdm.portal_roles import PortalRoles
PortalRoles.shipped_names()
# ['Portal Administrator', 'Data Curator', 'Community Manager', 'Developer']
PortalRoles.rights_carrying()
# ['Portal Administrator', 'Data Curator', 'Community Manager']
PortalRoles.DATA_CURATOR.permissions
# ('project.view_project', 'project.add_project', ...)
PortalRoles.is_held_by(person, PortalRoles.COMMUNITY_MANAGER)
Ask what a person may do with the permission system, never with a role name:
person.has_perm("dataset.change_dataset", dataset)
Installation#
FairDMConfig.ready() connects PortalRoles.reconcile to Django’s post_migrate signal with dispatch_uid="fairdm.reconcile_portal_roles". It is connected with no sender, so it runs after the migration of every app, and a run that comes before the permissions of a later app exist is followed by one that finds them. The roles are therefore installed by manage.py migrate. fairdm.E500 reports a portal where a role is missing. See Configuration checks.
Protection of the role groups#
ContributorsConfig.ready() connects two receivers to auth.Group. Both raise ValidationError.
Receiver |
Signal |
Refuses |
|---|---|---|
|
|
Deleting a group named like a shipped role, including through a queryset delete |
|
|
Renaming a shipped role. A new group, including one that |
PortalRolePermissionBackend#
fairdm.permissions.PortalRolePermissionBackend is last in AUTHENTICATION_BACKENDS. A role’s permissions are declared at the model level and Django answers False to every object-level question about a model-level permission. This backend derives the object-level answer from role membership.
has_perm(user_obj, perm, obj=None) returns true when all of these hold:
objis notNone. The model-level question is never answered here.The user is active.
permis notcontributors.manage_organizationormanage_organization, which is never answered here.permhas the formapp_label.codename. A bare codename gives false.The user is in a group named like a shipped role, and that group holds the permission.
A permission granted straight to a person, or through a group your portal created, is not carried to individual records. The answer applies to every instance of the model.
Administration interface#
Name |
In |
What it does |
|---|---|---|
|
|
The default admin site. |
|
|
The admin login form. |
Removing someone from their last rights-carrying role closes the administration interface to them again with no second step.
TeamView#
TeamView is in fairdm.contrib.contributors.views.team. It renders the Team page of the Community menu, at community/team/ under the URL name team. It lists each shipped role with the active people who hold it, in declaration order, and leaves out a role nobody holds. It shows portal roles only. A role on a contribution is credit on a record and is never shown. The page is public.
Attribute |
Type |
Default |
What it does |
|---|---|---|---|
|
|
|
The page template |
|
|
|
The template that draws one holder. It receives the person as |
|
|
|
The grid the holders are laid out in |
|
lazy |
“Portal Team” |
The page title |
|
lazy |
Fixed texts |
The text under the title and the information text |
|
|
One link, “About portal roles” |
The actions beside the information text |
Method |
Returns |
What it does |
|---|---|---|
|
|
One entry for each role that has active holders, in declaration order. Uses two queries however many roles or holders there are. The holders are ordered by name and prefetched with |
|
|
Adds |
What the page lists is not configurable. It reads PortalRoles, so the page and the rights agree. To change how it looks, see How to change how the team page looks. To define a role that the page does not list, see How to define a portal role of your own.