Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-11 Thread Mehmet Dogan
Hello all,

I had opened a ticket re issue noted in subject, which happened to be a 
duplicate, anyways, the text is here 
:

Tim Graham told that it needs to be discussed here. Seems this is a long 
going issue, with several related issues (see also this one 
). I propose a 
solution in the first link 
:

If receives public support, I can also start working on a patch. 

Regards,

Mehmet

-- 
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/a597ce64-4d0c-43d5-a2c6-eb7813dca244%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-11 Thread Mehmet Dogan
Here is the text of linked stuff for convenience:

For authorization backends checking object level permissions (like 
guardian) usually requires calling the django's default authorization 
backend as a fallback to the more general set of permissions:

if user.has_perm('foo.change_bar', obj=bar) or user.has_perm('foo.change_bar'):
...


However, this not only looks ugly, but also requires polling of all the 
backends twice, and thus, is a performance loss. 


First, and possibly the best, solution to this is that, django does not 
deny permission if obj argument is provided, but just ignores it. This is 
also very logical, one who has a permission for the entire model/table, 
would also have it for an instance/row. This way by properly ordering 
backends in the settings, it could be a fallback solution for the lower 
level checkers. This might be the move in the right direction, although it 
is backwards incompatible. 


A second solution is a keyword argument, such as fallback_to_model=None, 
that will allow lower-level checkers mimic the model level permissions that 
django does. Obviously, this is not DRY. But is needed if the first 
solution is not accepted to get the necessary permissions with one round of 
polling, and without cluttering the code. If it was accepted, it would 
still be a useful addition since it would allow backends to prefer to 
handle the fallback by themselves. Or, it would allow users who fallback by 
default override that behavior and not fallback (via a value of False), 
i.e., when object level permissions are definitive. 

-- 
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/6dec9e1b-e017-47ad-98bb-83a9e9d9b975%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-11 Thread Mehmet Dogan
And the other:

Here is what I propose in terms of working around the backward 
compatibility that seems to have kept it from being solved for so long. 


1) define a global setting, say: OBJECT_PERMISSION_FALLBACK_TO_MODEL=False. 
This is to help maintain the default behavior (unless the setting is 
changed of course). 


2) (as mentioned in the above comment) define a keyword argument at the 
method level for occasional override, say: fallback_to_model=None. Default 
value of None means it will be ignored in favor of the global setting, 
otherwise, it will take precedence. 


I can work on a patch if found reasonable. 

-- 
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/2786c98d-cb01-4a22-b483-e6dd07b061fc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-11 Thread Mehmet Dogan
Here is a sample patch:

https://github.com/doganmeh/django/commit/d85cd3a530984ab5e4cb42f93629a64eb0b65b07

-- 
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/612b26a2-4d13-4d9b-a52a-ed36276a51aa%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-11 Thread Mehmet Dogan

Based on this patch: the following 3 methods in the custom authorization 
backends will have to admit a *fallback_to_model *keyword argument:

*def *has_perm(self, user_obj, perm, obj=None, fallback_to_model=None)

def get_group_permissions(self, user_obj, obj=None, fallback_to_model=None)

def get_all_permissions(self, user_obj, obj=None, fallback_to_model=None)


this is the backward incompatible part


-- 
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/42c61480-fa7d-4031-bede-f54126fa3966%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-12 Thread Mehmet Dogan
Created a pull request: https://github.com/django/django/pull/9581

Mehmet

-- 
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/e617c213-a5c7-4b84-a12f-58a4154d1482%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-16 Thread Mehmet Dogan


Seems like I found a better keyword argument than fallback_to_model. For 
the following backends setting:

AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',  
'guardian.backends.ObjectBackend',
'roles.backends.RoleBackend',
)

And the ways to check:

user.has_perm('foo.change_bar', obj) 
# default: check all, model checker expected to NOT disown her child

user.has_perm('foo.change_bar', obj, backends=('object', 'role', ))  
# just check backends specified; 'role' for *.RoleBackend

Advantages:

   - One will not have to use package specific API for checking just the 
   object permissions, for example.
   - Cleaner and generic: allows backends re-use each other. For example, I 
   am writing a RoleBackend and can easily make calls to model or object 
   permission backends, in order not to reinvent the wheel.

-- 
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/f637e9ca-b345-4c0f-92e7-b80464e9b6da%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-16 Thread Mehmet Dogan
And I forgot; 3rd advantage:


   - The 3 backend methods mentioned above won't have to take an extra 
   kwarg such as fallback_to_model; thus backward compatible there.

-- 
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/7b494b07-bef1-4824-87f8-d010f9b5432a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-16 Thread Mehmet Dogan
I updated my patch:

https://github.com/django/django/pull/9581

-- 
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/b309e677-816b-4c5f-a2d1-e642d6c3551a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-17 Thread Mehmet Dogan
Florian,

Can you clarify this part, I am not sure what you meant:

> in the worst case the user would have to change the permission backend
which is easy enough…

On Wed, Jan 17, 2018 at 10:31 AM Florian Apolloner 
wrote:

>
>
> On Wednesday, January 17, 2018 at 11:45:05 AM UTC+1, Carlton Gibson wrote:
>>
>> The objection is to this kind of check:
>>
>> if user.has_perm('foo.change_bar', obj=bar) or
>> user.has_perm('foo.change_bar'):
>> ...
>>
>
> FWIW  I would never write code like this. `user.has_perm('foo.change_bar',
> obj=bar)` would be enough, in the worst case the user would have to change
> the permission backend which is easy enough…
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/django-developers/MLWfvPPVwDk/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/242593f2-b218-43b7-bb17-bd5ca7e2634f%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/CAFdefwNXkA8c2SD2kRsMBuzKk2Xwt4SJMtpWyro3q%2BtXzYEHpQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


RE: Default Authorization BackEnd Denying Permissions if ObjectProvided

2018-01-17 Thread Mehmet Dogan
Carlton,

First, thanks for stirring the conversation. Can you give an example of what 
you mean by option 3. The comment you linked did not have much detail. Thanks, 

From: Carlton Gibson
Sent: Wednesday, January 17, 2018 4:45 AM
To: Django developers (Contributions to Django itself)
Subject: Re: Default Authorization BackEnd Denying Permissions if ObjectProvided

Hi Mehmet, 

Due to the BC issues, this is fairly in-depth. 

Having looked at the history, here are my initial thoughts. 



The initial issue here is this behaviour from `ModelBackend`:

```
user.has_perm('foo.change_bar', obj)
False
user.has_perm('for.change_bar')
True
```

