Django and Common Access Cards (CAC) - django

A web app written in Python is planned, Django is a leading contender as framework.
One requirement is CAC access, wihout the need to hand enter username and password. From what I can tell, CAC access is not part of the "batteries" included with Django.
As a monolithic framework (not necessarily a bad attribute) Django has a rep for being high-maintenance once you modify the core. Can I easily add CAC access to a Django site? Can it be easily maintained thereafter?
Or maybe we should consider a different Python framework?
FYI.. interesting presentation on CAC access link

You don't need to modify the core to enable this. Django supports third-party authentication backends and they're fairly easy to write - you just need to support two methods, get_user and authenticate. So your implementation just needs to perform these operations using your CAC interface, and all will work as usual.
See the documentation for details.
Edited after other answers I don't know why people are saying this is difficult in Django. Yes, many parts of Django are difficult to customise. But this is one particular part that is made very easy. I've written several authentication backends in Django and they are not only really simple, but they "just work" with the rest of the framework, including the admin. There isn't any need to modify anything else to get this to work.

I just did this today by subclassing django.contrib.auth.middleware.RemoteUserMiddleware and changed the header property to the one I had set in my apache conf. I just added the django.contrib.auth.backends.RemoteUserBackend and my middleware to the settings and it works perfectly.

Extending contrib.auth is a pain in the neck. It's the single worst thing in django. If you need highly customized auth backend, i would suggest using a different framework.

Related

Should I split my Django and DRF project into separate projects?

I am currently at the planning stage of an app that will consist of standard
Django part for supervisors that can perform all CRUD operations on employee users mostly add, delete and view statistics - viewed in browser (no frontend framework just using Djangos server side rendering), two step email authentication on each login, session based auth
DRF part for employees - API connected to mobile app, authentication based on device ID. (no username, or password)
DRF part for clients to contact the supervisors if employees do something wrong - Token or JWT based authentication using passcode delivered by mail.
I am not used to splitting Django projects into multiple sub-projects (or using same database for different projects) but it feels like every part of the project should be a standalone app due to different authentication type and the fact of simultaniousily using DRF with standard Django
Can anyone who had similar problem or has some experience, advise what should I do considering different authentications and overall different user types in this project? What would be pros and cons of going into solo or multiple projects? Thanks in advance!
You're asking for opinions, so don't be surprised if the question gets closed, but I'll answer with facts:
A split over different projects using the same database has the following issue: shared migrations. They all use built-in users, so require some standard apps to be enabled that have migrations and they won't run on the 2nd and 3rd project.
You're going to need a custom user model to support the device id authentication method: You need information that is not on the standard user model to be available at authentication time - the number 1 reason to create a custom user model. Ties into migrations and also a synchronization hell code-wise.
Django's Authentication Backends system allows for different authentication methods to exist at the same time, so there is no need to split anything. If you're worried about security, you can always use different hostnames and the Sites framework to add an extra layer of protection, but they would still use the same code.
DRF started as an addition to Django's view-based approach, not a replacement to make part of a project's code available as an API. While current usage is more "DRF or templates" this is a result of people increasingly becoming binary ("this" or "that") and wanting to be in the cool club, but has nothing to do with technical reasons. They can and always will be able to co-exist as they solve different problems. In fact, DRF's generic views make use of Django's CBV's and the built-in browsable API makes use of templates. Also, the admin is template/view based and it's convenient to develop the app or manage data with the built-in admin.

What are reasons for not using Django Admin with Django Rest Framework

It's been a while since I last used Django for a project and there have been some really great advances in the core project and the ecosystem around it.
One of those is the mature API development libraries like django-rest-framework.
So far I'm loving it. But it seems that all the guides I've found are disabling the Django Admin when using Django Rest Framework.
The reasons I've seen given were essentially "We don't need it for anything" or "We aren't using sessions, which Admin uses, so it won't work, so we're not using it."
"Don't need it" is a valid reason.
But other than that, are there reasons that it's bad practice to keep the Django Admin enabled when the project is primarily used as an API?
For my purposes, I find it convenient to manage user permissions and as a simple way to code admin only functions for dealing with the underlying data.
note: I've considered whether this question is designed to elicit opinions, which is not appropriate on SO. I believe that the answers I'm asking for will be technical or security based reasons with fact or experience based reasoning.
Totally agree.
On my current project, users are getting and setting ALL data via django-rest-framework.
Like you, I find the admin site convenient to manage user permissions, permissions groups, writing emails, sms, mobile applications push and more.
More, all these models are being translated, and translation is set in THE ADMIN SITE !!!
So, if we need a new object with translation, we do not need a new app release (example in pic of a question).
objects translations are readable and clear.
Data is organized nicely with minimal effort.
Admin get cool skins (jet / grappelli etc etc)
Language activation works like a charm in the APIViews.

built-in django.contrib.auth.models.User VS own User model?

I'm writing a web app using the django framework and I was just wondering what are the pros/cons of using the built-in django.contrib.auth.models.User model over my own user model?
Please explain in terms of performance, scalability and security.
Many thanks
I always use the contrib.auth.models.User model, as many other apps also use it. Even if you want to have differences, it usually ends up being simpler to extend using a UserProfile than to try to build your own.
Unless you need to integrate with an auth backend that doesn't reasonably fit with contrib.auth, there aren't really any reasons to roll your own authentication app. auth provides its own access control models, but if they don't match your needs you don't need to use them. it provides a number of auth backends but if none of them are quite an exact match, then you can write your own backend and still use the rest of contrib.auth

