How to add more user Roles in Spring Lemon? - spring-lemon

Spring Lemon comes with UNVERIFIED, BLOCKED and ADMIN Roles. I'm refering to the Role interface in the AbstractUser class.
What do I do in my code, to have several additionnal roles ?
I need two roles, say TEACHER, and STUDENT, and also to make the user be a student by default on signup.

Because roles are nothing but Strings, just defining some more String constants anywhere in your application, say in the concrete User class, should do.
You need to override methods of LemonService to alter its behavior. For adding a STUDENT role to a newly signed up user, just overriding the initUser method should do, I think. The overridden method should call its super, and additionally add a "STUDENT" role to the roles collection.

Related

Maintain Two Types Of User

So I have a requirement where I have to maintain two types of users.
A company and all of its users, to manage day-to-day work. And also create public data like showing a few items and related images and set availability for meetings and more.
Public user who can see the items, images. and can book the meetings.
Now for the first case, every user is created by official email and password as registeruser endpoint from rest-framework. there is user profile and other company data.
For the second type of user (public), I have to give access for social login as well as login by email/mobile (maybe).
I am confused as how to configure this in the best possible way. the company datas' are important.
Should I create both user types in the same database (differentiating by user types)? or should I use a seprerate database then how to fetch data from two databases (never done this)? Also to keep my datas safe from unauthorized access.
Or is there a better way to manage all of my requirements which I'm totally unaware of? Like a better approach.
Looking for an explanation from an experienced person.
Thanks
Maybe what you want is creating a custom User model (or even keep the default one) and implement permissions on views/ressource. This can be implemented by groups, for instance, the public group, in which everyone is (can be public or even no groups) and the private group.
Once you can differentiate between your users, you can add a reference to a ressource and its subressource to the group (ForeignKey on the group) and filters necessary queryset laters on your view. On certain view, you can also restrict some endpoints, through permissions.
Another way would be to use Object Permissions.
Anyway here are the ressources :
https://www.django-rest-framework.org/api-guide/permissions/ (and django-guardian for object-level permission)
and
https://docs.djangoproject.com/en/4.0/topics/auth/default/#permissions-and-authorization
Also, you can take a look on how it is implemented on a opensource project like Sentry: https://github.com/getsentry/sentry/blob/master/src/sentry/api/endpoints/api_applications.py

How to Implement multiple kinds of users in Django?

I am new to Django so please bear with me if my questions seem too basic.
So, I want to create a web app for a kind of a store in which I have three different kinds of users.
Admin(Not Superuser) who can:
create, view, update, delete account for a Seller(agent)
issue them inventory
Seller who can:
sell an inventory item to a Customer(customers cannot themselves purchase it, only the seller can do it by filling in a form)
a Customer account should automatically be created upon submission of the form by Seller or if the Customer already has an account, the purchase should be added to their account
Customer
can login and view their account
What would be the best way to go about it? Using auth Groups, Profile models or anything else?
Any help would be wonderful. If something is not very clear in the question, I can provide more details. Thanks.
Django already has a solution for this: a Group [Django-doc]. A user can belong to zero, one or more groups. A group can have zero, one or more Permissions [Django-doc].
These permissions can be defined by a Django model, for example for all models there are permissions, to view, add, change, and delete objects of a certain model, but you can define custom permissions as well, for example to visit a certain page. A user then has such permission if there is at least one group they are a member of that has such permission.
You can work for example with the #permission_required decorator [Django-doc], or the PermissionRequiredMixin [Django-doc] to enforce that only users that have the required permission(s) can see the given page.
You thus can make groups for a seller, customer, etc. Often people can have multiple roles, for exame being both a seller and a customer which thus is elegantly solved through the permission framework.

Django model design advice