Although the long-standing behaviour, this is considered _unexpected_.

Ticket is: https://code.djangoproject.com/ticket/20218

There are two related tickets regarding permission-checking in the Admin:

* https://code.djangoproject.com/ticket/13539
* https://code.djangoproject.com/ticket/11383

Currently, I see three options:

1. Close as "Won't Fix", perhaps with a review of the documentation to see if we
   can't clarify/emphasise the behaviour somewhere.

    This is the path of least resistance. It conforms to the original design
    decision. It preserves the long-standing behaviour. (Whilst, yes, some find 
the
    behaviour unexpected, it has a sense; it just depends how you look at it.)

    The objection is to this kind of check:

        if user.has_perm('foo.change_bar', obj=bar) or 
user.has_perm('foo.change_bar'):
            ...

    * Whilst, granted, it's a little clumsy, there's no reason this couldn't be
      wrapped in a utility function. (There's a suggestion to that effect on the
      Django-Guardian issue tracker[^1]. This seems like a good idea, simple 
enough
      to live in user code.)
    * `ModelBackend` permission lookups are cached[^2] so the performance worry
      here should be negligible.

2. Implement the (straight) backwards incompatible change.

    The difficulty here is (we guess) why this ticket has been open so long.

    If we are convinced this is the right way to go — i.e. that the current
    behaviour is in fact **wrong** — then we should go ahead despite the
    difficulty.

    Working out what that entails is non-trivial. That's why it needs a decent
    discussion and consensus here.

    Which leads to...

3. Break out the permissions aspect of `ModelBackend` in order to make it 
   pluggable in some way. Then allow users to opt-in to a new version with the 
   adjusted behaviour.
   
   There is some discussion of this on one of the related tickets[^3].
   
   Again, exactly what the migration path is needs some planning. 

I'm not sure what the correct answer is. 

[^1]: https://github.com/django-guardian/django-guardian/issues/459
[^2]: 
https://docs.djangoproject.com/en/2.0/topics/auth/default/#permission-caching
[^3]: f.f. https://code.djangoproject.com/ticket/13539#comment:16


Kind Regards,

Carlton

-- 
You received this message because you are subscribed to a topic in the Google 
Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/django-developers/MLWfvPPVwDk/unsubscribe.
To unsubscribe from this group and all its topics, 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/cab981b8-7dc7-4e9d-9dcc-442b36820cdf%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/5a5fa805.0543ca0a.cde47.dde6%40mx.google.com.
For more options, visit https://groups.google.com/d/optout.


RE: Default Authorization BackEnd Denying Permissions if ObjectProvided

2018-01-17 Thread Mehmet Dogan
Although I found it very interesting at first, this looks dangerous since it 
changes how the API work for all apps installed. Example, guardian makes calls 
to user.has_perm(perm) in several places to check model permissions. Although 
periphery features, they would be broken. 

From: Florian Apolloner
Sent: Wednesday, January 17, 2018 12:45 PM
To: Django developers (Contributions to Django itself)
Subject: Re: Default Authorization BackEnd Denying Permissions if ObjectProvided

On Wednesday, January 17, 2018 at 5:48:03 PM UTC+1, Mehmet Dogan wrote:
Florian,

Can you clarify this part, I am not sure what you meant:


class MyBackend(ModelBackend):

   def has_perm(…, obj=None,…):
     if obj: obj = None
     return super().has_perm(…)

something along the lines of this should do it. 
-- 
You received this message because you are subscribed to a topic in the Google 
Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/django-developers/MLWfvPPVwDk/unsubscribe.
To unsubscribe from this group and all its topics, 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/ff0142a5-cca0-4d8c-8497-b988b04ba4ca%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/5a5fac41.1b5b9d0a.5a28c.069e%40mx.google.com.
For more options, visit https://groups.google.com/d/optout.


RE: Default Authorization BackEnd Denying Permissions ifObjectProvided

2018-01-17 Thread Mehmet Dogan
Or, extend ModelBackend to override the object-denying behavior, and provided 
that as an option. Am I getting you right?

Seems like options for changing the global behavior is growing. However, I 
still think there is need for local override. Otherwise, re-usable apps will 
have to adopt either of the global defaults, and so will the app developers, 
since it will not be possible to mix the two exclusive groups. 


From: Carlton Gibson
Sent: Wednesday, January 17, 2018 2:04 PM
To: Django developers (Contributions to Django itself)
Subject: Re: Default Authorization BackEnd Denying Permissions ifObjectProvided

Hi. 

@Andrew: I'll look at your post anon, as it's longer. 

On Wednesday, 17 January 2018 20:46:27 UTC+1, Mehmet Dogan wrote:
Can you give an example of what you mean by option 3. 

Well, I don't a concrete suggestion in mind, but the general idea would be to 
have ModelBackend proxy to another class (a Strategy ?) that did the actual 
permission check. 

We'd then have (at least) two versions: one with the current implementation, 
and one with the alternative. 

Exactly how the user would configure which version to use (etc) would need 
thinking about. 

The question is whether it's worth the price of admission, vs just, say, 
subclassing ModelBackend. 

C.
-- 
You received this message because you are subscribed to a topic in the Google 
Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/django-developers/MLWfvPPVwDk/unsubscribe.
To unsubscribe from this group and all its topics, 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/fc4b4544-dd15-4672-8a5b-27e9bcb7d4a9%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/5a5fb78e.cc579d0a.c60a5.0459%40mx.google.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if ObjectProvided

2018-01-17 Thread Mehmet Dogan
Yea :) I just figured that after a few emails. I am learning a lot!

On Wed, Jan 17, 2018 at 3:39 PM Florian Apolloner 
wrote:

>
>
> On Wednesday, January 17, 2018 at 9:04:30 PM UTC+1, Mehmet Dogan wrote:
>>
>> Although I found it very interesting at first, this looks dangerous since
>> it changes how the API work for all apps installed. Example, guardian makes
>> calls to user.has_perm(perm) in several places to check model permissions.
>> Although periphery features, they would be broken.
>>
>
> Funny that you would say that, because your proposed setting
> OBJECT_PERMISSION_FALLBACK_TO_MODEL does exactly the same thing ;)
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/django-developers/MLWfvPPVwDk/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/6f2b5df3-84dd-4bc2-b945-4cc80a838372%40googlegroups.com
> <https://groups.google.com/d/msgid/django-developers/6f2b5df3-84dd-4bc2-b945-4cc80a838372%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> 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/CAFdefwOmrFG7HocZsgq76-GDknGenjagp%2BfqCFmc5WN6stG1HA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-17 Thread Mehmet Dogan
Andrew,

