Skip to content

Commit

Permalink
Expose Header Option (#24)
Browse files Browse the repository at this point in the history
* - Added `EXPOSE_HEADER` setting

* - Added and improved docs
- Added more tests for the relationship between `EXPOSE_HEADER` and `RETURN_HEADER` setting

* - Fixed incorrect key in config.py
- Removed redundant logtest from `EXPOSE_HEADER` tests

* - Added changelog
  • Loading branch information
ingvaldlorentzen committed Feb 10, 2020
1 parent 20d373e commit 7621af2
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 2 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
Changelog
=========

`1.1.0`_ - 2020-02-10
---------------------

**Features**

* Added a ``EXPOSE_HEADER`` setting, which will add the ``Access-Control-Expose-Headers`` with the ``RETURN_HEADER`` as value to the response. This is to allow the JavaScript Fetch API to access the header with the GUID



`1.0.1`_ - 2020-02-08
---------------------

**Bugfix**

* Fixed validation of incoming GUID

**Improvements**

* Changed the ``middleware.py`` logger name to ``django_guid``
Expand Down Expand Up @@ -120,3 +133,4 @@ Changelog
.. _0.3.1: https://github.com/jonasks/django-guid/compare/0.3.0...0.3.1
.. _1.0.0: https://github.com/jonasks/django-guid/compare/0.3.0...1.0.0
.. _1.0.1: https://github.com/jonasks/django-guid/compare/1.0.0...1.0.1
.. _1.1.0: https://github.com/jonasks/django-guid/compare/1.0.1...1.1.0
9 changes: 8 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ Settings

Default: True

* :code:`RETURN_HEADER`
Whether to return :code:`Access-Control-Expose-Headers` for the GUID header if
:code:`RETURN_HEADER` is :code:`True`, has no effect if :code:`RETURN_HEADER` is :code:`False`.
This is allows the JavaScript Fetch API to access the header when CORS is enabled.

Default: True


Installation
------------
Expand Down Expand Up @@ -174,4 +181,4 @@ If you wish to aggregate the django-guid logs to your console or other handlers,
----------

Inspired by `django-log-request-id <https://github.com/dabapps/django-log-request-id>`_ with a complete rewritten
`django-echelon <https://github.com/seveas/django-echelon>`_ approach.
`django-echelon <https://github.com/seveas/django-echelon>`_ approach.
2 changes: 1 addition & 1 deletion django_guid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
Adding imports here will break setup.py
"""

__version__ = '1.0.1'
__version__ = '1.1.0'
3 changes: 3 additions & 0 deletions django_guid/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def __init__(self) -> None:
self.VALIDATE_GUID = True
self.SKIP_CLEANUP = False
self.RETURN_HEADER = True
self.EXPOSE_HEADER = True

if hasattr(django_settings, 'DJANGO_GUID'):
_settings = django_settings.DJANGO_GUID
Expand All @@ -33,6 +34,8 @@ def __init__(self) -> None:
raise ImproperlyConfigured('GUID_HEADER_NAME must be a string') # Note: Case insensitive
if not isinstance(self.RETURN_HEADER, bool):
raise ImproperlyConfigured('RETURN_HEADER must be a boolean')
if not isinstance(self.EXPOSE_HEADER, bool):
raise ImproperlyConfigured('EXPOSE_HEADER must be a boolean')
else:
pass # Do nothing if DJANGO_GUID not found in settings

Expand Down
2 changes: 2 additions & 0 deletions django_guid/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def __call__(self, request: HttpRequest) -> Union[HttpRequest, HttpResponse]:
response = self.get_response(request)
if settings.RETURN_HEADER:
response[settings.GUID_HEADER_NAME] = self.get_guid() # Adds the GUID to the response header
if settings.EXPOSE_HEADER:
response['Access-Control-Expose-Headers'] = settings.GUID_HEADER_NAME
if not settings.SKIP_CLEANUP:
# Delete the current request to avoid memory leak
self.delete_guid()
Expand Down
10 changes: 10 additions & 0 deletions docs/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,13 @@ RETURN_HEADER

Whether to return the GUID (Correlation-ID) as a header in the response or not.
It will have the same name as the :code:`GUID_HEADER_NAME` setting.


EXPOSE_HEADER
-------------
* **Default**: ``True``
* **Type**: ``boolean``

Whether to return :code:`Access-Control-Expose-Headers` for the GUID header if
:code:`RETURN_HEADER` is :code:`True`, has no effect if :code:`RETURN_HEADER` is :code:`False`.
This is allows the JavaScript Fetch API to access the header when CORS is enabled.
50 changes: 50 additions & 0 deletions tests/functional/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,56 @@ def test_no_return_header_and_drf_url(client, caplog, monkeypatch, mock_uuid):
assert not response.get('Correlation-ID')


def test_no_expose_header_return_header_true(client, monkeypatch, mock_uuid):
"""
Tests that it does not return the Access-Control-Allow-Origin when EXPOSE_HEADER is set to False
and RETURN_HEADER is True
"""
from django_guid.config import settings as guid_settings

monkeypatch.setattr(guid_settings, 'EXPOSE_HEADER', False)
response = client.get('/api')
assert not response.get('Access-Control-Expose-Headers')


def test_expose_header_return_header_true(client, monkeypatch, mock_uuid):
"""
Tests that it does return the Access-Control-Allow-Origin when EXPOSE_HEADER is set to True
and RETURN_HEADER is True
"""
from django_guid.config import settings as guid_settings

monkeypatch.setattr(guid_settings, 'EXPOSE_HEADER', True)
response = client.get('/api')
assert response.get('Access-Control-Expose-Headers')


def test_no_expose_header_return_header_false(client, monkeypatch, mock_uuid):
"""
Tests that it does not return the Access-Control-Allow-Origin when EXPOSE_HEADER is set to False
and RETURN_HEADER is False
"""
from django_guid.config import settings as guid_settings

monkeypatch.setattr(guid_settings, 'EXPOSE_HEADER', False)
monkeypatch.setattr(guid_settings, 'RETURN_HEADER', False)
response = client.get('/api')
assert not response.get('Access-Control-Expose-Headers')


def test_expose_header_return_header_false(client, monkeypatch, mock_uuid):
"""
Tests that it does not return the Access-Control-Allow-Origin when EXPOSE_HEADER is set to True
and RETURN_HEADER is False
"""
from django_guid.config import settings as guid_settings

monkeypatch.setattr(guid_settings, 'EXPOSE_HEADER', True)
monkeypatch.setattr(guid_settings, 'RETURN_HEADER', False)
response = client.get('/api')
assert not response.get('Access-Control-Expose-Headers')


#
# Important: All tests below this comment should have SKIP_CLEANUP set to True.
#
Expand Down
7 changes: 7 additions & 0 deletions tests/unit/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ def test_invalid_return_header_setting(monkeypatch):
Settings()


def test_invalid_expose_header_setting(monkeypatch):
monkeypatch.setattr(django_settings, 'DJANGO_GUID', {'EXPOSE_HEADER': 'string'})
with pytest.raises(ImproperlyConfigured, match='EXPOSE_HEADER must be a boolean'):
Settings()


def test_valid_settings(monkeypatch):
monkeypatch.setattr(
django_settings,
Expand All @@ -44,6 +50,7 @@ def test_valid_settings(monkeypatch):
'VALIDATE_GUID': False,
'GUID_HEADER_NAME': 'Correlation-ID-TEST',
'RETURN_HEADER': False,
'EXPOSE_HEADER': False,
},
)
assert not Settings().VALIDATE_GUID
Expand Down

0 comments on commit 7621af2

Please sign in to comment.