A feature I would love to see is the ability to support multiple forms of authentication for a single user account. (One account to many credentials.)
On Sat, Mar 17, 2012 at 11:19 PM, Ian Lewis <ianmle...@gmail.com> wrote: > Hi, > > On Sun, Mar 18, 2012 at 9:41 AM, Russell Keith-Magee > <russ...@keith-magee.com> wrote: > >> 1. Django shouldn't decide what fields go on the user model. The app > >> provides an abstract base class which developers subclass to add the > >> appropriate fields they need. > > > > +1 > > THX > > >> 2. Django shouldn't decide the type of the primary key. The app only > >> relies on the fact that the object has a pk. The id field can be named > >> anything you wish and can be any type (integer, char, uuid, etc.). > > > > +1 > > THX again > > >> 3. Third party apps don't rely on the user having any fields but > >> rather the base user class defines methods that are implemented by > >> subclasses. Methods like get_display_name() which provides a way for > >> third party apps to get something to display. > >> 4. Rather than provide mixins or something, we should have conventions > >> for the field names like 'email' and third party apps should check if > >> the user has one using duck typing e.g. hasattr(user, 'email'). An > >> alternative could be to provide some kind of API for commonly used > >> actions like emailing users. > > > > This is essentially all I was proposing when I spoke of an "admin User > contract"; that we define some basic "identity" functions that every User > object is expected to provide -- short name, long name, and so on. > > > > The admin case is a little more complicated because there is also a > required API for permissions and groups, but to my mind, these are > different contracts, and should be documented as such. > > My solution is simply authentication, authorization would need to be > added on or in a separate app built on top of newauth. > > >> 5. Basic username (or email)/password authentication can be provided. > >> The app has a base user class from which a basic abstract user with > >> username/password is defined. This can implement setting passwords > >> properly and provide forms etc. > >> 6. Multiple user models can be defined (Like say for normal users and > >> affiliate users or admin users). If one wants to create a project > >> currently with a separate user model, none of the machinery in the > >> auth app can be used. > > > > Sure you can -- you have a base User, and then subclasses to get > AdminUser and NormalUser -- both of which are effectively just another type > of UserProfile. > > I meant one that was a completely separate concrete base model. The > current auth forces you to take along with you all the fields on the > User model. > > >> You create users by creating your own app in your project and creating > >> a User there: > >> > >> account/models.py > >> > >> from django.db import models > >> > >> from newauth.models import UserBase > >> > >> class User(BaseUser): > >> full_name = models.CharField(u"Full Name", max_length=255) > >> email = models.EmailField('Email Address') > >> profile = models.TextField('Profile Bio', blank=True, null=True) > >> avatar = models.ImageField('Avatar', upload_to='profileimg/', > >> blank=True, null=True) > >> > >> def get_display_name(self): > >> return self.full_name > >> > >> class Meta: > >> db_table = 'my_user_table' > >> verbose_name = u"Djangonaut" > >> verbose_name_plural = u"Djangonaut" > >> > >> There are even docs and tests. > > > > How does this address the issue of reusable apps referencing User? Let's > say I write a comments app, and want an Author field. I need a ForeignKey > to "User". But I can't have a foreign key to BaseUser, because it's an > abstract class. How do I define my Comment model in such a way that it can > reference a generic "User"? > > > > It seems to me that the solution you're proposing requires the LazyFK > and app-refactor infrastructure I've described in order to be useful in the > general case (not that I'm complaining, mind -- just pointing out that our > two proposals are complementary :-). > > This is a bad example for showing how that works. I just wanted to > illustrate how you would make your own User model. In the case where > you want a foreign key to User you can import the default user model > from newauth.models as User much like you do with the current django > auth app. > > See: http://ianlewis.bitbucket.org/django-newauth/third_party.html > > >> This is going to be the biggest problem with my solution. There would > >> probably have to be some kind of compatibility layer added to make > >> existing apps work or to provide a simpler migration path. > > > > Isn't the compatibility layer just an implementation of the existing > auth.User class that extends from BaseUser? We're going to have to ship > this user class anyway, so that everything works out of the box; then if > anyone wants to define their own User class, they can. > > Perhaps. I think in reality it will be a bit more complicated though I > haven't really thought about it. I didn't really consider > authorization or backwards compatibility as a goal of the project when > first writing it. > > >>> * 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. > >> > >> I agree this is the most immediate problem. If you could do this it > >> would be ok though I have other issues with auth that prevent me from > >> using it so even if I could modify the fields on auth.User I still > >> won't use it. > > > > I'm not completely convinced that your proposal isn't just the "long > term refactor" of auth that I referred to. I've only had a quick look at > your code, but it seems to share a lot of similarities with oldauth. Yes, > there have been modifications to remove dependencies on certain attributes > of User, but from my quick check, I didn't see anything that we couldn't > achieve through a process of modification of the existing code (if we > didn't have an existing pret-a-porter implementation like yours) > > That's perhaps true. I suppose the primary key thing and being able to > separate admin and regular users were the things I personally wanted > the most. > > >> There isn't much you need on a user object besides a primary key and > >> maybe a way to authenticate it. Everything else is profile so things > >> like the name, email, etc. are all profile. I just don't really see > >> the benefit of breaking all this up and requiring you to do multiple > >> lookups in every view or make a middleware that goes and gets the > >> profile object for you. It's terribly inconvenient. On top of that the > >> difference between a user and a profile isn't really all that clear > >> in a lot of apps. I think if you need or want this kind of topology > >> you can create it yourself in your project. > > > > Yes, all that is strictly needed is a PK and a way to authenticate -- > but in practice, a user object isn't much use unless you can say "Hello > <user>", so I don't see why basic identity mechanisms shouldn't be part of > the basic User contract (not necessarily defined at a data level, just at a > data access level). > > Sure. That's kind of why I defined an method for getting how to > display the user's name. I think that when you say "but in practice, a > user object isn't much use unless you can say "Hello <user>"", you are > really saying that the user isn't much without the profile data. It's > a very short step from wanting to display the user's name to wanting > to display his email or something else. > > > Personally, I don't have a problem with UserProfile as a pattern, > especially when it comes to per-app settings. However, the good news is > that both approaches are possible once the User model is configurable. We > can describe the approach of a generic User with UserProfile objects > containing app settings; and also document the fact that if you have > performance (or taste/convenience) concerns about the joins to a > UserProfile object, you can define a per-project User object that > incorporates all the profile data you want. > > Yes. That's what I thought as well. There isn't stopping you from > using the user profile approach or even defining multiple profiles. > > Thanks for taking a look at it, > Ian > > -- > Ian > > http://www.ianlewis.org/ > > -- > 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. > > -- Joe Tennies tenn...@gmail.com -- 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.