I got a little confused about the auth docs.
Both is_staff and is_active designates that a user can log into the
admin, so... what's the real difference?
I've made some tests combining active, staff and superuser:
- Only active: no login
- Only staff: login but no default permissions
- Only super: no login
- Active+staff: login but no default perms
- Active+super: no login
- Staff+super: login but no default perms
- Active+staff+super: ok
And what fields should be checked (True) to a normal site user
(non-admin)?
Sorry about the mess...
Regards.
Enrico
My (limited) understanding is that a User who `is_active` is a user in
the system which may be able to access restricted views that you
create (according to your specifications). However, that user cannot
access the admin (usually a good thing).
`is_staff` indicates that the user can access the admin. Of course,
that only works when the user also `is_active`. The idea is that
rather than deleting a user (staff or not), the record would remain in
the db but would be set to "not active." Django is smart enough to
know that a "non-active" user has no perms regardless of any other
settings in that users records.
As far as "super" goes, that is just a shortcut to give "staff" all
perms. Otherwise, perms need to be manually set for each user (groups
certainly make this easier). Obviously, if a user is not "staff" they
could not be "super" either and Django is smart enough to figure that
out. the "non-active" user stuff applies here as well.
Hope that helps clear the fog. :-)
--
----
Waylan Limberg
way...@gmail.com
Thanks for your help, the fog has gone now. :)
Maybe the docs should be a little clearer...
Regards.
Enrico
Just to further Waylan's comments:
The purpose of 'is_active' is to identify an 'active' user - that is,
a user whose account can still be used to log in.
This is an alternative to deleting an account when you want to remove
access for a user. If there are artefacts in your database that
reference a specific user (e.g., a comment), you may not want to
delete the user, as this would delete the related artefacts.
> Maybe the docs should be a little clearer...
Do you have any specific suggestions? Is there any specific area that
you feel could be improved? Something that has been ommitted?
Something that is misleading? The documentation on authentication
describes is_active in the API reference for the fields of the User
model - is this description inadequate? Should it be
repeated/referenced somewhere else?
Specific requests and/or specific problems can be addressed and fixed;
blanket statements tend to get ignored due to a lack of telepathy on
the part of the developers :-)
Yours,
Russ Magee %-)
As I said, in my tests an inactive user with staff status could log
into the admin, but had no permissions even if he's a superuser.
I think he shouldn't be able to log in at all, instead of logging in
and being able to do nothing.
In the admin, he can't see nothing, but in other parts of the project
he'll be able to log in. If I use the is_authenticated() to show/hide
private content, an inactive user would be able to see this content,
and that doesn't feel right. The user should be treated almost as
'deleted'.
The is_staff and is_active description in the docs looks very similar.
Maybe should be clarified that is_staff is only Django admin related,
and is_active is related to the entire Django Auth, not only admin.
Just my thoughts, hope I'm not being picky with this.
Best Regards.
Enrico
That is my reading of the docs, too; I was a little surprised when
testing revealed that this wasn't the actual behaviour. I've just
committed r3884 to rectify this situation.
> In the admin, he can't see nothing, but in other parts of the project
> he'll be able to log in. If I use the is_authenticated() to show/hide
> private content, an inactive user would be able to see this content,
> and that doesn't feel right. The user should be treated almost as
> 'deleted'.
This is a slightly different matter; is_authenticated() only validates
that the user has provided a username and password that match. It is
up to your views to validate that the currently authenticated user
(i.e., they have provided a correct username and password, so we know
who they are) is allowed to see a page, modify data etc. The
AuthenticationForm that is part of contrib.auth.forms validates that a
user account is active before allowing login; if you are writing your
own login views, you should take similar steps.
> The is_staff and is_active description in the docs looks very similar.
I've clarified this a little in the r3884.
> Maybe should be clarified that is_staff is only Django admin related,
> and is_active is related to the entire Django Auth, not only admin.
Not strictly true; since Django can't make guarantees about the views
that end users write.
> Just my thoughts, hope I'm not being picky with this.
Picky is a good thing, as long as its constructive. Constructive
pickyness means that bugs get found and Django gets improved for all
to benefit.
Yours,
Russ Magee %-)
Nice to see that my "report" was useful, I'll try to keep with the
pickyness then. :)
> This is a slightly different matter; is_authenticated() only validates
> that the user has provided a username and password that match.
About this, I just thought that the authenticate method should require
an active user. But it won't hurt to check myself or use the default
AuthenticationForm.
Thanks for the help and for the fixes.
Best regards.
Enrico
This was my understanding as well, from reading the docs. I would consider
an "is_active = False" to be the same as user/password did not match. After
all, the main logic behind is_active is we want to "delete" a user without
actually deleting him (to not create missing foreign keys).
I have not looked further into this, I just blindly assumed that a user that
is authenticated has both supplied correct username/password and can actually
login (ie. is_active). The inverse situation, where we would want to check a
user/pass even if the user cannot login, is far less likely. Maybe it would
be appropriate to make the situations more explicit. For example,
is_valid_user() [user exists, passwords match] and is_authenticated()
[is_valid_user() and can actually use the system]. The method names need
work, but I think this is a valid issue -- maybe at least make this more
explicit in the docs.
Norbert
I agree. I'm just not so sure about the is_valid_user method, people
will have to start checking for this method instead of checking for an
existent user.
I can't imagine someone needing to authenticate a non-active user, and
even if someone do, he'll be able to do it manually, or passing
"is_active=False" to the authenticate method.
In other hand, maybe (note: maybe) this can break projects that don't
check for this flag.
So, I can see two paths:
- change this behaviour;
- make a note in the docs that inactive users can authenticate.
Best regards.
Enrico
I can think of one obvious use case - notifying a user that their
account has been disabled: e.g.,
if authenticated:
if active:
show content
else:
show "account disabled"
else:
show "invalid username"
> In other hand, maybe (note: maybe) this can break projects that don't
> check for this flag.
>
> So, I can see two paths:
> - change this behaviour;
> - make a note in the docs that inactive users can authenticate.
I've updated docs to clarify is_authenticated and has_perm (r3885).
However, I'm not convinced of the merits of the change you are
proposing. The existing behaviour is atomic, allow for a range of user
authentication possibilities. Hopefully, with the recent documentation
fixes, these features make more sense.
Yours,
Russ Magee