Re: Configuration of "level" in LOGGING

2022-04-04 Thread Jason Johns
How would this work with secret stores like hashicorp vault, aws secrets 
manager?  Or even via environment variables?  This approach would work if 
you define the logging level in your configuration, but not so friendly for 
other approaches.

On Monday, April 4, 2022 at 9:26:02 PM UTC-4 Dan Swain wrote:

> The current Django LOGGING setup requires a string for the "level".  This 
> is not intuitive since the Python logging module defines logging.DEBUG, 
> logging.INFO, etc.  I think one should be able to configure the logging 
> level using {  'level': logging.DEBUG  } rather than being required to use  
> {  'level': 'DEBUG'  }.
>

-- 
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/9e295cb2-e009-4a0a-b506-cb1ebec77761n%40googlegroups.com.


Configuration of "level" in LOGGING

2022-04-04 Thread Dan Swain
The current Django LOGGING setup requires a string for the "level".  This is
not intuitive since the Python logging module defines logging.DEBUG,
logging.INFO, etc.  I think one should be able to configure the logging
level using {  'level': logging.DEBUG  } rather than being required to use
{  'level': 'DEBUG'  }.

-- 
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/010b01d8487b%24683216c0%2438964440%24%40shenberger.org.


Re: Ticket #21289 - Login rate limiting

2022-04-04 Thread Hrushikesh Vaidya
Hi all,
I'm trying to work on adding rate-limiting to core as part of this year's 
GSoC, and I'd like to work on this 
ticket as a part of the project. I'm aiming to write an API for 
rate-limiting (which is a lot like django-ratelimit merged into core),
which we could use to add some default rate-limiting to the 
AuthenticationForm.

It seems like it's hard to add rate limiting to the form without 
introducing a DoS vector. The ideal solution would be a soft block
like a captcha, but that is not currently possible to do in the core. For 
now, I propose that we allow a small amount of login attempts
per minute - maybe 10 or so attempts per minute for each username and IP 
considered together, and then rate-limit using a fixed window.
The IP would come from a user-specified header configured by a setting.

I think this would work better for good actors by allowing them to try 
again immediately after a few incorrect passwords, and limit bad actors 
significantly.
We will make the rate, the key, etc. for the enforced rate-limit 
customizable, as you can read in my proposal for the implementation here 

.

Thanks,
Hrushikesh

On Monday, 27 July 2020 at 20:25:35 UTC+5:30 Adam Johnson wrote:

> Hi Claude,
>
> A delay of 5 seconds seems quite long. Often I fail to log into a site due 
> to mis-selection of credentials from my password manager, so I can resubmit 
> a login form within 1-2 seconds. A real rate-limiting solution has the 
> advantage of buckets of requests per time period, allowing users a few 
> rapid attempts before being locked.
>
> Additionally, the default PBKDF2 hasher already enforces a (smaller) 
> arbitrary delay via its algorithm iterations. I can't find a source but I 
> think I remember reading it should be tuned to take about 100ms. This is 
> about 1.5 orders of magnitude less than a 5 second delay, which is perhaps 
> not so significant in terms of password brute-forcing (less difference than 
> one extra password character). Not sure if 100ms is where Django's current 
> default ends up on a modern CPU, but we probably aren't far off given we 
> increase the iterations according to a formula that roughly tracks Moore's 
> law.
>
> I'd rather see something like django-ratelimit merged to core. It's more 
> general purpose so users can reuse and customize it, and we could 
> potentially use it for other features in Django too.
>
> Thanks,
>
> Adam
>
> On Mon, 27 Jul 2020 at 12:13, Claude Paroz  wrote:
>
>> Hi all,
>>
>> I thought a bit about login rate limiting again in recent times.
>> https://code.djangoproject.com/ticket/21289
>>
>> We know that there are some packages (django-ratelimit, django-defender,
>> etc.) that can do the job, but the main issue here is to provide a
>> *default* behavior for any fresh new Django project.
>>
>> A must-read on this subject is:
>> https://owasp.org/www-community/controls/Blocking_Brute_Force_Attacks
>>
>> I would like to suggest one mitigation measure for default Django, which
>> seems to me the least controversial, considering that hard-locking by
>> username and/or ip address can open Denial of Service vectors which may
>> or may not be acceptable for some sites.
>>
>> My suggestion is to add a time delay of 5 seconds in the
>> contrib.auth.forms.AuthenticationForm after the first failure on any
>> username. This choice of 5 seconds is a compromise between not too much
>> annoying users after a failed login attempt, and still set a significant
>> throttling limit for some brute force attacks. You can consider that
>> after a failed login, a real user will spend at least 2-3 seconds just
>> to re-enter a new password and re-submit the form, so the real wait
>> penalty should not be more than 2-3 seconds.
>>
>> This is of course NOT the panacea against all type of brute force
>> attacks, as you can read on the OWASP article above. But it appears to
>> me as a reasonable measure that can be widely accepted by most Django
>> projects that use the default authentication form.
>>
>> The WIP PR is available here:
>> https://github.com/django/django/pull/13242
>>
>> Kind regards,
>>
>> Claude
>> -- 
>> www.2xlibre.net
>>
>> -- 
>> 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 view this discussion on the web visit 
>> https://groups.google.com/d/msgid/django-developers/49b80757-9117-fa11-3f53-731af1f0c206%402xlibre.net
>> .
>>
>
>
> -- 
> 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 view this discussion on the 

