Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#3669 closed (duplicate)

Restructure django.contrib.auth, make Models replaceable

Reported by: David Danier <goliath.mailinglist@…> Owned by: adrian
Component: Contrib apps Version: master
Severity: Keywords: auth rewrite replace models
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:



I'm currently not very happy with the current auth-module. It mixed three different things I think:

  • API for user-authentication and permission-checks
  • implementation of user-system
  • implementation of permission-system

The problem is, that you cannot replace parts of this system, without replacing everything (and ending in having to write a new auth-system thats incompatible with some generic_views, the admin, ...). So I think this parts should be separated and some generic-API should be created.

Btw.: I was told, that there was a bug for this problem, but I didn't find it, sorry.

Possible solution

I think that should be separated into three apps. Some generic API should be used to authenticate the user and check permissions. The implementation of the real models/checks should be done in separate applications that can be replaced (so you would be able to replace the user-model for example).

If doing so I suggest dropping the current backends-implementation, because it may break things. The problem is that request.user is filles by these backends and as backends may return objects that are not django.contrib.auth.models.User code will fail that needs that class (-> foreign keys). So I think one user-model should be used, and only one. Backends could be done by using some user-model that saved some type and id and wrapps the real user-object, if backends are really needed. This has the advantage of one user-model that can be used in your models for foreign keys.

As some(/many) code depends on the current auth-models this must be rewritten (this is probably the most annoying part), as an example the create_update-generic-views use the message-system and user.is_authenticated(). Some user-API could be defined as a standard for such cases.

Perhaps the message-system should get it's own application, as many users like and use this.

Possible contributions by me so far

I started creating a auth-replacement for the first part (the API), while trying to keep the current API where possible.

The current code includes parts of whats done in the generic-auth/row-level-permissions-branch so far. But no implementation is included, only some API is defined, that can be used.

In the setting-file the user can set two additional options:

  • AUTHENTICATION_MODULE: Module used for authentication
  • AUTHORIZATION_MODULE: Module used for authorization (aka permission checks)

These modules have to implement some simple API, in detail:

    • get_anonymous_user: done as a function, as the user may be saved in the database
    • get_user_model: used to create working foreign keys
    • login_redirect: redirect to the login (the modules get full control over the views, nothing is implemented in the auth-module so far)
    • authenticate: like with the backends
    • is_authenticated: moved from the user-object
    • has_model_permission: test if a user may access a model
    • has_object_permission: test if a user may access an object (may (only) include model-check of course)
    • denied_redirect: as above (may just return a HttpResponse, too)

The code includes some decorators and a fork of the middleware/context_processor (with changed import-statements).

The models-file is only used to get the User-model into models (for backwards compability).

I think the code can be written nicer by just importing the functions of the modules (like done with the User-Model), but I haven't tested this yet.

If you are interested in this branch I will continue converting the old models and functionality. ;-)

Change History (4)

comment:1 Changed 9 years ago by SmileyChris

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

This probably belongs more in the wiki than the ticket system for now.

comment:2 Changed 9 years ago by Gary Wilson <gary.wilson@…>

  • Resolution invalid deleted
  • Status changed from closed to reopened

comment:3 in reply to: ↑ description ; follow-up: Changed 9 years ago by Gary Wilson <gary.wilson@…>

  • Resolution set to duplicate
  • Status changed from reopened to closed

Replying to David Danier <>:

Btw.: I was told, that there was a bug for this problem, but I didn't find it, sorry.

Perhaps you were looking for #3011?

comment:4 in reply to: ↑ 3 Changed 8 years ago by David Danier <goliath.mailinglist@…>

Replying to Gary Wilson <>:

Perhaps you were looking for #3011?

Not really, this ticket does things very different. I merged my approach with ideas of the the generic-auth-branch, as I think this goes side-by-side. Additionaly I separated things up to get django more flexible (users and permissions are two different apps, user-backends is a possible addon-app). With this changes it is easy to replace the current models (including the groups and message-system, as not everyone uses this...this could be put into separate apps, too) or implement things like row-level-permissions very easily. However some generic API stays that can be used by third-party-apps to ensure usage of one user-system (needed for single-sign-on solutions or simply to ensure the usage of only one user-table). Usersystems that are using some non-db backend are also possible, but may need to provide some model to get foreign keys working (current solution needs you to copy the user to the django-model and return this...usage of LDAP is very ugly with this approach).

As I updated to branch under things may get more clearly:

Note: The code is still only some proof-of-concept. The generic API works here, but as I replaced the user- and permission-system I haven't really tested this. In addition many things inside django need to be arranged (generic views for example).

I'll leave this ticket closed, but comments are always welcome.

Note: See TracTickets for help on using tickets.
Back to Top