[contrib.auth] Separating tightly coupled User model and auth processes implementations

2020-06-29 Thread Maciej Gol
Hey!

I've been recently working on my small project where I'm trying to keep the 
domain as separated as possible from Django and other libs/frameworks. 
Unfortunately, implementing the auth processes using django's machinery 
turned out to be a bit difficult.

The django auth module depends on the `User.pk` attribute, "silently" 
supports `User.get_session_auth_hash()` method, uses the model reflection 
to serialize ids into the session object and forces the usage of 
AnonymousUser without an easy way out.

It looks like the contrib.auth module does way more than just being a 
simple glue code that re-uses already existing mechanisms: session backends 
and auth backends.

I have a proposal of implementation of auth processes in such a way that 
the old API remains, but it gives Django users way more control over the 
auth system whilst providing the same security guarantees.
Before going out with my proposal, I would like to know your opinion 
whether this attempt actually makes sense?

To give you more context:

I have a domain object called `User` which contains id, {first,last}_name, 
password. And a model `UserModel` which is a subclass of Django's 
`AbstractUser`. The model is just a mean of persistence for the domain 
object, handled via `DatabaseRepository`.
My User does not implement the `pk` attribute, nor the 
`get_session_auth_hash()`. I'm not interested in transforming the 
`UserModel` model and the `AnonymousUser` django object into my own `User` 
domain object, either, because that's just taping over leaking 
implementations.

In the end, I would like to have a way to make sure 
authenticate/login/logout and other contrib.auth methods use my own auth 
backend and return the instances of my own domain object.

What do you think?

Best,
Maciej

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/7ba4fbb5-d7b5-4a3d-8b33-bec2a3bc761eo%40googlegroups.com.


Re: Add autocomplete attribute to contrib.auth fields?

2018-08-30 Thread Adam Johnson
I wouldn't think such pentest tools are a major concern, as I'd guess not
many users have to meet such requirements, and it would always be possible
to subclass the forms and set autocomplete=off where appropriate. Also the
referred mdn docs

state
that autocomplete=off is often ignored.

Browser may be limited but I would think it's fine to add them now, they'll
ignore the values they don't know until they support them.



On Sat, 25 Aug 2018 at 20:11, Tom Forbes  wrote:

> I don’t have much to add other than it’s pretty common for pentests to
> flag autocomplete being enabled on sensitive fields (email/password) and
> recommend disabling it (autocomplete=off). While I’m not sure if I agree
> with that recommendation in some situations you have little choice but to
> follow it.
>
>
>
>
> On 25 August 2018 at 16:54:08, Tim Graham (timogra...@gmail.com) wrote:
>
> Browser support looks somewhat limited, so I wanted to ask if there are
> any concerns or drawbacks with adding
> autocomplete=username/email/current-password/new-password to contrib.auth's
> forms?
>
>
> Pull request: ​https://github.com/django/django/pull/9921
>
>
> From the ticket [https://code.djangoproject.com/ticket/29379]:
>
>
> The most useful one is autocomplete=new-password, which prevents browsers
> prefill with current password, Chrome will also suggest a random strong
> password for users who turned on account sync.
> Related docs:
> ​
> https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
> ​
> https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands
> ​
> https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion#The_autocomplete_attribute_and_login_fields
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/d398c554-3fe2-4e0f-9deb-a61dabc4cbf3%40googlegroups.com
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAFNZOJMektU_6pQ6vXnRrBHEisGbUzp8sm-cE2m0-597dShHGA%40mail.gmail.com
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>


-- 
Adam

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAMyDDM2%3DPsWhjsdLr-EHOhGZOurCC1DKn2g%2BqF8e1qUFoOgm%2Bg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Add autocomplete attribute to contrib.auth fields?

2018-08-25 Thread Tom Forbes
I don’t have much to add other than it’s pretty common for pentests to flag
autocomplete being enabled on sensitive fields (email/password) and
recommend disabling it (autocomplete=off). While I’m not sure if I agree
with that recommendation in some situations you have little choice but to
follow it.




On 25 August 2018 at 16:54:08, Tim Graham (timogra...@gmail.com) wrote:

Browser support looks somewhat limited, so I wanted to ask if there are any
concerns or drawbacks with adding
autocomplete=username/email/current-password/new-password to contrib.auth's
forms?


Pull request: ​https://github.com/django/django/pull/9921


>From the ticket [https://code.djangoproject.com/ticket/29379]:


The most useful one is autocomplete=new-password, which prevents browsers
prefill with current password, Chrome will also suggest a random strong
password for users who turned on account sync.
Related docs:
​
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
​
https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands
​
https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion#The_autocomplete_attribute_and_login_fields
--
You received this message because you are subscribed to the Google Groups
"Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/d398c554-3fe2-4e0f-9deb-a61dabc4cbf3%40googlegroups.com

.
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAFNZOJMektU_6pQ6vXnRrBHEisGbUzp8sm-cE2m0-597dShHGA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Add autocomplete attribute to contrib.auth fields?

2018-08-25 Thread Tim Graham


Browser support looks somewhat limited, so I wanted to ask if there are any 
concerns or drawbacks with adding 
autocomplete=username/email/current-password/new-password to contrib.auth's 
forms?


Pull request: ​https://github.com/django/django/pull/9921


>From the ticket [https://code.djangoproject.com/ticket/29379]:


The most useful one is autocomplete=new-password, which prevents browsers 
prefill with current password, Chrome will also suggest a random strong 
password for users who turned on account sync.
Related docs:
​
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
​
https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands
​
https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion#The_autocomplete_attribute_and_login_fields

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/d398c554-3fe2-4e0f-9deb-a61dabc4cbf3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2017-06-13 Thread m . levental
I would like to explain a potential solution I have been working on (See 
commit 
https://github.com/mlevental/django/commit/51dbaa6748076e06d91b361c2fa60ecf24f5c27e
 
).
 
I think it's not complete but I don't have the time to continue working on 
it.

*Overview:*

   - In order to check if a user is authenticated with one or two factors, 
   the attributes *is_one_factor_authenticated* and 
   *is_two_factor_authenticated* were added to *AbstractBaseUser *(and 
   therefore to *AbstractUser *and *User*) and *AnonymousUser*.
   - For *AnonymousUser *both attributes are always False. For 
*AbstractBaseUser 
   is_one_factor_authenticated* is always True because an authenticated 
   user is authenticated with at least one factor, *is_two_factor_authenticated 
   *is explained in the next paragraph.
   - *is_authenticated* stays unchanged but the meaning becomes 
   "authenticated with one or two factors". This way an application can have 
   users who use 1FA and others who enabled 2FA.



   - Similar to the backends in django.contrib.auth there are backends for 
   2FA. But instead of returning a *User *object they must return a *Device 
   *object on success.
   - *Device *is a model class that encapsulates all the necessary data of 
   a 2FA method for a single user, e.g. cryptographic keys. It can but doesn't 
   have to represent a real device.
   - After a successful two factor authentication the device is stored in 
   the session. The middleware *TFAMiddleware *(which must be installed 
   after *AuthenticationMiddleware*) sets this device for the user coming 
   from the request object.
   - *is_two_factor_authenticated* of *AbstractBaseUser *evaluates to True 
   only if a device is set.



   - The authentication process is handled by two views. *FirstFactorLoginView 
   *is responsible for authenticating with the first factor and redirecting 
   to *SecondFactorLoginView *on success. *SecondFactorLoginView *handles 
   the authentication with the second factor and redirects to a defined URL on 
   success. If the user accessing the *SecondFactorLoginView* isn't 
   authenticated with the first factor he is redirected to the 
   *FirstFactorLoginView*.
   - The *SecondFactorLoginView *can have multiple forms. 
   - This is done because different 2FA methods can require different input 
  fields (e.g different input types, labels, number of input fields). 
  - Also this allows to display multiple forms, for example when it is 
  desired to show the form for the default 2FA method and the backup method 
  on one page.
  - By default *SecondFactorLoginView *loads all the forms specified in 
  the setting *TFA_FORMS*. Which forms are displayed can be adjusted in 
  the template or by overriding *get_form_classes()*. Only one form 
  gets validated on a POST request. Therefore when submitting the form the 
  2FA method name needs to be included as a HTTP POST parameter.
  - For example if the setting *TFA_FORMS* is the following:
   
TFA_FORMS = [
{'METHOD_NAME': 'TOTP', 'FORM_PATH': 
'django.contrib.twofactorauth.forms.TOTPAuthenticationForm'},
{'METHOD_NAME': 'Backup Token', 'FORM_PATH': 
'django.contrib.twofactorauth.forms.BackupTokenAuthenticationForm'},
]
   
  and the *TOTPAuthenticationForm *is submitted, then 
type=TOTP must be included, for example in a button tag:


  {% csrf_token %}
  {{ forms.TOTP.as_p }}
  {% trans 
'Submit' %}
   


   - For convenience there is the *tfa_required* decorator and the mixin 
   *TFARequiredMixin*. They work analogous to the *login_required* 
   decorator and *LoginRequiredMixin *from django.contrib.auth. Instead of 
   checking for *is_authenticated* they check for 
   *is_two_factor_authenticated*. If the user is not two factor 
   authenticated he is redirected to a specified URL.
   - For example the URL can be specified by setting *TFA_LOGIN_URL* to 
   "tfa:first_factor_login" and would point to the *FirstFactorLoginView*. 
   By default the *FirstFactorLoginView *requires the user to authenticate 
   with the first factor and redirects on success to *SecondFactorLoginView*. 
   If desired the *FirstFactorLoginView *can redirct an already one factor 
   authenticated user to *SecondFactorLoginView *right away, for this 
   *redirect_authenticated_user* needs to be set to True. After 
   successfully authenticating with the second factor the user is redirected 
   to the initially inaccessible page. For this last redirect to work the 
   redirect URL is transfered from *FirstFactorLoginView *to 
*SecondFactorLoginView 
   *by appending it as a HTTP GET parameter.



   - For the admin site to support 2FA the class *AdminSiteTFARequired *was 
   created which i

Re: Should contrib.auth include support for 2fa out of the box?

2017-06-13 Thread m . levental
I would like to explain a potential solution I have been working on (See 
commit https://github.com/mlevental/django/tree/ticket_25612). I think it's 
not complete but I don't have the time to continue working on it.

*Overview:*

   - In order to check if a user is authenticated with one or two factors, 
   the attributes *is_one_factor_authenticated* and 
   *is_two_factor_authenticated* were added to *AbstractBaseUser *(and 
   therefore to *AbstractUser *and *User*) and *AnonymousUser*.
   - For *AnonymousUser *both attributes are always False. For 
*AbstractBaseUser 
   is_one_factor_authenticated* is always True because an authenticated 
   user is authenticated with at least one factor, *is_two_factor_authenticated 
   *is explained in the next paragraph.
   - *is_authenticated* stays unchanged but the meaning becomes 
   "authenticated with one or two factors". This way an application can have 
   users who use 1FA and others who enabled 2FA.



   - Similar to the backends in django.contrib.auth there are backends for 
   2FA. But instead of returning a *User *object they must return a *Device 
   *object on success.
   - *Device *is a model class that encapsulates all the necessary data of 
   a 2FA method for a single user, e.g. cryptographic keys. It can but doesn't 
   have to represent a real device.
   - After a successful two factor authentication the device is stored in 
   the session. The middleware *TFAMiddleware *(which must be installed 
   after *AuthenticationMiddleware*) sets this device for the user coming 
   from the request object.
   - *is_two_factor_authenticated* of *AbstractBaseUser *evaluates to True 
   only if a device is set.



   - The authentication process is handled by two views. *FirstFactorLoginView 
   *is responsible for authenticating with the first factor and redirecting 
   to *SecondFactorLoginView *on success. *SecondFactorLoginView *handles 
   the authentication with the second factor and redirects to a defined URL on 
   success. If the user accessing the *SecondFactorLoginView* isn't 
   authenticated with the first factor he is redirected to the 
   *FirstFactorLoginView*.
   - The *SecondFactorLoginView *can have multiple forms. 
   - This is done because different 2FA methods can require different input 
  fields (e.g different input types, labels, number of input fields). 
  - Also this allows to display multiple forms, for example when it is 
  desired to show the form for the default 2FA method and the backup method 
  on one page.
  - By default *SecondFactorLoginView *loads all the forms specified in 
  the setting *TFA_FORMS*. Which forms are displayed can be adjusted in 
  the template or by overriding *get_form_classes()*. Only one form 
  gets validated on a POST request. Therefore when submitting the form the 
  2FA method name needs to be included as a HTTP POST parameter.
  - For example if the setting *TFA_FORMS* is the following:
   
TFA_FORMS = [
{'METHOD_NAME': 'TOTP', 'FORM_PATH': 
'django.contrib.twofactorauth.forms.TOTPAuthenticationForm'},
{'METHOD_NAME': 'Backup Token', 'FORM_PATH': 
'django.contrib.twofactorauth.forms.BackupTokenAuthenticationForm'},
]
   
  and the *TOTPAuthenticationForm *is submitted, then 
type=TOTP must be included, for example in a button tag:


  {% csrf_token %}
  {{ forms.TOTP.as_p }}
  {% trans 
'Submit' %}
   


   - For convenience there is the *tfa_required* decorator and the mixin 
   *TFARequiredMixin*. They work analogous to the *login_required* 
   decorator and *LoginRequiredMixin *from django.contrib.auth. Instead of 
   checking for *is_authenticated* they check for 
   *is_two_factor_authenticated*. If the user is not two factor 
   authenticated he is redirected to a specified URL.
   - For example the URL can be specified by setting *TFA_LOGIN_URL* to 
   "tfa:first_factor_login" and would point to the *FirstFactorLoginView*. 
   By default the *FirstFactorLoginView *requires the user to authenticate 
   with the first factor and redirects on success to *SecondFactorLoginView*. 
   If desired the *FirstFactorLoginView *can redirct an already one factor 
   authenticated user to *SecondFactorLoginView *right away, for this 
   *redirect_authenticated_user* needs to be set to True. After 
   successfully authenticating with the second factor the user is redirected 
   to the initially inaccessible page. For this last redirect to work the 
   redirect URL is transfered from *FirstFactorLoginView *to 
*SecondFactorLoginView 
   *by appending it as a HTTP GET parameter.



   - For the admin site to support 2FA the class *AdminSiteTFARequired *was 
   created which inherits from *AdminSite *and the new mixin 
   *AdminSiteTFARequiredMixin*. This mixin overrides *has_permission()* so 
   that admin urls can only be accessed by two factor authenticat

Re: Should contrib.auth include support for 2fa out of the box?

2016-10-03 Thread Aymeric Augustin
Hello,

FYI django-two-factor-auth builds upon django-otp; they aren't alternatives. 

This is an ambitious project. I suggest to start by getting a better 
understanding of what these libraries do, what the different scenarios for two 
factor authentication are, and writing a DEP to describe the APIs that would be 
added to Django. Look at the current public APIs of django.contrib.auth and 
figure out what would be needed to support 2FA with similar principles.

Starting from the lower layers — the equivalent of django-otp — seems (to me) 
to be a better way to go about this, but perhaps this is just a bottom-up vs 
top-down thing. Anyway, I suspect that a DEP that boils down to “merge 
django-two-factor-auth into Django” and includes integration with arbitrarily 
chosen commercial services would face some resistance; you need more structure 
and details.

I hope this helps,

-- 
Aymeric.

> On 03 Oct 2016, at 15:21, m.leven...@web.de wrote:
> 
> I would like to work on this ticket. As for the implementation there doesn't 
> seem to be much choice. The implementation with the most features is from 
> Bouke . It supports U2F, 
> TOTP, SMS and phone call (with Twilio by default). Beside that one only a few 
> packages exist:
> https://github.com/gavinwahl/django-u2f 
> : supports only U2F, according to 
> the developer it's not production ready
> https://bitbucket.org/psagers/django-otp/ 
> : supports TOTP, HOTP
> Based on the ticket description and the django developers discussion U2F and 
> TOTP are the most desired authentication methods. So I would like to 
> integrate them (orienting on Bouke 
> 's implementation) first. 
> And if SMS and email based authentication are also desired I would go about 
> them next.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to django-developers+unsubscr...@googlegroups.com 
> .
> To post to this group, send email to django-developers@googlegroups.com 
> .
> Visit this group at https://groups.google.com/group/django-developers 
> .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/0e80fdf8-2387-4835-8ba0-2d2af01442ec%40googlegroups.com
>  
> .
> For more options, visit https://groups.google.com/d/optout 
> .

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0999AB8D-3CEF-494E-B9A6-A1F8E6F120EC%40polytechnique.org.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2016-10-03 Thread m . levental
I would like to work on this ticket. As for the implementation there 
doesn't seem to be much choice. The implementation with the most features 
is from Bouke . It 
supports U2F, TOTP, SMS and phone call (with Twilio by default). Beside 
that one only a few packages exist:

   - https://github.com/gavinwahl/django-u2f: supports only U2F, according 
   to the developer it's not production ready
   - https://bitbucket.org/psagers/django-otp/: supports TOTP, HOTP

Based on the ticket description and the django developers discussion U2F 
and TOTP are the most desired authentication methods. So I would like to 
integrate them (orienting on Bouke 
's implementation) first. 
And if SMS and email based authentication are also desired I would go about 
them next.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0e80fdf8-2387-4835-8ba0-2d2af01442ec%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-27 Thread bliyanage
+1

This sounds like a great feature, depending on the implementation.

On Monday, October 26, 2015 at 10:22:46 AM UTC-7, Tim Graham wrote:
>
> On Trac [1], Alex says, "Django did a tremendous service to its users by 
> making strong password hashing be the default. The world is pushing 
> forward, and now 2fa is the next standard that many sites fail to meet. 
> Django should include support for 2fa out of the box, ideally with support 
> for both u2f and TOTP (Google Authenticator)."
>
>
> Doing a quick search, I found 
> https://github.com/Bouke/django-two-factor-auth as a possible existing 
> implementation that might be a starting point if we decide to integrate 
> something. What do you think? One sticking point could be that it uses a 
> ThreadLocals middleware. I didn't look to see how "necessary" that is.
>
>
> [1] https://code.djangoproject.com/ticket/25612
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/37f2ad54-c6c0-4e13-a1a3-bd44a1c6adc6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-27 Thread Florian Apolloner

On Tuesday, October 27, 2015 at 12:46:47 AM UTC+1, Joey Wilhelm wrote:
>
> Fwiw, 2fa is on my short list of things to implement into my current 
> project. It's a fairly important feature to me, as this is a financial 
> project. And that particular implementation is precisely what I was looking 
> to use. I would happily contribute money and/or time toward this 
> implementation, especially if there was a happy upgrade path from Bouke's 
> library.
>

I think if Django supports 2fa the changes will go much deeper than what 
django-otp etc currently do, in that sense it is unlikely that there will 
be any supported upgrade path. If you can transfer the current data to the 
new system is hard to say, but probably doable… 

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/35ab5dd7-e326-4fe3-8b04-d895c8b81ec2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-27 Thread Florian Apolloner
Yes, I would like to see that in contrib.auth, which will require rewriting 
the backends and introduce a auth pipeline ala django-social-auth (has/had) 
-- I was planning to get some thoughts about that on DUTH. Also see this 
(short) twitter discussion: 
https://twitter.com/jacobian/status/651527202119397376 -- so the need is 
definitely there. 

Cheers,
Florian

On Monday, October 26, 2015 at 6:22:46 PM UTC+1, Tim Graham wrote:
>
> On Trac [1], Alex says, "Django did a tremendous service to its users by 
> making strong password hashing be the default. The world is pushing 
> forward, and now 2fa is the next standard that many sites fail to meet. 
> Django should include support for 2fa out of the box, ideally with support 
> for both u2f and TOTP (Google Authenticator)."
>
>
> Doing a quick search, I found 
> https://github.com/Bouke/django-two-factor-auth 
> <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2FBouke%2Fdjango-two-factor-auth&sa=D&sntz=1&usg=AFQjCNH8Ts_b2AxVUoqCYI1J240W1uKe3A>
>  
> as a possible existing implementation that might be a starting point if we 
> decide to integrate something. What do you think? One sticking point could 
> be that it uses a ThreadLocals middleware. I didn't look to see how 
> "necessary" that is.
>
>
> [1] https://code.djangoproject.com/ticket/25612
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/140a74cc-6bea-40c8-892b-aeb0079669a4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-26 Thread Dheerendra Rathor
Other then u2f and TOTP, I'll favour for email and sms (using external api
like twilio) based OTP as well. Keeping different pluggable backends will
be better in my opinion.

On Tue, 27 Oct 2015 at 07:01 Russell Keith-Magee 
wrote:

>
> +1. Sounds like a great idea to me.
>
> Russ %-)
>
> On Tue, Oct 27, 2015 at 1:22 AM, Tim Graham  wrote:
>
>> On Trac [1], Alex says, "Django did a tremendous service to its users by
>> making strong password hashing be the default. The world is pushing
>> forward, and now 2fa is the next standard that many sites fail to meet.
>> Django should include support for 2fa out of the box, ideally with support
>> for both u2f and TOTP (Google Authenticator)."
>>
>>
>> Doing a quick search, I found
>> https://github.com/Bouke/django-two-factor-auth as a possible existing
>> implementation that might be a starting point if we decide to integrate
>> something. What do you think? One sticking point could be that it uses a
>> ThreadLocals middleware. I didn't look to see how "necessary" that is.
>>
>>
>> [1] https://code.djangoproject.com/ticket/25612
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Django developers (Contributions to Django itself)" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to django-developers+unsubscr...@googlegroups.com.
>> To post to this group, send email to django-developers@googlegroups.com.
>> Visit this group at http://groups.google.com/group/django-developers.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/django-developers/5ae7be8e-949c-4074-b613-04ca2a62fed8%40googlegroups.com
>> 
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAJxq8494WzyFUS%2B4J93dQfge64HkmSOmWK9Lg5dyuqmhmxpUOA%40mail.gmail.com
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAByqUggu2tcBY13DQr9fWuQJJeFF6Hs1VG%2BdFfn465TH%3DCULrg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-26 Thread Russell Keith-Magee
+1. Sounds like a great idea to me.

Russ %-)

On Tue, Oct 27, 2015 at 1:22 AM, Tim Graham  wrote:

> On Trac [1], Alex says, "Django did a tremendous service to its users by
> making strong password hashing be the default. The world is pushing
> forward, and now 2fa is the next standard that many sites fail to meet.
> Django should include support for 2fa out of the box, ideally with support
> for both u2f and TOTP (Google Authenticator)."
>
>
> Doing a quick search, I found
> https://github.com/Bouke/django-two-factor-auth as a possible existing
> implementation that might be a starting point if we decide to integrate
> something. What do you think? One sticking point could be that it uses a
> ThreadLocals middleware. I didn't look to see how "necessary" that is.
>
>
> [1] https://code.djangoproject.com/ticket/25612
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/5ae7be8e-949c-4074-b613-04ca2a62fed8%40googlegroups.com
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAJxq8494WzyFUS%2B4J93dQfge64HkmSOmWK9Lg5dyuqmhmxpUOA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-26 Thread Joey Wilhelm
Fwiw, 2fa is on my short list of things to implement into my current
project. It's a fairly important feature to me, as this is a financial
project. And that particular implementation is precisely what I was looking
to use. I would happily contribute money and/or time toward this
implementation, especially if there was a happy upgrade path from Bouke's
library.
On Oct 26, 2015 15:47, "Josh Smeaton"  wrote:

> Having pluggable 2fa backends is a great idea.
>
> Many sites that allow 2fa have it as an option per user. I would think
> Django would allow the same. Allow admins to force 2fa, or allow Users to
> choose if they'd like it enabled.
>
> There'd have to be ORM/Model support (presumably) for user choices. A
> migration may be necessary, or just a completely separate table. Just
> things to consider.
>
> Cheers
>
> On Tuesday, 27 October 2015 04:30:25 UTC+11, Donald Stufft wrote:
>>
>> I agree with Alex, no idea about that particular implementation though.
>> It supports a lot of different implementations of two factor, though I
>> suspect Django wouldn’t need all of those things. I think it would be
>> reasonable to define something like auth_backends, but for 2fa and just
>> ship u2f and TOTP by default.
>>
>> On October 26, 2015 at 1:22:54 PM, Tim Graham (timog...@gmail.com)
>> wrote:
>> >
>> >
>> > On Trac [1], Alex says, "Django did a tremendous service to its users
>> by
>> > making strong password hashing be the default. The world is pushing
>> > forward, and now 2fa is the next standard that many sites fail to meet.
>> > Django should include support for 2fa out of the box, ideally with
>> support
>> > for both u2f and TOTP (Google Authenticator)."
>> >
>> >
>> > Doing a quick search, I found
>> > https://github.com/Bouke/django-two-factor-auth as a possible existing
>> > implementation that might be a starting point if we decide to integrate
>> > something. What do you think? One sticking point could be that it uses
>> a
>> > ThreadLocals middleware. I didn't look to see how "necessary" that is.
>> >
>> >
>> > [1] https://code.djangoproject.com/ticket/25612
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> Groups "Django developers
>> > (Contributions to Django itself)" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> an email to django-develop...@googlegroups.com.
>> > To post to this group, send email to django-d...@googlegroups.com.
>> > Visit this group at http://groups.google.com/group/django-developers.
>> > To view this discussion on the web visit
>> https://groups.google.com/d/msgid/django-developers/5ae7be8e-949c-4074-b613-04ca2a62fed8%40googlegroups.com.
>>
>> > For more options, visit https://groups.google.com/d/optout.
>> >
>>
>> -
>> Donald Stufft
>> PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372
>> DCFA
>>
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/fe9102ce-a136-40f9-a95e-0254ebc340e2%40googlegroups.com
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADBkHd%2Be%3DA4BLvRrO2Q0K2QfxgX4cN-6Nh6tejZYFQ2j6F3NPw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-26 Thread Josh Smeaton
Having pluggable 2fa backends is a great idea.

Many sites that allow 2fa have it as an option per user. I would think 
Django would allow the same. Allow admins to force 2fa, or allow Users to 
choose if they'd like it enabled.

There'd have to be ORM/Model support (presumably) for user choices. A 
migration may be necessary, or just a completely separate table. Just 
things to consider.

Cheers

On Tuesday, 27 October 2015 04:30:25 UTC+11, Donald Stufft wrote:
>
> I agree with Alex, no idea about that particular implementation though. It 
> supports a lot of different implementations of two factor, though I suspect 
> Django wouldn’t need all of those things. I think it would be reasonable to 
> define something like auth_backends, but for 2fa and just ship u2f and TOTP 
> by default. 
>
> On October 26, 2015 at 1:22:54 PM, Tim Graham (timog...@gmail.com 
> ) wrote: 
> >   
> >   
> > On Trac [1], Alex says, "Django did a tremendous service to its users by 
> > making strong password hashing be the default. The world is pushing 
> > forward, and now 2fa is the next standard that many sites fail to meet. 
> > Django should include support for 2fa out of the box, ideally with 
> support 
> > for both u2f and TOTP (Google Authenticator)." 
> >   
> >   
> > Doing a quick search, I found 
> > https://github.com/Bouke/django-two-factor-auth as a possible existing 
> > implementation that might be a starting point if we decide to integrate 
> > something. What do you think? One sticking point could be that it uses a 
> > ThreadLocals middleware. I didn't look to see how "necessary" that is. 
> >   
> >   
> > [1] https://code.djangoproject.com/ticket/25612 
> >   
> > -- 
> > You received this message because you are subscribed to the Google 
> Groups "Django developers   
> > (Contributions to Django itself)" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> an email to django-develop...@googlegroups.com .   
> > To post to this group, send email to django-d...@googlegroups.com 
> . 
> > Visit this group at http://groups.google.com/group/django-developers. 
> > To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/5ae7be8e-949c-4074-b613-04ca2a62fed8%40googlegroups.com.
>  
>   
> > For more options, visit https://groups.google.com/d/optout. 
> >   
>
> - 
> Donald Stufft 
> PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 
> DCFA 
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/fe9102ce-a136-40f9-a95e-0254ebc340e2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-26 Thread Aymeric Augustin
On 26 oct. 2015, at 18:22, Tim Graham  wrote:
> What do you think?

I would very much like Django to have 2FA out of the box.

Let’s bring django.contrib.auth kicking and screaming into the 2010’s ;-)

I even considered crowdfunding it but that didn’t go much beyond idle thoughts.

-- 
Aymeric.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0E9E2730-52BF-4F59-9A73-EC4AB2801B7B%40polytechnique.org.
For more options, visit https://groups.google.com/d/optout.


Re: Should contrib.auth include support for 2fa out of the box?

2015-10-26 Thread Donald Stufft
I agree with Alex, no idea about that particular implementation though. It 
supports a lot of different implementations of two factor, though I suspect 
Django wouldn’t need all of those things. I think it would be reasonable to 
define something like auth_backends, but for 2fa and just ship u2f and TOTP by 
default.

On October 26, 2015 at 1:22:54 PM, Tim Graham (timogra...@gmail.com) wrote:
>  
>  
> On Trac [1], Alex says, "Django did a tremendous service to its users by
> making strong password hashing be the default. The world is pushing
> forward, and now 2fa is the next standard that many sites fail to meet.
> Django should include support for 2fa out of the box, ideally with support
> for both u2f and TOTP (Google Authenticator)."
>  
>  
> Doing a quick search, I found
> https://github.com/Bouke/django-two-factor-auth as a possible existing
> implementation that might be a starting point if we decide to integrate
> something. What do you think? One sticking point could be that it uses a
> ThreadLocals middleware. I didn't look to see how "necessary" that is.
>  
>  
> [1] https://code.djangoproject.com/ticket/25612
>  
> --
> You received this message because you are subscribed to the Google Groups 
> "Django developers  
> (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to django-developers+unsubscr...@googlegroups.com.  
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/5ae7be8e-949c-4074-b613-04ca2a62fed8%40googlegroups.com.
>   
> For more options, visit https://groups.google.com/d/optout.
>  

-
Donald Stufft
PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA


-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/etPan.562e6323.1664632e.924e%40Draupnir.home.
For more options, visit https://groups.google.com/d/optout.


Should contrib.auth include support for 2fa out of the box?

2015-10-26 Thread Tim Graham


On Trac [1], Alex says, "Django did a tremendous service to its users by 
making strong password hashing be the default. The world is pushing 
forward, and now 2fa is the next standard that many sites fail to meet. 
Django should include support for 2fa out of the box, ideally with support 
for both u2f and TOTP (Google Authenticator)."


Doing a quick search, I found 
https://github.com/Bouke/django-two-factor-auth as a possible existing 
implementation that might be a starting point if we decide to integrate 
something. What do you think? One sticking point could be that it uses a 
ThreadLocals middleware. I didn't look to see how "necessary" that is.


[1] https://code.djangoproject.com/ticket/25612

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/5ae7be8e-949c-4074-b613-04ca2a62fed8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: form validation in contrib.auth

2015-05-13 Thread Tim Graham
1. I don't see much benefit to adding a max length for one form 
(AuthenticationForm) to give some sense of security as opposed to properly 
addressing the issue at the webserver level. As Paul said, "As documented 
in the deployment docs, it is your responsibility as the deployer to limit 
post bodies to a size which is reasonable for your server. Otherwise, a 
user can make very large post requests to any view at all, which may 
overwhelm other parts of your web stack as well. 4k is a commonly accepted 
good starting point for forms which do not expect file upload; you will 
have to tune file upload forms to match your needs depending on how they're 
processed."

2. AuthenticationForm is intentionally generic to allow it to be used with 
custom user models which may have different restrictions on the user name.

3. What's the use case? I'm not sure the signal without any credentials 
would be of much value. Anyway, it shouldn't be difficult to write your own 
login() view with the behavior you desire if we don't make a change in 
Django.

On Tuesday, May 12, 2015 at 3:14:56 AM UTC-4, Jens Diemer wrote:
>
>
> The default auth.form.AuthenticationForm() did not set a max_length for 
> the 
> password field: 
>
>
> https://github.com/django/django/blob/72f6513ebaa7a3fd43c26300e9a8c430dc07cdb5/django/contrib/auth/forms.py#L120-L126
>  
>
> Ok there is not really a max_length constraint. Because in the end the 
> auth.models.User must only store the hash value. 
>
> The available hashers will consume more RAM if the password is very long. 
> (The 
> CPU usage is very similar to a short password) 
> Only if the server has a POST data limit, the password size is limited. 
> But it 
> seems that POST limits are not set or very large on default 
> installations... 
>
>
> On the other side: I didn't see any side effects with a limitation e.g.: 
> max_length=1024 
>
>
>
>
> Another thing: The auth.models.AbstractUser has the 'username' field with 
> max_length=30 and validators.RegexValidator(r'^[\w.@+-]+$',...) 
>
> The AuthenticationForm has max_length=254 and no validator... 
>
>
>
> IMHO one principle is: Validate incoming data as soon as possible, isn't 
> it? 
>
>
>
> Next thing is "auth.signals.user_login_failed" 
>
> This signal will only fired if the auth backends was called. 
> IMHO it should be called on every failed login. Also if the form is not 
> valid. 
>
>
>
>
>
>
> -- 
>
>
> Mfg. 
>
> Jens Diemer 
>
>
>  
> http://www.jensdiemer.de 
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0f7eacf2-c7b8-4599-a708-546daa249413%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


form validation in contrib.auth

2015-05-12 Thread Jens Diemer


The default auth.form.AuthenticationForm() did not set a max_length for the 
password field:


https://github.com/django/django/blob/72f6513ebaa7a3fd43c26300e9a8c430dc07cdb5/django/contrib/auth/forms.py#L120-L126

Ok there is not really a max_length constraint. Because in the end the 
auth.models.User must only store the hash value.


The available hashers will consume more RAM if the password is very long. (The 
CPU usage is very similar to a short password)
Only if the server has a POST data limit, the password size is limited. But it 
seems that POST limits are not set or very large on default installations...



On the other side: I didn't see any side effects with a limitation e.g.: 
max_length=1024





Another thing: The auth.models.AbstractUser has the 'username' field with 
max_length=30 and validators.RegexValidator(r'^[\w.@+-]+$',...)


The AuthenticationForm has max_length=254 and no validator...



IMHO one principle is: Validate incoming data as soon as possible, isn't it?



Next thing is "auth.signals.user_login_failed"

This signal will only fired if the auth backends was called.
IMHO it should be called on every failed login. Also if the form is not valid.






--


Mfg.

Jens Diemer



http://www.jensdiemer.de

--
You received this message because you are subscribed to the Google Groups "Django 
developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/mis98k%24n71%241%40ger.gmane.org.
For more options, visit https://groups.google.com/d/optout.


Re: Draft branch: Swappable User models in contrib.auth

2012-08-23 Thread Russell Keith-Magee
On Thu, Aug 23, 2012 at 10:16 PM, sergzach  wrote:
> The question about databases.
>
> Do I understand correctly that if we create a MyUser class (as in your
> example) then extra fields (e.g. date_of_birth) will be stored in the same
> table of a database with inherited fields (from AbstractBaseUser)?

The example I provided will result in the creation of a single MyUser
table that contains all the fields that will be needed to operate as a
user in Django. The auth_user table (from auth.User) *won't* be
created; and the AbtractBaseUser doesn't cause the creation of a table
at all.

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.



Re: Draft branch: Swappable User models in contrib.auth

2012-08-23 Thread sergzach
The question about databases.

Do I understand correctly that if we create a MyUser class (as in your 
example) then extra fields (e.g. date_of_birth) will be stored in the same 
table of a database with inherited fields (from AbstractBaseUser)?


> === 
> from django.db import models 
>
> from django.contrib.auth.models import BaseUserManager, AbstractBaseUser 
>
> class MyUserManager(BaseUserManager): 
> def create_user(self, email, date_of_birth, password=None): 
> if not email: 
> raise ValueError('Users must have an email address') 
>
> user = self.model( 
> email=MyUserManager.normalize_email(email), 
> date_of_birth=date_of_birth, 
> ) 
>
> user.set_password(password) 
> user.save(using=self._db) 
> return user 
>
> def create_superuser(self, username, password, date_of_birth): 
> u = self.create_user(username, password=password, 
> date_of_birth=date_of_birth) 
> u.is_admin = True 
> u.save(using=self._db) 
> return u 
>
>
> class MyUser(AbstractBaseUser): 
> email = models.EmailField(verbose_name='email address', 
> max_length=255, unique=True) 
> date_of_birth = models.DateField() 
> is_admin = models.BooleanField(default=False) 
>
> objects = MyUserManager() 
>
> USERNAME_FIELD = 'email' 
> REQUIRED_FIELDS = ['date_of_birth'] 
>
> def get_full_name(self): 
> return self.email 
>
> def get_short_name(self): 
> return self.email 
>
> def __unicode__(self): 
> return self.email 
>
> # Admin required fields 
> def has_perm(self, perm, obj=None): 
> return True 
>
> def has_module_perms(self, app_label): 
> return True 
>
> @property 
> def is_staff(self): 
> return self.is_admin 
>
> @property 
> def is_active(self): 
> return True 
> === 
>
>  * Set AUTH_USER_MODEL = 'myauth.MyUser' 
>
>  * Run syncdb. 
>
> At this point, feedback and offers of assistance are most welcome. 
>
> [1] 
> https://code.djangoproject.com/wiki/ContribAuthImprovements#Recommendations 
> [2] https://github.com/freakboy3742/django/tree/t3011 
> [3] http://www.w3.org/International/questions/qa-personal-names 
>
> Yours, 
> Russ Magee %-) 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/e_eXtydc004J.
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.



Re: Draft branch: Swappable User models in contrib.auth

2012-08-22 Thread Daniel Sokolowski

Just felt compelled to say: "Thank you for the hard work".

-Original Message- 
From: Russell Keith-Magee

Sent: Monday, August 20, 2012 9:40 PM
To: django-developers@googlegroups.com
Subject: Re: Draft branch: Swappable User models in contrib.auth

On Mon, Aug 20, 2012 at 7:11 AM, Russell Keith-Magee
 wrote:
On Sun, Aug 19, 2012 at 10:02 AM, Victor Hooi  
wrote:

Hi,

I'm just wondering, has there been any updates on the User model 
refactor?


My understanding is that this is the official way of handling Users going
forward.

Is there any roadmap on when it might hit trunk? I didn't see any 
reference

to User models in the 1.5 release notes.


The precise answer? Soon. Ish. :-)

There's a draft branch which works [1], but requires some more testing
and documentation. It also hasn't been updated to reflect the recent
py3k changes.

I'm sprinting at PyCon AU this year, so I'm hoping to at least get the
branch up to date. I might also be able to convince someone to work on
the documentation issue.

I still want to get this in for 1.5; it's just a matter of find the spare 
time.


[1] https://github.com/freakboy3742/django/tree/t3011


A follow up on post-PyCon AU sprint activity -- I've gotten my branch
up to date with Django trunk; there has been some work done on getting
some documentation ready; and a few more pairs of eyes have been over
the code looking for admin integration problems and other assumptions
that I've made that might not shake out. Thanks to everyone at PyCon
AU that pitched in (Thomas Ashelford, Greg Turner, Brenda Moon, Simon
Meers, and a few others).

There's one issue lurking with testing that has some potential to turn
into a yak shaving exercise, but if we shave that yak, we'll have
another big feature to put on the list for Django 1.5. I'll try to
post to django-developers about this in the near future (hopefully
before DjangoCon US).

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.



Daniel Sokolowski
Senior Web Engineer
KL Insight
http://klinsight.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.



Re: Draft branch: Swappable User models in contrib.auth

2012-08-20 Thread Russell Keith-Magee
On Mon, Aug 20, 2012 at 7:11 AM, Russell Keith-Magee
 wrote:
> On Sun, Aug 19, 2012 at 10:02 AM, Victor Hooi  wrote:
>> Hi,
>>
>> I'm just wondering, has there been any updates on the User model refactor?
>>
>> My understanding is that this is the official way of handling Users going
>> forward.
>>
>> Is there any roadmap on when it might hit trunk? I didn't see any reference
>> to User models in the 1.5 release notes.
>
> The precise answer? Soon. Ish. :-)
>
> There's a draft branch which works [1], but requires some more testing
> and documentation. It also hasn't been updated to reflect the recent
> py3k changes.
>
> I'm sprinting at PyCon AU this year, so I'm hoping to at least get the
> branch up to date. I might also be able to convince someone to work on
> the documentation issue.
>
> I still want to get this in for 1.5; it's just a matter of find the spare 
> time.
>
> [1] https://github.com/freakboy3742/django/tree/t3011

