How to restrict a plugin to some users#
A plugin’s tab and its page are open to everyone who can reach the record until you give it a rule. You restrict one when only some people should see the tab or open the page.
Before you start#
You need a plugin. See How to create a plugin.
A plugin has two settings that decide who gets in, and they are one guarantee. A page that is not shown cannot be reached, and a page that cannot be reached is not shown. The tab and the page both ask the same function, which reads the plugin’s check and permission. See Plugins for both.
Steps#
To hide the plugin from records it does not suit, or from people it is not for, set
check. It receives the request and the record, and returns a bool.from fairdm import plugins from fairdm.core.sample.models import Sample from fairdm.plugins import Plugin, is_instance_of from fairdm.views import FairDMTemplateView from myapp.models import CoreSample @plugins.register(Sample, label="Petrology") class Petrology(Plugin, FairDMTemplateView): check = staticmethod(is_instance_of(CoreSample))
CoreSamplestands for a sample type of your own. The tab appears only on samples of that type.Write
checkas a plain function, a lambda or astaticmethod. Registration refuses aclassmethod, because it is truthy but cannot be called and would let everyone in.To require a permission, set
permissionon the plugin or on each view.from fairdm.views import FairDMUpdateView @plugins.register(Sample, label="Curate") class Curate(Plugin, FairDMUpdateView): permission = "sample.change_sample"
A permission counts when the user holds it for the whole portal or on this record. Give a list to require all of them.
If the record can be private, write its visibility rule yourself. A plugin reads its record through the model’s
all_objectsmanager when the model has one, which skips the filtering of the default manager. A private record therefore reaches the plugin, and the plugin must refuse it. This is the rule FairDM’s project pages use:from fairdm.plugins import has_perm from fairdm.utils.choices import Visibility def project_is_visible(request, obj): """A public project always, a private one only with project.view_project.""" if obj is None: return True if obj.visibility == Visibility.PUBLIC: return True return has_perm(request, "project.view_project", obj)
Set it as
check = staticmethod(project_is_visible)on every plugin registered against projects.To answer 404 for a private record instead of a sign-in redirect or a permission error, list
PrivateRecordNotFoundMixinbeforePlugin.from fairdm.contrib.plugins.mixins import PrivateRecordNotFoundMixin from fairdm.core.project.models import Project @plugins.register(Project, label="Review") class Review(PrivateRecordNotFoundMixin, Plugin, FairDMTemplateView): check = staticmethod(project_is_visible)
A 403 or a redirect would tell whoever typed the address that something exists there. A refusal on a public record is the usual one, so the person is told why. The mixin reads
visibilityfrom the record, so it suits projects and datasets.
The result#
A person who fails the rule does not see the tab. If they type the address, they get the refusal: a sign-in redirect when they are signed out, a permission error when they are signed in, or a 404 with the mixin on a private record.
Each page states its own rule. An additional view in extra_views takes nothing from its plugin, so give each one its own check or permission. See How to add pages to a plugin. The reason is recorded in Every page states its own access rules.
How a person comes to hold a permission on a record is explained in How access to a record is decided.