summaryrefslogtreecommitdiff
path: root/zuul/web
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-06-23 18:33:45 +0000
committerGerrit Code Review <review@openstack.org>2020-06-23 18:33:45 +0000
commit4c62c35bf72252c4f3a8ed28fb274505c95285c6 (patch)
tree0d6eae3c6648364545ee229d3a910da479d39a58 /zuul/web
parent35128d24c93c6e97cb780decc3211f2beaf01b6a (diff)
parent74ff81998f76178ebb233240fa6c5885ac97072d (diff)
downloadzuul-4c62c35bf72252c4f3a8ed28fb274505c95285c6.tar.gz
Merge "zuul-web: support OPTIONS for protected endpoints"
Diffstat (limited to 'zuul/web')
-rwxr-xr-xzuul/web/__init__.py32
1 files changed, 32 insertions, 0 deletions
diff --git a/zuul/web/__init__.py b/zuul/web/__init__.py
index 40441bc4d..bd526c4ec 100755
--- a/zuul/web/__init__.py
+++ b/zuul/web/__init__.py
@@ -68,6 +68,30 @@ class SaveParamsTool(cherrypy.Tool):
cherrypy.tools.save_params = SaveParamsTool()
+def handle_options(allowed_methods=None):
+ if cherrypy.request.method == 'OPTIONS':
+ methods = allowed_methods or ['GET', 'OPTIONS']
+ if allowed_methods and 'OPTIONS' not in allowed_methods:
+ methods = methods + ['OPTIONS']
+ # discard decorated handler
+ request = cherrypy.serving.request
+ request.handler = None
+ # Set CORS response headers
+ resp = cherrypy.response
+ resp.headers['Access-Control-Allow-Origin'] = '*'
+ resp.headers['Access-Control-Allow-Headers'] =\
+ ', '.join(['Authorization', 'Content-Type'])
+ resp.headers['Access-Control-Allow-Methods'] =\
+ ', '.join(methods)
+ # Allow caching of the preflight response
+ resp.headers['Access-Control-Max-Age'] = 86400
+ resp.status = 204
+
+
+cherrypy.tools.handle_options = cherrypy.Tool('on_start_resource',
+ handle_options)
+
+
class ChangeFilter(object):
def __init__(self, desired):
self.desired = desired
@@ -240,6 +264,7 @@ class ZuulWebAPI(object):
@cherrypy.expose
@cherrypy.tools.json_in()
@cherrypy.tools.json_out(content_type='application/json; charset=utf-8')
+ @cherrypy.tools.handle_options(allowed_methods=['POST', ])
def dequeue(self, tenant, project):
basic_error = self._basic_auth_header_check()
if basic_error is not None:
@@ -284,6 +309,7 @@ class ZuulWebAPI(object):
@cherrypy.expose
@cherrypy.tools.json_in()
@cherrypy.tools.json_out(content_type='application/json; charset=utf-8')
+ @cherrypy.tools.handle_options(allowed_methods=['POST', ])
def enqueue(self, tenant, project):
basic_error = self._basic_auth_header_check()
if basic_error is not None:
@@ -356,6 +382,7 @@ class ZuulWebAPI(object):
@cherrypy.expose
@cherrypy.tools.json_out(content_type='application/json; charset=utf-8')
+ @cherrypy.tools.handle_options(allowed_methods=['GET', 'POST', ])
def autohold(self, tenant, project=None):
# we don't use json_in because a payload is not mandatory with GET
# Note: GET handling is redundant with autohold_list
@@ -443,6 +470,7 @@ class ZuulWebAPI(object):
@cherrypy.expose
@cherrypy.tools.json_out(content_type='application/json; charset=utf-8')
+ @cherrypy.tools.handle_options(allowed_methods=['GET', 'DELETE', ])
def autohold_by_request_id(self, tenant, request_id):
if cherrypy.request.method == 'GET':
return self._autohold_info(request_id)
@@ -586,7 +614,11 @@ class ZuulWebAPI(object):
# TODO good candidate for caching
@cherrypy.expose
@cherrypy.tools.json_out(content_type='application/json; charset=utf-8')
+ @cherrypy.tools.handle_options(allowed_methods=['GET', ])
def user_authorizations(self):
+ basic_error = self._basic_auth_header_check()
+ if basic_error is not None:
+ return basic_error
rawToken = cherrypy.request.headers['Authorization'][len('Bearer '):]
try:
claims = self.zuulweb.authenticators.authenticate(rawToken)