Re: Revisiting MSSQL and Azure SQL Support in Django

2022-04-04 Thread אורי
Hi All,

After reading your comments, I think Django should keep supporting only
open source databases, as well as other staff (operating systems, packages)
and drop support for the closed source databases, operating systems etc. It
seems to me that some of you think supporting Oracle was a mistake. I also
think that it's better for an open source package (Django) to support other
open source software and operating systems, and keep the closed source
support for the providers. Nobody's stopping them from providing their own
support for their closed source databases and packages, but I don't think
Django should make an effort to support them in its core.

Thanks,
Uri Rodberg, Speedy Net.
אורי
u...@speedy.net


On Thu, Mar 31, 2022 at 7:30 PM Warren Chu  wrote:

> Hi All,
>
> There is increasing interest within Microsoft to have stronger ties
> between Microsoft SQL Server and Django. As you may be aware, Microsoft and
> their connectivity teams have been managing the 3rd party backend for
> "mssql-django" for over a year now at:
> https://github.com/microsoft/mssql-django
>
> Inclusion of SQL Server as a 1st party backend is viewed as a potential
> big milestone in that regard.
>
> @adamjohnson mentioned a year ago that ideally the community would like to
> see multiple years of ongoing Microsoft support before considering merging
> as a 1st party backend.
>
> We'd love to hear thoughts and feedback around the possibility of moving
> forward with a DEP enhancement proposal, with a commitment from Microsoft
> to providing continued dedicated support for the 1st party backend through
> the Django project itself (rather than the 3rd party repo).
>
> Cheers,
> Team Microsoft
>
> --
> 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/0c6ca059-d50e-4c84-bef6-ab0742fc4fa9n%40googlegroups.com
> 
> .
>

-- 
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/CABD5YeFvK%3DroAqxcZTq12W68RgLERn%3D6%2BcDAKcY0YzUOJ%3D_mEQ%40mail.gmail.com.


Re: Revisiting MSSQL and Azure SQL Support in Django

2022-04-04 Thread Gert Burger
As a commercial user of all the builltin DB backends and the MSSQL backend
(both the MS fork and its parent), I tend to agree more with Florian's
arguments.

Our experience with the MS MSSQL and Oracle DB backends in supporting our
enterprise customers have been difficult at best, in comparison to the
other backends.
Due to the immaturity of these two backends we have resorted to maintaining
our own set of patches for each, to handle the seemingly endless list of
edge cases they currently do not support.

So I would argue that the MS MSSQL backend should not be included due to
its current level of maturity and its rough history since the fork. On the
surface it seems like Microsoft's current level of support is minimal,
resulting in slow progress and varying levels of stability.

I do still hope that MS and Oracle will step up and provide a higher level
of support so that their DB backends can match the popular community
maintained ones.

Regards

