GithubHelp home page GithubHelp logo

django-prbac's Introduction

Django PRBAC

(Parameterized Role-Based Access Control)

https://github.com/dimagi/django-prbac

Build Status Test coverage PyPi version

About RBAC and PRBAC

Role-based access control (RBAC) is the standard method for access control in large systems. With RBAC, you grant privileges to roles. For example you might grant the privilege Reporting to the role Analyst. In most systems, you can nest roles as deeply as you want, and give users however many roles. A good example of this in practice is PostgreSQL roles and privileges.

The roles and privileges are whatever abstract concepts make sense for your system. It is up to application code to determine what actions to take based on the privileges granted. You can use django-prbac to implement lower level concepts such as row-level or object-level access control.

Parameterized role-based access control (PRBAC) adds parameters to roles and privileges. Now, for example, you might grant "Reporting(organization="Dimagi",area="Finance") to FinancialAnalyst(organization="Dimagi"). If you don't use parameters, then it is just RBAC. If you use parameters with finite sets of choice, then it is exponentially more powerful. If you use parameters with infinitely many choices (such as strings or integers) then it is infinitely more powerful. A good example of limited parameterization is how particular privileges (SELECT, UPDATE, etc) in PostgreSQL may be parameterized by an object. In PRBAC this parameterization is pervasive.

In-depth documentation

To learn more about parameterized role-based access control as implemented in this library, please visit http://django-prbac.readthedocs.org/

Access Control for Django

  • django.contrib.auth: This app, shipped with Django, provides unix-style access control (users, groups, permissions) with an extensible set of permissions that are implicitly parameterized by a content type. This is fundamentally different than role-based access control. It is only worth mentioning because it comes with Django and everyone is going to want to know "why did you reimplement the wheel?". If django.contrib.auth is the wheel, then RBAC is the car and PRBAC is a transformer. I leave it as an exercise to the reader to attempt to implement PRBAC using django.contrib.auth :-)
  • django-rbac: This project appears defunct and is not parameterized in any rate.
  • django-role-permissions: This app implements a sort of RBAC where roles are statically defined in code.
  • Others can be perused at https://www.djangopackages.com/grids/g/perms/. Many offer object-level permissions, which is as orthogonal to role-based access control as unix permissions. In fact, this is probably true of anything using the term "permissions".

Quick Start

To install, use pip:

$ pip install django-prbac

License

Django-prbac is distributed under the MIT license. (See the LICENSE file for details)

django-prbac's People

Contributors

artembernatskyy avatar benrudolph avatar biyeun avatar czue avatar dannyroberts avatar davidberardozzi avatar dmyung avatar emord avatar esoergel avatar gertburger avatar gherceg avatar kennknowles avatar millerdev avatar movermeyer avatar nickpell avatar noahcarnahan avatar orangejenny avatar snopoke avatar sravfeyn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-prbac's Issues

Grant.objects.get doesn't honor the assignment parameter

Hiya! Like this module, even though there doesn't seem to be any active development. I noticed the following error:

from django_prbac.models import Role, Grant

role1 = Role.objects.create(slug="foo", name="foo", parameters=["param1"])
role2 = Role.objects.create(slug="bar", name="bar")

Grant.objects.create(from_role=role2, to_role=role1, assignment={"param1": 5})

Grant.objects.get(from_role=role2, to_role=role1, assignment={"param1": 5})
# DoesNotExist: Grant matching query does not exist.

I came across this because I was trying to delete a Grant, if it exists. Is there another way to revoke Grants, or is this the method you recommend using this module?

Hi guys

I was wondering if this project is still alive?

I was running through the documentation and setting it all up for my own project. I am having issues with that the documentation seems out of date and or not complete.

I am trying to add parameters like you show in your tutorial (may_view_report = Role.objects.create(name='may_view_report', parameters='report_name'). When i try this i get this error (ValueError: Invalid value 'report_name' for StringSetField)

If you guys want some help with expanding the documentation i will gladly help :)

Can not add/edit user roles in the admin interface

If you try to add or edit a role in the Admin interface on Django 3.0.9 and this is likely also in Django 2.1+ we get the following error:

