Is there a way to enable application users to create their own template within the django app? One example would be how MailChimp enables users to create their own custom email template.
Currently i'm thinking of creating a model that captures information the user wants to display. that model can point to a template and populate it with the information the user wants to display. But is there a better way?
As stated in the docs:
Warning
The template system isn’t safe against untrusted template authors. For example, a site shouldn’t allow its users to provide their own templates, since template authors can do things like perform XSS attacks and access properties of template variables that may contain sensitive information.
Having a user define templates, even if the templates are stored in a model, can lead to xss vulnerabilities, and will be extremely difficult to implement safely.
Another answered noted a warning from the docs that included:
access properties of template variables that may contain sensitive information
This is a big concern. All Django tables are linked together, often in "magical" ways. The template system does not concern itself with permissions granted to authenticated users. If a template can be processed then it will process anything & everything that it can - i.e., if a link between tables exists, it will follow it. This means that something like a Customer record that is linked to a User record that is linked to Vendor records to Item records, etc. could allow any user (or at least, any user with permission to create a template) to view almost any data in the system. They would not, at least with the standard User package, be able to see User passwords. But they could get to almost anything else. For example, they might be able to figure out who else is using the system, how much people are paying, names of administrators (very useful for phishing!), etc.
So while it would be relatively easy to create a user-defined Django template system, it is not a good idea, at least not on any publicly accessible system.
Related
I could use some help creating a plan of attack for a project I'm working on.
Imagine that the site is for a group that oversees regional sales offices, distributed around the world. The purpose of this project is to let superusers spin up a new sub-site specific to each and every office, at a fast pace -- sites are added on a frequent basis. The office sub-sites should be wholly contained with "admin" users specific to that sub-site and should be user-friendly CMS. A superuser should be able to step in and manage all of these office sub-sites.
In addition to the self-contained office sub-site instance, there is also a need for each sub-site to manage contacts, leads, etc and store this in one central area for the superusers.
I've done a few sites using Django, but never anything multi-tenant. I'd like suggestions for technologies to use or tutorials/documentation that might be helpful.
Requirements:
Each sub-site uses the same source (templates, JS, available features, etc), but can be modified to reflect custom content within the templates.
Assigned subdomains (with an option of using a fully qualified domain) per sub-site, configured within the project, not in a hardcoded settings file.
Sub-site specific user access controls, in addition to superusers who can access all sub-sites.
The ability to provide an "independent" CMS for each sub-site. i.e., A sub-site admin only sees their content. My preference for this project would be django-cms, but I'm open to suggestions.
Support for apps that pool the data from all the sub-sites, but limit sub-site "admins" to only viewing their records into that app.
Considering the above, what approach would you recommend? I am open to reconsidering technologies, but I would like to stick with Python.
There is a great app called django-tenant-schemas that uses PostgreSQL schemas mechanism to create multi-tenancy.
What you get is specyfing SHARED_APPS that contain objects shared across all the schemas (sub-sites), and TENANT_APPS that contain objects specific for a sub-site, i.e. users, records etc. The schemas are completely isolated from each other.
Each PostgreSQL schema is tied to a domain url, so that middleware checks the HOST part of the request and sets the db connection's schema to appriopriate one.
In addition, it allows you to define a PUBLIC_SCHEMA_URLCONF which allows you to specify urlconf file for public schema - the meta site that is not tied to any sub-site.
Sorry for quick and dirty answer, i just share what i've done to achieve multi tenancy:
django-tenancy I like the author's approach of using "dynamic model"
django-dynamicsite This is where dynamic SITE_ID based on domain will be linked to a tenant
Both libraries above, when combined, is able to serve a django instance which is multi-tenant, and flexible. What i mean flexible here is: you can define any model whether is it "tenant" or "global". So, you can have a site with global user but per tenant product catalogue, or per tenant + product. From many django app i've tried, this is the most flexible way to achieve multi tenancy
The Django based CMS Mezzanine also has multi-tenancy support.
It has most of the features you requested except the sub-site user controls I think. The admin page can be separated by site for admin users, but the normal users not.
However, if you dont need a CMS this might be an overkill for your use-case, But I wanted to mention it here for completeness.
I have been trying to use django-tenants for a while along with Wagtail but this combination didn't work very well, or let me say, despite of a lot of try I was not able to get wagtail admin-page working correctly. I think will try to switch to django-tenant-schemas which I more widely used .
NOTE: django-tenant-schemas is not maintained now.
I have a settings app inside my project, and every record in DB table that this app uses, represents particular setting.
And it is important that settings always must be consistent, so Im looking for way to protect them from accidental deletion by admin-panel users, or by buggy code.
Another cases for this feature might be - error messages stored in DB and available for editing in admin-site or templates for email messages for web-site users.
Possible solutions that I have in mind:
- Store each setting as table column or multiple columns, so the table will extends column-wise, not row-wise. Pros - simple, reliable, Cons - ugly
- DB-side solution.
- Implement some kind of permissions system which will control access for CRUD operations based on objects ownership, like file system permissions in Linux. Pros - less ugly, abstract from DB, Cons - I have no idea yet how to make easy and elegant implementation of it for Django.
Does anybody have better ideas?
The short answer is: if you don't want someone to have certain database abilities don't grant them. It appears that you are thinking there are admin panel superusers and everyone else.
Django allows much more fine grained control over Users, Permissions, Authorization, and even Admin Panel privileges. Indeed, too much control to elaborate here when the documentation does such a good job of it.
I'm not sure I completely understood your question, but here it goes:
I see two ways of protecting a model for being deleted:
Override the delete() method, and make it check a set of rules that enforce the consistency you require. E.g. if one of the consistency rules fail, you raise an exception to be properly handled.
The other is through autorization, aka permissions. You can manage permissions users have to delete particular models, as explained in this answer.
I notice that Django default permissions API does not support specific object's permissions, only permissions applied on models. However, there are third-party apps that provide this, such as this one.
In Django there is no real built-in way (that I am aware of) that prevents "accidental deletion". If you are using the admin, they do provide confirmation pages whenever you want to delete a record that can help curb the potential problem. As #msw mentioned, the user authentication system is designed to help you enforce permissions, but would not prevent accidental deletions if the individual has the proper permission to begin with...
...an alternative strategy would be to prevent deletions on the database entirely (at the web application level). You can give the "illusion" of a delete from the user's perspective by flagging and filtering out any "deleted" records to your user. That way, restoring information would be as simple as toggling/resetting the flag in the record. You would have to override the proper deletion signals as well.
I would like to view some user information on over half of my website's views.
This information should contain not only trivial username but also some fields from other tables of my project that are associated with current user.
I would also like to put this information into the template that my current view extends, just to keep it DRY.
I already did some research and coded some templatetags hoping that registering tags would help me achieve this but I have no idea how to get user information when there's no request like in views' functions.
Any tips on how to achieve this will be much appreciated. I just started django yesterday and am still a bit confused by it's philosophy.
You can use a context processor to add data to the template context in a DRY way.
In a nutshell, a context processor is simply a function that accepts a request as its first argument, does some additional processing that you add and augments the context with whatever values you want.
You can query an objects models, add the current datetime...pretty much anything you can do with Python or Django can go into a context processor.
On the website, it says this:
One of the most powerful parts of
Django is the automatic admin
interface. It reads metadata in your
model to provide a powerful and
production-ready interface that
content producers can immediately use
to start adding content to the site.
In this document, we discuss how to
activate, use and customize Django’s
admin interface.admin interface.
So what? I still don't understand what the Admin interface is used for. Is it like a PHPMYADMIN? Why would I ever need this?
Let's say you create a model called Entry. IE an extremely simple blog. You write a view to show all the entries on the front page. Now how do you put those entries on the webpage? How do you edit them?
Enter the admin. You register your model with the admin, create a superuser and log in to your running webapp. It's there, with a fully functional interface for creating the entries.
Some of the uses I can think of -
Editing data or Adding data. If you have any sort of data entry tasks, the admin app handles it like a breeze. Django’s admin especially shines when non-technical users need to be able to enter data.
If you have understood above point, then this makes it possible for programmers to work along with designers and content producers!
Permissions - An admin interface can be used to give permissions, create groups with similar permissions, make more than one administrators etc. (i.e. if you have a login kinda site).
Inspecting data models - when I have defined a new model, I call it up in the admin and enter some dummy data.
Managing acquired data - basically what a moderator does in case of auto-generated content sites.
Block out buggy features - Also if you tweak it a little, you can create an interface wherein say some new feature you coded is buggy. You could disable it from admin interface.
Think of the power this gives in a big organization where everyone need not know programming.
I am currently writing an application which I plan to sell as SaaS. Without giving away "secrets," I can say that it is basically a "document editing system" in which many users will be submitting documents.
The basic heirarchy is this:
Institution
Individual
Document
Sub-document
So each Individual should be able to BROWSE all documents that were submitted by anybody in their institution, but should only be able to EDIT documents that they created.
No individual should even be aware of the existence of another Institution--that should all be completely hidden.
I have written a Django/Python class that would facilitate this, but every document regarding authentication that I have read requires that I use the User object. Is this just a limitation of Django, or is there a way to do this?
If there is a way, how can I get my own "Individual" class details attached to the "request" objects so I can validate the things I should be showing the users?
What you're looking for is authorization, not authentication. Django's built-in authorization system is fairly crude, as you've discovered. You'll need something like django-authority if you want a more complete solution.
The auth module is typically used to cover authentication cases.
Gives you groups (Institutions), Users (Individuals) and permissions.
Using these features you can perform checking if a user is a member of a group or owns a doc before allowing them to see or edit the doc.
http://docs.djangoproject.com/en/dev/topics/auth/
If you need to go beyond the typical use case, supporting LDAP for example, then you can look at writing your own authentication backend.
http://docs.djangoproject.com/en/dev/topics/auth/#other-authentication-sources
In general, if you need to attach more information to the builtin User model, you would create new model which subclasses models.Model (not User), and identify it in settings as AUTH_PROFILE_MODULE. You can get the appropriate instance of your model from a user by calling user.get_profile(). (see http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users).
This is generally useful for adding extra fields to User such as address, contact information, etc. While it would be possible to use this for your authentication needs, you'd most likely be better off using the built in groups, or a more comprehensive solution like django-authority as others have mentioned. I've included this answer only because it seems to be what you were asking for (a way to attach a class to User), but not really what you need (authorization).