On Sun, 3 Apr 2022 at 23:21, Tim Allen  wrote:

> Thanks for the thoughtful replies, and the context - I'm mostly in
> agreement, and do hope that both Oracle and Microsoft step up as corporate
> sponsors (not to mention other companies that have been sold for eight or
> nine figures).
>
> My hope is that we can give credit where credit is due, and acknowledge
> that Microsoft has made significant strides as an open-source partner. I
> want to encourage this behavior, as I've witnessed a change since Satya
> Nadella came on board. They have made life much easier for many of us in
> the Django community. My reply was primarily due to what I perceived as
> overly-harsh comments which don't seem to reflect the current-day Microsoft.
>
> Take care,
>
> Tim
>
>
>
> On Sunday, April 3, 2022 at 2:23:35 PM UTC-4 f.apo...@gmail.com wrote:
>
>> Hi Tim,
>>
>> On Friday, April 1, 2022 at 5:02:00 PM UTC+2 Tim Allen wrote:
>>
>>> The DB popularity index at db-engines.com has regularly listed the top
>>> four as Oracle, MySQL, Microsoft SQL Server, and PostgreSQL, in that order.
>>> I notice some comments in this thread about Microsoft being for-profit...
>>> well, what about Oracle? I don't see Oracle on the Support Django page
>>> either, yet two of their databases have support in core. MSSQL is the only
>>> one of the big-four RDBMS's without support in core Django. That seems to
>>> be a pretty big hole in Django's offering.
>>>
>>
>> I understand that comparing to existing databases seems like to make an
>> argument for MSSQL but it is not that easy. First off, Django was released
>> way earlier than Oracle acquired MySQL -- I think it is understandable that
>> we do not simply drop support for a database just because Oracle buys it.
>> Postgres and MySQL (or now MariaDB) are both easily installable via every
>> Linux distribution and have been there since the beginning. Support for
>> Oracle itself (iirc) was added because the team at that point in time
>> thought it would enable Django to get access to areas where it hadn't
>> access before. Oracle itself has (imo) been proven to be quite a burden
>> over time and there had been discussion about removing it from core more
>> than once.
>>
>> Truth to be told, if the inclusion request for MSSQL gets serious we will
>> have to start a discussion about whether or not we simply nuke all database
>> backends (aside from sqlite maybe) from core. I'd be slightly in favor of
>> simply setting a policy for core that it should only include backends of
>> OSS databases. Why? Because it is way easier to install those on various
>> systems than their commercial alternatives (even if there are test licenses
>> and possibly free containers around there).
>>
>>
>>> They have put a lot of time and effort into this project, and I think
>>> they're well on their way to where they need to be for the long-term goal
>>> of being in core Django.
>>
>>
>> I applaud to that, but I still do not understand why a well maintained
>> database backend needs to be inside core? And I am not just talking about
>> database backends here, we are saying no to pretty much every library
>> inclusion.
>>
>>
>>> A lot of the questions being asked of Microsoft in this thread just
>>> don't seem fair to me - we're not asking the same of Oracle, Redis
>>> Enterprise Software, or any of the other commercial products that Django
>>> has built-in support for. Why Microsoft and not the others?
>>>
>>
>> We are asking Oracle but we are also not getting far, and simply kicking
>> it out is not something we do easily. As for Redis, as far as I am
>> concerned (and to the extend we support it) is open source.
>>
>> Cheers,
>> Florian
>>
>>> --
> 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
> 

Re: Feature requests for queryset

2022-04-04 Thread Jason Johns
filter takes in a decomposed dict of keys and values, ie 

filter_dict = {
"id_in": SomeIterable
}

qs = SomeModel.objects.filter(**filter_dict)

from your example, IGNORE_FILTER does not return an iterable, so how is 
that to work with a SQL query?

Seems to me that ths might be an x-y problem

On Monday, April 4, 2022 at 8:33:38 AM UTC-4 laurent...@gmail.com wrote:

> Hello,
>
> Below are 2 feature requests :
> - the first would just be to add a constant object for ignoring some 
> filters,
> to avoid lists of "if ... is not None: q = q.filter(...)" like I must
> do right now,
> q = q.filter(id_in=[1,2,3]) filters something
> q = q.filter(id_in=IGNORE_FILTER) does not filter
> - the second would be to have "in-place" variants of filter and exclude, 
> like :
> q.filter_in_place(id_lt=5)
> instead of
> q = q.filter(id_lt=5)
> Maybe other people asked for one or both of these features before,
> but I did check the search here :
> https://code.djangoproject.com/search
> and also the archive here :
> https://groups.google.com/g/django-developers/search?q=ignore%20filter
> etc.
> and found nothing related.
>
> I proposed this morning the following class with better example at my
> team at work,
> but the decision was took that we stay on bare Django.
> Nevertheless, some of my teammates agreed that the IGNORE_FILTER
> feature was nice.
>
> class EnhancedQuerySet:
> """
> Extends the functionalities of Django QuerySet
> Example:
> - before:
> def some_function(
> fk1_ids: Optional[List[int]] = None,
> fk2_ids: Optional[List[int]] = None,
> fk3_ids: Optional[List[int]] = None,
> fk4_ids: Optional[List[int]] = None,
> pk_ids: Optional[List[int]] = None,
> ...
> ):
> some_instances_queryset = SomeModelClass.objects.all()
> if fk1_ids is not None:
> some_instances_queryset =
> some_instances_queryset.filter(fk1_id__in=fk1_ids)
> if fk2_ids is not None:
> some_instances_queryset =
> some_instances_queryset.filter(fk2_id__in=fk2_ids)
> if fk3_ids is not None:
> some_instances_queryset =
> some_instances_queryset.filter(fk3_id__in=fk3_ids)
> if fk4_ids is not None:
> some_instances_queryset =
> some_instances_queryset.filter(fk4_id__in=fk4_ids)
> if pk_ids is not None:
> some_instances_queryset =
> some_instances_queryset.filter(id__in=pk_ids)
> for some_instance in some_instances_queryset:
> ...
> - after:
> def some_function(
> fk1_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
> fk2_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
> fk3_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
> fk4_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
> pk_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
> ...
> ):
> some_instances_queryset = EnhancedQuerySet(SomeModelClass.objects.all())
> some_instances_queryset.filter(
> fk1_id__in=fk1_ids,
> fk2_id__in=fk2_ids,
> fk3_id__in=fk3_ids,
> fk4_id__in=fk4_ids,
> id__in=pk_ids,
> )
> for some_instance in some_instances_queryset:
> ...
> You may alias EnhancedQuerySet for shorter code :
> from ... import EnhancedQuerySet as EQS
> def some_function(
> fk1_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
> fk2_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
> fk3_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
> fk4_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
> pk_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
> ...
> ):
> some_instances_queryset = EQS(SomeModelClass.objects.all())
> some_instances_queryset.filter(
> fk1_id__in=fk1_ids,
> fk2_id__in=fk2_ids,
> fk3_id__in=fk3_ids,
> fk4_id__in=fk4_ids,
> id__in=pk_ids,
> )
> for some_instance in some_instances_queryset:
> ...
> """
>
> IGNORE_FILTER = object() # a sentinel for ignoring some filter to
> distinguish from None
>
> def __init__(self, queryset):
> self.queryset = queryset
>
> def _get_true_kwargs(self, kwargs: dict):
> true_kw_args = {}
> for key, value in kwargs.items():
> if value is EnhancedQuerySet.IGNORE_FILTER:
> continue
> true_kw_args[key] = value
> return true_kw_args
>
> def filter(self, *args, **kwargs):
> """
> Enhanced filter function with 2 features :
> - ignore some filters given with some default value
> - never forget the affectation after filtering, i.e. avoid this mistake:
> queryset.filter()
> instead of queryset = queryset.filter()
> """
> true_kw_args = self._get_true_kwargs(kwargs)
> self.queryset = self.queryset.filter(*args, **true_kw_args)
>
> def exclude(self, *args, **kwargs):
> """
> Similar to filter method but with exclude
> """
> true_kw_args = self._get_true_kwargs(kwargs)
> self.queryset = self.queryset.exclude(*args, **true_kw_args)
>
>
> Best regards,
> Laurent Lyaudet
>

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