A follow up on post-PyCon AU sprint activity -- I've gotten my branch
up to date with Django trunk; there has been some work done on getting
some documentation ready; and a few more pairs of eyes have been over
the code looking for admin integration problems and other assumptions
that I've made that might not shake out. Thanks to everyone at PyCon
AU that pitched in (Thomas Ashelford, Greg Turner, Brenda Moon, Simon
Meers, and a few others).

There's one issue lurking with testing that has some potential to turn
into a yak shaving exercise, but if we shave that yak, we'll have
another big feature to put on the list for Django 1.5. I'll try to
post to django-developers about this in the near future (hopefully
before DjangoCon US).

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.



Re: Draft branch: Swappable User models in contrib.auth

2012-08-19 Thread Marc Tamlyn
Ah, thanks Russ, I'd missed the final resolution to that.

M

On Monday, 20 August 2012 00:12:18 UTC+1, Russell Keith-Magee wrote:
>
> On Sun, Aug 19, 2012 at 5:23 PM, Marc Tamlyn 
> > 
> wrote: 
> > I believe changes to auth (and several other things) are waiting for 
> > contrib.migrations. It will be some time... 
>
> Incorrect. The strategy that was approved for trunk won't require 
> migrations unless you want to change an existing project, which means 
> it will be entirely opt-in. There was an extensive django-dev 
> discussion about 6 months ago about this; the redux is on the wiki: 
>
> https://code.djangoproject.com/wiki/ContribAuthImprovements 
>
> Yours, 
> Russ Magee %-) 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/YRjWXtBIuD0J.
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.



Re: Draft branch: Swappable User models in contrib.auth

2012-08-19 Thread Russell Keith-Magee
On Sun, Aug 19, 2012 at 5:23 PM, Marc Tamlyn  wrote:
> I believe changes to auth (and several other things) are waiting for
> contrib.migrations. It will be some time...

Incorrect. The strategy that was approved for trunk won't require
migrations unless you want to change an existing project, which means
it will be entirely opt-in. There was an extensive django-dev
discussion about 6 months ago about this; the redux is on the wiki:

https://code.djangoproject.com/wiki/ContribAuthImprovements

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.



Re: Draft branch: Swappable User models in contrib.auth

2012-08-19 Thread Russell Keith-Magee
On Sun, Aug 19, 2012 at 10:02 AM, Victor Hooi  wrote:
> Hi,
>
> I'm just wondering, has there been any updates on the User model refactor?
>
> My understanding is that this is the official way of handling Users going
> forward.
>
> Is there any roadmap on when it might hit trunk? I didn't see any reference
> to User models in the 1.5 release notes.

The precise answer? Soon. Ish. :-)

There's a draft branch which works [1], but requires some more testing
and documentation. It also hasn't been updated to reflect the recent
py3k changes.

I'm sprinting at PyCon AU this year, so I'm hoping to at least get the
branch up to date. I might also be able to convince someone to work on
the documentation issue.

I still want to get this in for 1.5; it's just a matter of find the spare time.

[1] https://github.com/freakboy3742/django/tree/t3011

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.



Re: Draft branch: Swappable User models in contrib.auth

2012-08-19 Thread Marc Tamlyn
I believe changes to auth (and several other things) are waiting for 
contrib.migrations. It will be some time...

On Sunday, 19 August 2012 03:02:51 UTC+1, Victor Hooi wrote:
>
> Hi,
>
> I'm just wondering, has there been any updates on the User model refactor?
>
> My understanding is that this is the official way of handling Users going 
> forward.
>
> Is there any roadmap on when it might hit trunk? I didn't see any 
> reference to User models in the 1.5 release notes.
> Cheers,
> Victor
>
> On Wednesday, 6 June 2012 21:34:42 UTC+10, Andrew Ingram wrote:
>>
>> On 4 June 2012 16:12, Russell Keith-Magee  
>> wrote: 
>> >  * The swapping mechanic is set up using a new Meta option on models 
>> > called 'swappable' that defines the setting where an alternate model 
>> > can be defined. Technically, the swappable option *could* be used for 
>> > any model; however, I'm not proposing that we actually document this. 
>> > I've implemented it as a generic approach purely to make the internals 
>> > cleaner -- mostly to avoid needing to make references to auth.User in 
>> > the model syncdb code, and to make testing possible (i.e., we can do 
>> > validation tests on a dummy 'swappable' model, rather than trying to 
>> > munge a validation test for auth.User specifically). 
>>
>> I like the idea of a 'swappable' option, but I can see some potential 
>> issues with the implementation. I'm one of the developers of Oscar 
>> (https://github.com/tangentlabs/django-oscar/) and providing a clean 
>> method to for overriding models has been a major pain point. One of 
>> our key requirements is that any model in Oscar may be overridden, to 
>> that end every model has both abstract and concrete versions (much 
>> like your implementation of AbstractBaseUser and User). 
>>
>> Our current way of handling overrides is for every reference to a 
>> model in Oscar to use get_model rather than the explicit classname. 
>> But this does end up causing some ugly things like this: 
>>
>> from oscar.apps.catalogue.abstract_models import AbstractProduct 
>>
>> class Product(AbstractProduct): 
>> # stuff 
>>
>> from oscar.apps.catalogue.models import * 
>>
>>
>> Issues: 
>> 1) The override model HAS to have the same name as the default model, 
>> otherwise get_model('catalogue', 'Product') won't work. 
>> 2) We have to import all the remaining default models after we declare 
>> our overrides. But this only works because Django's model metaclass 
>> prevents the default Product replacing the one we've just defined. I 
>> don't like this because it's a little bit magic. 
>> 3) You have to remove Oscar's version of the app from INSTALLED_APPS 
>> and replace it with your own. Actually, technically you don't. If you 
>> leave Oscar's app installed but put your own one ('foo.catalogue') in 
>> front of it, you can even get rid of the nasty import * thing - but 
>> again, more magic. (Aside: you can actually use this approach already 
>> to override Django's User model, because the metaclass means any 
>> references to Django's User will be replaced with references to your 
>> own. ) 
>>
>> I had investigated using a class decorator to handle overrides: 
>>
>> @replace_model('catalogue.Product') 
>> class MyProduct(AbstractProduct): 
>> # foo 
>>
>> But this got seriously complicated because the metaclass modifies the 
>> class before the decorator can be applied, so I was looking into ways 
>> to sever all the ties with the app cache before I went insane and gave 
>> up. 
>>
>> Back to my main points... Your swappable option would solve quite a 
>> lot, in the case of the User model it's ideal. But I'm concerned that 
>> if people start using it more widely we'd end up having dozens of new 
>> settings that would get quite silly in the case of a large project 
>> like Oscar. I think it's important that overrides can be defined in 
>> the settings file, but I'd also like to see it possible at model 
>> definition time, either using a decorator (like above) or a Meta 
>> option like 'replaces'. The risk, of course, is that it means any 
>> third-party app could override any other model without you necessarily 
>> being aware of it, not sure how this would be mitigated. 
>>
>> If I've not made much sense let me know, I've always found it hard to 
>> articulate on this particular topic. 
>>
>>
>> Regards, 
>> Andrew Ingram 
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/VkctqktqAxMJ.
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.



Re: Draft branch: Swappable User models in contrib.auth

2012-08-18 Thread Victor Hooi
Hi,

I'm just wondering, has there been any updates on the User model refactor?

My understanding is that this is the official way of handling Users going 
forward.

Is there any roadmap on when it might hit trunk? I didn't see any reference 
to User models in the 1.5 release notes.
Cheers,
Victor