Thank you for the input. Having options is good. My concern about that is,
it may divide the already small backends population. If a backend relies on
PermissionAuthorizationBackend, and another require the
ModelOnlyPermissionAuthorizationBackend; then one cannot use both.
Guardian, at its core, is agnostic of the default backend
behavior, however, relies on it in some utilities. However, I am working on
a simple RolePermissionsBackend now that leverages existing Object and
Model backends at its core. Currently, if I do
`user.has_perm('foo.change_bar')` or `user.has_perm('foo.change_bar', obj)`
I know one is the model and the other is the object permissions. In case of
plug-ins, that will go away, and it will be even harder to leverage
existing backends. Also, the logic that polls backends is in
auth/models.py, I do not see how would it be possible to design an API that
will let picking and choosing.

On Wed, Jan 17, 2018 at 12:58 PM Andrew Standley <
astand...@linear-systems.com> wrote:

> Hi Carlton,
> Thanks for the thoughts. I just wanted to share my opinion on your
> options.
>
> 1. "Won't Fix"
> I have yet to find anywhere the original design decisions were
> documented. Based on what I can find, it appears that object level
> permissions where a bit of an after-though for the initial auth framework.
> Unless we can find the motivation for the original design decision it seems
> foolish to leave *unexpected* behaviour simply because that's how it has
> always been.
>
> I understand the motivation for wanting to only check object level
> permissions, but I would argue that the design of the API insinuates a
> hierarchical behaviour which is part of the reason the current behaviour is
> unexpected.
> Specifically why use an 'obj' kwarg instead of having two methods?
>
> To me if the API where:
> ```
> has_perm('foo.change_bar')
> has_obj_perm('foo.change_bar', bar_obj)
> ```
> I would expect `has_perm` to only deal with model level permissions and
> `has_obj_perm` to only deal with object level permissions
>
> To me the current API:
> ```
> has_perm('foo.change_bar', obj=bar_obj)
> ```
> Implies that the method will always check model level permissions and can
> *optionally* check object level permissions.
>
> Having to always call `if user.has_perm('foo.change_bar', obj=bar) or
> user.has_perm('foo.change_bar')` both seems ugly, and relies on backend
> authors following ModelBackend's example of caching permission look-ups.
> Otherwise there may be a performance cost. The AUTH_BACKEND system's
> strength is the ability to plug in third-party and custom backends, it
> seems dangerous to make assumptions based on ModelBackend unless those
> assumptions are clearly documented.
>
> 2. Change ModelBackend
> Initially this would have been my preferred option. However having given
> the issue significant thought, I think that it is important that users are
> still given the option of the current behaviour.
> Having an API return only object level permissions when called with obj,
> while returning only model level permissions when called without obj is a
> legitimate use case.
> Which leads me to
>
> 3. Break out permissions aspects.
> I agree this would require some planning for migration. It also requires
> discussion on whether the desire would be to separate authentication from
> authorization or if the auth framework should just offer more default
> options.
> However overall I think this is the best option. It leverages the
> flexibility of the backend system and offers the option of maintaining BC
> if desired.
>
> For example it would make sense to me to plan on restructuring the
> auth.backends to something like:
>
> ```
> ModelAuthenticationBackend(object):
> # defines get_user and authenticate
>
> PermissionAuthorizationBackend(object):
> # defines get_user_permissions, get_group_permissions,
> get_all_permissions, has_perm, has_module_perms
> # 'New' behaviour: checks model level permissions *even* when obj is None
>
> ModelOnlyPermissionAuthorizationBackend(object):
> # defines get_user_permissions, get_group_permissions,
> get_all_permissions, has_perm, has_module_perms
> # Current behaviour: checks model level permissions *only* when obj is Non
>
> ModelPermissionBackend(ModelAuthenticationBackend,
> PermissionAuthorizationBackend):
>
>pass
>
> ModelBackend(ModelAuthenticationBackend,
> ModelOnlyPermissionAuthorizationBackend):
>
> pass
> ```
>
> This offers users more options for their authorization/authentication
> needs, and should make migration easier as you could gradually depreciate
> the name 'ModelBackend' in favour of something like
> 'ModelPermissionOnlyBackend'
> Additionally if Mehmet wanted to finalize an API that allowed users to
> specify a subset of backends to check against, this approach would support
> that.
>
> Cheers,
> Andrew
>
>
> On 1/17/2018 2:45 AM, Carlton Gibson wrote:
>
> Hi Mehmet,
>
> Due to the BC issues, this is fairly in-depth.
>

Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-17 Thread Mehmet Dogan
The "expected behavior" is that *one has permission on an entire table
would also have permission on a row of it*. This seems to be the one thing
that everyone can agree on. And, I am yet to see a person that argues
otherwise. But, it seems, we just need someone or some people to make
that *hard
*decision.

If that is the way forward, I will volunteer for the code. But, as you also
point out, there needs to be a *path* out. That I don't know :)

If I could pick and choose the backends, or types of backends, such as:

user.has_perm('foo.change_bar', obj, backends=('object', 'role', 'model'))

that would be lovely. However, I think I can live without it.

Cheers,

Mehmet


On Wed, Jan 17, 2018 at 3:38 PM Florian Apolloner 
wrote:

> On Wednesday, January 17, 2018 at 7:58:17 PM UTC+1, Carlton Gibson wrote:
>>
>> Given your comment, would it be along the lines of "Close as "Won't Fix",
>> perhaps with a review of the documentation", to point users to subclassing
>> ModelBackend if they need the alternate behaviour?
>>
>
> My comment
> https://github.com/django/django/pull/9581#pullrequestreview-88665130
> sums up my thoughts. We should decide what the expected behavior for auth
> backends should be and then work towards that (if that means it should
> return True instead of False for obj!=None so be it). I am not happy with
> any of the proposed solutions so far (be that new arguments or settings).
>
> Btw, it would be nice if you could be on IRC if your time permits it.
>
> Cheers,
> Florian
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/django-developers/MLWfvPPVwDk/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/c981a74f-4dd1-418f-b1f1-a2d6d383466c%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/CAFdefwOXpKRNhDN-55XGFN%2Bk9Gsb6g9feW1uLWiUCwzD8JLr6w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-18 Thread Mehmet Dogan
Andrew,

Yes, I think we can safely assume *apps *would be backend agnostic. I was
actually referring to the *backends *themselves, if they use
user.has_perm(...). This might sound counter-intuitive at first but I think
it is possible, and actually I am working on one right now (see my long
answer for details).

*Long Answer:* I am trying to write a Roles backend with, and without
reinventing the wheels for, object and model permissions. The logic is very
simple.

