Extending Django User for Permission - django

I just want List user to be under permission , so i just made one custom model like below
from django.db import models
from django.contrib.auth.models import Permission,User
class Mycustomuser(User):
class Meta:
permissions = (
('users','users'),
('view_user', 'View user'),
)
In views i simply called
items=Mycustomuser.objects.all()
It is returning user id with 4 only.
I did so because i made following permission using django guardian
task = MyCustomuser.objects.create()
joe = User.objects.get(username__exact='admin')
assign('view_category', joe, task)
Now i want to check that permission whenever MyCustomuser is called.

It is not necessary and also not recommended to extend User model. See Storing additional information about users.
That said, you can create Permissions without setting permissions model Meta attribute, see Programmatically creating permissions.

Related

Django groups, roles and permissions

I have a question: there's employee app in my project and I want employees to have different titles such as sales representative, manager and etc. and my views behave differently depending on employee's title. For now I have model Titles (title_code, title_name) but I feel like it could've been done with Django's builtin modules. So what do I use for building hierarchy? Groups, roles or permissions?
The django groups, role and permissions system is for allow or denay action in administration pannel, for this reason these three components work together.
If in your application all these type of user have access in admin pannel I suggestion you to use the Groups, roles and permission system
But If your users haven't the access to admin pannel you can avoid using it.
In first option you can create a different roles for every users and allow some permissions for each but if you have groups of users with same permission you can regroup they in a group. For more info view this https://docs.djangoproject.com/en/4.0/topics/auth/default/#permissions-and-authorization
If you do not need any specific privileges for each employee title, then choices would be pretty simple to implement like below
Sample Example
from django.db import models
class Employee(models.Model):
SALES_MANAGER = 1
HR_MANAGER = 2
ENGINEERING_MANAGER = 3
ROLE_CHOICES = (
(SALES_MANAGER, 'Sales Manager'),
(HR_MANAGER, 'HR Manager'),
(ENGINEERING_MANAGER, 'Manager'),
)
employee_title = models.CharField(max_length=100, choices=ROLE_CHOICES, default='Manager')
But do note that if you want to add new employee title's then a re-run of migrations would be required. If you need to avoid this then groups would be a better choice.
from django.db import models
from django.contrib.auth.models import Group
class Employee(models.Model):
employee_title = models.ManyToManyField(Group)
With groups, you would be able to create new entries without any migrations directly from admin panel.

How to get user permissions for non supervisor user by using request user attribute

I developed an django app which register user and give resources based on resource level permissionIn this I am using django basic level permissions on my model and templates, there for view permission I set permission tuple in my model like:
class Model(AbstractUser):
group = models.ForeignKey(AppGroup)
class Meta:
permissions = ( ('view_app', 'user can view app'), )
and I migrate my model after create my model like above.
Now for permissions, I created a group from admin and including all app view/change/delete permissions, using that group I generated a drop down in form class. Now user(admin) can create other users based on selected permissions and after register successfully the new user able to login successfully and access all resources but when I am trying to access user permissions which is a many-to-many relationship using like
class UserListView(ListView):
def get_queryset(self):
print(self.request.user.user_permissions.all())
return super(UserListView, self).get_queryset()
When I list my view, it gives me a relation error (500 error):
relation views_list_user_permission does not exist
Now when I access the same view by superuser it gives me all permissions, but from a user which is neither superuser nor staff it spit out the above error. By reviewing djancgo.contrib.auth.models PermissionMixin class code it seems like to me the user_permissions m2m field can only access by superuser but I doubt it. So this is what I am doing and got the issue, please correct me if I take this in wrong way
The superuser has all the set of permissions granted. Therefore you are able to see all the permissions. But when a new user is created he will not have any of the permissions set therefore there is no relation between the user and permissions so you are getting the above error.
Note:-
You can check for the available permissions for the logged in user inside template by using
{{ perms }}
For a specific app:-
{{ perms.app_name }}
For a specific model:-
{{ perms.app_name.model_name }}
Suppose you want to grant access to a user with specific permission to a particular model for a view you can use the permission required decorator like this:-
from django.contrib.auth.decorators import permission_required
#permission_required('polls.can_vote')
def my_view(request):
...
Now here the user with the permission can_vote on "polls" will be allowed the access grant.
For further detailed use you can refer:-
Django documentation on permissions.
The authentication back-end is responsible for user permissions. I guess you are using your own custom authentication back-end. However if you are doing so you may have forgot to import ModelBackend.
from django.contrib.auth.backends import ModelBackend
Now make sure to extend this back-end into your own custom back-end
class EmailBackend(ModelBackend):