On Wednesday, 6 June 2012 21:34:42 UTC+10, Andrew Ingram wrote:
>
> On 4 June 2012 16:12, Russell Keith-Magee 
> > 
> wrote: 
> >  * The swapping mechanic is set up using a new Meta option on models 
> > called 'swappable' that defines the setting where an alternate model 
> > can be defined. Technically, the swappable option *could* be used for 
> > any model; however, I'm not proposing that we actually document this. 
> > I've implemented it as a generic approach purely to make the internals 
> > cleaner -- mostly to avoid needing to make references to auth.User in 
> > the model syncdb code, and to make testing possible (i.e., we can do 
> > validation tests on a dummy 'swappable' model, rather than trying to 
> > munge a validation test for auth.User specifically). 
>
> I like the idea of a 'swappable' option, but I can see some potential 
> issues with the implementation. I'm one of the developers of Oscar 
> (https://github.com/tangentlabs/django-oscar/) and providing a clean 
> method to for overriding models has been a major pain point. One of 
> our key requirements is that any model in Oscar may be overridden, to 
> that end every model has both abstract and concrete versions (much 
> like your implementation of AbstractBaseUser and User). 
>
> Our current way of handling overrides is for every reference to a 
> model in Oscar to use get_model rather than the explicit classname. 
> But this does end up causing some ugly things like this: 
>
> from oscar.apps.catalogue.abstract_models import AbstractProduct 
>
> class Product(AbstractProduct): 
> # stuff 
>
> from oscar.apps.catalogue.models import * 
>
>
> Issues: 
> 1) The override model HAS to have the same name as the default model, 
> otherwise get_model('catalogue', 'Product') won't work. 
> 2) We have to import all the remaining default models after we declare 
> our overrides. But this only works because Django's model metaclass 
> prevents the default Product replacing the one we've just defined. I 
> don't like this because it's a little bit magic. 
> 3) You have to remove Oscar's version of the app from INSTALLED_APPS 
> and replace it with your own. Actually, technically you don't. If you 
> leave Oscar's app installed but put your own one ('foo.catalogue') in 
> front of it, you can even get rid of the nasty import * thing - but 
> again, more magic. (Aside: you can actually use this approach already 
> to override Django's User model, because the metaclass means any 
> references to Django's User will be replaced with references to your 
> own. ) 
>
> I had investigated using a class decorator to handle overrides: 
>
> @replace_model('catalogue.Product') 
> class MyProduct(AbstractProduct): 
> # foo 
>
> But this got seriously complicated because the metaclass modifies the 
> class before the decorator can be applied, so I was looking into ways 
> to sever all the ties with the app cache before I went insane and gave 
> up. 
>
> Back to my main points... Your swappable option would solve quite a 
> lot, in the case of the User model it's ideal. But I'm concerned that 
> if people start using it more widely we'd end up having dozens of new 
> settings that would get quite silly in the case of a large project 
> like Oscar. I think it's important that overrides can be defined in 
> the settings file, but I'd also like to see it possible at model 
> definition time, either using a decorator (like above) or a Meta 
> option like 'replaces'. The risk, of course, is that it means any 
> third-party app could override any other model without you necessarily 
> being aware of it, not sure how this would be mitigated. 
>
> If I've not made much sense let me know, I've always found it hard to 
> articulate on this particular topic. 
>
>
> Regards, 
> Andrew Ingram 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/AKe1T5bePTkJ.
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.



Re: Draft branch: Swappable User models in contrib.auth

2012-06-10 Thread Anssi Kääriäinen
On 10 kesä, 10:42, Russell Keith-Magee 
wrote:
> I'm not sure I see why. This looks to me like *exactly* what apps are
> designed to achieve. By way of implementation, it might make sense to
> introduce this as a 'sub app' - i.e., contrib.auth.improveduser would
> be an installable app in itself; this would avoid the need to dirty up
> the contrib namespace. However, for me that's a relatively minor
> implementation detail.
>
> I don't understand the objection to using app installation as the
> basis for declaring what features you want a particular project to
> have. Can you elaborate on why you think this isn't a reasonable
> solution to the problem?

You have dual-control for the same thing: you need to change both a
setting and the installed apps to pick improved user as your user
model. So, you can accidentally end up with the improved model
installed, but still have the original model as the settings model.
There can't be any validation errors in this case. Nothing ties the
ImprovedUser to the User model on code level. Additionally, the
requirement of separate apps places restrictions on where you must
place your code.

But, I have bugged you enough already. I don't fully agree on all of
the details of the API. Luckily there is no need for full agreement. I
don't see others complaining about the API, so maybe the API is
actually good and it's just me... :)

> > I was driving for the use case where you define multiple different
> > models for the same "slot" using the swappable option. If there can be
> > only one model with swappable set for each slot, then there is no
> > problem here.
>
> To me, that seems like solving an entirely different problem. It
> *might* be a problem that could be solved with app-refactor -- the
> configuration of an app could potentially specify all sorts of
> configuration points, such as "Model X has a foreign key to
> placeholder A; what model will A be?". That's an orthogonal problem to
> replacing all references to User with a custom model across an entire
> project.

Misunderstanding here, I didn't explain myself well above. The idea
was that in a single models.py file you could have multiple choices
for the same slot:

class User(models.Model):
...
class Meta:
  swappable = 'AUTH_USER_MODEL'

class ImprovedUser(models.Model):
...
class Meta:
swappable = 'AUTH_USER_MODEL'

Thus, two models for the same swappable slot. You can pick project
wide which one to use by AUTH_USER_MODEL = 'auth.User' or
AUTH_USER_MODEL = 'auth.ImprovedUser'. You can pick only one in your
project. And the original problem was that if you don't control the
settings, both models think they are the chosen one if no setting is
defined for the AUTH_USER_MODEL. If you can have only one model with
swappable set, then there is no problem.

> I'm not sure I understand what you're saying here. We can specify that
> the model class itself needs to provide certain methods (e.g.,
> User.get_full_name()), and we can specify that the Manager must
> provide certain methods (e.g., User.objects.create_superuser()). If we
> really needed to, we could also specify that the queryset
> implementation for the model had to provide certain methods, or that
> the model class had to provide certain class methods.
>
> If you're saying that we have no way to require that certain queries
> work or are parameterized, then I agree -- but I also think that this
> is a good thing. If you're building an app that is going to utilise
> pluggable models, then it's up to you to abstract away the
> implementation behind an interface that provides whatever utility you
> require. If you're not in a position to define an interface like that,
> then I'd argue that you don't really have a model that is a candidate
> for being swapped out.
>
> For the purposes of this work, the only model we actually care about
> is User (since swappability as a general feature isn't on the table
> here), and we can definitely define an interface for User.

What I was driving for was a way to do
User.objects.order_by('shortname') and have the ORM basically rewrite
this to User.objects.order_by(User.short_name_order_field()). Two
reasons: the lookup interface is really nice, and it is easily usable
across relations. Thus, the interface is not on queryset method level
or model level - it is on lookup level.

This doesn't actually seem to be that big of a problem: if there are
queryset interfaces you could always do
Document.objects.filter(creator__in=User.objects.fullname_search('Anssi')).order_by('creator__'
+ User.short_name_order_field())

That should be good enough.

 - Anssi

-- 
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

Re: Draft branch: Swappable User models in contrib.auth

2012-06-10 Thread Russell Keith-Magee
On Fri, Jun 8, 2012 at 7:50 PM, Anssi Kääriäinen
 wrote:
> On 8 kesä, 13:43, Russell Keith-Magee  wrote:
>> That's certainly an interesting use case. However, I can think of at
>> least 2 ways it could be mitigated.
>>
>> One way would be to treat this as part of the contract of a pluggble
>> app. We've always said that an app should do one thing, and one thing
>> only; providing a *single* swappable model candidate, and any
>> associated support (e.g., forms, admin declarations) would seem to fit
>> that definition fairly well. In this context, a "library" of reusable
>> User models is really just a collection of apps, one of which will be
>> installed in your project. The CMS with a range of User model options
>> would provide them as a series of apps, one (and only one) of which
>> needs to be installed.
>
> We might want to have two user models already in the auth.models. The
> current User, and then an "ImprovedUser", which is like the default
> user, but has the worst limitations lifted (email field can be 255
> chars long, username restrictions lifted, ...). It seems the current
> implementation would not allow for this, because only one model could
> define itself as swappable, and the other would get installed even if
> it wasn't needed. For our use case this would work as we control
> global_settings.py, and we can use the hidden swappable attribute for
> both models, but I guess the ImprovedModel/BackwardsCompatibilityModel
> pattern isn't such a rare case. To make the swappable option nicer to
> use for 3rd party apps a better solution than different app for each
> swappable model would be welcome.

I'm not sure I see why. This looks to me like *exactly* what apps are
designed to achieve. By way of implementation, it might make sense to
introduce this as a 'sub app' - i.e., contrib.auth.improveduser would
be an installable app in itself; this would avoid the need to dirty up
the contrib namespace. However, for me that's a relatively minor
implementation detail.

I don't understand the objection to using app installation as the
basis for declaring what features you want a particular project to
have. Can you elaborate on why you think this isn't a reasonable
solution to the problem?

>> > The model_label_for_default_model can't be defined anywhere in the
>> > current implementation. The Model._meta.swapped uses:
>> >    return self.swappable and getattr(settings, self.swappable, None)
>> > not in (None, model_label)
>>
>> Sure - but model_label_of_default_model doesn't *need* to be defined
>> anywhere - it's the model that has swappable=XXX defined on it.
>
> I was driving for the use case where you define multiple different
> models for the same "slot" using the swappable option. If there can be
> only one model with swappable set for each slot, then there is no
> problem here.

To me, that seems like solving an entirely different problem. It
*might* be a problem that could be solved with app-refactor -- the
configuration of an app could potentially specify all sorts of
configuration points, such as "Model X has a foreign key to
placeholder A; what model will A be?". That's an orthogonal problem to
replacing all references to User with a custom model across an entire
project.

>> Again - for me this is one of those things where it's all about the 
>> interface.
>>
>> In this example, your end problem isn't "I need to issue a query with
>> Q(creator__last_name__ilike=q)|Q(creator__first_name__ilike=q)" --
>> it's "I need to search for document creator by name", and  *that* is
>> what your interface should be defining. If your interface spec said
>> you had to provide a "find_document_by_author()" method, and one
>> particular implementation happens to use that query, then you've just
>> solved the problem. The specific document attributes *should* be
>> irrelevant -- and if they aren't, you haven't defined your document
>> interface well enough.
>>
>> It's impossible to claim that every model will be usable in every
>> circumstance. At some point, you have to lock down an interface
>> specification, which will define what it is possible to do in a
>> 'generic' sense with your swappable model. This isn't some new concept
>> we're inventing here - interfaces have been a major part of more than
>> one language for decades. Luckily, with Python, we get the benefits of
>> interfaces without needing to be strict about it -- we can rely on
>> duck typing, rather than rigorous and inflexible compile-time checks.
>
> The problem is that we have no ability to define ORM interface for the
> model. The ORM doesn't allow for this. It would be nice, but you can't
> have everything. I am not claiming this is a blocker issue at all, I
> was just wondering if there were any plans to define an ORM interface
> for the model.

I'm not sure I understand what you're saying here. We can specify that
the model class itself needs to provide certain methods (e.g.,
User.get_full_name()), and we can specify that the Manager

Re: Draft branch: Swappable User models in contrib.auth

2012-06-08 Thread Anssi Kääriäinen
On 8 kesä, 13:43, Russell Keith-Magee  wrote:
> That's certainly an interesting use case. However, I can think of at
> least 2 ways it could be mitigated.
>
> One way would be to treat this as part of the contract of a pluggble
> app. We've always said that an app should do one thing, and one thing
> only; providing a *single* swappable model candidate, and any
> associated support (e.g., forms, admin declarations) would seem to fit
> that definition fairly well. In this context, a "library" of reusable
> User models is really just a collection of apps, one of which will be
> installed in your project. The CMS with a range of User model options
> would provide them as a series of apps, one (and only one) of which
> needs to be installed.

We might want to have two user models already in the auth.models. The
current User, and then an "ImprovedUser", which is like the default
user, but has the worst limitations lifted (email field can be 255
chars long, username restrictions lifted, ...). It seems the current
implementation would not allow for this, because only one model could
define itself as swappable, and the other would get installed even if
it wasn't needed. For our use case this would work as we control
global_settings.py, and we can use the hidden swappable attribute for
both models, but I guess the ImprovedModel/BackwardsCompatibilityModel
pattern isn't such a rare case. To make the swappable option nicer to
use for 3rd party apps a better solution than different app for each
swappable model would be welcome.

> > The model_label_for_default_model can't be defined anywhere in the
> > current implementation. The Model._meta.swapped uses:
> >    return self.swappable and getattr(settings, self.swappable, None)
> > not in (None, model_label)
>
> Sure - but model_label_of_default_model doesn't *need* to be defined
> anywhere - it's the model that has swappable=XXX defined on it.

I was driving for the use case where you define multiple different
models for the same "slot" using the swappable option. If there can be
only one model with swappable set for each slot, then there is no
problem here.

> Again - for me this is one of those things where it's all about the interface.
>
> In this example, your end problem isn't "I need to issue a query with
> Q(creator__last_name__ilike=q)|Q(creator__first_name__ilike=q)" --
> it's "I need to search for document creator by name", and  *that* is
> what your interface should be defining. If your interface spec said
> you had to provide a "find_document_by_author()" method, and one
> particular implementation happens to use that query, then you've just
> solved the problem. The specific document attributes *should* be
> irrelevant -- and if they aren't, you haven't defined your document
> interface well enough.
>
> It's impossible to claim that every model will be usable in every
> circumstance. At some point, you have to lock down an interface
> specification, which will define what it is possible to do in a
> 'generic' sense with your swappable model. This isn't some new concept
> we're inventing here - interfaces have been a major part of more than
> one language for decades. Luckily, with Python, we get the benefits of
> interfaces without needing to be strict about it -- we can rely on
> duck typing, rather than rigorous and inflexible compile-time checks.

The problem is that we have no ability to define ORM interface for the
model. The ORM doesn't allow for this. It would be nice, but you can't
have everything. I am not claiming this is a blocker issue at all, I
was just wondering if there were any plans to define an ORM interface
for the model.

 - Anssi

-- 
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.



Re: Draft branch: Swappable User models in contrib.auth

2012-06-08 Thread Russell Keith-Magee
On Fri, Jun 8, 2012 at 8:53 AM, Anssi Kääriäinen
 wrote:
> On 8 kesä, 02:43, Russell Keith-Magee  wrote:
>> >  - For documentation: It should be suggested that the example MyUser
>> > should define class Meta: swappable = 'AUTH_USER_MODEL'. Otherwise it
>> > will be synced to the database even if it is not the chosen user model
>> > for the project, which is likely not wanted. Maybe AbstractBaseUser
>> > should define swappable = 'AUTH_USER_MODEL' so that anybody who
>> > inherits from that gets the setting automatically?
>>
>> Ah - I think I see the problem now. The swappable Meta option isn't
>> visible to to end user -- ever -- unless they go spelunking in the
>> source code for auth.models.
>>
>> If I define MyUser, I *dont'* need to define it as swappable. I just
>> need to define AUTH_USER_MODEL in my settings file to point at my
>> replacement model definition. The only place where swappable is
>> defined is on the base model that is being swapped out -- in this
>> case, auth.User.
>>
>> I'm expecting that there will be *no* documentation of the swappable
>> option (unless, at some point in the future, we decide to make
>> swappable models an official feature). It exists purely to make the
>> internals clean, and avoid making auth.User a special case in code.
>
> The real problem comes when you have multiple swappable models defined
> for the same swappable "slot". This could happen in a CMS for example
> - they might define a couple of classes to use, you can choose which
> one to use by using a setting. Or, maybe you have some library
> installed which defines some reusable User models. Problem is, every
> one of these models will be installed unless they provided the
> swappable = 'AUTH_USER_MODEL' meta option. If you don't provide that
> option, nothing ties the models to the same slot.

That's certainly an interesting use case. However, I can think of at
least 2 ways it could be mitigated.

One way would be to treat this as part of the contract of a pluggble
app. We've always said that an app should do one thing, and one thing
only; providing a *single* swappable model candidate, and any
associated support (e.g., forms, admin declarations) would seem to fit
that definition fairly well. In this context, a "library" of reusable
User models is really just a collection of apps, one of which will be
installed in your project. The CMS with a range of User model options
would provide them as a series of apps, one (and only one) of which
needs to be installed.

Alternatively, I suppose we could introduce a separate Meta option
(lets call it "swapper" for the moment -- I don't particularly like
the name, but it will do for discussion purposes) which has the
opposite behaviour of swappable - i.e., a model with swappable=XXX is
only synchronised if settings.XXX is undefined, or XXX points to the
default model; a model with swapper=True is only synchronised if XXX
points to it. Otherwise, it's treated as an abstract model.

Personally, my preference would be the former approach.

>> >  - Assume a 3rd party developer was going to use the swappable Meta
>> > attribute. The developer provides a couple of different swappable
>> > implementations to use, each defining swappable = 'MY_SETTING'.
>> > However, by default settings.MY_SETTING is None, and thus each of
>> > these models will be synced into the DB. How does the 3rd party
>> > developer designate the default implementation? For auth.user this is
>> > easy, as global_settings can contain the default setting. A 3rd party
>> > developer doesn't have this option. (This one isn't important for the
>> > auth.User case, only for making this feature someday publicly
>> > available).
>>
>> If MY_SETTING isn't defined, all the code I've written should be
>> assuming that the model isn't swapped out (i.e., it's effectively
>> getattr(settings, 'MY_SETTING', model_label_of_default_model) ). As
>> proof of concept, it certainly wouldn't hurt to drop out the
>> AUTH_USER_MODEL setting from globals.
>
> The model_label_for_default_model can't be defined anywhere in the
> current implementation. The Model._meta.swapped uses:
>    return self.swappable and getattr(settings, self.swappable, None)
> not in (None, model_label)

Sure - but model_label_of_default_model doesn't *need* to be defined
anywhere - it's the model that has swappable=XXX defined on it.

>> >> > About the ORM capabilities of the interface: It seems there can not be
>> >> > any assumptions about the swapped in model here: for example
>> >> > SomeModel.filter(user__is_staff=True) or
>> >> > SomeModel.order_by('user__lastname', 'user__firstname') works
>> >> > currently, but there are no such lookups available for the interface.
>> >> > Maybe there should be some way to order by "full_name" and
>> >> > "short_name" at least. But, this gets us quickly to virtual fields or
>> >> > virtual lookups territory...
>>
>> >> Imo it's fine if we require some fields on a Usermodel to be compatible
>> >> with admin

Re: Draft branch: Swappable User models in contrib.auth

2012-06-07 Thread Anssi Kääriäinen
On 8 kesä, 02:43, Russell Keith-Magee  wrote:
> Good idea. I haven't tried to see what it actually does; I'm guessing
> you're going to get Table Does Not Exist errors. A nicer error
> wouldn't hurt.

Yes, that is what happens.

> >  - For documentation: It should be suggested that the example MyUser
> > should define class Meta: swappable = 'AUTH_USER_MODEL'. Otherwise it
> > will be synced to the database even if it is not the chosen user model
> > for the project, which is likely not wanted. Maybe AbstractBaseUser
> > should define swappable = 'AUTH_USER_MODEL' so that anybody who
> > inherits from that gets the setting automatically?
>
> Ah - I think I see the problem now. The swappable Meta option isn't
> visible to to end user -- ever -- unless they go spelunking in the
> source code for auth.models.
>
> If I define MyUser, I *dont'* need to define it as swappable. I just
> need to define AUTH_USER_MODEL in my settings file to point at my
> replacement model definition. The only place where swappable is
> defined is on the base model that is being swapped out -- in this
> case, auth.User.
>
> I'm expecting that there will be *no* documentation of the swappable
> option (unless, at some point in the future, we decide to make
> swappable models an official feature). It exists purely to make the
> internals clean, and avoid making auth.User a special case in code.

The real problem comes when you have multiple swappable models defined
for the same swappable "slot". This could happen in a CMS for example
- they might define a couple of classes to use, you can choose which
one to use by using a setting. Or, maybe you have some library
installed which defines some reusable User models. Problem is, every
one of these models will be installed unless they provided the
swappable = 'AUTH_USER_MODEL' meta option. If you don't provide that
option, nothing ties the models to the same slot.

> >  - Assume a 3rd party developer was going to use the swappable Meta
> > attribute. The developer provides a couple of different swappable
> > implementations to use, each defining swappable = 'MY_SETTING'.
> > However, by default settings.MY_SETTING is None, and thus each of
> > these models will be synced into the DB. How does the 3rd party
> > developer designate the default implementation? For auth.user this is
> > easy, as global_settings can contain the default setting. A 3rd party
> > developer doesn't have this option. (This one isn't important for the
> > auth.User case, only for making this feature someday publicly
> > available).
>
> If MY_SETTING isn't defined, all the code I've written should be
> assuming that the model isn't swapped out (i.e., it's effectively
> getattr(settings, 'MY_SETTING', model_label_of_default_model) ). As
> proof of concept, it certainly wouldn't hurt to drop out the
> AUTH_USER_MODEL setting from globals.

The model_label_for_default_model can't be defined anywhere in the
current implementation. The Model._meta.swapped uses:
return self.swappable and getattr(settings, self.swappable, None)
not in (None, model_label)

> >> > About the ORM capabilities of the interface: It seems there can not be
> >> > any assumptions about the swapped in model here: for example
> >> > SomeModel.filter(user__is_staff=True) or
> >> > SomeModel.order_by('user__lastname', 'user__firstname') works
> >> > currently, but there are no such lookups available for the interface.
> >> > Maybe there should be some way to order by "full_name" and
> >> > "short_name" at least. But, this gets us quickly to virtual fields or
> >> > virtual lookups territory...
>
> >> Imo it's fine if we require some fields on a Usermodel to be compatible
> >> with admin and friends. (eg a first/last_name field which is nullable [or
> >> not required in the form validation sense] shouldn't hurt anyone, the admin
> >> could check if the field is filled and if not display something else like
> >> the username).
>
> > Admin is actually somewhat easy to make work re the ordering, because
> > in there you can use get_full_name.admin_order_field =
> > 'somemodelfield'. This doesn't work outside Admin. This isn't a major
> > issue, it prevents things like ordering comments on the commenter's
> > "get_short_name" output. Even then, this is only an issue for reusable
> > code - in your project you know the concrete user model you have in
> > use, and can thus use the specific lookups your model has.
>
> I can see two approaches here.
>
> The first is the full audit of admin that I've mentioned previously.
> That will reveal everything that admin is depending on, and will allow
> us to define a full "admin user interface" that any swappable user
> must define.
>
> The second is to abstract away the ordering field in the same was as
> we've abstracted get_short_name -- i.e., don't specify what the field
> needs to be called, just require that the user provide an option that
> defines how it can be retrieved. This is similar to what we've done
>

Re: Draft branch: Swappable User models in contrib.auth

2012-06-07 Thread Russell Keith-Magee
On Thu, Jun 7, 2012 at 7:48 PM, Anssi Kääriäinen
 wrote:
> On Jun 7, 11:57 am, Florian Apolloner  wrote:
>> Hi,
>>
>> On Wednesday, June 6, 2012 4:32:02 PM UTC+2, Anssi Kääriäinen wrote:
>>
>> > Still, yet another API idea: [snip]
>>
>> Then, Model.__new__ will replace the SwappableUser class with the
>>
>> > swapped in class. The 'swappable' in model.Meta tells which concrete
>> > model implementation to use.
>>
>> I'd rather not dynamically replace models. The system proposed by Russell
>> is clean and requires no extra magic. The only thing which might look a bit
>> odd is inheriting from a swapped model, eg like:
>>
>> class MyUserProxy(get_user_model()):
>>   class Meta:
>>     proxy = True
>>
>> etc… (Which obviously can get a bit nicer by using User = get_user_model()
>> and then inheriting from that).
>
> I just don't see it as a good idea to hard-code meta.swappable to be a
> settings variable in user-visible way, without any option to use
> anything else. I see I am in minority here, so I will let this issue
> be.
>
> Review issues spotted:
>  - Queries using a swapped-out model should be prevented (probably at
> "execute sql" time).