class Role(models.Model):
   delegate = models.OneToOneField(Permission,* ...*)
   perms = models.ManyToManyField(Permission, *...*)
*...*

Delegate is a permission for each role that lets a user use it, e.g.,
'roles.use_role_xx'; and the `perms` are the actual
permission in the Role. And my backend (pseudo code):

def has_perm(self, user_obj, perm, obj=None):
   if perm is delegate:
 ignore;

   delegates = get_delegates_representing(perm)

   for delegate in delegates:
  if user_obj.has_perm(delegate, obj):  # refer to existing other backends
 return True
   return False

1) Now, as seen above user_obj.has_perm(delegate, obj) is written for
the proposed way, and would not work with the current
way as model permissions would be excluded.

2) In order to prevent infinite loops, I have to strictly separate
permissions that represent Roles (namely delegates) and
permissions in the roles. If I could specify backends as I proposed
earlier, I could even take this even one step further
and allow roles include other roles (that would be awesome).

3) I have not tested or used this. And one might see it as a hairy design
to be disregarded. But I claim it has a fair chance to be
otherwise. *When it comes to backends we don't have plenty of choices, and
allowing them leverage each other will just make*
*it easier to write them. *

*Thanks for reading so far! :)*

On Wed, Jan 17, 2018 at 8:42 PM Andrew Standley <
astand...@linear-systems.com> wrote:

> Mehmet,
> Can you explain to me what the situation would be that an app could
> simply not be backend agnostic?
> Given that AUTHENTICATION_BACKENDS is a *user* configuration, it seems
> odd that an app would ever design around specific backends being installed.
> I'm not sure I follow your logic on this.
> Regarding an API that will allow picking and choosing I already have some
> ideas, but I think Carlton made an excellent point that that is another
> discussion all together.
>
> Cheers,
> Andrew
>
>
> On 1/17/2018 5:34 PM, Mehmet Dogan wrote:
>
> Andrew,
>
> Thank you for the input. Having options is good. My concern about that is,
> it may divide the already small backends population. If a backend relies on
> PermissionAuthorizationBackend, and another require the
> ModelOnlyPermissionAuthorizationBackend; then one cannot use both.
> Guardian, at its core, is agnostic of the default backend
> behavior, however, relies on it in some utilities. However, I am working on
> a simple RolePermissionsBackend now that leverages existing Object and
> Model backends at its core. Currently, if I do
> `user.has_perm('foo.change_bar')` or `user.has_perm('foo.change_bar', obj)`
> I know one is the model and the other is the object permissions. In case of
> plug-ins, that will go away, and it will be even harder to leverage
> existing backends. Also, the logic that polls backends is in
> auth/models.py, I do not see how would it be possible to design an API that
> will let picking and choosing.
>
> On Wed, Jan 17, 2018 at 12:58 PM Andrew Standley <
> astand...@linear-systems.com> wrote:
>
> Hi Carlton,
>> Thanks for the thoughts. I just wanted to share my opinion on your
>> options.
>>
>> 1. "Won't Fix"
>> I have yet to find anywhere the original design decisions were
>> documented. Based on what I can find, it appears that object level
>> permissions where a bit of an after-though for the initial auth framework.
>> Unless we can find the motivation for the original design decision it seems
>> foolish to leave *unexpected* behaviour simply because that's how it has
>> always been.
>>
>> I understand the motivation for wanting to only check object level
>> permissions, but I would argue that the design of the API insinuates a
>> hierarchical behaviour which is part of the reason the current behaviour is
>> unexpected.
>> Specifically why use an 'obj' kwarg instead of having two methods?
>>
>> To me if the API where:
>> ```
>> has_perm('foo.change_bar')
>> has_obj_perm('foo.change_bar', bar_obj)
>> ```
>> I would expect `has_perm` to only deal with model level permissions and
>> `has_obj_perm` to only deal with object leve

Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-18 Thread Mehmet Dogan
For the migration, I think most sensible way is to *extend *the current
backend and provide it as an option, until the other is depreciated and
removed. This would act as a global setting in the meantime. But
eventually, I think, we should have just 1 default backend for the sake of
consistency overall. People can always extend it and put it above it in the
setting to alter default behavior, or just replace it, if they need.

But I would also like to point out one disadvantage of the new way: it will
make harder, and maybe impossible in some cases, to pull object permissions
over the common API. For example in the existing scheme:
user.has_perm('foo.change_bar') and user.has_perm('foo.change_bar', obj)
are two exclusive sets.  Easy to add if needed, however, in the new scheme,
the latter will include the former, and set subtraction will cause loss of
data if there was overlap (i.e., intersection was not empty). This (again)
will bring us back to specifying backends for control and flexibility.

On Thu, Jan 18, 2018 at 10:25 AM Mehmet Dogan  wrote:

> Andrew,
>
> Yes, I think we can safely assume *apps *would be backend agnostic. I was
> actually referring to the *backends *themselves, if they use
> user.has_perm(...). This might sound counter-intuitive at first but I think
> it is possible, and actually I am working on one right now (see my long
> answer for details).
>
> *Long Answer:* I am trying to write a Roles backend with, and without
> reinventing the wheels for, object and model permissions. The logic is very
> simple.
>
> class Role(models.Model):
>delegate = models.OneToOneField(Permission,* ...*)
>perms = models.ManyToManyField(Permission, *...*)
> *...*
>
> Delegate is a permission for each role that lets a user use it, e.g., 
> 'roles.use_role_xx'; and the `perms` are the actual
> permission in the Role. And my backend (pseudo code):
>
> def has_perm(self, user_obj, perm, obj=None):
>if perm is delegate:
>  ignore;
>
>delegates = get_delegates_representing(perm)
>
>for delegate in delegates:
>   if user_obj.has_perm(delegate, obj):  # refer to existing other backends
>  return True
>return False
>
> 1) Now, as seen above user_obj.has_perm(delegate, obj) is written for the 
> proposed way, and would not work with the current
> way as model permissions would be excluded.
>
> 2) In order to prevent infinite loops, I have to strictly separate
> permissions that represent Roles (namely delegates) and
> permissions in the roles. If I could specify backends as I proposed
> earlier, I could even take this even one step further
> and allow roles include other roles (that would be awesome).
>
> 3) I have not tested or used this. And one might see it as a hairy design
> to be disregarded. But I claim it has a fair chance to be
> otherwise. *When it comes to backends we don't have plenty of choices,
> and allowing them leverage each other will just make*
> *it easier to write them. *
>
> *Thanks for reading so far! :)*
>
> On Wed, Jan 17, 2018 at 8:42 PM Andrew Standley <
> astand...@linear-systems.com> wrote:
>
>> Mehmet,
>> Can you explain to me what the situation would be that an app could
>> simply not be backend agnostic?
>> Given that AUTHENTICATION_BACKENDS is a *user* configuration, it seems
>> odd that an app would ever design around specific backends being installed.
>> I'm not sure I follow your logic on this.
>> Regarding an API that will allow picking and choosing I already have some
>> ideas, but I think Carlton made an excellent point that that is another
>> discussion all together.
>>
>> Cheers,
>> Andrew
>>
>>
>> On 1/17/2018 5:34 PM, Mehmet Dogan wrote:
>>
>> Andrew,
>>
>> Thank you for the input. Having options is good. My concern about that
>> is, it may divide the already small backends population. If a backend
>> relies on PermissionAuthorizationBackend, and another require the
>> ModelOnlyPermissionAuthorizationBackend; then one cannot use both.
>> Guardian, at its core, is agnostic of the default backend
>> behavior, however, relies on it in some utilities. However, I am working on
>> a simple RolePermissionsBackend now that leverages existing Object and
>> Model backends at its core. Currently, if I do
>> `user.has_perm('foo.change_bar')` or `user.has_perm('foo.change_bar', obj)`
>> I know one is the model and the other is the object permissions. In case of
>> plug-ins, that will go away, and it will be even harder to leverage
>> existing backends. Also, the logic that polls backends is in
>> auth/models.py, I do not 

