Skip to content

Commit

Permalink
testing: handle preflight requests rucio#5843
Browse files Browse the repository at this point in the history
  • Loading branch information
maany committed Aug 26, 2022
1 parent 763454f commit dd34d6c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
37 changes: 37 additions & 0 deletions lib/rucio/web/rest/flaskapi/v1/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,56 @@
from flask.views import MethodView
from werkzeug.datastructures import Headers
from werkzeug.exceptions import HTTPException
from werkzeug.wrappers import Request, Response

from rucio.api.authentication import validate_auth_token
from rucio.common.exception import RucioException, CannotAuthenticate, UnsupportedRequestedContentType
from rucio.common.schema import get_schema_value
from rucio.common.utils import generate_uuid, render_json
from rucio.core.vo import map_vo
from rucio.common import config
from configparser import NoOptionError, NoSectionError


if TYPE_CHECKING:
from typing import Optional, Union, Dict, Sequence, Tuple, Callable, Any, List

HeadersType = Union[Headers, Dict[str, str], Sequence[Tuple[str, str]]]


class CORSMiddleware(object):
"""
WebUI 2.0 makes preflight requests to the API, which are not handled by the API.
This middleware intercepts the preflight OPTIONS requests and returns a 200 OK response.
"""

def __init__(self, app):
self.app = app

def __call__(self, environ, start_response):
try:
webui_urls = config.config_get_list('webui', 'urls')
except (NoOptionError, NoSectionError, RuntimeError) as error:
logging.exception('Could not get webui urls from config file')
return str(error), 500

request = Request(environ)

if request.environ.get('REQUEST_METHOD') == 'OPTIONS':
if request.origin in webui_urls:
response = Response(status=200)
response.headers['Access-Control-Allow-Origin'] = request.origin
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = '*'
response.headers['Access-Control-Allow-Credentials'] = 'true'
return response(environ, start_response)
response = Response(status=403)
return response(environ, start_response)

# bypass this middleware for non-OPTIONS requests
return self.app(environ, start_response)


class ErrorHandlingMethodView(MethodView):
"""
Special MethodView that handles generic RucioExceptions and more generic
Expand Down
3 changes: 2 additions & 1 deletion lib/rucio/web/rest/flaskapi/v1/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import importlib

from flask import Flask

from rucio.web.rest.flaskapi.v1.common import CORSMiddleware
from rucio.common.config import config_get
from rucio.common.exception import ConfigurationError
from rucio.common.logging import setup_logging
Expand Down Expand Up @@ -72,6 +72,7 @@ def apply_endpoints(app, modules):
endpoints = DEFAULT_ENDPOINTS

application = Flask(__name__)
application.wsgi_app = CORSMiddleware(application.wsgi_app)
apply_endpoints(application, endpoints)
setup_logging(application)

Expand Down

0 comments on commit dd34d6c

Please sign in to comment.