Good idea. I haven't tried to see what it actually does; I'm guessing
you're going to get Table Does Not Exist errors. A nicer error
wouldn't hurt.

>  - For documentation: It should be suggested that the example MyUser
> should define class Meta: swappable = 'AUTH_USER_MODEL'. Otherwise it
> will be synced to the database even if it is not the chosen user model
> for the project, which is likely not wanted. Maybe AbstractBaseUser
> should define swappable = 'AUTH_USER_MODEL' so that anybody who
> inherits from that gets the setting automatically?

Ah - I think I see the problem now. The swappable Meta option isn't
visible to to end user -- ever -- unless they go spelunking in the
source code for auth.models.

If I define MyUser, I *dont'* need to define it as swappable. I just
need to define AUTH_USER_MODEL in my settings file to point at my
replacement model definition. The only place where swappable is
defined is on the base model that is being swapped out -- in this
case, auth.User.

I'm expecting that there will be *no* documentation of the swappable
option (unless, at some point in the future, we decide to make
swappable models an official feature). It exists purely to make the
internals clean, and avoid making auth.User a special case in code.

>  - Creating a "class UserDerived(User)" will not succeed if the User
> is swapped out. So, you can't make a swappable derived class.
> Documenting this limitation is IMO enough.

Documentation would be one option; another would be to treat a
reference to a swapped out base class as an abstract class. The
handling is identical in every other sense (i.e., an unsynchronized
model). Better error messages would be another option; I'm having
difficulty thinking of a case where you'd want to have a subclass of a
model that isn't being used in the rest of your system.

>  - Create model UserProxy(auth.User), swap out auth.User, and make a
> foreign key to UserProxy - you get an error that "DatabaseError:
> relation "auth_user" does not exist" instead of a mention that
> UserProxy is swapped out. The error should probably say something like
> "UserProxy derives from swapped out model auth.User - can't reference
> this model.", as telling to point to settings.AUTH_USER_MODEL in this
> case is incorrect.

Agreed -- error messages would be better.

>  - The abstract user class defines two fields: password, and
> last_login. Is the last_login really a core requirement?

last_login is at least arguable as an inclusion in the abstract base
model. We certainly *could* drop it from the list of requirements. The
reason to include it is so that all the 'user token' code works -- so
all the password reset views et al work as expected.

An alternative option would be to require that the user model provide
an implementation of a "login_timestamp" attribute (just like the
get_full_name and get_short_name requirements).

The last option -- make last_login completely optional, but document
the fact that the password reset views require the existence of the
last_login attribute.

>  - Assume a 3rd party developer was going to use the swappable Meta
> attribute. The developer provides a couple of different swappable
> implementations to use, each defining swappable = 'MY_SETTING'.
> However, by default settings.MY_SETTING is None, and thus each of
> these models will be synced into the DB. How does the 3rd party
> developer designate the default implementation? For auth.user this is
> easy, as global_settings can contain the default setting. A 3rd party
> developer doesn't have this option. (This one isn't important for the
> auth.User case, only for making this feature someday publicly
> available).

If MY_SETTING isn't defined, all the code I've written should be
assuming that the model isn't swapped out (i.e., it's effectively
getattr(setti

Re: Draft branch: Swappable User models in contrib.auth

2012-06-07 Thread Anssi Kääriäinen
On Jun 7, 11:57 am, Florian Apolloner  wrote:
> Hi,
>
> On Wednesday, June 6, 2012 4:32:02 PM UTC+2, Anssi Kääriäinen wrote:
>
> > Still, yet another API idea: [snip]
>
> Then, Model.__new__ will replace the SwappableUser class with the
>
> > swapped in class. The 'swappable' in model.Meta tells which concrete
> > model implementation to use.
>
> I'd rather not dynamically replace models. The system proposed by Russell
> is clean and requires no extra magic. The only thing which might look a bit
> odd is inheriting from a swapped model, eg like:
>
> class MyUserProxy(get_user_model()):
>   class Meta:
>     proxy = True
>
> etc… (Which obviously can get a bit nicer by using User = get_user_model()
> and then inheriting from that).

I just don't see it as a good idea to hard-code meta.swappable to be a
settings variable in user-visible way, without any option to use
anything else. I see I am in minority here, so I will let this issue
be.

Review issues spotted:
  - Queries using a swapped-out model should be prevented (probably at
"execute sql" time).

  - For documentation: It should be suggested that the example MyUser
should define class Meta: swappable = 'AUTH_USER_MODEL'. Otherwise it
will be synced to the database even if it is not the chosen user model
for the project, which is likely not wanted. Maybe AbstractBaseUser
should define swappable = 'AUTH_USER_MODEL' so that anybody who
inherits from that gets the setting automatically?

  - Creating a "class UserDerived(User)" will not succeed if the User
is swapped out. So, you can't make a swappable derived class.
Documenting this limitation is IMO enough.

  - Create model UserProxy(auth.User), swap out auth.User, and make a
foreign key to UserProxy - you get an error that "DatabaseError:
relation "auth_user" does not exist" instead of a mention that
UserProxy is swapped out. The error should probably say something like
"UserProxy derives from swapped out model auth.User - can't reference
this model.", as telling to point to settings.AUTH_USER_MODEL in this
case is incorrect.

  - The abstract user class defines two fields: password, and
last_login. Is the last_login really a core requirement?

  - Assume a 3rd party developer was going to use the swappable Meta
attribute. The developer provides a couple of different swappable
implementations to use, each defining swappable = 'MY_SETTING'.
However, by default settings.MY_SETTING is None, and thus each of
these models will be synced into the DB. How does the 3rd party
developer designate the default implementation? For auth.user this is
easy, as global_settings can contain the default setting. A 3rd party
developer doesn't have this option. (This one isn't important for the
auth.User case, only for making this feature someday publicly
available).

> > About the ORM capabilities of the interface: It seems there can not be
> > any assumptions about the swapped in model here: for example
> > SomeModel.filter(user__is_staff=True) or
> > SomeModel.order_by('user__lastname', 'user__firstname') works
> > currently, but there are no such lookups available for the interface.
> > Maybe there should be some way to order by "full_name" and
> > "short_name" at least. But, this gets us quickly to virtual fields or
> > virtual lookups territory...
>
> Imo it's fine if we require some fields on a Usermodel to be compatible
> with admin and friends. (eg a first/last_name field which is nullable [or
> not required in the form validation sense] shouldn't hurt anyone, the admin
> could check if the field is filled and if not display something else like
> the username).

Admin is actually somewhat easy to make work re the ordering, because
in there you can use get_full_name.admin_order_field =
'somemodelfield'. This doesn't work outside Admin. This isn't a major
issue, it prevents things like ordering comments on the commenter's
"get_short_name" output. Even then, this is only an issue for reusable
code - in your project you know the concrete user model you have in
use, and can thus use the specific lookups your model has.

 - Anssi

-- 
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.



Re: Draft branch: Swappable User models in contrib.auth

2012-06-07 Thread Florian Apolloner
Hi,

On Wednesday, June 6, 2012 4:32:02 PM UTC+2, Anssi Kääriäinen wrote:
>
> Still, yet another API idea: [snip]
>   
>
Then, Model.__new__ will replace the SwappableUser class with the 
> swapped in class. The 'swappable' in model.Meta tells which concrete 
> model implementation to use.
>

I'd rather not dynamically replace models. The system proposed by Russell 
is clean and requires no extra magic. The only thing which might look a bit 
odd is inheriting from a swapped model, eg like:

class MyUserProxy(get_user_model()):
  class Meta:
proxy = True

etc… (Which obviously can get a bit nicer by using User = get_user_model() 
and then inheriting from that).
 
>
> About the ORM capabilities of the interface: It seems there can not be 
> any assumptions about the swapped in model here: for example 
> SomeModel.filter(user__is_staff=True) or 
> SomeModel.order_by('user__lastname', 'user__firstname') works 
> currently, but there are no such lookups available for the interface. 
> Maybe there should be some way to order by "full_name" and 
> "short_name" at least. But, this gets us quickly to virtual fields or 
> virtual lookups territory... 
>

Imo it's fine if we require some fields on a Usermodel to be compatible 
with admin and friends. (eg a first/last_name field which is nullable [or 
not required in the form validation sense] shouldn't hurt anyone, the admin 
could check if the field is filled and if not display something else like 
the username).

Cheers,
Florian

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/3yOTO--OzlkJ.
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.



Re: Draft branch: Swappable User models in contrib.auth

2012-06-06 Thread Anssi Kääriäinen
On Jun 6, 9:20 am, Russell Keith-Magee 
wrote:
>  wrote:
> > Understood & agreed (the "this model is dynamic made explicit" part
> > seems really important specifically).
>
> > I am afraid of the hard-coding of meta.swappable must be 'SOME_VAR'
> > which then references settings.SOME_VAR, and that this is made part of
> > the public API by the error messages. I would imagine that after app-
> > loading refactor one would make the swappable an app-level constant,
> > but the use of settings.AUTH_USER_MODEL directly in the code makes
> > this change backwards incompatible. Any chance of making what the
> > "swappable" contains more abstract? Something like suggesting making
> > foreign keys point to auth_user_ref() instead of
> > settings.AUTH_USER_MODEL.
>
> > Another idea would be to change the "swappable" to contain a method
> > reference, and then hint in the foreign key error message that "point
> > to User._meta.swappable() instead". (Or, make that Model property, so
> > that you could say to point to User.swapped_by instead, and
> > User.swapped_by would contain the real reference by checking where
> > User._meta.swappable points to).
>
> I can see the problem you're driving at, but I'm not sure it will
> actually be a problem in practice.
>
> Of course, it's impossible to know for sure without knowing the final
> App-refactor API, but based on the most recent discussions, the idea
> is to define a class that defines the App. I imagine that swappable
> models would be a part of this definition -- something like:
>
> auth_app = App(
>    …
>    swappable_models = {
>       'User': 'myauth.MyUser'
>    })
>
> The exact syntax may be different, but the point should be clear --
> the App provides the point where the substituted User model can be
> configured, replacing the need for an AUTH_USER_MODEL setting.
>
> If this is the case, the requirement for "Meta: swappable" reduces
> from needing to name a specific setting, to just providing a boolean
> that defines the fact that the App is allowed to accept overrides.
> Conveniently, 'AUTH_USER_MODEL' (or any other string value) evaluates
> as True, so AUTH_USER_MODEL will be a slightly non-sensical value, but
> a perfectly legal on. It also means that the app can exist in both
> worlds (a settings-overridden model, and an App-defintion overridden
> model. There's some prioritisation logic required there, but thats a
> relatively minor detail). Long term, the syntax can reduce to 'class
> Meta: swappable=True'.

There is still something to not like about the "swappable is a
settings variable" system. Specifically, I am afraid of the fact that
the settings.AUTH_USER_MODULE will be spread all over user code, and
will thus be hard to deprecate. In addition, there is the possibility
some users might want to use another system than settings (like Andrew
Ingram's mention of Oscar). Maybe the settings variable is the
simplest thing that works.

Still, yet another API idea:

class SwappableUser(models.Model):
class Meta:
swappable = somemethod
# for example "lambda: getattr(settings, 'AUTH_USER_MODULE')

class User(models.Model):
class Meta:
swaps = 'auth.SwappableUser'

class AdvancedUser(models.Model):
class Meta:
 swaps = 'auth.SwappableUser'

in settings.py:
AUTH_USER_MODULE = 'auth.AdvancedUser'

Then, Model.__new__ will replace the SwappableUser class with the
swapped in class. The 'swappable' in model.Meta tells which concrete
model implementation to use. The "swaps" argument tells that this
model is meant as a swap-in for 'auth.SwappableUser'. The "swap-in"
models would be directly usable only when they happen to be configured
to be the chosen swap-in model (thus, ForeignKey(User) would still
work as long as the AUTH_USER_MODULE would be set to 'auth.User'). If
trying to use a swap-in model which isn't chosen, you would get a
validation error.

The user could use SwappableUser with the knowledge (through naming)
that it might be something else than the default user model. This
would be the user code:

from django.contrib.auth.models import SwappableUser

class MyObj(models.Model):
user = models.ForeignKey(SwappableUser)

> > As for the User model as an ORM object - what lookups can be assumed
> > to exist? It seems the only requirement is that it has a numeric
> > primary key called 'id', otherwise there isn't anything that can be
> > assumed of it?
> However, if your requirement is to work with Admin, there are a couple
> more requirements. I *think* the minimum requirement is a definition
> for the following:
>
>  * get_full_name
>  * get_short_name
>  * __unicode__
>  * has_perm
>  * has_module_perms
>  * is_staff
>  * is_active

What is the format of "perm" for has_perm? I guess it is the
app_label.permission_code, instead of "write", "modify" etc. Maybe
there is no way to change this now, but the app_label.permission_code
will make it somewhat hard to write generic "this user has view
permissions to all o

Re: Draft branch: Swappable User models in contrib.auth

2012-06-06 Thread Andrew Ingram
On 4 June 2012 16:12, Russell Keith-Magee  wrote:
>  * The swapping mechanic is set up using a new Meta option on models
> called 'swappable' that defines the setting where an alternate model
> can be defined. Technically, the swappable option *could* be used for
> any model; however, I'm not proposing that we actually document this.
> I've implemented it as a generic approach purely to make the internals
> cleaner -- mostly to avoid needing to make references to auth.User in
> the model syncdb code, and to make testing possible (i.e., we can do
> validation tests on a dummy 'swappable' model, rather than trying to
> munge a validation test for auth.User specifically).

I like the idea of a 'swappable' option, but I can see some potential
issues with the implementation. I'm one of the developers of Oscar
(https://github.com/tangentlabs/django-oscar/) and providing a clean
method to for overriding models has been a major pain point. One of
our key requirements is that any model in Oscar may be overridden, to
that end every model has both abstract and concrete versions (much
like your implementation of AbstractBaseUser and User).

Our current way of handling overrides is for every reference to a
model in Oscar to use get_model rather than the explicit classname.
But this does end up causing some ugly things like this:

from oscar.apps.catalogue.abstract_models import AbstractProduct

class Product(AbstractProduct):
# stuff

from oscar.apps.catalogue.models import *


Issues:
1) The override model HAS to have the same name as the default model,
otherwise get_model('catalogue', 'Product') won't work.
2) We have to import all the remaining default models after we declare
our overrides. But this only works because Django's model metaclass
prevents the default Product replacing the one we've just defined. I
don't like this because it's a little bit magic.
3) You have to remove Oscar's version of the app from INSTALLED_APPS
and replace it with your own. Actually, technically you don't. If you
leave Oscar's app installed but put your own one ('foo.catalogue') in
front of it, you can even get rid of the nasty import * thing - but
again, more magic. (Aside: you can actually use this approach already
to override Django's User model, because the metaclass means any
references to Django's User will be replaced with references to your
own. )

I had investigated using a class decorator to handle overrides:

@replace_model('catalogue.Product')
class MyProduct(AbstractProduct):
# foo

But this got seriously complicated because the metaclass modifies the
class before the decorator can be applied, so I was looking into ways
to sever all the ties with the app cache before I went insane and gave
up.

Back to my main points... Your swappable option would solve quite a
lot, in the case of the User model it's ideal. But I'm concerned that
if people start using it more widely we'd end up having dozens of new
settings that would get quite silly in the case of a large project
like Oscar. I think it's important that overrides can be defined in
the settings file, but I'd also like to see it possible at model
definition time, either using a decorator (like above) or a Meta
option like 'replaces'. The risk, of course, is that it means any
third-party app could override any other model without you necessarily
being aware of it, not sure how this would be mitigated.

If I've not made much sense let me know, I've always found it hard to
articulate on this particular topic.


Regards,
Andrew Ingram

-- 
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.



Re: Draft branch: Swappable User models in contrib.auth

2012-06-05 Thread Russell Keith-Magee
On Tue, Jun 5, 2012 at 9:00 PM, Anssi Kääriäinen
 wrote:
> Understood & agreed (the "this model is dynamic made explicit" part
> seems really important specifically).
>
> I am afraid of the hard-coding of meta.swappable must be 'SOME_VAR'
> which then references settings.SOME_VAR, and that this is made part of
> the public API by the error messages. I would imagine that after app-
> loading refactor one would make the swappable an app-level constant,
> but the use of settings.AUTH_USER_MODEL directly in the code makes
> this change backwards incompatible. Any chance of making what the
> "swappable" contains more abstract? Something like suggesting making
> foreign keys point to auth_user_ref() instead of
> settings.AUTH_USER_MODEL.
>
> Another idea would be to change the "swappable" to contain a method
> reference, and then hint in the foreign key error message that "point
> to User._meta.swappable() instead". (Or, make that Model property, so
> that you could say to point to User.swapped_by instead, and
> User.swapped_by would contain the real reference by checking where
> User._meta.swappable points to).

I can see the problem you're driving at, but I'm not sure it will
actually be a problem in practice.

Of course, it's impossible to know for sure without knowing the final
App-refactor API, but based on the most recent discussions, the idea
is to define a class that defines the App. I imagine that swappable
models would be a part of this definition -- something like:

auth_app = App(
   …
   swappable_models = {
  'User': 'myauth.MyUser'
   })

The exact syntax may be different, but the point should be clear --
the App provides the point where the substituted User model can be
configured, replacing the need for an AUTH_USER_MODEL setting.

If this is the case, the requirement for "Meta: swappable" reduces
from needing to name a specific setting, to just providing a boolean
that defines the fact that the App is allowed to accept overrides.
Conveniently, 'AUTH_USER_MODEL' (or any other string value) evaluates
as True, so AUTH_USER_MODEL will be a slightly non-sensical value, but
a perfectly legal on. It also means that the app can exist in both
worlds (a settings-overridden model, and an App-defintion overridden
model. There's some prioritisation logic required there, but thats a
relatively minor detail). Long term, the syntax can reduce to 'class
Meta: swappable=True'.

> As for the User model as an ORM object - what lookups can be assumed
> to exist? It seems the only requirement is that it has a numeric
> primary key called 'id', otherwise there isn't anything that can be
> assumed of it?

The short answer is that there aren't any *hard* requirements. The
only time requirements come into the picture is if you want to
minimise the amount of additional code you want to write.

If you want to integrate with a minimum of effort, the only
requirement that exists is that your model must provide a unique
string-based identifier field (e.g. username), a password field, and a
last login timestamp. The latter two you get for free from the
AbstractBaseUser class; the unique identifier field must be provided
as part of your model definition. It doesn't matter what the unique
identifier field is called -- it just needs to exist, and if it's not
called username, you need to define USERNAME_FIELD as a class
attribute. Strictly, the login timestamp isn't required, but it's used
for password reset tokens, so I figured it makes sense to include it
by default.

I've done some further checking, and the primary key restriction I
wrote about previously doesn't actually exist. As long as your primary
key can be stored as a string in the session, the default auth backend
will work.

As your model gets less like the out-of-the-box auth.User model, your
workload increases. Depending on your exact User model, you may need
to define forms to create/update a user, and define a ModelAdmin for
your custom User model. I still need to look into how much of these
forms can be made even easier to reuse.

If your User model requires something more than 1 identifier field
(e.g., username and domain), you're still ok -- you just need to
define your own Authentication forms and auth backend.

So - in summary, it really should be a case of "Any User model will
do"; it's just a matter of how much extra work needs to be done.

However, if your requirement is to work with Admin, there are a couple
more requirements. I *think* the minimum requirement is a definition
for the following:

 * get_full_name
 * get_short_name
 * __unicode__
 * has_perm
 * has_module_perms
 * is_staff
 * is_active

However, I need to do a full audit for this list to make sure I
haven't missed anything. The permissions in particular are
interesting, because they don't need to be "auth.Permission" objects
-- you just need to be able to answer True/False for a string name.
This means you can handle permissions using Django's approach if you
want, but any other approac

Re: Draft branch: Swappable User models in contrib.auth

2012-06-05 Thread Anssi Kääriäinen
On Jun 5, 2:44 pm, Russell Keith-Magee 
wrote:
> Two significant reasons:
>
> Firstly, if we use the Meta attribute approach, we can raise a
> specific validation error when the user has an app with a model that
> references auth.User directly, and User has been swapped out. This is
> mostly useful as a migration trigger -- as soon as you change
> AUTH_USER_MODEL, you'll get a bunch of errors about all the apps that
> haven't been updated and will break as a result. This catches as a
> development-time validation error the most-likely set of problems that
> will occur when swappable User models start getting into the wild.
> Using the code you've provided, changing AUTH_USER_MODEL would
> silently fail at some point in production, because auth.User still
> "exists", but is now a very different beast.
>
> Secondly, there's some avoidance of nightmares from Django's past.
> Using the approach you describe, you're making auth.User a dynamic
> model reference -- the model that is referred to by auth.User is
> changed at runtime, based on the value of a setting. This means that
> just because you have a auth.User object, doesn't mean you can know
> for sure anything about it.
>
> This is somewhat comparable to the bad old "magic removal" days of
> Django. A lot of the problems we experienced back then were caused by
> the fact that you couldn't be certain that a model existed, or if it
> did exist, that it was the model that you thought it was, because
> other mechanisms in the load sequence would swap out models/modules,
> and/or move them somewhere else. This is a set of headaches that I'd
> rather not revisit.
>
> There's a scaled back alternative of what you describe -- essentially,
> where you only have the "else" clause from your sample code. This is
> slightly better, but still leads to the situation where the failure
> mode is an import failing, rather than a helpful message that points
> at the model that you shouldn't be referencing.
>
> By using the swappable approach, a model reference is always exactly
> the model that you've imported, unless you've got the reference
> through a get_user_model() method call, and other validation
> mechanisms work out whether that model reference is legal. At the end
> of the day, these validation mechanisms aren't really that complex,
> either. If you look at the additions to the validation logic, they're
> essentially just "if f.rel.to.swapped, make noise".
>
> The only other complex part is the synchronisation code, but even that
> is just layering on top of code that's already there. Abstract, proxy
> and non-managed models all fall in the group of "importable, but not
> synchronisable" models; swappable just adds one more to that list.
>
> There are two other lesser reasons that I've taken this approach.
>
> Firstly, I'm not wild about module level if statements. For me, a
> module should be a container of logic, not an executable unit in
> itself. I appreciate that there are sometimes valid reasons to make
> module level code executable, and at some level a def statement is
> just the execution of a declaration statement, but to my mind it's
> worth keeping a clear distinction. A good practical example of why
> this matters is testing -- module level if statements can only be
> (easily) tested at time of import, so you really only get one chance
> to test that code.
>
> Secondly, I don't like special cases, and a swappable Meta attribute
> -- even if it's a stealth option -- means that the underlying
> mechanism is generic, and doesn't require any User-specific references
> anywhere. Again, testing is a good reason for why this matters. We can
> test that the mechanics of swappable models work as expected with a
> suite of non-User swapped/unswapped models. If the mechanism was User
> specific, we'd only be able to test using User, but the swappability
> would be determined as an import-time definition, so we'd only be able
> to test one configuration per test run (unless we got into some messy
> reload/app cache flushing).
>
> As a side effect, it also means that if we were to ever 'bless'
> swappable models as an official feature, we just need to document what
> we've already got. In the interim, we have a hidden feature that
> adventurous members of the community can start playing with. As an
> unofficial feature, we're not obligated to support or maintain it, but
> it gives us a way to test out the waters to see whether the idea
> should be encouraged as broader practice.
>
> This approach to API development has precedent in Django. For example,
> shadow reverse attributes (i.e, related_name="+foo") existed as an
> undocumented feature for some time before we decided that they weren't
> actually harmful and added them as official API.

Understood & agreed (the "this model is dynamic made explicit" part
seems really important specifically).

I am afraid of the hard-coding of meta.swappable must be 'SOME_VAR'
which then references settings.SOME_VAR, and that

Re: Draft branch: Swappable User models in contrib.auth

2012-06-05 Thread Russell Keith-Magee
On Tue, Jun 5, 2012 at 3:56 AM, Anssi Kääriäinen
 wrote:
> On Jun 4, 6:12 pm, Russell Keith-Magee 
> wrote:
>>  * The swapping mechanic is set up using a new Meta option on models
>> called 'swappable' that defines the setting where an alternate model
>> can be defined. Technically, the swappable option *could* be used for
>> any model; however, I'm not proposing that we actually document this.
>> I've implemented it as a generic approach purely to make the internals
>> cleaner -- mostly to avoid needing to make references to auth.User in
>> the model syncdb code, and to make testing possible (i.e., we can do
>> validation tests on a dummy 'swappable' model, rather than trying to
>> munge a validation test for auth.User specifically).
>
> The "swappable" meta attribute part of the patch raises a question:
> would the following pattern work instead of the meta attribute:
> # in auth/models.py
>
> if settings.AUTH_USER_MODEL:
>    User = get_model(AUTH_USER_MODEL)
> else:
>    class User(models.Model):
>        # the traditional auth-user model definition here
>
> If I understand the patch correctly the "swappable" Meta option
> basically just removes the model from the app-cache. This means the
> model will not be synced or validated. In addition you can't make
> foreign keys to the swapped out model due to other changes in the
> patch. Still, the auth.User model exists, and is importable.
>
> The idea above gets rid of the User model 100% if
> settings.AUTH_USER_MODEL is set. In runtime it never exists at any
> level. It is very simple in this regard, and of course the
> implementation is simple, too.
>
> Is there some design consideration which prevents the use of the above
> mentioned idea?

Two significant reasons:

Firstly, if we use the Meta attribute approach, we can raise a
specific validation error when the user has an app with a model that
references auth.User directly, and User has been swapped out. This is
mostly useful as a migration trigger -- as soon as you change
AUTH_USER_MODEL, you'll get a bunch of errors about all the apps that
haven't been updated and will break as a result. This catches as a
development-time validation error the most-likely set of problems that
will occur when swappable User models start getting into the wild.
Using the code you've provided, changing AUTH_USER_MODEL would
silently fail at some point in production, because auth.User still
"exists", but is now a very different beast.

Secondly, there's some avoidance of nightmares from Django's past.
Using the approach you describe, you're making auth.User a dynamic
model reference -- the model that is referred to by auth.User is
changed at runtime, based on the value of a setting. This means that
just because you have a auth.User object, doesn't mean you can know
for sure anything about it.

This is somewhat comparable to the bad old "magic removal" days of
Django. A lot of the problems we experienced back then were caused by
the fact that you couldn't be certain that a model existed, or if it
did exist, that it was the model that you thought it was, because
other mechanisms in the load sequence would swap out models/modules,
and/or move them somewhere else. This is a set of headaches that I'd
rather not revisit.

There's a scaled back alternative of what you describe -- essentially,
where you only have the "else" clause from your sample code. This is
slightly better, but still leads to the situation where the failure
mode is an import failing, rather than a helpful message that points
at the model that you shouldn't be referencing.

By using the swappable approach, a model reference is always exactly
the model that you've imported, unless you've got the reference
through a get_user_model() method call, and other validation
mechanisms work out whether that model reference is legal. At the end
of the day, these validation mechanisms aren't really that complex,
either. If you look at the additions to the validation logic, they're
essentially just "if f.rel.to.swapped, make noise".

The only other complex part is the synchronisation code, but even that
is just layering on top of code that's already there. Abstract, proxy
and non-managed models all fall in the group of "importable, but not
synchronisable" models; swappable just adds one more to that list.

There are two other lesser reasons that I've taken this approach.

Firstly, I'm not wild about module level if statements. For me, a
module should be a container of logic, not an executable unit in
itself. I appreciate that there are sometimes valid reasons to make
module level code executable, and at some level a def statement is
just the execution of a declaration statement, but to my mind it's
worth keeping a clear distinction. A good practical example of why
this matters is testing -- module level if statements can only be
(easily) tested at time of import, so you really only get one chance
to test that code.

Secondly, I don't like special cases, and a swappable Meta

Re: Draft branch: Swappable User models in contrib.auth

2012-06-04 Thread Anssi Kääriäinen
On Jun 4, 6:12 pm, Russell Keith-Magee 
wrote:
>  * The swapping mechanic is set up using a new Meta option on models
> called 'swappable' that defines the setting where an alternate model
> can be defined. Technically, the swappable option *could* be used for
> any model; however, I'm not proposing that we actually document this.
> I've implemented it as a generic approach purely to make the internals
> cleaner -- mostly to avoid needing to make references to auth.User in
> the model syncdb code, and to make testing possible (i.e., we can do
> validation tests on a dummy 'swappable' model, rather than trying to
> munge a validation test for auth.User specifically).

The "swappable" meta attribute part of the patch raises a question:
would the following pattern work instead of the meta attribute:
# in auth/models.py

if settings.AUTH_USER_MODEL:
User = get_model(AUTH_USER_MODEL)
else:
class User(models.Model):
# the traditional auth-user model definition here

If I understand the patch correctly the "swappable" Meta option
basically just removes the model from the app-cache. This means the
model will not be synced or validated. In addition you can't make
foreign keys to the swapped out model due to other changes in the
patch. Still, the auth.User model exists, and is importable.

The idea above gets rid of the User model 100% if
settings.AUTH_USER_MODEL is set. In runtime it never exists at any
level. It is very simple in this regard, and of course the
implementation is simple, too.

Is there some design consideration which prevents the use of the above
mentioned idea?

 - Anssi

-- 
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.



Draft branch: Swappable User models in contrib.auth

2012-06-04 Thread Russell Keith-Magee
Hi all,

Following the BDFL pronouncement of a preferred option for
customisable User models in contrib.auth [1], I've just pushed a
branch to Github that contains a draft implementation [2].

It's not ready for trunk quite yet, but you can use this code to set
up a custom User model, and then log into admin with that User model,
and the effort required to do this is fairly minimal.

There isn't a whole lot by way of documentation -- all I've done is
add the documentation for the new AUTH_USER_MODEL setting, and a stub
for where the documentation about swappable User models will finally
go.

Testing is also an interesting area. I've got some tests in place for
the validation code, and for parts of the management. Widespread
testing that apps (e.g., admin) will work with a different User model
will be a bit difficult because the app cache is populated at the
start of the test run, which prohibits switching the User model later
in the suite. Any suggestions on areas where more testing is necessary
and possible are welcome.

So - how does it work? Here's a minimal example in which MyUser has a
unique, required EmailField acting as the identifier for users.
There's also a required "date_of_birth" field for every user. To
switch to using this User model:

 * Define a new "myauth" app, and put the following into your models.py file

===
from django.db import models

from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

class MyUserManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
if not email:
raise ValueError('Users must have an email address')

user = self.model(
email=MyUserManager.normalize_email(email),
date_of_birth=date_of_birth,
)

user.set_password(password)
user.save(using=self._db)
return user

def create_superuser(self, username, password, date_of_birth):
u = self.create_user(username, password=password,
date_of_birth=date_of_birth)
u.is_admin = True
u.save(using=self._db)
return u


class MyUser(AbstractBaseUser):
email = models.EmailField(verbose_name='email address',
max_length=255, unique=True)
date_of_birth = models.DateField()
is_admin = models.BooleanField(default=False)

objects = MyUserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['date_of_birth']

def get_full_name(self):
return self.email

def get_short_name(self):
return self.email

def __unicode__(self):
return self.email

# Admin required fields
def has_perm(self, perm, obj=None):
return True

def has_module_perms(self, app_label):
return True

@property
def is_staff(self):
return self.is_admin

@property
def is_active(self):
return True
===

 * Set AUTH_USER_MODEL = 'myauth.MyUser'

 * Run syncdb.

It's important that you do all this on a clean project; once you've
run syncdb, the foreign keys are already set up, and changing
AUTH_USER_MODEL will lead to hilarity.

Some implementation notes:

 * As the branch currently stands, you can log into admin with a
custom User model by doing nothing more than defining an
'admin-compatible' User model and setting AUTH_USER_MODEL.

 * The fields on MyUser are the minimum subset that I've been able to
establish in order to be "admin-compatible". The implementation of
MyUser is intentionally simple -- every user is effectively a
superuser. If you want fine-grained permissions, you'll need to
implement them.

 * The createsuperuser and changepassword management commands both
work with the designated User model.

 * The custom manager is required to make sure that the
createsuperuser management command works. Strictly, only
create_superuser is required, but create_user is an obvious utility to
have, so I've included it here.

 * I've made get_full_name() and get_short_name() part of the required
API; this follows the most practical and applicable of the suggestions
from the W3C guidelines on personal names [3].

 * USERNAME_FIELD and REQUIRED_FIELDS are constants used for
metaprogramming. For example, createsuperuser needs to ask for data
for all the required fields; these constants let you define what
createsuperuser should ask for. They're also used whenever the auth
backend needs to retrieve the User based on credentials (the backend
can't say User.objects.get(username=…), because the field may not be
called username). I'm not completely happy about the way these
constants are defined, but I also can't think of a better option,
other than top-level settings (e.g., AUTH_USER_USERNAME_FIELD).
Suggestions and opinions welcome.

 * The swapping mechanic is set up using a new Meta option on models
called 'swappable'

Re: [GSoC 2012] Enhanced contrib.auth

2012-04-04 Thread Stratos Moros
On Wed, 04 Apr 2012 19:25:26 +0300, Adrian Holovaty   
wrote:



Hi Stratos,

The core team is going to take the lead on the auth.User refactoring
-- specifically, yours truly. :-)

Given that the Summer of Code policy prohibits code contributions from
non-students (right?), I don't think the User refactoring would work
as a Summer of Code project. Sorry to break this news, as you've
clearly done a lot of preparation and thinking about the issue, but of
course we'd love to have you contribute to this particular feature
*outside* the Summer of Code.

Adrian



Ok. I'd love to contribute either way.

Thanks for the info.

--
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.



Re: [GSoC 2012] Enhanced contrib.auth

2012-04-04 Thread Adrian Holovaty
On Wed, Apr 4, 2012 at 10:16 AM, Stratos Moros  wrote:
> I'm apologizing for replying to my own post, but there are only two days
> left before GSoC's submission deadline and my proposal has received very
> little feedback.
>
> Since other proposals about contrib.auth are being discussed, I was
> wondering if mine has any merit and whether I should submit it through
> google-melange.

Hi Stratos,

The core team is going to take the lead on the auth.User refactoring
-- specifically, yours truly. :-)

Given that the Summer of Code policy prohibits code contributions from
non-students (right?), I don't think the User refactoring would work
as a Summer of Code project. Sorry to break this news, as you've
clearly done a lot of preparation and thinking about the issue, but of
course we'd love to have you contribute to this particular feature
*outside* the Summer of Code.

Adrian

-- 
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.



Re: [GSoC 2012] Enhanced contrib.auth

2012-04-04 Thread Stratos Moros
Hello,

I'm apologizing for replying to my own post, but there are only two days 
left before GSoC's submission deadline and my proposal has received very 
little feedback.

Since other proposals about contrib.auth are being discussed, I was 
wondering if mine has any merit and whether I should submit it through 
google-melange.

Thanks.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/eVNJcUUEJ1wJ.
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.



Re: [GSoC 2012] Enhanced contrib.auth

2012-03-30 Thread Stratos Moros
On Fri, 30 Mar 2012 17:35:16 +0300, Tom Evans   
wrote:


On Fri, Mar 30, 2012 at 10:39 AM, Stratos Moros   
wrote:

You can read the proposal nicely formatted here:
https://gist.github.com/8dd9fb27127b44d4e789


Hi Stratos

It's a long proposal, so this is a brain dump of bits that I find
interesting/worrisome.


Hi Tom.

I'm answering your 3 questions together because they are related to each  
other.


In my proposal, a user model represents an authentication/authorization  
scheme. This is why you have to mixin the authentication scheme directly  
in the model. All other information, such as first_name, last_name etc.  
should live in the user's profile.


The idea isn't to remove custom profiles, but to let developers control  
where they're used. The example I provided about adding custom profiles  
was rather bad. The way I expect most developers to add a fields to a user  
is:


class CustomUser(SomeMixins):
profile = models.ForeignKey(UserPorfile)

This way you can allow your frontend users to log in with, say, either  
with username & password or openid and have a single profile between them,  
while allowing your backend users to login with credentials from an LDAP  
server and have a different profile for them.


This is why authentication backends are deprecated. If you can't specify  
which authentication mechanism is used for each user model, you can't  
easily accomplish the above scenario. You would have to have a single  
table to represent the two different profiles and you would somehow make  
sure that a user trying to log in with facebook doesn't go through the  
LDAP server.


This is also why the identity in the user model is a method and not a  
field. If you want a single user to be authenticated in multiple ways, you  
can override the identity method and return the same value.


Perhaps the profile field should be made part of the user contract, but  
this would be an annoyance in cases where you don't want to store any  
additional information about the users, but use them only for  
authorization purposes (ie. I don't care about his info, I just want to  
know if he can access this page).


Having login and logout be part of the user model was one of the things  
that I wasn't sure about. The reason I put them in the user model is to  
decouple the whole process from the session. This way an authentication  
scheme that doesn't want to use the session to store a logged in user can  
do so. The common case would obviously be to store them in the session, so  
I included the SessionAuthenticationMixin.


The same goes for authorization. Inheriting from a mixin implementing the  
authorization contract would probably add a foreign key to the table  
storing the permissions plus a few methods to query it. This way you can  
handle different user models' permissions in completely different ways.


Thanks for the feedback. I hope I've answered your questions.

--
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.



Re: [GSoC 2012] Enhanced contrib.auth

2012-03-30 Thread Tom Evans
On Fri, Mar 30, 2012 at 10:39 AM, Stratos Moros  wrote:
> You can read the proposal nicely formatted here:
> https://gist.github.com/8dd9fb27127b44d4e789

Hi Stratos

It's a long proposal, so this is a brain dump of bits that I find
interesting/worrisome.

I'm sure you've followed the recent threads on the topic. The (wildly)
different solutions garnered from those long threads are all listed on
this wiki page:

  https://code.djangoproject.com/wiki/ContribAuthImprovements

I don't think this proposal ties in with any of them? Your proposal
involves multiple user models, whilst none of them do.

Login:

Where have auth backends gone in your plan? Why do user objects have a
login method, login should be distinct from user objects, otherwise
login is coupled to a user object, and you cannot log in to the same
user using different authentication techniques.

It is common these days to provide multiple ways of authenticating to
your users, if I authenticate by smartcard, user/password, Facebook
auth, SAML federation, or a "remember me" signed auth cookie, I should
still get the same user object. The choice of authentication is
irrelevant.

More to the point, it should be *my* choice. Forcing authentication
into the user model removes that choice, or requires us to have N user
models per user, one per auth method.


Authentication mixins:

This goes to the above point; if I have to mixin an authentication
class to my user object (adding the required login() + others
methods), it means I can only have one authentication mechanism for a
particular user model.


Deprecating user profiles:

The purpose of user profiles is to provide a place for a pluggable app
to store its own information about a user. Adding a pluggable app
should not mean having to add fields to your user model, but with no
user profiles, that's what is suggested.

Once you have a significant number of pluggable apps, you could have a
User model with a crazy number of fields - I can envisage scenarios
where you have over 100 fields. This makes doing anything with the
user model slower. Furthermore, storage for each field is now required
for every user, whilst with a pluggable profile, it would only exist
if the user utilizes that app.

Cheers

Tom

-- 
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.



[GSoC 2012] Enhanced contrib.auth

2012-03-30 Thread Stratos Moros
You can read the proposal nicely formatted here:  
https://gist.github.com/8dd9fb27127b44d4e789


GSoC 2012 Proposal - enhanced contirb.auth
==

Hello, my name is Stratos Moros and I am a Computer Science student in the  
University of Piraeus in Greece.


I would like to participate in Google Summer of Code with Django, working  
on an enhanced contrib.auth.


Goals
-

-   Long term solution

	The proposed replacement doesn't aim at just improving some of the  
current limitations of contrib.auth (e.g. increasing the email field  
size), but at providing a long term solution.


-   Backwards compatibility

	The new contrib.auth will be 100% backwards compatible with the current  
implementation. Developers updating their existing Django installation  
will have the same features available, without having to update their code  
or undergo a database migration.


-   Separation of concerns

	The concepts of identity, authentication and authorization should not be  
tightly coupled by default. Developers will be able to mix and match  
schemes if they want, or use a more integrated approach otherwise.


-   Extensibility

	It's impossible to cover all existing and future authentication /  
authorization schemes. Developers who have needs that aren't covered by  
Django should be able to extend contrib.auth by writing their own or using  
third party user models. Other apps that need to interact with users (e.g.  
a commenting app) will be able to interact with them without knowing the  
specific implementation.


-   Batteries included

	Developers will not be required to implement their own authentication or  
authorization schemes for the common cases. Contrib.auth will have one or  
more built in user models ready for production.


-   Admin compatibility

	Contrib.admin is one of the things that make Django great. It should be  
easy for developers to make their user models accessible through the admin  
interface.


Terminology
---

In order to distinguish between Django's users, a website's users and the  
proposed concept of a user, the terms "developer", "visitor" and "user"  
are used respectively.



Implementation
--

The new contrib.auth will serve three primary functions:

-   Assist developers in writing custom user models.
-   Provide built in user models.
-   Provide a way for developers to interact generically with user models.

The new contrib.auth will allow developers to specify multiple user  
models. A new setting will be introduced called `USER_MODELS` which will  
be a tuple of strings. Each string's format will be `'%(app).%(model)'`,  
similarly to how `AUTH_PROFILE_MODULE` is currently defined. This setting  
will look something like:


USER_MODELS = (
'auth.EmailUser',
'myapp.CustomUser',
# ...
)

### Separation of concerns and the user contract

A user model will be a regular model that fulfills a predefined contract.  
Developers will be able to write their own user models in their  
applications and register them through the `USER_MODELS` setting. Any  
model that fulfills the user contract and is specified in `USER_MODELS`  
will be considered a valid user model. The contract will be subdivided in  
three subcontracts that will be concerned with identity, authentication  
and authorization.


 Identity

The identity contract will answer the "who are you" question for a user  
model. This could be anything from a twitter handle to a biometric  
identifier, or anything else that can uniquely identify a user in a user  
model. To fulfill the identity contract the user model will have to:


-   Implement an `identity` method.

	This method must return a string that uniquely represents a user in a  
user model.


-   Implement a `get_by_identity` method on the model's default manager.

	This method must accept a string representing a user, as returned by the  
`identity` method, and return the either a user object, if it finds one,  
or `None` otherwise.


-   Implement a `__unicode__` method.

	This method must return a string representation of a user that is  
suitable for displaying on the frontend. This will not be required to be  
unique across all users in a user model.


 Authentication

The authentication contract will be concerned with verifying that the user  
is indeed who he claims to be. Again, this could be anything from a  
password to a hardware dongle. To fulfill the authentication contract the  
user model will have to:


-   Implement an `is_authenicated` method.

	This method must accept a request. Contrary to the current  
implementation, the `is_authenticated` method will not always return  
`True`. It is up to the implementation to decide whether the user is  
a

[GSoC 2012] Questions regarding the contrib.auth project

2012-03-24 Thread Florian Apolloner
Hi,

I would like to participate in this years Google Summer of Code. As a 
project I would like to tackle Django's beloved auth.User model. The topic 
has been discussed quite extensively the last days so I won't repeat 
everything here again.

My prefered solution would be "Solution 3" from the ContribAuthImprovements 
wiki page [1] since it does solve the problem in the most generic way (and 
I think we should eat our own food once we land app-refactor). Given the 
current discussions I have the feeling that the discussion is moving toward 
this solution too -- but I'd like to be sure, so I'd like to see consensus 
between the core devs (or a BDFL ruling) before I submit a proposal to 
Google.

Thx & Cheers,
Florian

1: https://code.djangoproject.com/wiki/ContribAuthImprovements

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/Ex7fJVg-9_kJ.
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.



Re: Security - contrib.auth hashing

2010-12-14 Thread Bret W
On Tuesday, July 20, 2010 2:23:52 PM UTC-4, Craig Younkins wrote:
>
> Maybe. The issue in my mind with bcrypt and scrypt is that they are not 
> validated by NIST or NSA, unlike SHA-2. Blowfish was examined by NIST for 
> the AES competition but to my knowledge the use of hashing has not been. 
> SHA-2 was developed by NSA and is recommended by NIST (
> http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html).
>
> That being said, I'm asking the opinion of a few other folks at OWASP and 
> trying to get a consensus of 1 sentence to summarize how passwords should be 
> stored. In my mind, this sentence should be "Use a SHA-2 algorithm with a 
> 64-bit random salt and 1000 iterations," but this statement is my own and 
> does not necessarily reflect the views of OWASP. I'll post here 
> with developments.
>

I wanted to follow up on this discussion to see if any further thought had 
been given to using bcrypt.

With the recent Gawker hacking incident, there has been another round of 
discussion happening regarding best practices for securely storing 
credentials, and from the discussions I've seen at Hacker News, those in the 
know are still recommending bcrypt.

I am not a security researcher or a cryptographer, so I don't have much to 
add to this conversation, other than that I want to be sure that Django's 
following the best practices put forth by security professionals.

Backward compatibility is definitely an issue to be addressed, and it's not 
in the scope of this message to do so, but I would like to say that some 
changes worth ugly fixes. It's obvious that it's not possible to rehash 
passwords that application developers don't have, so it seems likely that 
there's going to need to be a hack to support an old and a new hashing 
scheme for a couple of versions of Django. I believe most developers would 
be accepting of a little interim cruft if it meant a more secure product in 
the long term.