RE: Default Authorization BackEnd Denying Permissions if ObjectProvided

2018-01-18 Thread Mehmet Dogan
Andrew,

> Why you would use the user API if you cared about a specific backend?

True. I wouldn’t. 

> Using your example of the RolesBackend, either 
> A) You want to leave it up to the user whether a role grants object level 
> permissions or not.
> B) You want to have consistent behavior for your backend. 

Seemed like I wanted consistent behavior without relying on any particular 
backend. But, I see this restricts the design choices elsewhere or for others. 
Whether advantages outweigh disadvantages, or vice versa, I am not sure. 

I was envisioning that one who uses multiple backends, say at least 3, would 
get everything needed through the common API, as well as seamless reusability 
of backends within each other. 

But your scenario B gave me some ideas for backup. Thanks 😊

Mehmet

From: Andrew Standley
Sent: Thursday, January 18, 2018 1:29 PM
To: django-developers@googlegroups.com
Subject: Re: Default Authorization BackEnd Denying Permissions if ObjectProvided

Hey Mehmet,
If a backend relies on PermissionAuthorizationBackend, and another require the 
ModelOnlyPermissionAuthorizationBackend
    So I think this is the point that confuses me. Why you would use the user 
API if you cared about a specific backend?

Using your example of the RolesBackend, either 
A) You want to leave it up to the user whether a role grants object level 
permissions or not.
B) You want to have consistent behavior for your backend. 

Explanation:

A) In this case you would use your pseudo code example. 
To return true (proposed) for an object when a user has the model level 
permission (ie a role with this permission) the user would configure their 
setting so
```
AUTHENTICATION_BACKENDS = [
    'PermissionAuthorizationBackend',
    'RolesBackend',
]
```
To return false (current) for an object when a user has the model level 
permission the user would configure their setting so
```
AUTHENTICATION_BACKENDS = [
    'ModelOnlyPermissionAuthorizationBackend',
    'RolesBackend',
]
```
In either case the backend order does not particularly matter for this example.

B) In this case the backend should derive or call the backend whose behaviour 
it requires.
```
class RolesBackend(PermissionAuthorizationBackend):
    def has_perm(self, user_obj, perm, obj=None):
    ...
    for delegate in delegates:
  if super(RolesBackend, self).has_perm(user_obj, perm, obj):
  return True
   return False
```

Cheers,
    Andrew

-- 
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/5a60fdc2.c91b9d0a.50b0.7583%40mx.google.com.
For more options, visit https://groups.google.com/d/optout.


RE: Default Authorization BackEnd Denying Permissions ifObjectProvided

2018-01-18 Thread Mehmet Dogan
Andrew,

After further thought I came to think that, even if multiple options kept in 
the framework forever, the disadvantages will not be considerable. I still 
think it will limit inter-changeability (what is the word for this?), but most 
people/backends would follow the one that makes more sense, so it will should 
not be an issue. 

Sent from Mail for Windows 10

From: Mehmet Dogan
Sent: Thursday, January 18, 2018 2:04 PM
To: django-developers@googlegroups.com
Subject: RE: Default Authorization BackEnd Denying Permissions ifObjectProvided

Andrew,

> Why you would use the user API if you cared about a specific backend?

True. I wouldn’t. 

> Using your example of the RolesBackend, either 
> A) You want to leave it up to the user whether a role grants object level 
> permissions or not.
> B) You want to have consistent behavior for your backend. 
Seemed like I wanted consistent behavior without relying on any particular 
backend. But, I see this restricts the design choices elsewhere or for others. 
Whether advantages outweigh disadvantages, or vice versa, I am not sure. 

I was envisioning that one who uses multiple backends, say at least 3, would 
get everything needed through the common API, as well as seamless reusability 
of backends within each other. 

But your scenario B gave me some ideas for backup. Thanks 😊

Mehmet

From: Andrew Standley
Sent: Thursday, January 18, 2018 1:29 PM
To: django-developers@googlegroups.com
Subject: Re: Default Authorization BackEnd Denying Permissions if ObjectProvided

Hey Mehmet,
If a backend relies on PermissionAuthorizationBackend, and another require the 
ModelOnlyPermissionAuthorizationBackend
    So I think this is the point that confuses me. Why you would use the user 
API if you cared about a specific backend?

Using your example of the RolesBackend, either 
A) You want to leave it up to the user whether a role grants object level 
permissions or not.
B) You want to have consistent behavior for your backend. 

Explanation:

A) In this case you would use your pseudo code example. 
To return true (proposed) for an object when a user has the model level 
permission (ie a role with this permission) the user would configure their 
setting so
```
AUTHENTICATION_BACKENDS = [
    'PermissionAuthorizationBackend',
    'RolesBackend',
]
```
To return false (current) for an object when a user has the model level 
permission the user would configure their setting so
```
AUTHENTICATION_BACKENDS = [
    'ModelOnlyPermissionAuthorizationBackend',
    'RolesBackend',
]
```
In either case the backend order does not particularly matter for this example.

