django-commons/django-cookie-consent

No need to show cookie bar if only required cookies are used (no third party cookies)

Closed this issue · 5 comments

9mido commented

I don't think it is necessary to show the cookie bar and have users accept/decline anything if only required cookies are involved and not third party cookies. Unless of course the law requires you to show it no matter what.

Maybe this should be an optional setting just in case it needs to turn on again even for required cookies.

I may be missing something but I only created a required cookie group and a cookie within that required cookie group. The cookie bar did not show up when I did this and buttons for accept/decline did not show up on cookiegroup_list.html for that required cookie group. There are no other non-required cookie groups in the database. Can someone else confirm that this is the current behaviour? I don't think anything needs to be done with this unless it is necessary to accept/decline required cookies.

Added this for 0.4.0 to verify:

  • Check that there is a unit test, if not, write it
  • Confirm the desired behaviour is in place, or implement it (possibly behind an option)

Okay, I checked the docs and code, and as far as I can see:

  • cookie-consent does not ship with a consent bar by default this is the javascript cookie bar function :)
  • there is also no way to currently determine if only required cookie groups exist, which would inform your template whether to render a bar or not
  • You can (we have) build this based on the not_accepted_or_declined_cookie_groups template tag, which indeed seems to not take into account required cookie groups

cookie_consent_tags.py:

from cookie_consent.models import CookieGroup

@register.simple_tag()
def only_required_cookie_groups_exists():
    if CookieGroup.objects.filter(is_required=False).count() == 0 and CookieGroup.objects.filter(is_required=True).count() > 0:
        return True
    else:
        return False

test_page.html:

{% only_required_cookie_groups_exists %}

Util.py not_accepted_or_declined_cookie_groups:

get_cookie_groups()
dict_values([<CookieGroup: Stripe>])

[cookie_group for cookie_group in get_cookie_groups() if get_cookie_value_from_request(request, cookie_group.varname) is None]
[<CookieGroup: Stripe>]

Indeed, this not_accepted_or_declined_cookie_groups function does not account for required cookies.

Sites need to have required cookies like sessionid and csrftoken loaded to be able to view the webpage without acceptance.

Are we suggesting to allow users to accept required cookies? I don't think it is necessary to change anything here besides adding the template tag. The django developer could choose to have required cookies that do not need acceptance and then for other first party cookies that do some sort of intrusive privacy thing, the django developer could make another Cookie Group that gives the site visitor the option to accept/decline that first party Cookie Group.

I dove into this, via the test application locally and by checking test coverage and unit tests.

Starting point is the example app which uses the JS cookie bar: https://github.com/jazzband/django-cookie-consent/blob/2cdf00288dacc690cf83bdb20a3db42799b03236/testapp/templates/test_page.html#L70

In this block, the JS function is only called/loaded when non-required cookies are present through the use of the {% not_accepted_or_declined_cookie_groups %} tag. This tag only returns the optional cookiegroups. If only required cookie groups are present, the {% if %} condition on line 73 is false (https://github.com/jazzband/django-cookie-consent/blob/2cdf00288dacc690cf83bdb20a3db42799b03236/testapp/templates/test_page.html#L73) and the script snippet never ends up in the response body, thus it doesn't execute either.

Looking at the code, not_accepted_or_declined_cookie_groups calls the utility get_not_accepted_or_declined_cookie_groups (https://github.com/jazzband/django-cookie-consent/blob/2cdf00288dacc690cf83bdb20a3db42799b03236/cookie_consent/util.py#L135) which in turn calls get_cookie_groups. This one in turn calls all_cookie_groups, which returns results from the cache. I think I observed a delete failing to update the cache, but that's another item. Crucially, all_cookie_groups filters database records for is_required=False, which implements the expected behaviour. See https://github.com/jazzband/django-cookie-consent/blob/2cdf00288dacc690cf83bdb20a3db42799b03236/cookie_consent/cache.py#L32.

I've added explicit tests for this in #95, as test coverage for these functions was all "accidental" and I couldn't find an explicit test.

Conclusion

This means that the developer setting up their templates and these scripts are in full control, you can decide if you want to always show the cookiebar (by not gating it behind an if check), or only show it when non-required cookiegroups are present (by using the not_accepted_or_declined_cookie_groups template tag and combining it with an if check.