Feature requests for queryset

2022-04-04 Thread Laurent Lyaudet
Hello,

Below are 2 feature requests :
- the first would just be to add a constant object for ignoring some filters,
to avoid lists of "if ... is not None: q = q.filter(...)" like I must
do right now,
q = q.filter(id_in=[1,2,3]) filters something
q = q.filter(id_in=IGNORE_FILTER) does not filter
- the second would be to have "in-place" variants of filter and exclude, like :
q.filter_in_place(id_lt=5)
instead of
q = q.filter(id_lt=5)
Maybe other people asked for one or both of these features before,
but I did check the search here :
https://code.djangoproject.com/search
and also the archive here :
https://groups.google.com/g/django-developers/search?q=ignore%20filter
etc.
and found nothing related.

I proposed this morning the following class with better example at my
team at work,
but the decision was took that we stay on bare Django.
Nevertheless, some of my teammates agreed that the IGNORE_FILTER
feature was nice.

class EnhancedQuerySet:
"""
Extends the functionalities of Django QuerySet
Example:
- before:
def some_function(
fk1_ids: Optional[List[int]] = None,
fk2_ids: Optional[List[int]] = None,
fk3_ids: Optional[List[int]] = None,
fk4_ids: Optional[List[int]] = None,
pk_ids: Optional[List[int]] = None,
...
):
some_instances_queryset = SomeModelClass.objects.all()
if fk1_ids is not None:
some_instances_queryset =
some_instances_queryset.filter(fk1_id__in=fk1_ids)
if fk2_ids is not None:
some_instances_queryset =
some_instances_queryset.filter(fk2_id__in=fk2_ids)
if fk3_ids is not None:
some_instances_queryset =
some_instances_queryset.filter(fk3_id__in=fk3_ids)
if fk4_ids is not None:
some_instances_queryset =
some_instances_queryset.filter(fk4_id__in=fk4_ids)
if pk_ids is not None:
some_instances_queryset =
some_instances_queryset.filter(id__in=pk_ids)
for some_instance in some_instances_queryset:
...
- after:
def some_function(
fk1_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
fk2_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
fk3_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
fk4_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
pk_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
...
):
some_instances_queryset = EnhancedQuerySet(SomeModelClass.objects.all())
some_instances_queryset.filter(
fk1_id__in=fk1_ids,
fk2_id__in=fk2_ids,
fk3_id__in=fk3_ids,
fk4_id__in=fk4_ids,
id__in=pk_ids,
)
for some_instance in some_instances_queryset:
...
You may alias EnhancedQuerySet for shorter code :
from ... import EnhancedQuerySet as EQS
def some_function(
fk1_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
fk2_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
fk3_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
fk4_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
pk_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
...
):
some_instances_queryset = EQS(SomeModelClass.objects.all())
some_instances_queryset.filter(
fk1_id__in=fk1_ids,
fk2_id__in=fk2_ids,
fk3_id__in=fk3_ids,
fk4_id__in=fk4_ids,
id__in=pk_ids,
)
for some_instance in some_instances_queryset:
...
"""

IGNORE_FILTER = object()  # a sentinel for ignoring some filter to
distinguish from None

def __init__(self, queryset):
self.queryset = queryset

def _get_true_kwargs(self, kwargs: dict):
true_kw_args = {}
for key, value in kwargs.items():
if value is EnhancedQuerySet.IGNORE_FILTER:
continue
true_kw_args[key] = value
return true_kw_args

def filter(self, *args, **kwargs):
"""
Enhanced filter function with 2 features :
- ignore some filters given with some default value
- never forget the affectation after filtering, i.e. avoid this mistake:
queryset.filter()
instead of queryset = queryset.filter()
"""
true_kw_args = self._get_true_kwargs(kwargs)
self.queryset = self.queryset.filter(*args, **true_kw_args)

def exclude(self, *args, **kwargs):
"""
Similar to filter method but with exclude
"""
true_kw_args = self._get_true_kwargs(kwargs)
self.queryset = self.queryset.exclude(*args, **true_kw_args)


Best regards,
 Laurent Lyaudet

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