B) In this case the backend should derive or call the backend whose behaviour 
it requires.
```
class RolesBackend(PermissionAuthorizationBackend):
    def has_perm(self, user_obj, perm, obj=None):
    ...
    for delegate in delegates:
  if super(RolesBackend, self).has_perm(user_obj, perm, obj):
  return True
   return False
```

Cheers,
    Andrew


-- 
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/5a610980.8a40ca0a.70bfa.42b3%40mx.google.com.
For more options, visit https://groups.google.com/d/optout.


Authorization Backend Proposals for Utility Methods

2018-01-19 Thread Mehmet Dogan
Hello All,

I would like to get your opinions on what seemed to me useful additions to 
the `auth.backends.ModelBackend`. These are polled by the `auth.models` and 
not every backend has to implement them.

1) clear_cache()

default backend caches permissions at `user._user_perm_cache`, 
`user._group_perm_cache` and cumulatively: `user._perm_cache`. Most other 
backends also do things similar. If an app uses 2-3 backends, resetting 
cache after adding a permission becomes a chore. 

2) has_perms_any ()

we have one (has_perms) that requires *all* permissions given, why not *any*? 
If this makes it, the other may also be renamed to has_perms_all ()

3) get_permisson_objects ()

guardian has something like this, and i think it would be nice if the 
default backend also provided similar. if it did, it would be either 
Model.objects.all() or Model.objects.none(); does not look much useful, 
however if one uses say 3 backends, it does seem useful. If implemented, 
due to diverse nature of backends it may be hard, if at all possible, to 
implement lazy loading, thus, may incur performance costs. If you think 
this is useful, please also share if you have design ideas. 

4) get_backends ()

this is not really a utility method, but a move request. It is currently 
under auth.__init__(); I think if it was moved to somewhere that could be 
overrided, it would allow one to pick and choose backends locally from the 
code if needed. 

Regards,

Mehmet

-- 
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/0ca47426-e700-473e-ba49-5eb748210a38%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-19 Thread Mehmet Dogan


Hey Carlton,

 

I think everybody said what they would. What do you say? 

 

I propose throwing out the proposed behavior as Option B, and see what 
happens. Something along these lines:

 

*class *ModelBackendIgnoreObject(ModelBackend):

*def *get_user_permissions(self, user_obj, obj=*None*):

*if *obj *is None*:

obj = 
*"NOT_NONE"
*super().get_user_permissions(user_obj, obj)



*def *get_group_permissions(self, user_obj, obj=*None*):

*if *obj *is None*:

obj = 
*"NOT_NONE"
*super().get_group_permissions(user_obj, obj)



*def *get_all_permissions(self, user_obj, obj=*None*):

*if *obj *is None*:

obj = 
*"NOT_NONE"
*super().get_all_permissions(user_obj, obj)



*def *has_perm(self, user_obj, perm, obj=*None*):

*if *obj *is None*:

obj = 
*"NOT_NONE"
*super().has_perm(user_obj, obj)



By the time, I am getting acclimated to the idea of "do not fix" but I think 
this is good for new comers to the framework, and general population. 

-- 
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/6d05b14d-dd56-4030-b9f9-15c8c8d8439a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Default Authorization BackEnd Denying Permissions if Object Provided

2018-01-19 Thread Mehmet Dogan
Aymeric,

If one doesn’t have time to read 21 emails, then should also not have time
to judge them.

Regards,
On Fri, Jan 19, 2018 at 2:33 PM Aymeric Augustin <
aymeric.augus...@polytechnique.org> wrote:

> 2018-01-19 17:54 GMT+01:00 Mehmet Dogan :
>
>> I propose throwing out the proposed behavior as Option B, and see what
>> happens.
>>
>
> "Make changes and see what happens" doesn't sound like the way Django is
> maintained in general.
>
> Unfortunately I don't have enough motivation to go through the 21 emails
> you sent over the last week so I can't offer more constructive advice.
>
> Keep in mind that each email to this list is sent to thousands of people.
> You'll get more help if you demonstrate respect for other people's time.
>
> Thanks for your understanding!
>
> --
> Aymeric.
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/django-developers/MLWfvPPVwDk/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/CANE-7mViGxVs%3DvP3-%2BkZxuHyuNSHeAaU5Pfg2Ts7Z957rFmK8g%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-developers/CANE-7mViGxVs%3DvP3-%2BkZxuHyuNSHeAaU5Pfg2Ts7Z957rFmK8g%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
> 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/CAFdefwMtPs2K%3DRXAvbdBViQvEXupEbZyt%3D-pADsV7GGj%3DFXLRw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


RE: Default Authorization BackEnd Denying Permissions if ObjectProvided

2018-01-23 Thread Mehmet Dogan
Thanks for the response. Do you think what Florian or I sent is a good example 
to include in the docs for the way #1?

From: Carlton Gibson
Sent: Monday, January 22, 2018 2:13 AM
To: Django developers (Contributions to Django itself)
Subject: Re: Default Authorization BackEnd Denying Permissions if ObjectProvided

Hi Mehmet, 

Sorry for the slow reply. I didn't have capacity to return to this last week. 

> Hey Carlton ... What do you say?

Well, my first thought is that I don't see any great consensus for a change 
here.
I don't see it as **my** decision to make. 

This has been open a while, however, so...

I've used this API, with Django Guardian and without. It never occurred to me 
that there was a problem with ModelBackend's behaviour. 

For me the it (i.e. the docs) says:

> I don't do object permissions so I always return `False` if you ask. 

That seems clear, safe, and unambiguous. 

I see users read the API as hierarchical. Having thought about this issue,
ultimately, I think it's a misunderstanding (and so a docs issue).

I come back to Florian's point about what the right API should be? 

`user.has_perm("for.change_bar", obj=some_bar)`

What are we offering here? 
The ability to cycle through a number of backends checking permissions, **plus**
a (moderately) simple default permissions system. That's it. 
(We're not offering the most full-featured ACL-powered goodness. That's 
deliberate.)

Is this a good API for that? I think probably yes. 

Short of looking at ≈all the major frameworks out there and seeing what they 
offer instead, I don't see a ground for change. Not currently. 

I do see two ways forward: 

* A possible change to the docs: highlight what we're doing (again) 
  — provide the example of an alternate backend, with the other behaviour. 
  
* Possible backwards compatible refactoring of the authentication and 
authorization 
  roles of the authentication backends. Right now we have a class with two 
  responsibilities, so splitting that may make sense. (It may make future steps 
  clearer.) I think that would need to be done piecemeal and in PRs, with tests 
  and docs etc to be sensibly assessed. (It's impossible to assess code on the 
  mailing list, at least for me.)
  
