Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
django-permissionedforms
Advanced tools
Django extension for creating forms that vary according to user permissions
django-permissionedforms
is an extension to Django's forms framework, allowing you to define forms where certain fields are shown or omitted according to the user's permissions.
Run: pip install django-permissionedforms
To add permission rules to a basic Django form, subclass permissionedforms.PermissionedForm
in place of django.forms.Form
and add an inner Meta
class:
from permissionedforms import PermissionedForm
class PersonForm(PermissionedForm):
first_name = forms.CharField()
last_name = forms.CharField()
class Meta:
field_permissions = {
'last_name': 'myapp.change_last_name'
}
field_permissions
is a dict, mapping field names to permission codenames. For each field listed, that field will only be included in the final form if the user has the specified permission, as defined by the user.has_perm()
method. See Django's documentation on custom permissions and programmatically creating permissions for details on how to set permissions up; alternatively, if you want to set a field as only available to superusers, you can use any arbitrary string (such as 'superuser'
) as the codename, since has_perm
always returns True for them.
Then, when instantiating the form, pass the keyword argument for_user
:
form = PersonForm(for_user=request.user)
This will result in a form where the last_name
field is only present if the logged-in user has the change_last_name
permission.
The keyword argument for_user
is optional, and if not passed, the form will behave as an ordinary form with all named fields available.
For a ModelForm, the procedure is the same, except that you should inherit from permissionedforms.PermissionedModelForm
instead. field_permissions
is added alongside the existing Meta
options:
from permissionedforms import PermissionedModelForm
class CountryForm(PermissionedModelForm):
class Meta:
model = Country
fields = ['name', 'description']
field_permissions = {
'description': 'tests.change_country_description'
}
form = CountryForm(instance=country, for_user=request.user)
You may wish to integrate the permission handling from django-permissionedforms
into some other base form class, such as ClusterForm
from the django-modelcluster package. If that base form class is a straightforward subclass of django.forms.Form
or django.forms.ModelForm
, then using multiple inheritance to additionally inherit from PermissionedForm
or PermissionedModelForm
should work:
from fancyforms import FancyForm # made up for example purposes
from permissionedforms import PermissionedForm
class FancyPermissionedForm(PermissionedForm, FancyForm):
pass
However, this will fail if the base form class implements its own metaclass. In this case, you will need to define a new metaclass inheriting from both the existing one and permissionedforms.PermissionedFormMetaclass
:
from fancyforms import FancyForm
from permissionedforms import PermissionedForm, PermissionedFormMetaclass
FancyFormMetaclass = type(FancyForm)
class FancyPermissionedFormMetaclass(PermissionedFormMetaclass, FancyFormMetaclass):
pass
class FancyPermissionedForm(PermissionedForm, FancyForm, metaclass=FancyPermissionedFormMetaclass):
pass
This could still fail if the base form class incorporates a custom Options class to allow it to accept its own class Meta
options. If so, it will be necessary to define a new Options class, again using multiple inheritance to subclass both the existing Options class and permissionedforms.PermissionedFormOptionsMixin
, and then set this as options_class
on the metaclass. The following recipe will work for ClusterForm
:
from modelcluster.forms import ClusterForm, ClusterFormMetaclass, ClusterFormOptions
from permissionedforms import PermissionedForm, PermissionedFormMetaclass, PermissionedFormOptionsMixin
class PermissionedClusterFormOptions(PermissionedFormOptionsMixin, ClusterFormOptions):
pass
class PermissionedClusterFormMetaclass(PermissionedFormMetaclass, ClusterFormMetaclass):
options_class = PermissionedClusterFormOptions
class PermissionedClusterForm(PermissionedForm, ClusterForm, metaclass=PermissionedClusterFormMetaclass):
pass
django-permissionedforms
was developed as part of Wagtail's next-generation page editor, sponsored by Google.
FAQs
Django extension for creating forms that vary according to user permissions
We found that django-permissionedforms demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.