Request Method:  GET
Request URL: http://localhost:8080/admin/django_prbac/role/1/change/
Django Version: 3.0.9
Exception Type: TypeError
Exception Value: render() got an unexpected keyword argument 'renderer'
Exception Location: /usr/local/lib/python3.7/site-packages/django/forms/boundfield.py in as_widget, line 96
Python Executable: /usr/local/bin/python
Python Version: 3.7.7
...

Related link:
https://docs.djangoproject.com/en/2.1/releases/2.1/#features-removed-in-2-1

We need to add renderer=None to the render signature.

Error when deleting a role from the Admin site

If you try to delete a role from the admin interface on Django 3.0.9 you get:

Request Method:  POST
Request URL: http://localhost:8080/admin/django_prbac/role/1/change/
Django Version: 3.0.9
Exception Type: TypeError
Exception Value: unhashable type: 'UserRole'
Exception Location: /usr/local/lib/python3.7/site-packages/django/contrib/admin/utils.py in collect, line 179
Python Executable: /usr/local/bin/python
Python Version: 3.7.7
...

Is object-level permission control available?

Thank you for your awesome product! I have one question.

I read in the README that django-prbac provides object-level permission, but when I look at the code, I don't see the object relationship being mapped. The examples in the official documentation also don't show any examples of object-level management. How can I do this?

Update to allow django 3

Django 3 has been out for a few months now, but setup doesn't allow usage of django-prbac with django 3.

0.0.4 breaks backcompatiblity by changing the serialization format of Grant.assignment

Hi!

This is more of an FYI for other users since it is probably too late to fix now.

When json_field was replaced with jsonfield it changed the string json format for Grant.assignment.
This is due to jsonfield.JSONField using ',' and ':' as separators (note the missing spaces) which differ from the previous output and the default.

'{"mymodel": 5}' becomes '{"mymodel":5}'

This only affects queries which filter directly on assignment such as Grant.objects.filter(assignment=dict(mymodel=5)) since a text comparison is performed by the DB.

Obviously such a comparison is fragile and should be used with care.

The old behaviour can be achieved with jsonfield.JSONField by setting dump_kwargs={} on the field definition.

Hi there!

Is this thing alive? Will you make it compatible with Django 1.10?

Publish version 0.0.6

Any chance 0.0.6 version can be published to use for django 2.0 projects?

(pd) โžœ  pip install django-prbac==0.0.6
Collecting django-prbac==0.0.6
  Could not find a version that satisfies the requirement django-prbac==0.0.6 (from versions: 0.0.1, 0.0.2, 0.0.4, 0.0.5)
No matching distribution found for django-prbac==0.0.6

Circular Grants should not be allowed.

Seems like library cannot handle with a circular dependency.

Should be reproducible with something like that:

role1 = create_role('r1')
role2 = create_role('r2')
role3 = create_role('r3')
role4 = create_role('r4')
grant(from_role=role1, to_role=role2)
grant(from_role=role2, to_role=role3)
grant(from_role=role3, to_role=role1)
role1.has_privilege(role4) # Endless loop

question about UserRole model

Hi, I noticed that there's a UserRole model to have one to one mapping between user and role. It seems quite useful but it's not being used automatically, the example did not mention it at all, and it is not even registered for admin. Is there any reason for the case? If there's some flaw in the design, I feel it may be useful to let people know and perhaps someone can contribute to fix it.

Thanks

Django 1.8+ support

I'm getting into several problems when using this package under Django 1.8:

  • ImproperlyConfigured exception:
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/core/management/__init__.py", line 351, in execute_from_command_line
    utility.execute()
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/core/management/__init__.py", line 325, in execute
    django.setup()
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/apps/registry.py", line 115, in populate
    app_config.ready()
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/contrib/admin/apps.py", line 22, in ready
    self.module.autodiscover()
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/contrib/admin/__init__.py", line 24, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/utils/module_loading.py", line 74, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/importlib/__init__.py", line 109, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1129, in _exec
  File "<frozen importlib._bootstrap>", line 1471, in exec_module
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django_prbac/admin.py", line 23, in <module>
    class RoleAdminForm(forms.ModelForm):
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/forms/models.py", line 274, in __new__
    "needs updating." % name
django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited; form RoleAdminForm needs updating.

