summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Danjou <julien@danjou.info>2015-09-07 15:20:29 +0200
committerJulien Danjou <julien@danjou.info>2015-09-07 15:33:37 +0200
commit6b949cdcb73aa0f41d1c58384ab22988ec721eb0 (patch)
tree6e9e6a376f7c0bc4e198c92b77ee451d76460ab3
parentb73aa5c3abcea74716e236e8fd41475a5dc8dbdd (diff)
downloadoslo-middleware-6b949cdcb73aa0f41d1c58384ab22988ec721eb0.tar.gz
cors: fix wildcard in actual request
Currently, the code only handle * (wildcard) in allowed_origins when using OPTIONS. When doing the actual request, * is not handled at all and therefore the request is denied. This patch fixes that by handling the wildcard the same way in both code path. Change-Id: I7c19b818b5845baca2a999b714ca6ebb90d9633d
-rw-r--r--oslo_middleware/cors.py41
-rw-r--r--oslo_middleware/tests/test_cors.py13
2 files changed, 40 insertions, 14 deletions
diff --git a/oslo_middleware/cors.py b/oslo_middleware/cors.py
index 21ce94c..1951575 100644
--- a/oslo_middleware/cors.py
+++ b/oslo_middleware/cors.py
@@ -53,6 +53,14 @@ CORS_OPTS = [
]
+class InvalidOriginError(Exception):
+ """Exception raised when Origin is invalid."""
+ def __init__(self, origin):
+ self.origin = origin
+ super(InvalidOriginError, self).__init__(
+ 'CORS request from origin \'%s\' not permitted.' % origin)
+
+
class CORS(base.ConfigurableMiddleware):
"""CORS Middleware.
@@ -263,15 +271,11 @@ class CORS(base.ConfigurableMiddleware):
return response
# Is this origin registered? (Section 6.2.2)
- origin = request.headers['Origin']
- if origin not in self.allowed_origins:
- if '*' in self.allowed_origins:
- origin = '*'
- else:
- LOG.debug('CORS request from origin \'%s\' not permitted.'
- % (origin,))
- return response
- cors_config = self.allowed_origins[origin]
+ try:
+ origin, cors_config = self._get_cors_config_by_origin(
+ request.headers['Origin'])
+ except InvalidOriginError:
+ return response
# If there's no request method, exit. (Section 6.2.3)
if 'Access-Control-Request-Method' not in request.headers:
@@ -335,6 +339,16 @@ class CORS(base.ConfigurableMiddleware):
return response
+ def _get_cors_config_by_origin(self, origin):
+ if origin not in self.allowed_origins:
+ if '*' in self.allowed_origins:
+ origin = '*'
+ else:
+ LOG.debug('CORS request from origin \'%s\' not permitted.'
+ % origin)
+ raise InvalidOriginError(origin)
+ return origin, self.allowed_origins[origin]
+
def _apply_cors_request_headers(self, request, response):
"""Handle Basic CORS Request (Section 6.1)
@@ -347,12 +361,11 @@ class CORS(base.ConfigurableMiddleware):
return
# Is this origin registered? (Section 6.1.2)
- origin = request.headers['Origin']
- if origin not in self.allowed_origins:
- LOG.debug('CORS request from origin \'%s\' not permitted.'
- % (origin,))
+ try:
+ origin, cors_config = self._get_cors_config_by_origin(
+ request.headers['Origin'])
+ except InvalidOriginError:
return
- cors_config = self.allowed_origins[origin]
# Set the default origin permission headers. (Sections 6.1.3 & 6.4)
response.headers['Vary'] = 'Origin'
diff --git a/oslo_middleware/tests/test_cors.py b/oslo_middleware/tests/test_cors.py
index 4b8ffb0..abc47cf 100644
--- a/oslo_middleware/tests/test_cors.py
+++ b/oslo_middleware/tests/test_cors.py
@@ -1019,6 +1019,19 @@ class CORSTestWildcard(CORSTestBase):
allow_credentials='true',
expose_headers=None)
+ # Test valid domain
+ request = webob.Request.blank('/')
+ request.method = "GET"
+ request.headers['Origin'] = 'http://default.example.com'
+ response = request.get_response(self.application)
+ self.assertCORSResponse(response,
+ status='200 OK',
+ allow_origin='http://default.example.com',
+ max_age=None,
+ allow_headers='',
+ allow_credentials='true',
+ expose_headers=None)
+
# Test invalid domain
request = webob.Request.blank('/')
request.method = "OPTIONS"