While we're on the subject of security, have the security-related pieces of 
Django ever undergone a security audit? I remember Simon W. asking for a 
code review of his signed-cookie implementation 
(https://groups.google.com/forum/#topic/django-developers/KX6LIgBvfzo), and 
I now see that Jacob didn't feel that a security audit was worthwhile, given 
what the DSF can afford and the implications for peer review. If 
contrib.auth hasn't been reviewed by a security expert, I'd like to suggest 
that someone investigate the possibility of having it reviewed. Security, 
and specifically cryptography, is one area of computing that requires tons 
of expertise. Even with many eyeballs, it's hard to be certain that a 
salient detail wasn't overlooked. That being said, I'm not close to the 
framework development process, and I don't know what's been done in the past 
or who's been consulted.

Bret

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: Bug with testing framework when not using contrib.auth

2010-11-06 Thread Yo-Yo Ma
Ok, I finally created a ticket for this: 
http://code.djangoproject.com/ticket/14632

On Nov 3, 5:26 pm, Russell Keith-Magee 
wrote:
> On Thu, Nov 4, 2010 at 3:58 AM, Yo-Yo Ma  wrote:
> > Ok, thanks. I'm using CookieStorage for messages, so the issue may not
> > reside only with legacy storage. Should I create a ticket for this?
>
> If you'd be so kind.
>
> 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-develop...@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.



Re: Bug with testing framework when not using contrib.auth

2010-11-03 Thread Russell Keith-Magee
On Thu, Nov 4, 2010 at 3:58 AM, Yo-Yo Ma  wrote:
> Ok, thanks. I'm using CookieStorage for messages, so the issue may not
> reside only with legacy storage. Should I create a ticket for this?

If you'd be so kind.

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-develop...@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.



Re: Bug with testing framework when not using contrib.auth

2010-11-03 Thread Yo-Yo Ma
Ok, thanks. I'm using CookieStorage for messages, so the issue may not
reside only with legacy storage. Should I create a ticket for this?


On Nov 3, 6:11 am, Russell Keith-Magee 
wrote:
> On Wed, Nov 3, 2010 at 1:43 PM, Yo-Yo Ma  wrote:
> > I've been using CookieStorage (for less DB usage). Us that frowned
> > upon nowadays, in favor of the DB backend?
>
> There is no "db" backend for messages, there is only a "legacy"
> backend, which, as the name suggests, is for legacy applications --
> applications that used Django's older (pre 1.2) user-messages table
> and need to migrate to using the Django-1.2 messages framework.
>
> There is a db backend for sessions, but the choice of session backend
> is independent of the choice of messages backend.
>
> The "right" solution is entirely up to your own requirements; Django
> doesn't discourage the use of any of the options it provides, other
> than to say that the legacy backend only exists for backwards
> compatibility purposes.
>
> 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-develop...@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.



Re: Bug with testing framework when not using contrib.auth

2010-11-03 Thread Russell Keith-Magee
On Wed, Nov 3, 2010 at 1:43 PM, Yo-Yo Ma  wrote:
> I've been using CookieStorage (for less DB usage). Us that frowned
> upon nowadays, in favor of the DB backend?

There is no "db" backend for messages, there is only a "legacy"
backend, which, as the name suggests, is for legacy applications --
applications that used Django's older (pre 1.2) user-messages table
and need to migrate to using the Django-1.2 messages framework.

There is a db backend for sessions, but the choice of session backend
is independent of the choice of messages backend.

The "right" solution is entirely up to your own requirements; Django
doesn't discourage the use of any of the options it provides, other
than to say that the legacy backend only exists for backwards
compatibility purposes.

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-develop...@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.



Re: Bug with testing framework when not using contrib.auth

2010-11-03 Thread Yo-Yo Ma
BTW, my program doesn't have any issues with gangrene. I meant "a slew
of 35 errors" in my original post. Sometimes I look back at what I've
typed and it amazes me.

On Nov 2, 6:26 pm, Russell Keith-Magee 
wrote:
> On Wed, Nov 3, 2010 at 8:18 AM, David P. Novakovic
>
>  wrote:
> > This is certainly an artifact of the fact that messages recent started
> > supporting anonymous messages. Previously it depended on auth.
>
> > I suspect you just need to open a ticket for this.
>
> Yes - this is oversight, not intention.
>
> contrib.messages depends on contrib.auth for reasons of backwards
> compatibility, but unless you're using the legacy fallback storage
> mechanism, that dependency doesn't exist in practice. You're the first
> person to report this dependency as a practical concern.
>
> I suspect we'll need to crack out some of the new unittest2 features
> to fix this; skipping the user_messages tests unless contrib.auth is
> available.
>
> Yours,
> Russ Magee %-)
>
>
>
> > On Wed, Nov 3, 2010 at 4:43 AM, Yo-Yo Ma  wrote:
> >> I have a large application that doesn't user contrib.auth, and when I
> >> run `manage.py test` I get a slough of 35 errors, all of which are
> >> DatabaseError: no such table: auth_user (differing Tracebacks for
> >> each). I don't have any actual tests yet, just the SimpleTest that
> >> comes free in tests.py. INSTALLED_APPS is:
>
> >>    'django.contrib.sessions',
> >>    'django.contrib.messages',
> >>    'myproject.myapp',  # Plus 8 more custom apps omitted.
>
> >> With this bug, Django's testing framework is seemingly coupled to a
> >> contrib app.
>
> >> One of the Tracebacks:
>
> >> ==
> >> ERROR: test_add
> >> (django.contrib.messages.tests.user_messages.UserMessagesTest)
> >> --
> >> Traceback (most recent call last):
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\contrib
> >> \messages\tests\user_messages.py", line 13, in setUp
> >>    self.user = User.objects.create(username='tester')
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \manager.py", line 138, in create
> >>    return self.get_query_set().create(**kwargs)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \query.py", line 351, in create
> >>    obj.save(force_insert=True, using=self.db)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \base.py", line 452, in save
> >>    self.save_base(using=using, force_insert=force_insert,
> >> force_update=force_update)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \base.py", line 545, in save_base
> >>    result = manager._insert(values, return_id=update_pk, using=using)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \manager.py", line 195, in _insert
> >>    return insert_query(self.model, values, **kwargs)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \query.py", line 1490, in insert_query
> >>    return query.get_compiler(using=using).execute_sql(return_id)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
> >> \compiler.py", line 786, in execute_sql
> >>    cursor = super(SQLInsertCompiler, self).execute_sql(None)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
> >> \compiler.py", line 730, in execute_sql
> >>    cursor.execute(sql, params)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\backends
> >> \sqlite3\base.py", line 221, in execute
> >>    return Database.Cursor.execute(self, query, params)
> >> DatabaseError: no such table: auth_user
>
> >> --
> >> You received this message because you are subscribed to the Google Groups 
> >> "Django developers" group.
> >> To post to this group, send email to django-develop...@googlegroups.com.
> >> To unsubscribe from this group, send email to 
> >> django-developers+unsubscr...@googlegroups.com.
> >> For more options, visit this group 
> >> athttp://groups.google.com/group/django-developers?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "Django developers" group.
> > To post to this group, send email to django-develop...@googlegroups.com.
> > To unsubscribe from this group, send email to 
> > django-developers+unsubscr...@googlegroups.com.
> > For more options, visit this group 
> > athttp://groups.google.com/group/django-developers?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: Bug with testing framework when not using contrib.auth

2010-11-03 Thread Yo-Yo Ma
I've been using CookieStorage (for less DB usage). Us that frowned
upon nowadays, in favor of the DB backend?

On Nov 2, 6:26 pm, Russell Keith-Magee 
wrote:
> On Wed, Nov 3, 2010 at 8:18 AM, David P. Novakovic
>
>  wrote:
> > This is certainly an artifact of the fact that messages recent started
> > supporting anonymous messages. Previously it depended on auth.
>
> > I suspect you just need to open a ticket for this.
>
> Yes - this is oversight, not intention.
>
> contrib.messages depends on contrib.auth for reasons of backwards
> compatibility, but unless you're using the legacy fallback storage
> mechanism, that dependency doesn't exist in practice. You're the first
> person to report this dependency as a practical concern.
>
> I suspect we'll need to crack out some of the new unittest2 features
> to fix this; skipping the user_messages tests unless contrib.auth is
> available.
>
> Yours,
> Russ Magee %-)
>
>
>
> > On Wed, Nov 3, 2010 at 4:43 AM, Yo-Yo Ma  wrote:
> >> I have a large application that doesn't user contrib.auth, and when I
> >> run `manage.py test` I get a slough of 35 errors, all of which are
> >> DatabaseError: no such table: auth_user (differing Tracebacks for
> >> each). I don't have any actual tests yet, just the SimpleTest that
> >> comes free in tests.py. INSTALLED_APPS is:
>
> >>    'django.contrib.sessions',
> >>    'django.contrib.messages',
> >>    'myproject.myapp',  # Plus 8 more custom apps omitted.
>
> >> With this bug, Django's testing framework is seemingly coupled to a
> >> contrib app.
>
> >> One of the Tracebacks:
>
> >> ==
> >> ERROR: test_add
> >> (django.contrib.messages.tests.user_messages.UserMessagesTest)
> >> --
> >> Traceback (most recent call last):
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\contrib
> >> \messages\tests\user_messages.py", line 13, in setUp
> >>    self.user = User.objects.create(username='tester')
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \manager.py", line 138, in create
> >>    return self.get_query_set().create(**kwargs)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \query.py", line 351, in create
> >>    obj.save(force_insert=True, using=self.db)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \base.py", line 452, in save
> >>    self.save_base(using=using, force_insert=force_insert,
> >> force_update=force_update)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \base.py", line 545, in save_base
> >>    result = manager._insert(values, return_id=update_pk, using=using)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \manager.py", line 195, in _insert
> >>    return insert_query(self.model, values, **kwargs)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> >> \query.py", line 1490, in insert_query
> >>    return query.get_compiler(using=using).execute_sql(return_id)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
> >> \compiler.py", line 786, in execute_sql
> >>    cursor = super(SQLInsertCompiler, self).execute_sql(None)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
> >> \compiler.py", line 730, in execute_sql
> >>    cursor.execute(sql, params)
> >>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\backends
> >> \sqlite3\base.py", line 221, in execute
> >>    return Database.Cursor.execute(self, query, params)
> >> DatabaseError: no such table: auth_user
>
> >> --
> >> You received this message because you are subscribed to the Google Groups 
> >> "Django developers" group.
> >> To post to this group, send email to django-develop...@googlegroups.com.
> >> To unsubscribe from this group, send email to 
> >> django-developers+unsubscr...@googlegroups.com.
> >> For more options, visit this group 
> >> athttp://groups.google.com/group/django-developers?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "Django developers" group.
> > To post to this group, send email to django-develop...@googlegroups.com.
> > To unsubscribe from this group, send email to 
> > django-developers+unsubscr...@googlegroups.com.
> > For more options, visit this group 
> > athttp://groups.google.com/group/django-developers?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: Bug with testing framework when not using contrib.auth

2010-11-02 Thread Russell Keith-Magee
On Wed, Nov 3, 2010 at 8:18 AM, David P. Novakovic
 wrote:
> This is certainly an artifact of the fact that messages recent started
> supporting anonymous messages. Previously it depended on auth.
>
> I suspect you just need to open a ticket for this.

Yes - this is oversight, not intention.

contrib.messages depends on contrib.auth for reasons of backwards
compatibility, but unless you're using the legacy fallback storage
mechanism, that dependency doesn't exist in practice. You're the first
person to report this dependency as a practical concern.

I suspect we'll need to crack out some of the new unittest2 features
to fix this; skipping the user_messages tests unless contrib.auth is
available.

Yours,
Russ Magee %-)


> On Wed, Nov 3, 2010 at 4:43 AM, Yo-Yo Ma  wrote:
>> I have a large application that doesn't user contrib.auth, and when I
>> run `manage.py test` I get a slough of 35 errors, all of which are
>> DatabaseError: no such table: auth_user (differing Tracebacks for
>> each). I don't have any actual tests yet, just the SimpleTest that
>> comes free in tests.py. INSTALLED_APPS is:
>>
>>    'django.contrib.sessions',
>>    'django.contrib.messages',
>>    'myproject.myapp',  # Plus 8 more custom apps omitted.
>>
>>
>> With this bug, Django's testing framework is seemingly coupled to a
>> contrib app.
>>
>> One of the Tracebacks:
>>
>> ==
>> ERROR: test_add
>> (django.contrib.messages.tests.user_messages.UserMessagesTest)
>> --
>> Traceback (most recent call last):
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\contrib
>> \messages\tests\user_messages.py", line 13, in setUp
>>    self.user = User.objects.create(username='tester')
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
>> \manager.py", line 138, in create
>>    return self.get_query_set().create(**kwargs)
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
>> \query.py", line 351, in create
>>    obj.save(force_insert=True, using=self.db)
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
>> \base.py", line 452, in save
>>    self.save_base(using=using, force_insert=force_insert,
>> force_update=force_update)
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
>> \base.py", line 545, in save_base
>>    result = manager._insert(values, return_id=update_pk, using=using)
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
>> \manager.py", line 195, in _insert
>>    return insert_query(self.model, values, **kwargs)
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
>> \query.py", line 1490, in insert_query
>>    return query.get_compiler(using=using).execute_sql(return_id)
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
>> \compiler.py", line 786, in execute_sql
>>    cursor = super(SQLInsertCompiler, self).execute_sql(None)
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
>> \compiler.py", line 730, in execute_sql
>>    cursor.execute(sql, params)
>>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\backends
>> \sqlite3\base.py", line 221, in execute
>>    return Database.Cursor.execute(self, query, params)
>> DatabaseError: no such table: auth_user
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Django developers" group.
>> To post to this group, send email to django-develop...@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.
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To post to this group, send email to django-develop...@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.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: Bug with testing framework when not using contrib.auth

2010-11-02 Thread David P. Novakovic
This is certainly an artifact of the fact that messages recent started
supporting anonymous messages. Previously it depended on auth.

I suspect you just need to open a ticket for this.

On Wed, Nov 3, 2010 at 4:43 AM, Yo-Yo Ma  wrote:
> I have a large application that doesn't user contrib.auth, and when I
> run `manage.py test` I get a slough of 35 errors, all of which are
> DatabaseError: no such table: auth_user (differing Tracebacks for
> each). I don't have any actual tests yet, just the SimpleTest that
> comes free in tests.py. INSTALLED_APPS is:
>
>    'django.contrib.sessions',
>    'django.contrib.messages',
>    'myproject.myapp',  # Plus 8 more custom apps omitted.
>
>
> With this bug, Django's testing framework is seemingly coupled to a
> contrib app.
>
> One of the Tracebacks:
>
> ==
> ERROR: test_add
> (django.contrib.messages.tests.user_messages.UserMessagesTest)
> --
> Traceback (most recent call last):
>  File "C:\Python26\Lib\site-packages\django-trunk\django\contrib
> \messages\tests\user_messages.py", line 13, in setUp
>    self.user = User.objects.create(username='tester')
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> \manager.py", line 138, in create
>    return self.get_query_set().create(**kwargs)
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> \query.py", line 351, in create
>    obj.save(force_insert=True, using=self.db)
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> \base.py", line 452, in save
>    self.save_base(using=using, force_insert=force_insert,
> force_update=force_update)
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> \base.py", line 545, in save_base
>    result = manager._insert(values, return_id=update_pk, using=using)
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> \manager.py", line 195, in _insert
>    return insert_query(self.model, values, **kwargs)
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
> \query.py", line 1490, in insert_query
>    return query.get_compiler(using=using).execute_sql(return_id)
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
> \compiler.py", line 786, in execute_sql
>    cursor = super(SQLInsertCompiler, self).execute_sql(None)
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
> \compiler.py", line 730, in execute_sql
>    cursor.execute(sql, params)
>  File "C:\Python26\Lib\site-packages\django-trunk\django\db\backends
> \sqlite3\base.py", line 221, in execute
>    return Database.Cursor.execute(self, query, params)
> DatabaseError: no such table: auth_user
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To post to this group, send email to django-develop...@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.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Bug with testing framework when not using contrib.auth

2010-11-02 Thread Yo-Yo Ma
I have a large application that doesn't user contrib.auth, and when I
run `manage.py test` I get a slough of 35 errors, all of which are
DatabaseError: no such table: auth_user (differing Tracebacks for
each). I don't have any actual tests yet, just the SimpleTest that
comes free in tests.py. INSTALLED_APPS is:

'django.contrib.sessions',
'django.contrib.messages',
'myproject.myapp',  # Plus 8 more custom apps omitted.


With this bug, Django's testing framework is seemingly coupled to a
contrib app.

One of the Tracebacks:

==
ERROR: test_add
(django.contrib.messages.tests.user_messages.UserMessagesTest)
--
Traceback (most recent call last):
  File "C:\Python26\Lib\site-packages\django-trunk\django\contrib
\messages\tests\user_messages.py", line 13, in setUp
self.user = User.objects.create(username='tester')
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
\manager.py", line 138, in create
return self.get_query_set().create(**kwargs)
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
\query.py", line 351, in create
obj.save(force_insert=True, using=self.db)
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
\base.py", line 452, in save
self.save_base(using=using, force_insert=force_insert,
force_update=force_update)
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
\base.py", line 545, in save_base
result = manager._insert(values, return_id=update_pk, using=using)
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
\manager.py", line 195, in _insert
return insert_query(self.model, values, **kwargs)
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models
\query.py", line 1490, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
\compiler.py", line 786, in execute_sql
cursor = super(SQLInsertCompiler, self).execute_sql(None)
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\models\sql
\compiler.py", line 730, in execute_sql
cursor.execute(sql, params)
  File "C:\Python26\Lib\site-packages\django-trunk\django\db\backends
\sqlite3\base.py", line 221, in execute
return Database.Cursor.execute(self, query, params)
DatabaseError: no such table: auth_user

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



contrib.auth tests depending on contrib.admin

2010-10-01 Thread Henrique Bastos
Hi All!

After installing django and creating a project runing "django-admin.py
startproject", if I setup a sqlite3 database and try to run the tests
(python manage.py test) it will fail.

Seems that contrib.auth tests are missing 2 template files, making it
dependent of contrib.admin templates, however, the admin app isn't installed
by default on the generated settings.py.

If I uncomment the contrib.admin line on the generated settings the tests
will work properly. It happens on both v1.2.3 and trunk.

I solved it simply creating the missing template files inside contrib.auth
tests. The patch is available at http://code.djangoproject.com/ticket/14374

Even it being a simple error, I feel it's an important issue to solve, so
new django users won't get wrong feedback when starting a new project.

All the best,
--
Henrique Bastos
henri...@bastos.net
http://henriquebastos.net
Skype: henriquebastos.net
+55 21 9618-6180

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: Security - contrib.auth hashing

2010-07-20 Thread Craig Younkins
On Tue, Jul 20, 2010 at 12:09 PM, Jacob Kaplan-Moss wrote:

> On Tue, Jul 20, 2010 at 8:41 AM, Craig Younkins 
> wrote:
> > I'm very glad you don't have MD5 as the default. SHA-1 (currently
> employed)
> > is acceptable for now, but at this point there are theoretical attacks
> that
> > can find collisions in time that is "within the realm of computational
> > possibility". It is recommended that SHA-2 be used for new applications.
> > See http://www.pythonsecurity.org/wiki/hashing/
>
> Actually, if we're being picky, it'd probably be best to use a
> high-cost hashing algorithm like bcrypt or scrypt. SHA (all flavors)
> is designed to be fairly fast, so by using MD5 or SHA we're
> essentially helping brute-force attacks take less time.
>
> http://code.djangoproject.com/ticket/5600 and
> http://code.djangoproject.com/ticket/5787 tracked this request; we
> eventually determined the trade-off in supporting multiple versions
> wasn't worth the extra feature. I might be convinced to change my mind
> now, though, but only if there's a good answer to the
> backwards-compatibility issues.
>

Maybe. The issue in my mind with bcrypt and scrypt is that they are not
validated by NIST or NSA, unlike SHA-2. Blowfish was examined by NIST for
the AES competition but to my knowledge the use of hashing has not been.
SHA-2 was developed by NSA and is recommended by NIST (
http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html).

That being said, I'm asking the opinion of a few other folks at OWASP and
trying to get a consensus of 1 sentence to summarize how passwords should be
stored. In my mind, this sentence should be "Use a SHA-2 algorithm with a
64-bit random salt and 1000 iterations," but this statement is my own and
does not necessarily reflect the views of OWASP. I'll post here
with developments.


> The hashing scheme uses random.random(). The random module uses the
> > deterministic Mersenne Twister algorithm to generate random numbers. This
> is
> > fine for most purposes, but it is not suitable for cryptographic
> purposes.
> > It is much better to create a random.SystemRandom instance to get random
> > data from the OS that is suitable for cryptography.
>
> The problem with SystemRandom is buried in the docs: it's "not
> available on all systems."
> (http://docs.python.org/library/random.html#random.SystemRandom). I'm
> open to a solution here, but we'd need to be very careful to determine
> if SystemRandom is available.
>

SystemRandom should be available on Linux, Solaris, Mac OS
X, NetBSD, OpenBSD, Tru64 UNIX 5.1B, AIX 5.2, and HP-UX 11i v2, and at least
Windows 2000 on up. It's unclear to me if CryptGenRandom was in the API for
95 or 98.

In any case, this is to generate the salt. There is no reason I can think of
why we can't default to SystemRandom and fall back to regular random module
methods if it raises NotImplementedError.


> The most concerning thing in the hashing algorithm is that a salt of only
> 5
> > hexadecimal characters is used. This is just over a million possible
> salts
> > (20 bits). We'd really like to see something closer to our recommendation
> of
> > 64 bits.
>
> I'm not sure why we're only using 5 characters. Anyone remember?
>
> Could you open a ticket to track this issue?
>

http://code.djangoproject.com/ticket/13969


> Is there a measure to prevent users from having dollar signs in their
> > passwords? This would mess up the concatenated string that is stored in
> the
> > database.
>
> Unless I'm really dense, I think it doesn't matter -- we hash
> passwords before they get stored, so we can't "mess up" the stored
> string: it's always just [0-9A-F]. Right?
>

You're right! I'm the one that's dense and looking too quickly. :-)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: Security - contrib.auth hashing

2010-07-20 Thread Jacob Kaplan-Moss
Hey Craig --

Thanks for the notes - this is good stuff!

On Tue, Jul 20, 2010 at 8:41 AM, Craig Younkins  wrote:
> I'm very glad you don't have MD5 as the default. SHA-1 (currently employed)
> is acceptable for now, but at this point there are theoretical attacks that
> can find collisions in time that is "within the realm of computational
> possibility". It is recommended that SHA-2 be used for new applications.
> See http://www.pythonsecurity.org/wiki/hashing/

Actually, if we're being picky, it'd probably be best to use a
high-cost hashing algorithm like bcrypt or scrypt. SHA (all flavors)
is designed to be fairly fast, so by using MD5 or SHA we're
essentially helping brute-force attacks take less time.

http://code.djangoproject.com/ticket/5600 and
http://code.djangoproject.com/ticket/5787 tracked this request; we
eventually determined the trade-off in supporting multiple versions
wasn't worth the extra feature. I might be convinced to change my mind
now, though, but only if there's a good answer to the
backwards-compatibility issues.

> The hashing scheme uses random.random(). The random module uses the
> deterministic Mersenne Twister algorithm to generate random numbers. This is
> fine for most purposes, but it is not suitable for cryptographic purposes.
> It is much better to create a random.SystemRandom instance to get random
> data from the OS that is suitable for cryptography.

The problem with SystemRandom is buried in the docs: it's "not
available on all systems."
(http://docs.python.org/library/random.html#random.SystemRandom). I'm
open to a solution here, but we'd need to be very careful to determine
if SystemRandom is available.

> The most concerning thing in the hashing algorithm is that a salt of only 5
> hexadecimal characters is used. This is just over a million possible salts
> (20 bits). We'd really like to see something closer to our recommendation of
> 64 bits.

I'm not sure why we're only using 5 characters. Anyone remember?

Could you open a ticket to track this issue?

> Is there a measure to prevent users from having dollar signs in their
> passwords? This would mess up the concatenated string that is stored in the
> database.

Unless I'm really dense, I think it doesn't matter -- we hash
passwords before they get stored, so we can't "mess up" the stored
string: it's always just [0-9A-F]. Right?

> You might consider hashing with multiple rounds. By applying the hash
> function many times, you essentially lengthen the hashing/password
> verification stage. Since users spend very little time in this stage, it
> will have minimal impact in them. Crackers spend nearly 100% of their time
> doing this, so it significantly slows them down.
> See http://www.pythonsecurity.org/wiki/hashing/#multiple-rounds

Yup -- or, as said above, use s/bcrypt. I *would* like to revisit slow
hashing algorithms -- maybe if we can't make s/bcrypt be a good option
we could switch to multiple rounds.

Jacob

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Security - contrib.auth hashing

2010-07-20 Thread Craig Younkins
Please note this email does not include or indicate a specific, immediately
viable flaw.

I'm doing a brief analysis of the contrib.auth system:
http://www.pythonsecurity.org/wiki/django/#authentication . I have a couple
of notes that I'd like to share with you.

   - I'm very glad you don't have MD5 as the default. SHA-1 (currently
   employed) is acceptable for now, but at this point there are theoretical
   attacks that can find collisions in time that is "within the realm of
   computational possibility". It is recommended that SHA-2 be used for new
   applications. See http://www.pythonsecurity.org/wiki/hashing/
   - The hashing scheme uses random.random(). The random module uses the
   deterministic Mersenne Twister algorithm to generate random numbers. This is
   fine for most purposes, but it is not suitable for cryptographic purposes.
   It is much better to create a
random.SystemRandom<http://docs.python.org/library/random.html#random.SystemRandom>
instance
   to get random data from the OS that is suitable for cryptography.
   - The most concerning thing in the hashing algorithm is that a salt of
   only 5 hexadecimal characters is used. This is just over a million possible
   salts (20 bits). We'd really like to see something closer to our
   recommendation of 64 bits.

Other tidbits:

   - Is there a measure to prevent users from having dollar signs in their
   passwords? This would mess up the concatenated string that is stored in the
   database.
   - You might consider hashing with multiple rounds. By applying the hash
   function many times, you essentially lengthen the hashing/password
   verification stage. Since users spend very little time in this stage, it
   will have minimal impact in them. Crackers spend nearly 100% of their time
   doing this, so it significantly slows them down. See
   http://www.pythonsecurity.org/wiki/hashing/#multiple-rounds


*Craig Younkins*

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-22 Thread Russell Keith-Magee
On Mon, Feb 22, 2010 at 6:03 PM, Sayane  wrote:
> It's not only about character restrictions on usernames. Some of developers
> want to use email as login (so we have to remove username and add unique
> option to email). Another example are english-only permissions. I would like
> to replace them with my own i18n permissions. Maybe someone needs something
> more complicated (for example authentication with external services, like
> twitter, facebook without creating a new, local user)?

A couple of things to keep in mind:

1) We know about the limitations, and we want to fix them.

2) No, seriously, we know about the limitations, and we want to fix them.