I'm was able to fix this by placing fields = '__all__' under the RoleAdminForm Meta class.

  • After that was fixed, I'm getting:
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/core/management/__init__.py", line 351, in execute_from_command_line
    utility.execute()
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/core/management/__init__.py", line 325, in execute
    django.setup()
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/apps/registry.py", line 115, in populate
    app_config.ready()
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/contrib/admin/apps.py", line 22, in ready
    self.module.autodiscover()
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/contrib/admin/__init__.py", line 24, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/utils/module_loading.py", line 74, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/importlib/__init__.py", line 109, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1129, in _exec
  File "<frozen importlib._bootstrap>", line 1471, in exec_module
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django_prbac/admin.py", line 23, in <module>
    class RoleAdminForm(forms.ModelForm):
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/forms/models.py", line 285, in __new__
    opts.help_texts, opts.error_messages)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/forms/models.py", line 212, in fields_for_model
    formfield = f.formfield(**kwargs)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django_prbac/fields.py", line 74, in formfield
    return super(StringListField, self).formfield(**defaults)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/db/models/fields/__init__.py", line 2169, in formfield
    return super(TextField, self).formfield(**defaults)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django/db/models/fields/__init__.py", line 912, in formfield
    return form_class(**defaults)
  File "/home/jeancventura/.virtualenvs/msw/lib/python3.4/site-packages/django_prbac/forms.py", line 47, in __init__
    super(StringListFormField, self).__init__(*args, **defaults)
TypeError: __init__() got an unexpected keyword argument 'max_length'

I was able to get around this problem by modifying StringLstFormField.init to not consider 'max_length' before calling super (kwargs.pop('max_length')). This doesn't seem like the right way to do this and would appreciate any suggestions as to how can I approach this.

  • Other than that, I'm getting Django 1.9 deprecation warnings:
/home/jeancventura/.virtualenvs/msw/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: The django.forms.util module has been renamed. Use django.forms.utils instead.
  return f(*args, **kwds)

/home/jeancventura/.virtualenvs/msw/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes.
  return f(*args, **kwds)

/home/jeancventura/.virtualenvs/msw/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: The django.forms.util module has been renamed. Use django.forms.utils instead.
  return f(*args, **kwds)

/home/jeancventura/.virtualenvs/msw/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes.
  return f(*args, **kwds)

No idea yet about this warnings.

I want to submit a pull request with this fixes, but I'll wait until I have all issues properly fixed.

Error adding a role in the Admin screen with an empty parameter list

Using Django 2.2.15 and just the django-prbac app installed, I tried to add a new role from the admin screen with an empty parameter list and received the following exception:

Internal Server Error: /admin/django_prbac/role/add/
Traceback (most recent call last):
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/contrib/admin/options.py", line 606, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/utils/decorators.py", line 142, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/contrib/admin/sites.py", line 223, in inner
    return view(request, *args, **kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/contrib/admin/options.py", line 1645, in add_view
    return self.changeform_view(request, None, form_url, extra_context)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/utils/decorators.py", line 45, in _wrapper
    return bound_method(*args, **kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/utils/decorators.py", line 142, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/contrib/admin/options.py", line 1529, in changeform_view
    return self._changeform_view(request, object_id, form_url, extra_context)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/contrib/admin/options.py", line 1572, in _changeform_view
    self.save_model(request, new_object, form, not add)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/contrib/admin/options.py", line 1088, in save_model
    obj.save()
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django_prbac/models.py", line 30, in save
    super(ValidatingModel, self).save(force_insert, force_update, **kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/base.py", line 741, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/base.py", line 779, in save_base
    force_update, using, update_fields,
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/base.py", line 870, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/base.py", line 908, in _do_insert
    using=using, raw=raw)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/query.py", line 1186, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1374, in execute_sql
    for sql, params in self.as_sql():
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1318, in as_sql
    for obj in self.query.objs
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1318, in <listcomp>
    for obj in self.query.objs
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1317, in <listcomp>
    [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1258, in prepare_value
    value = field.get_db_prep_save(value, connection=self.connection)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 793, in get_db_prep_save
    return self.get_db_prep_value(value, connection=connection, prepared=False)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 788, in get_db_prep_value
    value = self.get_prep_value(value)
  File "/Users/sgraham/.local/share/virtualenvs/temp2-ec52t3-K/lib/python3.7/site-packages/django_prbac/fields.py", line 99, in get_prep_value
    raise ValueError('Invalid value %r for StringSetField' % value)
ValueError: Invalid value [] for StringSetField```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.