Hi all,

First, I want to say that complex things fail in complex ways, so there it's probably a fallacy to look for a single root cause. I agree with various other points about mistakes that were made, but not others. Particularly:

On 22/11/16 12:41, Florian Apolloner wrote:
Hi,

On Monday, November 21, 2016 at 11:56:56 PM UTC+1, Tim Graham wrote:

    … that the existing tests would catch this type of obviously
    incorrect issue.


I think that is the main issue here. I was also really surprised to discover that the tests were missing cases like this -- then again, writing good tests is hard and I know that I am personally one not to write good tests usually. Either way, I think the way forward is to improve the testsuite in this case.

I disagree with this, there was no issue with the existing test suite for the FBV version. *Tests are never close to exhaustive and we should never think they are or can be.* Tests are spot checks of correctness in an infinite universe of possible input values. When trying to work out what you should test in this vast space, there are a few sensible ways:

1. Look at the requirements, and pick spots that match each requirement. In this case:

 * If a request has the required token, it should be allowed through
 * If a request does not have the required token, it should not be
   allowed through

2. Make some guesses about well known edge cases and test them (e.g the empty string case etc.). However this could be a complete waste of time

3. Look at the implementation at work out where it might go wrong. This one is really important in reality.

And this is what the existing tests did. Out of the infinite number of HTTP requests to test under point 1, they happened to pick a GET request, which was perfectly sensible. In the case of FBVs, the control flow is so clear that all of the following are equally silly tests to add:

 * Check that requests with query string parameter 'xyz' doesn't
   introduce a back door
 * Check that on leap years tokens are checked
 * Check that the security is correct for requests that are
   specifically GET, POST, HEAD, OPTIONS, DELETE....


The conclusion is this: in CBVs control flow is much, much less clear. In the FBV the mistake would have been immediately obvious, the CBV base classes obfuscated things to the point where it wasn't at all clear. To write adequate tests for the CBV version, under point 3 above, you have *much, much more work* to do.

I disagree that forcing people to write their own auth views is *necessarily* worse than providing a CBV that people can customise. Given this demonstration of how CBVs obfuscate control flow, it's quite possible that writing an FBV from scratch will be less error prone than using a CBV and subclassing, especially when we have encapsulated things like the token checking. Personally I would be massively happier auditing a custom FBV than a subclassed CBV, especially when you consider that the CBV subclass is inheriting from a stack of classes that could change in later versions of Django in some subtle way that breaks the code. Subclassing is not necessarily safer, it just feels safer ("I'm only changing this one little method"), and *that feeling of greater safety is itself a huge danger*.

Going forward, I think we need to:

1. Recognise that CBVs are much harder to reason about, and therefore require much more care.
2. Avoid using CBVs unless you really need them.
3. Recognise that tests for FBVs are inadequate against the CBV translation.
4. Not deprecate the FBVs. At the very least, they provide a sensible and easy to understand starting point for people that want to copy the logic to create their own, and do so in a way that they actually understand and can audit.

I'd be +0 on reverting to an FBV only, but it's part of a much bigger discussion

Regards,

Luke

--
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 [email protected].
To post to this group, send email to [email protected].
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/e160c9a0-0af0-7767-4b35-cb02a92d6a4d%40cantab.net.
For more options, visit https://groups.google.com/d/optout.

Reply via email to