3) I wasn't kidding on the first two points.

As has been said several times in this thread, the limitations with
contrib.auth Users are well known, and they are something we want to
address -- in the Django 1.3 timeframe. Now is *not* the time to be
discussing this.

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-develop...@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.



Re: contrib.Auth

2010-02-22 Thread Sayane
It's not only about character restrictions on usernames. Some of developers
want to use email as login (so we have to remove username and add unique
option to email). Another example are english-only permissions. I would like
to replace them with my own i18n permissions. Maybe someone needs something
more complicated (for example authentication with external services, like
twitter, facebook without creating a new, local user)?

2010/2/17 Clay Gerrard 

> How about fixing http://codeStrona główna   Dodaj firmęMoja
> firma   Pomoc   Blog   O nas   Konkurs
>  
> Kontakt.djangoproject.com/ticket/5786
> "Relax character restrictions on auth usernames"
>
> Jacob already said back in December '07:
> "we just need to relax the current restrictions"
>
> The ticket has a patch, and tests...
>
>
> On Feb 11, 11:44 am, James Bennett  wrote:
> > Once again:
> >
> > This is really not the time to be discussing this; anything in this
> > thread's going to be long forgotten by the time 1.2's out and 1.3
> > feature discussions are going on.
> >
> > --
> > "Bureaucrat Conrad, you are technically correct -- the best kind of
> correct."
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-develop...@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.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-16 Thread Clay Gerrard
How about fixing http://code.djangoproject.com/ticket/5786
"Relax character restrictions on auth usernames"

Jacob already said back in December '07:
"we just need to relax the current restrictions"

The ticket has a patch, and tests...


On Feb 11, 11:44 am, James Bennett  wrote:
> Once again:
>
> This is really not the time to be discussing this; anything in this
> thread's going to be long forgotten by the time 1.2's out and 1.3
> feature discussions are going on.
>
> --
> "Bureaucrat Conrad, you are technically correct -- the best kind of correct."

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-11 Thread James Bennett
Once again:

This is really not the time to be discussing this; anything in this
thread's going to be long forgotten by the time 1.2's out and 1.3
feature discussions are going on.


-- 
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-11 Thread Hanne Moa
On 10 February 2010 23:33, Sayane  wrote:
> I think that an easy way to define your own user model is better idea. Auth
> app should be more generic. It should define a protocol for user, group and
> permission objects /../

Why should permissions and groups be in the same app as the user? Less
reusable that way. Identity is different from authentication is
different from authorization.

Premature optimization or not, as it is today on many sites the
user-table is hit extremely frequently. I'm not sure it is wise to
have layer upon layer between the user in the db and the zillion
things that has a foreign key to it.


HM

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-10 Thread Sayane
I think that an easy way to define your own user model is better idea. Auth
app should be more generic. It should define a protocol for user, group and
permission objects (and of course there should be back compatible
implementation of this protocols used by default). There is a ticket about
extending auth app: http://code.djangoproject.com/ticket/3011, but I think
this could be done in a better way.

Sorry for my english :-)

2010/2/10 Harro 

> Good suggestions, I think removing username and email from the user
> might be a good idea.
> Right now I authenticate with the email address stored on the profile
> and the username is a random hash :)
>
> As for breaking data and migrations; it shouldn't be that hard to
> write a management command that does this.
>
>
> On Feb 9, 5:54 pm, Vitaly Babiy  wrote:
> > Vitaly Babiy
> >
> > On Tue, Feb 9, 2010 at 3:16 AM, James Bennett 
> wrote:
> > > On Tue, Feb 9, 2010 at 2:09 AM, Harro  wrote:
> > > > - Make email unique and username non-required on the model. That
> would
> > > > make implementing something that authenticated by email a lot
> > > > easier :)
> >
> > > 1. It's *extremely* unlikely that changes will be considered which
> > > require every Django install on the planet to undergo a DB schema
> > > migration.
> >
> > James this is true. Another reason it would be nice to have a
> > migration framework for Django.
> >
> >
> >
> >
> >
> > > 2. The appropriate time to discuss possible 1.3 features is when the
> > > feature-discussion window for 1.3 comes up. That will happen sometime
> > > in April, probably. Suggestions made now are likely to be forgotten by
> > > the time that happens.
> >
> > > Yeah I plan to bring this up again, around that time frame.
> >
> > > --
> > > "Bureaucrat Conrad, you are technically correct -- the best kind of
> > > correct."
> >
> > > --
> > > You received this message because you are subscribed to the Google
> Groups
> > > "Django developers" group.
> > > To post to this group, send email to
> django-develop...@googlegroups.com.
> > > To unsubscribe from this group, send email to
> > > django-developers+unsubscr...@googlegroups.com i...@googlegroups.com>
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/django-developers?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-develop...@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.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-10 Thread Harro
Good suggestions, I think removing username and email from the user
might be a good idea.
Right now I authenticate with the email address stored on the profile
and the username is a random hash :)

As for breaking data and migrations; it shouldn't be that hard to
write a management command that does this.


On Feb 9, 5:54 pm, Vitaly Babiy  wrote:
> Vitaly Babiy
>
> On Tue, Feb 9, 2010 at 3:16 AM, James Bennett  wrote:
> > On Tue, Feb 9, 2010 at 2:09 AM, Harro  wrote:
> > > - Make email unique and username non-required on the model. That would
> > > make implementing something that authenticated by email a lot
> > > easier :)
>
> > 1. It's *extremely* unlikely that changes will be considered which
> > require every Django install on the planet to undergo a DB schema
> > migration.
>
> James this is true. Another reason it would be nice to have a
> migration framework for Django.
>
>
>
>
>
> > 2. The appropriate time to discuss possible 1.3 features is when the
> > feature-discussion window for 1.3 comes up. That will happen sometime
> > in April, probably. Suggestions made now are likely to be forgotten by
> > the time that happens.
>
> > Yeah I plan to bring this up again, around that time frame.
>
> > --
> > "Bureaucrat Conrad, you are technically correct -- the best kind of
> > correct."
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Django developers" group.
> > To post to this group, send email to django-develop...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > django-developers+unsubscr...@googlegroups.com > i...@googlegroups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/django-developers?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-09 Thread Vitaly Babiy
Vitaly Babiy


On Tue, Feb 9, 2010 at 3:16 AM, James Bennett  wrote:

> On Tue, Feb 9, 2010 at 2:09 AM, Harro  wrote:
> > - Make email unique and username non-required on the model. That would
> > make implementing something that authenticated by email a lot
> > easier :)
>
> 1. It's *extremely* unlikely that changes will be considered which
> require every Django install on the planet to undergo a DB schema
> migration.
>

James this is true. Another reason it would be nice to have a
migration framework for Django.

>
> 2. The appropriate time to discuss possible 1.3 features is when the
> feature-discussion window for 1.3 comes up. That will happen sometime
> in April, probably. Suggestions made now are likely to be forgotten by
> the time that happens.
>
> Yeah I plan to bring this up again, around that time frame.

>
> --
> "Bureaucrat Conrad, you are technically correct -- the best kind of
> correct."
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-develop...@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.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-09 Thread James Bennett
On Tue, Feb 9, 2010 at 2:09 AM, Harro  wrote:
> - Make email unique and username non-required on the model. That would
> make implementing something that authenticated by email a lot
> easier :)

1. It's *extremely* unlikely that changes will be considered which
require every Django install on the planet to undergo a DB schema
migration.

2. The appropriate time to discuss possible 1.3 features is when the
feature-discussion window for 1.3 comes up. That will happen sometime
in April, probably. Suggestions made now are likely to be forgotten by
the time that happens.


-- 
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-09 Thread andybak
I recently tried to use the recommended approach for custom user
profiles: http://docs.djangoproject.com/en/dev/topics/auth/#auth-profiles

and all the brick walls I hit were admin related. Whether these are
better fixed in contrib.auth or contrib.admin is hard to say:

1. I can show profile fields in the user changelist but I can't sort,
filter or search on them or use list_editable on them.
2. I can re-register my own ModelAdmin for users to customize the User
admin but I can't add custom filterspecs as that requires editing the
auth models.py

#1 could be mitigated if contrib.admin allowed more ways to following
relationships for things like list_display and list_filter.
#2 requires a more elegant way to write custom filterspecs without
touching models.py - maybe this is already possible?

Andy Baker

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-09 Thread Dougal Matthews
On 9 February 2010 08:09, Harro  wrote:

> - Make email unique and username non-required on the model. That would
> make implementing something that authenticated by email a lot
> easier :)
>

For reference there are some good points here[1] on this topic started
by Hanne Moa.

I think ideally the user model would be as simple as only having an ID as we
shouldn't make assumptions about requirements for usernames, emails or even
passwords with the vast array of login options we have these days. The
backends can then extend this to create logins that are based on email,
username, oauth, openid etc. Essentially giving us an ID to tie things
together and relating different authentication methods for the same user.

Just some food for thought until 1.2 is out of the way and everybody is
feeling a bit more sover.

http://groups.google.com/group/django-developers/browse_thread/thread/c522f1e2bf01c3f7

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-09 Thread Hanne Moa
On 9 February 2010 09:09, Harro  wrote:
> - Make email unique and username non-required on the model. That would
> make implementing something that authenticated by email a lot
> easier :)

Pff, move emails out entirely. Email-addresses may change. Usernames
shouldn't change. One may have more than one email-address.

Maybe the time is right to make that branch now...


HM

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-09 Thread Harro
- Make email unique and username non-required on the model. That would
make implementing something that authenticated by email a lot
easier :)

On Feb 9, 1:34 am, Russell Keith-Magee  wrote:
> On Tue, Feb 9, 2010 at 8:15 AM, Justin Lilly  wrote:
> > To add another point, this doesn't mean that the day 1.2 hits release that
> > everyone is gung-ho on 1.3. If past releases are any indication, there is
> > usually a refactory period of a few weeks when everyone is basking in
> > post-release bliss.
>
> I believe the post-release period is typically referred to as "sobering up" 
> :-)
>
> To address Vitaly's original point - contrib.auth is on my list of
> things I want to address in 1.3.
>
> 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-develop...@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.



Re: contrib.Auth

2010-02-08 Thread Russell Keith-Magee
On Tue, Feb 9, 2010 at 8:15 AM, Justin Lilly  wrote:
> To add another point, this doesn't mean that the day 1.2 hits release that
> everyone is gung-ho on 1.3. If past releases are any indication, there is
> usually a refactory period of a few weeks when everyone is basking in
> post-release bliss.

I believe the post-release period is typically referred to as "sobering up" :-)

To address Vitaly's original point - contrib.auth is on my list of
things I want to address in 1.3.

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-develop...@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.



Re: contrib.Auth

2010-02-08 Thread Justin Lilly
To add another point, this doesn't mean that the day 1.2 hits release that
everyone is gung-ho on 1.3. If past releases are any indication, there is
usually a refactory period of a few weeks when everyone is basking in
post-release bliss.

 -justin

On Mon, Feb 8, 2010 at 6:46 PM, Karen Tracey  wrote:

> On Mon, Feb 8, 2010 at 6:39 PM, Vitaly Babiy  wrote:
>
>> Hey Guys,
>> So 1.2 is almost out the door so I wanted to raise an issue that I would
>> love to start working to fix for 1.3.
>>
>
> Not to discourage you, but be aware the focus of most attention until 1.2
> actually goes out is still 1.2. Feature freeze doesn't mean the release is
> done, it means attention shifts to bug fixing. You many not find many people
> ready to start thinking deeply about 1.3 just yet.
>
> Karen
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-develop...@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.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-08 Thread Vitaly Babiy
Thanks, for the pointer. I think even if this gets people think about the
problem its a good start, I will raise this question again after 1.2
release.
Vitaly Babiy


On Mon, Feb 8, 2010 at 6:46 PM, Karen Tracey  wrote:

> On Mon, Feb 8, 2010 at 6:39 PM, Vitaly Babiy  wrote:
>
>> Hey Guys,
>> So 1.2 is almost out the door so I wanted to raise an issue that I would
>> love to start working to fix for 1.3.
>>
>
> Not to discourage you, but be aware the focus of most attention until 1.2
> actually goes out is still 1.2. Feature freeze doesn't mean the release is
> done, it means attention shifts to bug fixing. You many not find many people
> ready to start thinking deeply about 1.3 just yet.
>
> Karen
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-develop...@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.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: contrib.Auth

2010-02-08 Thread Karen Tracey
On Mon, Feb 8, 2010 at 6:39 PM, Vitaly Babiy  wrote:

> Hey Guys,
> So 1.2 is almost out the door so I wanted to raise an issue that I would
> love to start working to fix for 1.3.
>

Not to discourage you, but be aware the focus of most attention until 1.2
actually goes out is still 1.2. Feature freeze doesn't mean the release is
done, it means attention shifts to bug fixing. You many not find many people
ready to start thinking deeply about 1.3 just yet.

Karen

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



contrib.Auth

2010-02-08 Thread Vitaly Babiy
Hey Guys,
So 1.2 is almost out the door so I wanted to raise an issue that I would
love to start working to fix for 1.3.

As we all have used the contrib.Auth application we know there are some
short comings in the application. Here is a couple of issue that I have
noticed since using it.

- If you change the auth backend it will make the test suite fail.
- Hard to extend the user object.

I know people have had more, I would like this thread to service as
an brainstorming section for what is wrong with the application and even
some idea on how to fix them.

--

This is also the first time I have been involved in a big part of django if
I am not following protocol please let me know, Thansk.

Vitaly Babiy

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.



Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-10 Thread Russell Keith-Magee
On Fri, Dec 11, 2009 at 8:14 AM, Russell Keith-Magee
 wrote:
> On Wed, Dec 9, 2009 at 11:36 PM, Jacob Kaplan-Moss  wrote:
>> On Tue, Dec 8, 2009 at 5:15 PM, Russell Keith-Magee
>>  wrote:
>>> There's overlap, but it isn't necessarily a perfect match.
>>
>> Good points -- you've clearly thought this through farther than me.
>> Consider the wrench withdrawn :)
>
> You might have withdrawn your wrench, but it has given me pause for
> thought. I've decided to go with 'natural key' rather than surrogate.
> It seems like a slightly better terminology match (there is only one
> by definition, and it's the 'natural' way of referring to an object.
>
>> If you need another set of eyes on the code, I'm happy to give it a
>> review later this week and/or during the sprint this weekend.
>
> If you'd be so kind. I've just uploaded RC1 of the patch to the ticket
> - this time, with docs!
>
> I've also uploaded RC1 for #7052 (cached templates). If you've got a
> spare moment, a review there wouldn't go astray.

Bah - of course, that should be #6262 (cached templates)

Russ %-)

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.




Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-10 Thread Russell Keith-Magee
On Wed, Dec 9, 2009 at 11:36 PM, Jacob Kaplan-Moss  wrote:
> On Tue, Dec 8, 2009 at 5:15 PM, Russell Keith-Magee
>  wrote:
>> There's overlap, but it isn't necessarily a perfect match.
>
> Good points -- you've clearly thought this through farther than me.
> Consider the wrench withdrawn :)

You might have withdrawn your wrench, but it has given me pause for
thought. I've decided to go with 'natural key' rather than surrogate.
It seems like a slightly better terminology match (there is only one
by definition, and it's the 'natural' way of referring to an object.

> If you need another set of eyes on the code, I'm happy to give it a
> review later this week and/or during the sprint this weekend.

If you'd be so kind. I've just uploaded RC1 of the patch to the ticket
- this time, with docs!

I've also uploaded RC1 for #7052 (cached templates). If you've got a
spare moment, a review there wouldn't go astray.

Russ %-)

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.




Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-09 Thread Jacob Kaplan-Moss
On Tue, Dec 8, 2009 at 5:15 PM, Russell Keith-Magee
 wrote:
> There's overlap, but it isn't necessarily a perfect match.

Good points -- you've clearly thought this through farther than me.
Consider the wrench withdrawn :)

If you need another set of eyes on the code, I'm happy to give it a
review later this week and/or during the sprint this weekend.

Jacob

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.




Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-08 Thread Russell Keith-Magee
On Wed, Dec 9, 2009 at 12:55 AM, Jacob Kaplan-Moss  wrote:
> Hi Russ --
>
> This is looking pretty great; I'm a big fan of this approach. I've
> looked through the places I've needed to work around this problem with
> serializers, and your fix would work in every case, so I think you
> nailed it.
>
> I do, however, have one wrench to throw into the works:
>
> As it stands, this gets incredibly close to what we'd need to support
> composite primary keys! The primary thing standing in the way of
> getting composite PKs is an API to refer to objects by something other
> than a single value; your `surrogate_key`/`get_by_surrogate` is that
> API.

There's overlap, but it isn't necessarily a perfect match.

Firstly, there's no reason that a surrogate needs to be multiple
columns - it could just be a reference to a different column. For
example, you could use the name of a Author as a surrogate. A single
string works really nicely as a surrogate.

Secondly, a surrogate doesn't need to be . auth.Permission is a
triple, but the second and third values are themselves the surrogate
of the content type.

Lastly, there's no guarantee that a CPK will automatically be an
appropriate surrogate for serialization.

> Now, I'm not suggesting that we shave the CPK yak just to get
> serialization of content types. However, it might be worth a bit of
> bikeshedding in the API to future-proof it so that 1.3 could grow CPK
> support out of this work.
>
> All that to say: perhaps it'd be worth naming it something other than
> "surrogate"?

The overlap between CPK and surrogate wasn't lost on me, but at the
time I couldn't think of an obvious alternate name that wasn't bound
to serialization. In the end, I came to the position that 'surrogate'
was a reasonable name for this particular feature, and we should
mentally reserve 'composite' (i.e., get_composite_key,
get_by_composite, etc) as the magic word for CPK.

I just kicked the idea around the office here, and we came up with two
other options:

* Natural key: on the grounds that we're picking a natural way to
refer to the object.

* Stable key: on the grounds that this whole problem exists because
the primary key *isn't* stable over syncdb calls, and we're picking a
set of columns that will be stable.

I'm happy to entertain any other bikeshed colors. Suggestions?

> On Fri, Dec 4, 2009 at 11:39 AM, Russell Keith-Magee
>  wrote:
>> Documentation is still to come.
>
> For shame! :) :)

If it makes you feel any better, I haven't been sleeping well since I
uploaded the patch :-)

Russ %-)

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.




Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-08 Thread Jacob Kaplan-Moss
Hi Russ --

This is looking pretty great; I'm a big fan of this approach. I've
looked through the places I've needed to work around this problem with
serializers, and your fix would work in every case, so I think you
nailed it.

I do, however, have one wrench to throw into the works:

As it stands, this gets incredibly close to what we'd need to support
composite primary keys! The primary thing standing in the way of
getting composite PKs is an API to refer to objects by something other
than a single value; your `surrogate_key`/`get_by_surrogate` is that
API.

Now, I'm not suggesting that we shave the CPK yak just to get
serialization of content types. However, it might be worth a bit of
bikeshedding in the API to future-proof it so that 1.3 could grow CPK
support out of this work.

All that to say: perhaps it'd be worth naming it something other than
"surrogate"?

On Fri, Dec 4, 2009 at 11:39 AM, Russell Keith-Magee
 wrote:
> Documentation is still to come.

For shame! :) :)

Jacob

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.




Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-04 Thread Russell Keith-Magee
On Fri, Dec 4, 2009 at 7:38 AM, Russell Keith-Magee
 wrote:
> On Fri, Dec 4, 2009 at 7:03 AM, Luke Plant  wrote:
>> On Thursday 03 December 2009 15:33:44 Russell Keith-Magee wrote:
>>
>> How easy would it be to fix this? If you used a list of string values,
>> instead of a single string, wouldn't all the serialization formats
>> handle this with very little work?  Without looking at the code, I
>> imagine that JSON and YAML at least would. You are still forcing
>> things to be to be converted to strings and back, but there are
>> usually standard ways to do that.
>
> Interesting thought. JSON and YAML serialization of list/tuples would
> be able to handle this almost transparently - in fact, it probably
> works right now if you modify the surrogate implementations to
> return/accept lists/tuples.

I've just uploaded an updated patch that implements this strategy. A
surrogate key can now be a string or a list/tuple. If it's a string,
the same thing happens as before. If the surrogate key is a
list/tuple, it will be unrolled as arguments to get_by_surrogate. This
means that content types are now serialized in JSON as:

   contenttype: ('auth','user')

which is rolled out in code to perform the following query:

ContentType.objects.get_by_surrogate('auth','User')

>>> On a practical note - there is one failing test, which highlights
>>>  the one flaw in this scheme that I am aware of. There is still a
>>>  circular dependency problem - an object must be deserialized
>>>  before it can be referenced using a surrogate key.
>>
>> I presume this problem would exist with the alternative method on that
>> ticket as well, right?
>
> Correct. We never arrived at a way to implement serialization under
> the old approach, so this never really became an issue.

The new patch addresses this issue in two ways.

Firstly, models that define a surrogate key are given priority in
serialization; surrogate key models are serialized first, followed by
normal models.

Secondly, to allow for dependencies between models with surrogate
keys, surrogate keys can define dependencies. For example, the
auth.Permissions model defines it's surrogate key as follows:

def surrogate_key(self):
return (self.codename, self.content_type.app_label, self.content_type.model)
surrogate_key.dependencies = ['contenttypes.contenttype']

This indicates that Permission has a dependency on ContentType, so
Permissions will always be serialized after ContentTypes if they are
in the same fixture.

Documentation is still to come.

Russ %-)

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.




Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-03 Thread Russell Keith-Magee
On Fri, Dec 4, 2009 at 12:19 PM, mattimust...@gmail.com
 wrote:
>
>
> On Dec 4, 2:56 pm, Russell Keith-Magee  wrote:
>> On Fri, Dec 4, 2009 at 11:46 AM, mattimust...@gmail.com
>>
>>
>>
>>
>>
>>  wrote:
>>
>> > On Dec 4, 2:33 am, Russell Keith-Magee  wrote:
>> >> Hi all,
>>
>> >> I've been looking at ticket #7052 again. I've got a draft patch up on
>> >> Trac, and I'd like feedback on the approach.
>>
>> >> Previously, I've been advocating the approach of embedding queries
>> >> into the serialization syntax - essentially, interpreting dictionaries
>> >> in JSON (and equivalent in other formats) as keyword arguments to a
>> >> Model.objects.get() call.
>>
>> >> This approach works, but very rapidly gets messy. It's painfully easy
>> >> to write a fixture that has circular, nested, or otherwise horribly
>> >> knotted dependencies. There is also the issue of serialization - a
>> >> query-based syntax is easy to deserialize, but how do you determine
>> >> which fields should be included in a serialization?
>>
>> >> So, I've taken a different approach with this new patch. The new
>> >> approach is much simpler and more explicit than the last. Rather than
>> >> trying to embed a query into the serialization language, I've taken a
>> >> step back and looked at the problem a different way.
>>
>> >> If there is some mechanism that can be used to look up instances of a
>> >> model, then by definition, it must be a surrogate key of some kind.
>> >> Completely independent of serialization, it would be nifty to be able
>> >> to perform lookups based on this surrogate key.
>>
>> >> So, lets add a convention for these methods. As an example, consider
>> >> contrib.auth Permissions (models have been slightly simplified for
>> >> demo purposes).
>>
>> >> class PermissionManager(models.Manager):
>> >>     def get_by_surrogate(self, key):
>> >>         codename, ct_key = key.split('|',1)
>> >>         return self.get(
>> >>             codename=codename,
>> >>             content_type=ContentType.objects.get_by_surrogate(ct_key)
>> >>         )
>>
>> >> class Permission(models.Model):
>> >>     name = models.CharField(max_length=50)
>> >>     content_type = models.ForeignKey(ContentType)
>> >>     codename = models.CharField(max_length=100)
>> >>     objects = PermissionManager()
>>
>> >>     def surrogate_key(self):
>> >>         return '%s|%s' % (self.codename, 
>> >> self.content_type.surrogate_key())
>>
>> >> There are two additions here - a get_by_surrogate() method on the
>> >> default manager, and a surrogate_key() method on the model itself. If
>> >> I have an instance of permission, I can call p.surrogate_key(), which
>> >> will return 'add_user|auth:user'. If I want to get a particular
>> >> permission, I can call
>> >> Permission.objects.get_by_surrogate('add_user|auth:user'), and that
>> >> will resolve to the appropriate permission (or raise an exception if
>> >> no answer exists.
>>
>> >> So far, this is independent of serialization. These methods could be
>> >> useful to end users for looking up permissions or content types.
>>
>> >> However, they're also really useful for serialization. The serializers
>> >> can use the existence of these methods as cues for changes in
>> >> serialization behavior. If a get_by_surrogate() method is found on the
>> >> manager, the deserializer will use that method to look up objects; if
>> >> surrogate_key() exists on the model, that will be used to serialize
>> >> references to the object instead of using primary key values.
>>
>> >> So, a JSON serialized reference to a permission that previously read:
>>
>> >> {
>> >>     "pk": 1,
>> >>     "model": "auth.User",
>> >>     "fields": {
>> >>         ...
>> >>         permissions = [ 1,3 ]
>> >>     }
>>
>> >> }
>>
>> >> will now read:
>>
>> >> {
>> >>     "pk": 1,
>> >>     "model": "auth.User",
>> >>     "

Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-03 Thread mattimust...@gmail.com


On Dec 4, 2:56 pm, Russell Keith-Magee  wrote:
> On Fri, Dec 4, 2009 at 11:46 AM, mattimust...@gmail.com
>
>
>
>
>
>  wrote:
>
> > On Dec 4, 2:33 am, Russell Keith-Magee  wrote:
> >> Hi all,
>
> >> I've been looking at ticket #7052 again. I've got a draft patch up on
> >> Trac, and I'd like feedback on the approach.
>
> >> Previously, I've been advocating the approach of embedding queries
> >> into the serialization syntax - essentially, interpreting dictionaries
> >> in JSON (and equivalent in other formats) as keyword arguments to a
> >> Model.objects.get() call.
>
> >> This approach works, but very rapidly gets messy. It's painfully easy
> >> to write a fixture that has circular, nested, or otherwise horribly
> >> knotted dependencies. There is also the issue of serialization - a
> >> query-based syntax is easy to deserialize, but how do you determine
> >> which fields should be included in a serialization?
>
> >> So, I've taken a different approach with this new patch. The new
> >> approach is much simpler and more explicit than the last. Rather than
> >> trying to embed a query into the serialization language, I've taken a
> >> step back and looked at the problem a different way.
>
> >> If there is some mechanism that can be used to look up instances of a
> >> model, then by definition, it must be a surrogate key of some kind.
> >> Completely independent of serialization, it would be nifty to be able
> >> to perform lookups based on this surrogate key.
>
> >> So, lets add a convention for these methods. As an example, consider
> >> contrib.auth Permissions (models have been slightly simplified for
> >> demo purposes).
>
> >> class PermissionManager(models.Manager):
> >>     def get_by_surrogate(self, key):
> >>         codename, ct_key = key.split('|',1)
> >>         return self.get(
> >>             codename=codename,
> >>             content_type=ContentType.objects.get_by_surrogate(ct_key)
> >>         )
>
> >> class Permission(models.Model):
> >>     name = models.CharField(max_length=50)
> >>     content_type = models.ForeignKey(ContentType)
> >>     codename = models.CharField(max_length=100)
> >>     objects = PermissionManager()
>
> >>     def surrogate_key(self):
> >>         return '%s|%s' % (self.codename, self.content_type.surrogate_key())
>
> >> There are two additions here - a get_by_surrogate() method on the
> >> default manager, and a surrogate_key() method on the model itself. If
> >> I have an instance of permission, I can call p.surrogate_key(), which
> >> will return 'add_user|auth:user'. If I want to get a particular
> >> permission, I can call
> >> Permission.objects.get_by_surrogate('add_user|auth:user'), and that
> >> will resolve to the appropriate permission (or raise an exception if
> >> no answer exists.
>
> >> So far, this is independent of serialization. These methods could be
> >> useful to end users for looking up permissions or content types.
>
> >> However, they're also really useful for serialization. The serializers
> >> can use the existence of these methods as cues for changes in
> >> serialization behavior. If a get_by_surrogate() method is found on the
> >> manager, the deserializer will use that method to look up objects; if
> >> surrogate_key() exists on the model, that will be used to serialize
> >> references to the object instead of using primary key values.
>
> >> So, a JSON serialized reference to a permission that previously read:
>
> >> {
> >>     "pk": 1,
> >>     "model": "auth.User",
> >>     "fields": {
> >>         ...
> >>         permissions = [ 1,3 ]
> >>     }
>
> >> }
>
> >> will now read:
>
> >> {
> >>     "pk": 1,
> >>     "model": "auth.User",
> >>     "fields": {
> >>         ...
> >>         permissions = [ "add_user|auth:user" ,"delete_user|auth:user" ]
> >>     }
>
> >> }
>
> >> The patch attached to #7052 implements this scheme, and includes
> >> surrogate key definitions for Permission and ContentType, plus tests
> >> to validate that this approach works.
>
> >> Two possible objections:
>
> >&g

Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-03 Thread Russell Keith-Magee
On Fri, Dec 4, 2009 at 11:46 AM, mattimust...@gmail.com
 wrote:
>
>
> On Dec 4, 2:33 am, Russell Keith-Magee  wrote:
>> Hi all,
>>
>> I've been looking at ticket #7052 again. I've got a draft patch up on
>> Trac, and I'd like feedback on the approach.
>>
>> Previously, I've been advocating the approach of embedding queries
>> into the serialization syntax - essentially, interpreting dictionaries
>> in JSON (and equivalent in other formats) as keyword arguments to a
>> Model.objects.get() call.
>>
>> This approach works, but very rapidly gets messy. It's painfully easy
>> to write a fixture that has circular, nested, or otherwise horribly
>> knotted dependencies. There is also the issue of serialization - a
>> query-based syntax is easy to deserialize, but how do you determine
>> which fields should be included in a serialization?
>>
>> So, I've taken a different approach with this new patch. The new
>> approach is much simpler and more explicit than the last. Rather than
>> trying to embed a query into the serialization language, I've taken a
>> step back and looked at the problem a different way.
>>
>> If there is some mechanism that can be used to look up instances of a
>> model, then by definition, it must be a surrogate key of some kind.
>> Completely independent of serialization, it would be nifty to be able
>> to perform lookups based on this surrogate key.
>>
>> So, lets add a convention for these methods. As an example, consider
>> contrib.auth Permissions (models have been slightly simplified for
>> demo purposes).
>>
>> class PermissionManager(models.Manager):
>>     def get_by_surrogate(self, key):
>>         codename, ct_key = key.split('|',1)
>>         return self.get(
>>             codename=codename,
>>             content_type=ContentType.objects.get_by_surrogate(ct_key)
>>         )
>>
>> class Permission(models.Model):
>>     name = models.CharField(max_length=50)
>>     content_type = models.ForeignKey(ContentType)
>>     codename = models.CharField(max_length=100)
>>     objects = PermissionManager()
>>
>>     def surrogate_key(self):
>>         return '%s|%s' % (self.codename, self.content_type.surrogate_key())
>>
>> There are two additions here - a get_by_surrogate() method on the
>> default manager, and a surrogate_key() method on the model itself. If
>> I have an instance of permission, I can call p.surrogate_key(), which
>> will return 'add_user|auth:user'. If I want to get a particular
>> permission, I can call
>> Permission.objects.get_by_surrogate('add_user|auth:user'), and that
>> will resolve to the appropriate permission (or raise an exception if
>> no answer exists.
>>
>> So far, this is independent of serialization. These methods could be
>> useful to end users for looking up permissions or content types.
>>
>> However, they're also really useful for serialization. The serializers
>> can use the existence of these methods as cues for changes in
>> serialization behavior. If a get_by_surrogate() method is found on the
>> manager, the deserializer will use that method to look up objects; if
>> surrogate_key() exists on the model, that will be used to serialize
>> references to the object instead of using primary key values.
>>
>> So, a JSON serialized reference to a permission that previously read:
>>
>> {
>>     "pk": 1,
>>     "model": "auth.User",
>>     "fields": {
>>         ...
>>         permissions = [ 1,3 ]
>>     }
>>
>> }
>>
>> will now read:
>>
>> {
>>     "pk": 1,
>>     "model": "auth.User",
>>     "fields": {
>>         ...
>>         permissions = [ "add_user|auth:user" ,"delete_user|auth:user" ]
>>     }
>>
>> }
>>
>> The patch attached to #7052 implements this scheme, and includes
>> surrogate key definitions for Permission and ContentType, plus tests
>> to validate that this approach works.
>>
>> Two possible objections:
>>
>>  * It's a string-based serialization format. This means the developer
>> will need to write parsing code and a microsyntax to handle composite
>> surrogate keys (e.g., separating permission name from content type
>> with a pipe, and separating app_label from model with a colon).
>>
>>  * You can only define one surrogate key. Some models mig

Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-03 Thread mattimust...@gmail.com


On Dec 4, 2:33 am, Russell Keith-Magee  wrote:
> Hi all,
>
> I've been looking at ticket #7052 again. I've got a draft patch up on
> Trac, and I'd like feedback on the approach.
>
> Previously, I've been advocating the approach of embedding queries
> into the serialization syntax - essentially, interpreting dictionaries
> in JSON (and equivalent in other formats) as keyword arguments to a
> Model.objects.get() call.
>
> This approach works, but very rapidly gets messy. It's painfully easy
> to write a fixture that has circular, nested, or otherwise horribly
> knotted dependencies. There is also the issue of serialization - a
> query-based syntax is easy to deserialize, but how do you determine
> which fields should be included in a serialization?
>
> So, I've taken a different approach with this new patch. The new
> approach is much simpler and more explicit than the last. Rather than
> trying to embed a query into the serialization language, I've taken a
> step back and looked at the problem a different way.
>
> If there is some mechanism that can be used to look up instances of a
> model, then by definition, it must be a surrogate key of some kind.
> Completely independent of serialization, it would be nifty to be able
> to perform lookups based on this surrogate key.
>
> So, lets add a convention for these methods. As an example, consider
> contrib.auth Permissions (models have been slightly simplified for
> demo purposes).
>
> class PermissionManager(models.Manager):
>     def get_by_surrogate(self, key):
>         codename, ct_key = key.split('|',1)
>         return self.get(
>             codename=codename,
>             content_type=ContentType.objects.get_by_surrogate(ct_key)
>         )
>
> class Permission(models.Model):
>     name = models.CharField(max_length=50)
>     content_type = models.ForeignKey(ContentType)
>     codename = models.CharField(max_length=100)
>     objects = PermissionManager()
>
>     def surrogate_key(self):
>         return '%s|%s' % (self.codename, self.content_type.surrogate_key())
>
> There are two additions here - a get_by_surrogate() method on the
> default manager, and a surrogate_key() method on the model itself. If
> I have an instance of permission, I can call p.surrogate_key(), which
> will return 'add_user|auth:user'. If I want to get a particular
> permission, I can call
> Permission.objects.get_by_surrogate('add_user|auth:user'), and that
> will resolve to the appropriate permission (or raise an exception if
> no answer exists.
>
> So far, this is independent of serialization. These methods could be
> useful to end users for looking up permissions or content types.
>
> However, they're also really useful for serialization. The serializers
> can use the existence of these methods as cues for changes in
> serialization behavior. If a get_by_surrogate() method is found on the
> manager, the deserializer will use that method to look up objects; if
> surrogate_key() exists on the model, that will be used to serialize
> references to the object instead of using primary key values.
>
> So, a JSON serialized reference to a permission that previously read:
>
> {
>     "pk": 1,
>     "model": "auth.User",
>     "fields": {
>         ...
>         permissions = [ 1,3 ]
>     }
>
> }
>
> will now read:
>
> {
>     "pk": 1,
>     "model": "auth.User",
>     "fields": {
>         ...
>         permissions = [ "add_user|auth:user" ,"delete_user|auth:user" ]
>     }
>
> }
>
> The patch attached to #7052 implements this scheme, and includes
> surrogate key definitions for Permission and ContentType, plus tests
> to validate that this approach works.
>
> Two possible objections:
>
>  * It's a string-based serialization format. This means the developer
> will need to write parsing code and a microsyntax to handle composite
> surrogate keys (e.g., separating permission name from content type
> with a pipe, and separating app_label from model with a colon).
>
>  * You can only define one surrogate key. Some models might have more
> than one natural serialization.
>
> Personally, I'm comfortable with both of these limitations, but I'm
> interested in hearing other opinions.
>
> On a practical note - there is one failing test, which highlights the
> one flaw in this scheme that I am aware of. There is still a circular
> dependency problem - an object must be deserialized before it can be
> referenced using a surrogate key. I have a couple of ideas of how t

Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-03 Thread Russell Keith-Magee
On Fri, Dec 4, 2009 at 7:03 AM, Luke Plant  wrote:
> On Thursday 03 December 2009 15:33:44 Russell Keith-Magee wrote:
>
>> So, I've taken a different approach with this new patch. The new
>> approach is much simpler and more explicit than the last. Rather
>>  than trying to embed a query into the serialization language, I've
>>  taken a step back and looked at the problem a different way.
>>
>> If there is some mechanism that can be used to look up instances of
>>  a model, then by definition, it must be a surrogate key of some
>>  kind. Completely independent of serialization, it would be nifty
>>  to be able to perform lookups based on this surrogate key.
>
> This approach seems good to me.  I had a brief look at the patches on
> the ticket, and it was *much* easier to understand your draft patch
> than the alternative, which is a good sign, other things being equal.
>
>> Two possible objections:
>>
>>  * It's a string-based serialization format. This means the
>>  developer will need to write parsing code and a microsyntax to
>>  handle composite surrogate keys (e.g., separating permission name
>>  from content type with a pipe, and separating app_label from model
>>  with a colon).
>
> How easy would it be to fix this? If you used a list of string values,
> instead of a single string, wouldn't all the serialization formats
> handle this with very little work?  Without looking at the code, I
> imagine that JSON and YAML at least would. You are still forcing
> things to be to be converted to strings and back, but there are
> usually standard ways to do that.

Interesting thought. JSON and YAML serialization of list/tuples would
be able to handle this almost transparently - in fact, it probably
works right now if you modify the surrogate implementations to
return/accept lists/tuples.

XML will require a bit more work, but it should still be possible.
I'll take a look and see what I can do.

>>  * You can only define one surrogate key. Some models might have
>>  more than one natural serialization.
>
> I agree that this limitation isn't serious.  If you added support for
> multiple surrogate keys, you'd need to add methods to specify which
> one should be used, and thread that option through all the
> serialization code...
>
> I think the limitation could become more significant if other parts of
> Django started relying on these surrogate key methods, we should think
> about that if it comes up.
>
>> On a practical note - there is one failing test, which highlights
>>  the one flaw in this scheme that I am aware of. There is still a
>>  circular dependency problem - an object must be deserialized
>>  before it can be referenced using a surrogate key.
>
> I presume this problem would exist with the alternative method on that
> ticket as well, right?

Correct. We never arrived at a way to implement serialization under
the old approach, so this never really became an issue.

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-develop...@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.




Re: #7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-03 Thread Luke Plant
On Thursday 03 December 2009 15:33:44 Russell Keith-Magee wrote:

> So, I've taken a different approach with this new patch. The new
> approach is much simpler and more explicit than the last. Rather
>  than trying to embed a query into the serialization language, I've
>  taken a step back and looked at the problem a different way.
> 
> If there is some mechanism that can be used to look up instances of
>  a model, then by definition, it must be a surrogate key of some
>  kind. Completely independent of serialization, it would be nifty
>  to be able to perform lookups based on this surrogate key.

This approach seems good to me.  I had a brief look at the patches on 
the ticket, and it was *much* easier to understand your draft patch 
than the alternative, which is a good sign, other things being equal.

> Two possible objections:
>
>  * It's a string-based serialization format. This means the
>  developer will need to write parsing code and a microsyntax to
>  handle composite surrogate keys (e.g., separating permission name
>  from content type with a pipe, and separating app_label from model
>  with a colon).

How easy would it be to fix this? If you used a list of string values, 
instead of a single string, wouldn't all the serialization formats 
handle this with very little work?  Without looking at the code, I 
imagine that JSON and YAML at least would. You are still forcing 
things to be to be converted to strings and back, but there are 
usually standard ways to do that.

>  * You can only define one surrogate key. Some models might have
>  more than one natural serialization.

I agree that this limitation isn't serious.  If you added support for 
multiple surrogate keys, you'd need to add methods to specify which 
one should be used, and thread that option through all the 
serialization code...

I think the limitation could become more significant if other parts of 
Django started relying on these surrogate key methods, we should think 
about that if it comes up.

> On a practical note - there is one failing test, which highlights
>  the one flaw in this scheme that I am aware of. There is still a
>  circular dependency problem - an object must be deserialized
>  before it can be referenced using a surrogate key. 

I presume this problem would exist with the alternative method on that 
ticket as well, right?

Regards,

Luke

-- 
"I am going to let you move around more, just to break up the 
mahogany." (True Quotes From Induhviduals, Scott Adams)

Luke Plant || http://lukeplant.me.uk/

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@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.




#7052 - Fixing serialization for contrib.contenttypes and contrib.auth

2009-12-03 Thread Russell Keith-Magee
Hi all,

I've been looking at ticket #7052 again. I've got a draft patch up on
Trac, and I'd like feedback on the approach.

Previously, I've been advocating the approach of embedding queries
into the serialization syntax - essentially, interpreting dictionaries
in JSON (and equivalent in other formats) as keyword arguments to a
Model.objects.get() call.

This approach works, but very rapidly gets messy. It's painfully easy
to write a fixture that has circular, nested, or otherwise horribly
knotted dependencies. There is also the issue of serialization - a
query-based syntax is easy to deserialize, but how do you determine
which fields should be included in a serialization?

So, I've taken a different approach with this new patch. The new
approach is much simpler and more explicit than the last. Rather than
trying to embed a query into the serialization language, I've taken a
step back and looked at the problem a different way.

If there is some mechanism that can be used to look up instances of a
model, then by definition, it must be a surrogate key of some kind.
Completely independent of serialization, it would be nifty to be able
to perform lookups based on this surrogate key.

So, lets add a convention for these methods. As an example, consider
contrib.auth Permissions (models have been slightly simplified for
demo purposes).

class PermissionManager(models.Manager):
def get_by_surrogate(self, key):
codename, ct_key = key.split('|',1)
return self.get(
codename=codename,
content_type=ContentType.objects.get_by_surrogate(ct_key)
)

class Permission(models.Model):
name = models.CharField(max_length=50)
content_type = models.ForeignKey(ContentType)
codename = models.CharField(max_length=100)
objects = PermissionManager()

def surrogate_key(self):
return '%s|%s' % (self.codename, self.content_type.surrogate_key())

There are two additions here - a get_by_surrogate() method on the
default manager, and a surrogate_key() method on the model itself. If
I have an instance of permission, I can call p.surrogate_key(), which
will return 'add_user|auth:user'. If I want to get a particular
permission, I can call
Permission.objects.get_by_surrogate('add_user|auth:user'), and that
will resolve to the appropriate permission (or raise an exception if
no answer exists.

So far, this is independent of serialization. These methods could be
useful to end users for looking up permissions or content types.

However, they're also really useful for serialization. The serializers
can use the existence of these methods as cues for changes in
serialization behavior. If a get_by_surrogate() method is found on the
manager, the deserializer will use that method to look up objects; if
surrogate_key() exists on the model, that will be used to serialize
references to the object instead of using primary key values.

So, a JSON serialized reference to a permission that previously read:

{
"pk": 1,
"model": "auth.User",
"fields": {
...
permissions = [ 1,3 ]
}
}

will now read:

{
"pk": 1,
"model": "auth.User",
"fields": {
...
permissions = [ "add_user|auth:user" ,"delete_user|auth:user" ]
}
}

The patch attached to #7052 implements this scheme, and includes
surrogate key definitions for Permission and ContentType, plus tests
to validate that this approach works.

Two possible objections:

 * It's a string-based serialization format. This means the developer
will need to write parsing code and a microsyntax to handle composite
surrogate keys (e.g., separating permission name from content type
with a pipe, and separating app_label from model with a colon).

 * You can only define one surrogate key. Some models might have more
than one natural serialization.

Personally, I'm comfortable with both of these limitations, but I'm
interested in hearing other opinions.

On a practical note - there is one failing test, which highlights the
one flaw in this scheme that I am aware of. There is still a circular
dependency problem - an object must be deserialized before it can be
referenced using a surrogate key. I have a couple of ideas of how to
address this (essentially fixing it at the dumpdata level with model
ordering), but I wanted to get community approval for the general idea
before I did too much work on fixing the edge cases.

So - opinions?

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-develop...@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.




Re: #7611 contrib.auth PasswordResetTest requires specific templates for tests to pass

2008-11-10 Thread Matt Brown

Not intending to derail the test-skip angle (which sounds generally
useful), but in this case, wouldn't a better fix be to eliminate the
dependency on admin, by providing the needed templates in the auth
test suite itself?  PasswordResetTest could also duplicate the setup/
teardown methods used by ChangePasswordTest, to ensure that the
correct templates are used during the test.

- Matt Brown


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: #7611 contrib.auth PasswordResetTest requires specific templates for tests to pass

2008-10-31 Thread Siddhi

On Sep 7, 6:32 am, sciyoshi <[EMAIL PROTECTED]> wrote:
> On Jul 19, 2:15 am, "Russell Keith-Magee" <[EMAIL PROTECTED]>
> wrote:
>
> Not sure if this should be considered a related issue - theauthtests
> use a different urlconf that only include theauthurls, so if you
> provide custom registration templates that do reverse lookups with {%
> url %} for other urls in your projects, the tests fail...

Exactly, I ran into this problem as well. By overriding the urls, all
the other reverse lookups in the template start failing. Maybe reverse
lookups should fail silently while running under a unit tests?

--
Siddharta Govindaraj
http://siddhi.blogspot.com
http://www.silverstripesoftware.com/blog/
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: Decouple messages from contrib.auth

2008-10-28 Thread SmileyChris

On Oct 29, 5:50 am, "Rob Hudson" <[EMAIL PROTECTED]> wrote:
> From the looks of it, the patch onhttp://code.djangoproject.com/ticket/4604 
> is heading this direction
> re: backwards compatible and part of contrib.sessions.
>
> Maybe SmileyChris can speak to both of these points and if it could be
> a potential solution?

Rob is correct. The goal of the patch is to:
1. have session messages functionality
2. make the `messages` context variable lazy (rather than forcing a
get_and_delete every request just because you use the processor)
3. make the `messages` context variable contain both session and user
messages for backwards compatibility

Apart from a required refactor to use lazy(), the patch works fine and
achieves backwards compatibility in quite a nice way (a messages
context processor is made available for those that don't want to use
the default-enabled auth processor).
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: Decouple messages from contrib.auth

2008-10-28 Thread Rob Hudson

On 10/28/08, Jacob Kaplan-Moss <[EMAIL PROTECTED]> wrote:
>
>  On Mon, Oct 20, 2008 at 12:33 PM, Rob Hudson <[EMAIL PROTECTED]> wrote:
>  > I think decoupling messages from contrib.auth is a worthy step to
>  > making auth a little bit more reusable.
>
> Agreed. However, doing this in a backwards-compatible manner is going
>  to be tricky.
>
>  > By doing so, however, Django would need to ship with a
>  > contrib.messages (or similar) app which brings with it other thoughts
>  > and considerations:
>
> Probably it'd make sense to make this part of
>  ``django.contrib.sessions``; there's no real way to pass messages
>  without at least an anonymous session.

>From the looks of it, the patch on
http://code.djangoproject.com/ticket/4604 is heading this direction
re: backwards compatible and part of contrib.sessions.

Maybe SmileyChris can speak to both of these points and if it could be
a potential solution?

Thanks,
Rob

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



  1   2   >