Disallow linking objects based on a rule - django

I have two models: Domain and Record. Many records link to a domain. The domains and records have their owners. I want to disallow users to create records in domains that they don't own. However they should be able to edit records if someone else (a superuser e.g.) created them and set owner to that specific user (even if they don't own a domain). This should work both for admin site and for API (rest_framework)
My question is - what is the simplest way to achieve this goal? Is there some django plugin that handles permissions for linking? Can I use model validators here (if so - how to distinguish if a new object is created)?

The problem here is that the Django Rest Framework and Django itself (via admin) are interacting only at the level of the models. In order to achieve your goal I would implement the following design:
Make the models aware of their owners and users. For that I would use django-audit-log.
Overwrite the default model Manager and build your logic in the create method, where I will query the user's attributes and throw appropriate exceptions.
Such a design shifts some of the business logic from the controller to the data model - there are some debates out there about the benefits and pitfalls of such an approach. But with the underlined constraints (Django admin and API) is the only common place where you could put it.
Is this what you are aiming for ?

Related

Adding permissions to Django model without table

I'm working on some Django Rest Framework based project (quite expected API for some web-app). It has as traditional Django models, and some kind of model-like objects: they behave like Django models but don't store anything in DB. No tables, no content-types. When we ask them for objects, they goes to external API and forms resulting Queryset.
Now I need to build some role-based access system. To make the architecture clear and extensible, I want to make groups and permissions managable through the Django Admin interface. So, I guess, we need to put some permissions to DB and then we'll be able to add these permissions to user groups. After that, we'll check these permissions in DRF.permissions class. But since we have neither tables, nor content-types for these 'models', we can't add records to permissions table right now.
What is the right way to make this possible? Should I rebuild these 'models' through the metaclass with proxy = True? Or should I add a proxy layer above? Maybe I should add some dummy content-types by hand?

Django app has multiple database and multiple user

I have written one Django cloud based app. This app will have multiple user and for them multiple database, so that their data should be separate and they can save only to same database.
1) How can we implement it
2) How to automatically one user from login page to assign the database to write on it.
I don't have a complete answer, since you do not give a lot of detail. But here are a couple ots that f hinDjango supports custom database router implementations. A database router is a class that helps django decide which database to use for a particular model. Unfortunately I don't think this mechanism is granular enough for your needs. You can also specify the database to use in your code by using using(name) queryset method and save(using=name) form of save() method for instances. Of course this also means that some features of Django are going to be unvailable to you, since you cannot always expect to have a user. Look at the docs here for more info
https://docs.djangoproject.com/en/dev/topics/db/multi-db/

How to write reusable apps with customizable models in Django?

I want to make reusable apps, that allow for customization by the integrator.
An example is if I make a newsletter signup app with the bare minimum of storing email address, but the integrator later wants to add additional fields, like say a name. What is the things I need to do to allow for this easily?
I went down the path of swapping out the models, like Django's auth system does, but that didn't work well. Then I found swappable attribute in the Meta class and a package that does this, but both are not intended for external use.
The only way I can think of for the integrator to do is, allow them to provide custom forms by passing it into the view in the urls for instance.
url('^someurl/$', MyView.as_view(form_class=SomeForm), name="myurl")
Then have a secondary model, with foreign keys to the internal newsletter model, but this means a secondary table that needs to be joined.
Another alternative is to try Abstract models, but I'm not sure what the impact will be there.
So what is the Django/Pythonic way of solving this?

Best way to forbidden access on object of other user in django;

Is there is best practice to forbid access to other user's objects in django? Let's say i can access to object by PK in path (some/path/to/object/PK/edit). What best way to forbid access User1 to User2 objects by pk in path?
I usually create a #owner_required decorator to wrap elements with such requirements, how the logic works depends on usecase
You should have an association in your user model, and then in you controllers you should do all object access through your user model associations, so each user can only access each own childs. Here is a related post How to create new (unsaved) Django model with associations?
If you need more granular security than what Django provides out-of-the-box then you might want to look into one of the ACL offerings. Starting with Django 1.2 it is possible to add object/row level permissions using a third-party plugin. There are several to choose from. See this SO question for suggestions:
Django 1.2 object level permissions - third party solutions?

Implementing multiple administration levels in Django

I have decided to move a project from PHP to Python and despite hours of searching, I cannot find a way to implement the following design. I have attempted extending the user class and doing customised Admin Sites but not really got anywhere useful.
I have at the root level, myself. I manage 'clients', who themselves manage 'customers'.
The customers control a kind of detailed survey, in which users and invitees take part.
An example of the rough design:
ME (Super User)
Clients
Customers
Survey Collections
Users
Invitees
Surveys
Invitees (invitee is a child of both survey and user)
Questions
Etc
I am unsure of the best implementation style. I like the django admin interface, but I would need clients to only be able to modify THEIR customers, surveysets etc, customers to only manage their own surveysets and so on.
Is there a way to implement this in Django, perhaps by doing customised user types via inheritance and assigning them custom Admin Sites?
I understand it may be easier to just make my own apps to manage the various 'admin' interfaces, in which case is there an easy way to manage separate authentication of these user types and their various admin-style management systems?
The closest I got to this was based on How to have 2 different admin sites in a Django project? and is related to another question I asked: seperate 'admin' interfaces for different user types in django
I ended up creating two seperate instances of django admin and each one had it's own validation which was applied to filters on models and CRUD actions shared between them.