Given the scope of the permissions system, I'm not convinced we need to make an 
actual code change here. (i.e. I'm not convinced about need for the second 
refactoring part.) The goal is to provide a simple but extensible system. We 
have that. I don't see any limitation that can't be worked around in user code 
if it doesn't suit. 

For me, I'd close as won't fix.
https://code.djangoproject.com/ticket/20218

Kind Regards,

Carlton




-- 
You received this message because you are subscribed to a topic in the Google 
Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/django-developers/MLWfvPPVwDk/unsubscribe.
To unsubscribe from this group and all its topics, 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/1fb3ac66-8d78-4393-b3ca-83cba330bccf%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/5a6740fd.f8429d0a.f1b4e.0c3c%40mx.google.com.
For more options, visit https://groups.google.com/d/optout.


New Password Validators

2018-08-30 Thread Mehmet Dogan
Hi Everybody,

Django currently ships with the following password validators:

UserAttributeSimilarityValidator
MinimumLengthValidator
CommonPasswordValidator
NumericPasswordValidator


However, it is typical nowadays to require uppercase, lowercase, at least a 
numeric character and a non-alphanumeric character, or a symbol. 

Is there any reason, why these not included in Django? I assume most 
serious Django applications use them. A sample implementation:

class HasLowerCaseValidator:
   def __init__(self):
  self.message = "The password must contain at least one lowercase 
character."

   def validate(self, password, user=None):
  if re.search('[a-z]', password) is None:
 raise ValidationError(
self.message,
code='missing_lower_case',
)

   def get_help_text(self):
  return self.message


class HasUpperCaseValidator:
   def __init__(self):
  self.message = "The password must contain at least one uppercase 
character."

   def validate(self, password, user=None):
  if re.search('[A-Z]', password) is None:
 raise ValidationError(
self.message,
code='missing_upper_case',
)

   def get_help_text(self):
  return self.message


class HasNumberValidator:
   def __init__(self):
  self.message = "The password must contain at least one numeric character."

   def validate(self, password, user=None):
  if re.search('[0-9]', password) is None:
 raise ValidationError(
self.message,
code='missing_numeric',
)

   def get_help_text(self):
  return self.message


class HasSymbolValidator:
   def __init__(self):
  self.message = "The password must contain at least one non-alphanumeric 
character (symbol)."

   def validate(self, password, user=None):
  if re.search('[^A-Za-z0-9]', password) is None:
 raise ValidationError(
self.message,
code='missing_symbol',
)

   def get_help_text(self):
  return self.message

Regards,


Mehmet 

-- 
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/afd6d57c-ce8c-4d72-85d4-867cacc8ba9a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


RE: New Password Validators

2018-08-31 Thread Mehmet Dogan
Hey James,

Thank you for the resources you provided. I really learned a lot. Here are a 
few points (references/details at the very bottom):

1) Blacklisting: Seems to be most effective, I agree. However, Django does not 
seem to be up to date on this either. The list of 1000 most common password it 
uses seem to be taken from an URL which is not available anymore, and the page 
it redirects to is dated 2011! So the list is at least around 10 years old, and 
it does not catch all of top 25 words listed on Wikipedia. Samples of passwords 
it allows: qwertyuiop, 987654321, 1234567890, abcdefgh

2) Are Complexity Requirements Deprecated?: I checked changing my password for 
3 major tech companies: Gmail, Microsoft account, and for my Apple Id. Only 
Gmail did not require password complexity. So, most do require password 
complexity although they do have 2-factor authentication in place. Most Django 
deployments, more than 95% I assume, would not have 2-factor authentication, so 
password complexity is more needed. 

3) Do Complexity Requirements Work?: 
a) Research: From the resources you linked, I read one article (ref’ed below). 
Here are key findings: 
i. A complex 8-character password had entropy of 34.3 where as a basic 
8-character one had 29.43 (calculated with the specific method mentioned in the 
article). Not a huge difference, however not too bad either, that is about 17% 
gain. 
ii. 188/972 (=20%) of the basic-8 passwords was cracked (with the tool 
mentioned in the article), whereas this number is 0 (zero) for the complex-8 
group. A big difference there. 
iii. About 15% of the basic group wrote down their passwords, either 
electronically or paper and pencil, where as this number is about 27% for the 
complex. Simpler passwords is the winner here, however one should not forget, 
written passwords are expected have their own protection (of some sort). 
Another thing to consider is that, if one is targeted individually, a written 
password might be a big vulnerability; however, for general account/password 
screenings this may not be as bad. 
All in all, I say, password complexity has benefits; although not as much as 
one would expect. 

b) Complexity and Blacklisting Can Interoperate: For the simple case of 
“Password1!” mentioned below, the best method to tackle, I think, would be 1) 
remove the numbers and characters at the end 2) lowercase the first character 
3) lookup in the black list. In other words, tackle the thinking pattern 
algorithmically, not by listing cases in a text file.  

c) Complexity support blacklisting: Check this list of common passwords, for 
example: 
https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/500-worst-passwords.txt
 (provided by the Author of the Django’s list of common passwords). Most items 
there are either all lowercase or all numbers etc. By just requiring 1 upper 
case character, one could know off 60% off them. Adding a number, and a symbol 
requirement would easily bring that up to 95%.. Sure, those who are committed 
to not password protecting their accounts would find something in the remaining 
5% (as in the example of “Password1!”), howerver, policies would be made for 
the mainstream, not for the extremes. 

Bottom line; I think password complexity do have some benefits, and inclusion 
in Django would provide options, and save time to those who would like to use 
them. Regards,

Mehmet






References/Details: 

1) URL referenced in Django for the list of 1000 most common passwords : 
https://xato.net/passwords/more-top-worst-passwords/ 
(location: django\contrib\auth\password_validation.py)
Wikipedia: https://en.wikipedia.org/wiki/List_of_the_most_common_passwords

2) G-Mail: Use at least 8 characters. Don’t use a password from another site, 
or something too obvious like your pet’s name.
Microsoft Account: Strong passwords contain at least 8 characters, do not 
include common words or names, and combine uppercase letters, lowercase 
letters, numbers, and symbols.
Apple Id: Your password must have: i) 8 or more characters ii) Upper & 
lowercase letters iii) At least one number