Django : looking for an implementation of an ldap db backend (or for any help on this)

Following this post (I was looking for a library allowing me to declare Django models on a ldap backend), I have decided to use ldapdb. After having played a while with this library, I figured out that it doesn't reach the level of control I need, and I am therefore looking for other solutions. What I am thinking of now is implementing a Django db backend based on python-ldap.
EDIT
I need this because I am currently implementing a user/group management system on a ldap directory (it requires to be able to manipulate not only users, but different classes of ldap objects as well). So basically, I would like to be able to use (nearly) full Django orm, but with a ldap backend.
Because I love Django (and would be rather motivated in learning the dirty low-level details of db.backends), and because there's already a lot of things implemented in this project, I would like to stick to Django (unless somebody has a very good reason why I shouldn't, and a very good alternative !).
Do some of you have a simpler solution to this problem ?
Do some of you know about an implementation of such a thing (ldap db backend) ?
Do some of you know some good reads to get started on "implementing a Django db backend"?
Are some of you interested in helping with this project ?
You make a lot of bold statements such as "lots of things broken because of the way it is implemented" and "the subclassing is very very far from being complete", would you care to elaborate on them? As the author of django-ldapdb I would welcome your suggestions as to what you would like changed/fixed, that's what the django-ldapdb mailing list is for!
FYI, I took the approach of subclassing the Model class because you will usually want to have just a couple of models using the LDAP backend, not all the models in your application, and django 1.1 did not support multiple databases. Also, LDAP is very different from existing SQL backends:
is not a relational database
it is not "flat", it is a tree-like
the true "primary key" for an entry is the Distinguished Name (DN), which is not an actual field, but a value computed from other fields
fields can be multi-valued
For all these reasons, I have serious doubts as to what can be achieved by writing a true LDAP backend. I think you will always have some LDAP-specific quirks, and subclassing Model allows just that.
Your best bet is probably to write an authentication backend for the application. Here is some documentation about it:
http://docs.djangoproject.com/en/dev/topics/auth/?from=olddocs#writing-an-authentication-backend
And here is an article that explains how to extend the User model to enable you to use this authentication backend seamlessly:
http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
Seems like there's no really good solution. And doing everything without Django's ORM is no good solution either.
I'll make new attempt at solving that problem soon, with a django-orm-based solution.

CodeIgniter & Datamapper as frontend, Django Admin as backend, database tables inconsistent

I created a database for a site i'm doing using Django as the admin backend. However because the server where the site is hosted on, won't be able to support Python, I find myself needing to do the front end in PHP and as such i've decided to use CodeIgniter along with Datamapper to map the models/relationship.
However DataMapper requires the tables to be in a specific format for it to work, and Django maps its tables differently, using the App name as the prefix in the table. I've tried using the prefix & join_prefix vars in datamapper but still doesn't map them correctly.
Has anyone used a combination of this? and if so how have the fixed the issue of db table names being inconsistent? Is there anything out there that i can use to make them work together?
----edit: clarification on backend---
Let me clarify: i'm going to be running the admin from a subdomain pointing to a python ready server. However i can't move the main domain name from the php only webserver because of certain constraints/binding contracts the company got itself in. and don't want to use cloaking/masking because of seo purposes.
i'm using the django admin because i'm using some packages to make a pretty/functional admin, such as grappelli for the admin template, along with its editor for editing news stories, etc. also using photologue to manage photos/galleries. etc.
If your problem is simply making Django use the same tables as your other software, use the db_column and db_table parameters in the models.
http://www.djangoproject.com/documentation/models/custom_columns/
Two apparent solutions:
Instead of hacking one or both to work well with each other, emulate the Django admin in PHP/CodeIgniter code. **
Get a server that supports Django. Make the frontend in Django.
Time-wise, either one of those solutions will be less involving than trying to make two different frameworks using different programming languages mesh well together. I can't imagine the future maintenance required to ensure everlasting compatibility and interoperability.
Also, I assume by saying:
I created a database for a site i'm doing using Django as the admin backend
You really mean that you modeled your apps using Django, and that you also intend on administrating the database that has resulted from this modeling in the Django admin. (In which case you already have your Models layer complete and should just try building the rest of the site in Django)
If that's the case then in your models you are going to need to define the exact column names (db_column) that DataMapper will expect, as well as manually define the table names (db_table), including M2M tables.
You may also have to define all of your primary keys manually, if DM expects something named differently.
Also:
If the server can't support Python, where are you going to be running your backend? Different server? Locally? This plan just isn't making a lot of sense.
** I would not suggest trying this. I had been attempting to make a CI backend that actually shared much of the same ideas as Django's admin, before I knew about Django's admin. And of course once discovering Django, I dropped the CI work immediately and continued on with what I have found to be a much more amazing framework that is much faster to develop on.
So as I understand you plan on using Django just because of django-admin, and you are trying to use CI for the actual site because the server runs PHP, right?
So why don't you use framework that generates something like Django's admin but that you can run on your server?
The Symfony Framework has a really nice admin generator, in the spirit of Django's and you might be able to run it on your server. This would save you from the maintainance nightmare that might come later as #jonwd7 answered