diff options
author | Julien Danjou <julien@danjou.info> | 2015-09-07 15:20:29 +0200 |
---|---|---|
committer | Julien Danjou <julien@danjou.info> | 2015-09-07 15:33:37 +0200 |
commit | 6b949cdcb73aa0f41d1c58384ab22988ec721eb0 (patch) | |
tree | 6e9e6a376f7c0bc4e198c92b77ee451d76460ab3 /oslo_middleware | |
parent | b73aa5c3abcea74716e236e8fd41475a5dc8dbdd (diff) | |
download | oslo-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
Diffstat (limited to 'oslo_middleware')
-rw-r--r-- | oslo_middleware/cors.py | 41 | ||||
-rw-r--r-- | oslo_middleware/tests/test_cors.py | 13 |
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" |