I am currently learning Django, specifically DRF to make an API that will be consumed by a web app client. The app is for a teacher who gives extracurricular classes in Mathematics and Science. My basic idea is that there will be two types of User, a Student and a Teacher. Teachers will obviously have more access rights than Students. The problem is, a django User class has the is_admin attribute and, since only Teachers could possibly be admin of the site, I cannot create a single User class that has is_admin and user_type attribute. For instance, the User with is_admin=True and user_type=Student will be an invalid combination. My idea is to make my User class as an Abstract Base Class and then make two seperate classes, Student and Teacher, that inherit from it. This is also ideal in the sense that only Teachers can publish articles, which means the Student class just won't have that permission, but then I face another problem. All Users have a single Profile. The Profile will store a bio, an avatar image of the user, etc. But when setting up the OneToOneField relationship in Profile, the profile must have that relationship with Students and Teachers, thus all User types. How can I set up that relationship? Can I say OneToOneField(User) and due to the inheritance that user could be a Student or a Teacher? If not, what should I do?
If you have experience and you are thinking, why on earth is he (that is me) doing that?, feel free to comment on my design plan and please show me how a better design would look. Thanks in advance.
EDIT: Is there any advantage in having a single profile for each user, storing a bio and image etc? Is there any gain in this over storing that info in the User model?
Don't create separate classes. Just that they have different permissions doesn't mean they need to be different classes! They can all be User (or your own subclass of that, but the same).
Then you configure two different groups (docs). You assign each new user to one of the two groups.
Your code can then use some custom permission (say a 'publish' permission on Article) and give that permission to the Teacher group, and check in your code that the current user has that permission.
Typically only one or a few users have "is_admin", is_admin means that you automatically have all existing permissions. It's for user management, configuring the groups, and such.
Keep it as one class unless you need each class to have different attributes. But in your case, you can just make is_staff=True synonymous with being a teacher, and then you could get rid of the user_type attribute. It's usually better practice to use boolean fields instead of char fields with a finite set of choices that do unknown things in the code. So staff would be teachers, and non-staff would be students.
Aside: By "is_admin", you meant "is_staff", right? I am not aware that the django User model has an "is_admin" attribute, only is_staff and is_superuser.

How to isolate all data on a per user base in sails.js for ember.js?

I wanna build a simple ember app with sails as the backend.
There are nice blueprints that will help me with that, but I want all data to be complete user isolated. So its actually a single user application, but for multiple users.
So all data is different for each user. So when ember makes a request to /notes/findAll I only wanna return the notes corresponding to the user. On the other side a user has full rights on all data that belongs to him (except maybe the user model, which is the only special case).
What is the simplest way to do this?
I could modify the blueprints itself! But is this a good idea? It would be nice to be able to combine it later by configuration on a per-model-base.
Is there a way to do this with a policy? So a policy setting a safe user-filter?
Is there another better/default way to solve my problem?
Thanks!
I am building the same sort of application. I accomplish this by adding an owner attribute to every model, and setting it in a policy.
https://github.com/tjwebb/xtuple-api/blob/master/api/models/base/xTupleObject.js#L29-L32
I created Permission and Role models, and if the object the user is asking for relates to their User object via a Permission and Role, then they are authorized for a particular action.
https://github.com/tjwebb/xtuple-api/blob/master/api/policies/authorize.js#L51-L56
If you want to grant access to the findAll method, you might want to re-implement it in a superclass that all your controllers inherit from. I haven't gotten to this part yet, but this is my plan for solving this problem.

Django Auth, Users and Permissions

I have a Organization and Employee models
class Organization(models.Model):
is_active = models.BooleanField()
name = models.CharField(u'Name', max_length = 255)
...
class Employee(models.Model):
user = models.OneToOneField(User)
organization = models.ForeignKey(Organization)
...
Will it be good if I use AUTH_PROFILE_MODULE, so Employee becomes user profile?
This way I can use Django permission system to set employees permissions, like
can see all documents
can see own organization documents
can see his own documents
Is is OK to have a permissions that are not a global one like "can see all documents"?
And what If I also want to have a permissions per Organization? How to do this? And how to distinguish permissions per Organization and per Employee?
Edit: I'm using Django 1.4
In short, yes, you're ok.
Because:
1) Using AUTH_PROFILE_MODULE=Employee will make Employee instance to be available for instance in this way:
def view(request):
employee_instance = request.user.get_profile()
2) Using custom permissions is easy, see: https://docs.djangoproject.com/en/dev/topics/auth/#custom-permissions
Edit:
having custom permissions on organizations is possible as well, probably best if you create permissions programatically, like mentioned in the manual, this way:
content_type = ContentType.objects.get(app_label='myapp', model='Organization')
permission = Permission.objects.create(codename='can_do_something', name='Can Do something',
content_type=content_type)
now, you have permission aware organization model, you just assign it to your user.
To clarify more:
Django auth system is sort of a fixed ACL. You assign roles to a user (or group) and that's pretty much it. Django offers helper wrapper function to easily filter out users who don't have a given permission. If you need to decide at runtime and/or in more generic way, whether an object has permission to do something, you either need full blown ACL system (and which django.auth is not) or you code that kind of behavior yourself. This depends on your needs and obviously on the need to manage those permissions. In the OP's case, the behavior is fixed, therefore I would recommend just coding this in and be happy. But the needs may vary and so does the solution. Django auth is good at assigning static permissions to user, gropu or a "profile" object. What that means to your app is up to you in the end.
So in this case, the good solution would be to have a fixed set of permissions like "can view own documents" or "can view organization documents" that is assigned to user/group. And you app should decide, what it means and serve documents accordingly, taking either runtime state in the account or using models structure to determine the proper data set to serve.