On 17/03/2012, at 12:53 AM, Jacob Kaplan-Moss wrote: > Hi folks -- > > This discussion of user authentication by email is getting pretty nasty; can > we start over? I know there's a lot of quite legitimate frustration here, but > we really need to drop the personal stuff and focus on the problem at hand. I > want to move this forward quickly, and I can commit to spending some time on > it in the coming weeks, but I'm going to lose interest faster than than you > can believe if the tone doesn't improve. Please: keep it professional, and > focus on the tech. I promise things'll go smoothly if we all do. > > As I see it, there's two basic approaches we could take: > > 1. Incremental improvement: fix the most glaring issues with auth.User > (starting with email addresses for login, clearly), and generally improve > things a bit at a time. Once User's in a state where we're happy, move on the > rest of the auth app -- again, a bit at a time. This approach would see the > largest issues fixed more quickly, but would probably do so at the expense of > code quality (e.g. requiring a one-off solution to schema migration of the > User model) and would delay a more sweeping reform until later. > > 2. Complete improvement: recognize that the auth app is fundamentally flawed, > and mercilessly refactor/replace/rewrite it, all in one go. The hypothetical > results here would be better -- a modern auth system unencumbered by the > decisions we made in 2005 -- but this would take far longer, and would block > on things like the app refactor and schema migrations. > > There's also a middle-ground proposal from Clay: make the auth app swappable, > thus making it possible for *users* to replace the auth app while leaving > time for us to make either incremental or complete change, as we see fit. > > I think we need to come together and agree on an approach before we move > forward, so I'd like to see some concrete proposals for each of these > approaches. Since all options have merits and since I think it's unlikely > we'll find consensus I'm prepared to make a BDFL ruling here. So if you feel > strongly about one approach or another, please write a concrete proposal and > post it here or on the wiki. I'll look these over -- and also review Clay's > branch -- and (again, baring consensus) make a ruling next week. > > Just so my biases are clear: normally I'd lean more towards the completionist > stance, but in this case I haven't seen an actual proposal to completely > replace auth. Further, I think the fact that it's blocked on *other* pretty > hairy issues means it'd be unlikely to see that much action that quickly. I'm > also somewhat opposed to the "pluggable auth" idea since I think it dilutes > the utility of having built-in auth. In other words, if we're going to make > auth up to users, why not just get rid of the built-in auth altogether? So > I'm leaning towards an incremental improvement approach, but only if I can > see a concrete proposal that articulates what to change, and deals with the > backwards-compatibility issues in a not-too-ugly way.
Ok - I've been keeping quiet on this; partially due to the same tone issues that you've described, but also because I don't have a huge amount of spare time at the moment, and I don't want to be the person who makes a bunch of promises (expressed or implied) to work on something and then can't deliver on those promises. My biggest concern is that the middle-ground proposals that are on the table are implementing a workaround for a problem when the starting point of a long-term solution won't require that much more effort. IMHO, rather than implement a bunch of settings to introduce an auth.User-specific solution, we need to do two things: * Merge the app-refactor from GSoC 2010. This has a whole bunch of long-needed awaited benefits -- reliable hooks for app startup, configurable app labels, predictable module loading, amongst others -- but the one that matters for the purposes of auth.User is that it allows Apps to be treated as items that need to be configured as a runtime activity. In this case, we need to be able to specify, at a project level, which model is your "User" model in the auth app. * Add the concept of a LazyForeignKey. LazyForeignKey is a normal foreign key, with all the usual foreign key behaviors; the only difference is that the model it links to isn't specified in the model -- it's a configuration item drawn from an application configuration. So, ForeignKey('auth.User') creates a foreign key to django.contrib.auth.User; LazyForeignKey('auth.User') asks the auth app for the model that is being used as the 'User' model, and creates a foreign key to that. This isn't a huge body of work -- it's just a matter of slotting into the existing model reference resolution code (which is something that the app refactor cleans up). What are the benefits of this approach? * It solves the general problem, rather than just focussing on auth.User. The broad idea of defining behavior against an interface, rather than a concrete model, is hardly new; auth.User is just the most obvious manifestation in Django's problem space. It doesn't take much work to find other examples: contrib.comments has an analogous "choose the comment model" problem (solved in it's own bespoke way). It wouldn't take much of a survey to find a whole lot of similar examples. If we just add settings to make auth.User configurable, we don't address the analgous problems of any other app. * It's completely backwards compatible. If you've got an existing app with normal ForeignKeys to auth.User, the app will continue to work, without any migrations, as long as the rest of your project uses auth.User. It will also co-exist with any configurable app that is configured to use auth.User as the user model. It will only fall down if you have a configurable app that uses a different User model (i.e., you can't use a new feature without ensuring all the parts you need support the new feature). * It's got a relatively simple forward migration path for app authors For most of the use cases being discussed in this thread (e.g., make email max_length=254), just replace ForeignKey(User) in your app with LazyForeignKey('admin.User'), and it should work without any problems. More specifically, you just need to be aware of the contract that you expect a User model to honor. We can help out here by clearly documenting the "admin" User contract (and doing a light refactor of admin as required to adhere to use that contract -- e.g., replacing uses of user.username with a "get_identifer()" type method). This would have the effect of setting a defacto standard for what you can expect to find on a User model. * It solves the immediate problem ... As I see it, the immediate problem is that developers want to be able to modify the base requirements of auth.User. There may well be people who want to completely change contrib.auth, but for the moment, the 90% case can be solved by modifying max_length or setting unique=True on the email field, and/or removing the username field. The rest of auth.User is fine, at least for now. * ... without making a rod for our back long term ... Once we have a configurable Auth app, we can work out the details of what else needs to be configured, and how, in order to satisfy other use cases that are presented. However, we'll have tackled the hard part -- getting a framework in place for adding configuration points -- as part of the initial effort. * ... or introducing a bunch of settings. 'nuff said. In fact, it would potentially allow us to *deprecate* a bunch of settings (e.g., REDIRECT_FIELD_NAME, LOGIN_URL) and make them application settings. Yours, Russ Magee %-) -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.