Django restrict views by User permissions which are editable in the Admin

I have a Django application where I need to restrict specific Views to subset of Users. I also want to be bale to edit which Users have this permission via the Django Admin. So in the admin I would like to be able to see all users and have a check box which can be checked to give permission to see this specific Views.
I believe the way to approach to this is to a permissions decorator on the Views in question:
from django.contrib.auth.decorators import permission_required
#login_required
#permission_required('user.can_view_restricted', login_url='/accounts/login/')
def Restrictedview(request, template_name='restricted.html'):
...
# restricted stuff
Now I know I need to define this permission (in permissions.py?), and register it with the Admin. I am unsure of how to do this and how to properly associate the permission with a specific User instance. Should this be an extra field on 'User', or a separate model to hold model to hole Users and Permissions?
You can read in details about django permissions in the docs
https://docs.djangoproject.com/en/dev/topics/auth/default/#permissions-and-authorization
Basically Django permissions use the Permission model, which is found at django.contrib.auth.models, but for most applications you don't need to directly import or use that model.
By default Django creates 3 default permissions for any model you have in your app. If you have a model named MyModel in an app named myapp, then Django will create create_mymodel, change_mymodel, and delete_mymodel permissions by default.
You can check if the user has a certain permission by calling
user.has_perm('myapp.create_mymodel')
if you're checking for the create permission for example. Or, like you did, you can use the decorator
permission_required('myapp.create_mymodel')
In addition to the default permissions provided by django, you can define custom permissions on your models by specifying the permissions attribute in the Meta class of your model like this:
class MyModel(models.Model):
[...]
class Meta:
permissions = (
("can_deliver_pizzas", "Can deliver pizzas"),
)
More on defining custom permissions here: https://docs.djangoproject.com/en/dev/ref/models/options/#permissions
By default, permissions can be easily edited for every user using the admin interface. Just visit a certain user's page and there will be a field named User Permissions with a list of all permissions in your project, from which you can add or remove permissions for your particular user.

Django - Granting custom permissions to a user

I have a user profile model with a custom permission defined as follows:
class Profile(models.Model):
# A few profile fields here...
class Meta:
permissions = (
('can_approve', _(u'Can review and approve new accounts')),
)
When I actually look at Profile objects in the Django admin site though, I don't see any way to actually grant this permission to users.
What's the easiest way to do this? (e.g. give user Joe the 'can_approve' permission?)
Adding a permission to Meta is not enough to see it in the admin panel. Permissions defined in Meta are only used to create a Permission in auth_permission table when you run manage.py syncdb.
Try running syncdb, or add the permission manually to database or create the permission from code. After it is added to db it will be visible in admin panel.
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get(app_label='myapp', model='Profile')
permission = Permission.objects.create(codename='can_approve',
name=_(u'Can review and approve new accounts'),
content_type=content_type)

How to create a permissions table independent of the user permissions in Django?

I want to create a permission table that takes django-users and another table as its foreign key . And then gives permissions to it . What should be there in models.py ?
The doubt can be put across as two separate questions :
How to use django-users (user id) as a foreign key in another app called
permissions .
How to use table-id that is generated by django when syncdb is
done as the priamry key of
that table (Different app) , to be used as foreign key of this app permissions .
Is there a reason you can't use the permissions features in django.contrib.auth? By using the permissions feature of the Meta object and the Groups table, you can easily create a matrix of "users in group X may perform action Y".
The more I think about this, the more it seems that your implementation would mirror the Groups/permissions feature without extra benefits.
See https://docs.djangoproject.com/en/1.3/topics/auth/ for details.
Your best best is to create a User Profile - which is a model that can be linked to the User model, where the Profile model contains whatever keys you want. Then you can call User.get_profile(), and get a model object, check what keys it has.
For the model, you want to look at the ContentTypes app in .contrib. (https://docs.djangoproject.com/en/1.3/ref/contrib/contenttypes/) and you can just create a foreign key to the user.
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
class Permission(models.Model):
user = models.ForeignKey(User)
table = models.ForeignKey(ContentType)
### the rest of the model.
Then in your view or whatever:
perm = Permission()
perm.user = request.user
perm.table = ContentType.objects.get_for_model(TableToAddPermissionFor)
perm.save()