3) a) Article: Of Passwords and People: Measuring the Effect of 
Password-Composition Policies 
(https://www.archive.ece.cmu.edu/~lbauer/papers/2011/chi2011-passwords.pdf). I 
picked this article since its name suggested it is very related to our topic, 
and that CMU is a reputable university. 


From: James Bennett
Sent: Thursday, August 30, 2018 10:32 PM
To: django-developers@googlegroups.com
Subject: Re: New Password Validators

This type of enforced "complexity" does not increase security, and relevant 
standards groups now recommend not trying to enforce these rules.

Quoting US NIST 800-63B, Appendix A:

> As noted above, composition rules are commonly used in an attempt to increase 
>the difficulty of guessing user-chosen passwords. Research has shown, however, 
>that users respond in very predictable ways to the requirements impo

RE: New Password Validators

2018-08-31 Thread Mehmet Dogan
2 points I forgot to mention:

1) I think it would be interesting to look at what other web frameworks are 
doing, e.g., Ruby on Rails
2) If what I offered is not added, I think it makes more sense to remove 
similar ones (e.g., NumericPasswordValidator) from Django to make it self 
consistent. 

Mehmet

From: Mehmet Dogan
Sent: Friday, August 31, 2018 12:59 PM
To: django-developers@googlegroups.com
Subject: RE: New Password Validators

Hey James,

Thank you for the resources you provided. I really learned a lot. Here are a 
few points (references/details at the very bottom):

1) Blacklisting: Seems to be most effective, I agree. However, Django does not 
seem to be up to date on this either. The list of 1000 most common password it 
uses seem to be taken from an URL which is not available anymore, and the page 
it redirects to is dated 2011! So the list is at least around 10 years old, and 
it does not catch all of top 25 words listed on Wikipedia. Samples of passwords 
it allows: qwertyuiop, 987654321, 1234567890, abcdefgh

2) Are Complexity Requirements Deprecated?: I checked changing my password for 
3 major tech companies: Gmail, Microsoft account, and for my Apple Id. Only 
Gmail did not require password complexity. So, most do require password 
complexity although they do have 2-factor authentication in place. Most Django 
deployments, more than 95% I assume, would not have 2-factor authentication, so 
password complexity is more needed. 

3) Do Complexity Requirements Work?: 
a) Research: From the resources you linked, I read one article (ref’ed below). 
Here are key findings: 
i. A complex 8-character password had entropy of 34.3 where as a basic 
8-character one had 29.43 (calculated with the specific method mentioned in the 
article). Not a huge difference, however not too bad either, that is about 17% 
gain. 
ii. 188/972 (=20%) of the basic-8 passwords was cracked (with the tool 
mentioned in the article), whereas this number is 0 (zero) for the complex-8 
group. A big difference there. 
iii. About 15% of the basic group wrote down their passwords, either 
electronically or paper and pencil, where as this number is about 27% for the 
complex. Simpler passwords is the winner here, however one should not forget, 
written passwords are expected have their own protection (of some sort). 
Another thing to consider is that, if one is targeted individually, a written 
password might be a big vulnerability; however, for general account/password 
screenings this may not be as bad. 
All in all, I say, password complexity has benefits; although not as much as 
one would expect. 
b) Complexity and Blacklisting Can Interoperate: For the simple case of 
“Password1!” mentioned below, the best method to tackle, I think, would be 1) 
remove the numbers and characters at the end 2) lowercase the first character 
3) lookup in the black list. In other words, tackle the thinking pattern 
algorithmically, not by listing cases in a text file.  
c) Complexity support blacklisting: Check this list of common passwords, for 
example: 
https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/500-worst-passwords.txt
 (provided by the Author of the Django’s list of common passwords). Most items 
there are either all lowercase or all numbers etc. By just requiring 1 upper 
case character, one could know off 60% off them. Adding a number, and a symbol 
requirement would easily bring that up to 95%.. Sure, those who are committed 
to not password protecting their accounts would find something in the remaining 
5% (as in the example of “Password1!”), howerver, policies would be made for 
the mainstream, not for the extremes. 

Bottom line; I think password complexity do have some benefits, and inclusion 
in Django would provide options, and save time to those who would like to use 
them. Regards,

Mehmet





References/Details: 

1) URL referenced in Django for the list of 1000 most common passwords : 
https://xato.net/passwords/more-top-worst-passwords/ 
(location: django\contrib\auth\password_validation.py)
Wikipedia: https://en.wikipedia.org/wiki/List_of_the_most_common_passwords
2) G-Mail: Use at least 8 characters. Don’t use a password from another site, 
or something too obvious like your pet’s name.
Microsoft Account: Strong passwords contain at least 8 characters, do not 
include common words or names, and combine uppercase letters, lowercase 
letters, numbers, and symbols.
Apple Id: Your password must have: i) 8 or more characters ii) Upper & 
lowercase letters iii) At least one number
3) a) Article: Of Passwords and People: Measuring the Effect of 
Password-Composition Policies 
(https://www.archive.ece.cmu.edu/~lbauer/papers/2011/chi2011-passwords.pdf). I 
picked this article since its name suggested it is very related to our topic, 
and that CMU is a reputable university. 


From: James Bennett
Sent: Thursday, August 30, 2018 10:32 PM
To: django-developers@googlegroups.com
Subject

RE: New Password Validators

2018-09-02 Thread Mehmet Dogan
Scot,

This is nice, thank you for sharing. I think something like this + an up to 
date black list should be good enough. 

Mehmet

From: Scot Hacker
Sent: Saturday, September 1, 2018 8:38 PM
To: Django developers (Contributions to Django itself)
Subject: Re: New Password Validators

Rather than enforce an arbitrary set of password construction rules, I prefer 
systems that gauge password strength as an overall entropy score, then let  
sites establish the minimum overall strength they require. How that strength is 
achieved is up to each user - uou can either go short and random, or long and 
memorable. Length trumps pretty much all other factors, especially if you 
disallow strings such as the user's own username, email, company name, etc.). 
Dropbox created a system like this called zxcvbn and open sourced it.  It was 
then ported to python. 

https://github.com/dropbox/zxcvbn
https://github.com/dwolfhub/zxcvbn-python

I use a "roll your own" solution on top of zxcvbn-python in some of my projects 
(in order to show dynamic strength meters in the UI as user types), but others 
have converted it to work as a Django password validator.

https://github.com/Pierre-Sassoulas/django-zxcvbn-password-validator

If Django were to bundle any additional validators, this or something like it 
would have my vote.

./s

-- 
You received this message because you are subscribed to a topic in the Google 
Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/django-developers/Xlovt28QIDo/unsubscribe.
To unsubscribe from this group and all its topics, 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/de03b9dd-ef24-4ee6-a7fd-287e79304465%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/5b8bf02a.1c69fb81.84d1a.1c4e%40mx.google.com.
For more options, visit https://groups.google.com/d/optout.