Role-based authorization system for a web application? - web-services

I'm currently working on designing a REST-style SQL-backed web application that is to support multiple types of user roles. I'm looking for ideas for implementing an authorization abstraction for it that's both simple and powerful.
The hierarchical roles in the system would be along the lines of:
superuser/admin -> group owner -> group user
A real world example of this system would be: "I'm a school administrator, I have teachers I manage, and they all have classes that contain students".
I'm thinking along the lines of a UNIX model, except one admin's data silo cannot overlap with another admin's. In the example above, one school should never have access to the data of another one.
An admin role would have full superuser powers over every group and user under him.
A group owner would only have access to the group itself and the users under it.
There can be multiple admins for one silo of data, multiple group owners per group etc.
Admins / group owners / users will generally not change what they can do, as in they abilities will pretty much fixed. The thing that will change is what pieces of data they can act upon.
I'm absolutely certain there have to be a few general patterns out there that I can start with and develop a custom authorization system around it that's fine-tuned to my system's needs. There's ACL, there are libraries along the lines of Rails' CanCan and I'm sure many more.
I'd love to know what my options are and what some of the trade-offs would be. Resources, readings, articles, books would be all great. It's likely I'll have to implement a Parse.com-like API for this web application (i.e. API clients can write custom queries as JSON maps and those will be translated to SQL on the backend) and it'll be extremely important to prevent unauthorized access in all sorts of different query variations.
Thank you.
P.S. Just to clarify, I'm not actually on Rails, the stack I'm using has no existing libraries for authorization, hence I need to roll my own.

I would check out the hartl tutorial to implement users and admins and user levels
http://ruby.railstutorial.org/chapters/modeling-users

Related

How to handle multi-level permissions in Django REST Framework?

I'm attempting to create a DRF API that can handle multi-level permissions. I have Users, Clients, and Brands. Clients can contain one or many Brands.
The way I'm trying to get User Permissions to work is a User can have access to one or many Clients. If given access to that Client they will also be given limited access to one or many Brands within that Client.
I can't wrap my head around how to manage the permissions on this. Does this need to object instance level permissions? or is there another way to organize it? I'm trying to avoid 3rd party packages, but I have seen several people mention django-guardian.
I understand this is a very general question. So I appreciate any type of response on this. Thank you.

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

Best practice to handle different group of users accessing their own content

I am building a web app where different companies will upload their own audio files with some additional information. I am building it using Django, Postgres and hosting it on AWS. Users belong to different companies will only be able to access their data when they log into the website.
The website allows those users to upload content, search content and access content.
My question is, what's the best practice to handle those uploaded content? Is it better to create different schema for each company or putting all the content together and allow users to access different content based on the company id that each entry associates with?
putting all the content together and allow users to access different content based on the company id that each entry associates with?
Personally, I would do this, for several reasons:
It's easier to maintain. Adding new companies probably just means a new ID, rather than a new schema and some tables.
You can add security with application code or with database views.
You can have other company specific functionality that uses the same design.
I would also suggest enforcing the data security on the database side, by only allowing the application to query from certain views, where the views are limited by company ID. This means that you won't accidentally SELECT from a base table and forget the company filter, causing the user to see data that isn't theirs.
This is just my opinion - happy to be proven otherwise.

Adding groups to django app

I'd like to add the capability for users to create their own groups and invite others to join the group (or leave the group) or for users to request access to a group to a django app.
The group in this case is basically a pool of potential players for a football match, from which the actual players will be chosen.
Is the standard django auth groups system the correct thing to use here or is there another way? I'd need it to be able to do invitations and stuff, obviously.
I can obviously write my own but is there another app out there that already does this kind of thing nicely?
If not, has anyone got any tips on how to go about this?
Creating your own model will give you more control to add extra information to those groups, such as the invitation system you described. The auth groups models was designed for classifying users by what level of control they have over the data on the website, which isn't what you want a groups model for. A new model will be much easier for you work with than trying to extend the existing groups model; which has built in functionality that you won't use, and probably has security features that will make it difficult to work with.

seperate 'admin' interfaces for different user types in django

I have recently being trying to create a project which has several levels of user involved.
(Just an example of an abbreviated and rough schema)
ME (Super User)
Client(s)
Customer(s)
Survey Collections
SurveyUser(s)
Invitee(s)
Surveys
Invitee(s) (invitee is a child of both survey and user)
Questions
Etc
I would ideally have:
www.example.com/client/ go to a client interface which you had to be a client to access
www.example.com/customer/ go to a customer interface which you had to be a customer to access
I have already established that using a customised Django admin interface for all of them is probably not going to be possible (or is it?). I am therefore leaning towards manually creating 'admin' interfaces for each level of user, allowing them to manage their respective roles. What is the best way of having different user types and separate interfaces for each one?
I like the way of inheriting users outlined at:
http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
But am unsure how I would set up different 'admin' areas for different users.
As a side issue that is related, I am also unsure of how to access the custom properties alongside standard user properties and how to edit/save them in the ACTUAL admin interface that I will use.
I would need to authenticate 'Client' users against a client database to check they are clients but somehow also authenticate against the user database which manages authentication, username, password etc.
I am switching from PHP to Python/Django so any advice greatly appreciated to help me along.
Thanks!
The closest I got to this was based on another stackoverflow article here: How to have 2 different admin sites in a Django project?
I ended up creating two entirely separate instances of django.contrib.admin.sites.AdminSite which seemed to work in the end, albeit not ideal.