Protect an existing wagtail application - django

I'm working on a Wagtail'based corporation intranet site. There are for now about 30,000 pages, with about 1500 users. I'm administrator of the application and the servers.
Actual situation
I'm serving the site through Apache2 with authnz_ldap, with 3 different LDAP domains.
I'm using the REMOTE_USER auth.
All pages are marked as "public", as the auth is provided globally.
Wanted situation
Serve the site with nginx, using django-auth-ldap as auth source (The auth module with multiple LDAP servers already works).
Remote auth will be disabled.
All users have to be connected to view the site content.
My problem is that I have to protect the site globally, marking ALL pages as private, and avoid that editors set pages as public accidentally.
Questions
How to set the entire site as private ?
How to block the public status of pages, to force the private status, aka. only visible for authenticated users ?
Thanks for your help !
PS: Wagtail / Django versions are not relevant for now, as I'm migrating the application to newer versions.

Wagtail privacy settings cascade so if you mark the site root as 'private' (I recommend "accessible to logged-in users"), then the entire site will be private. Then your only issue is to keep anyone from marking it public. One option would be to remove the "Change privacy" link by overriding this template file in Wagtail 4.1: wagtailadmin/shared/side_panels/includes/status/privacy.html
https://docs.wagtail.org/en/latest/advanced_topics/privacy.html#id1

Related

Authentication using Django’s sessions db from Apache

I have a Django application which I now want to integrate it with Kibana. So when authenticated users click on a link, they will be directed to Kibana. But this option should not be available to anonymous users.
My stack is Psql + Django + mod_wsgi + Apache. The solution I came up with was restricting access to Kibana via Apache, and authenticating users in Django before giving them access. This HowTo in Django website says how you can authenticate against Django from Apache, but that one uses Basic authentication. When I use this approach, even for users who already have an active session in my Django app, they will be asked to enter their username/password in a browser dialog!
I was hoping the authentication to happen using the current Django active sessions. I believe for that I need to use AuthType form and mod_session, instead of AuthType Basic, but it seems mod_wsgi does not support mod_session yet (as discussed here). I checked other WSGI alternatives as well (gunicorn and uWSGI), but couldn't find anything.
So my question is how I can Authenticate against Django session db? Is using mod_session + AuthType form correct? and if yes, what's the best way to achieve this?
Thanks a lot

django frontend and backend seperation for security

I have written a web app in Django with usual Django project structure. At my company, they want to separate front end and backend on different servers. Frontend server will have internet access and backend will have a strong firewall and no net access. What I understand from this concept is, they want to separate back-end (view.py) from Django project to shared folder (shared with the back-end server). Is it possible to separate view.py file to the different folder and then import it to project?
Also another question on the same topic. Does Django have good security or security ideas like this are required to protect against hacking? What measures should I take to ensure protecting my backend against hacking if I can't separate backend? (I have already implemented LDAP authentication, using CSRF tokens and all pages are protected by #login_required)
What you can do is creating two projects, one for serving your "front end" with a disabled admin (simply remove the 'admin' in your project's urls.py) and another one for managing the django admin and only accessible from inside your company's network.
Make them share the same database where the database server should only be accessible from within your company's network, as well. Be sure to only create the models only in one app, preferably in the front end app as you might want to have user input handled by django forms.
Register the "front-end" app models in the "back-end" project via the admin.py in the "back end" app. That should allow you accessing the data stored in the db.
When it comes to third party apps and plugins be sure to check their urls.py (and disable the admin in case), models.py and admin.py in order to implement it in your "back-end".
Hope that helps!

Protecting static files from non logged in users in Django

I have an existing site with a number of documents being served staticly. Client wants to add login protection to the site - not a problem using django_auth. However, the files being served from apache are still downloadable?
Is there a way to restrict access?
Ideally, this would require the path to these docs not changing on the site.
Was thinking of removing the alias from the apache config and having that route to a view that has the #login_required decorator on it, and then forwarding on.
See Having Django serve downloadable files on how to set up Django to work with Apache X-Sendfile. You can wrap the X-Sendfile header sending with some authentication checks and you should be good to go.

Django Admin - Re-authentication?

I'm in a bit of a dilemma at the moment regarding Django's admin backend. The default authentication system allows already logged-in users that have staff privileges to access the admin site, however it just lets them straight in.
This doesn't feel “right” to me, and I'm wondering if it would be difficult to at least require a re-authentication of that same session in order to get into the backend.
Preferably though, it'd be good if the frontend sessions could be separated from the backend ones (though still using the same user objects), this would allow a clean separation of both parts of the site. Would this perhaps require two separate authentication backends? Would something like this be difficult to achieve?
Here's an idea: run the admin app on a different domain to the frontend. The cookies won't be valid in the other domain, so the user will have to log in again. All you'd need would be a separate Apache vhost and a basic settings.py that just has contrib.admin in INSTALLED_APPS.
You could probably implement a middleware that asks for authentication when accessing the admin site from a referer not in the admin site. It could log the person out and make them log back in, but even that wouldn't be necessary. Just require another password entry, and redirect them if it fails. It might involve setting a session variable, is_admin_authenticated or something.

How to configure server for small hosting company for django-powered flash sites?

I'm looking at setting up a small company that hosts flash-based websites for artist portfolios. The customer control panel would be django-powered, and would provide the interface for uploading their images, managing galleries, selling prints, etc.
Seeing as the majority of traffic to the hosted sites would end up at their top level domain, this would result in only static media hits (the HTML page with the embedded flash movie), I could set up lighttpd or nginx to handle those requests, and pass the django stuff back to apache/mod_whatever.
Seems as if I could set this all up on one box, with the django sites framework keeping each site's admin separate.
I'm not much of a server admin. Are there any gotchas I'm not seeing?
Maybe. I don't think the built-in admin interface is really designed to corral admins into their own sites. The sites framework is more suited to publish the same content on multiple sites, not to constrain users to one site or another. You'd be better off writing your own admin interface that enforces those separations.
As far as serving content goes, it seems like you could serve up a common (static) Flash file that uses a dynamic XML file to fill in content. If you use Django to generate the XML, that would give you the dynamic content you need.
This django snippet might be what you need to keep them seperate:
http://www.djangosnippets.org/snippets/1054/
"A very simple multiple user blog model with an admin interface configured to only allow people to edit or delete entries that they have created themselves, unless they are a super user."
Depending on the amount of sites you're going to host it might be easier to write a single Django app once, with admin, and to create a separate Django project for each new site. This is simple, it works for sure AND as an added bonus you can add features to newer sites without running the risk of causing problems in older sites.
Then again, it might be handier to customize the admin such that you limit the amount of objects users can see to those on the given site itself. This is fairly easy to do, allthough you might want to use RequestSite instead of the usual Site from the sites framework as that requires separate settings for each site.
There exists this one method in the ModelAdmin which you can override to have manual control over the objects being edited.