blob: 10398f6d596af146bd8977ebe3ab8a3950be77fe [file] [log] [blame]
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Redirect Middleware for Monorail.
Handles traffic redirection before hitting main monorail app.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import flask
from redirect import redirect_utils
from redirect import redirectissue
class RedirectMiddleware(object):
def __init__(self, main_app, redirect_app):
self._main_app = main_app
self._redirect_app = redirect_app
def __call__(self, environ, start_response):
# Run the redirect app first.
response = flask.Response.from_app(self._redirect_app, environ)
if response.status_code == 404:
# If it returns 404, run the main app.
return self._main_app(environ, start_response)
# Otherwise, return the response from the redirect app.
app_iter, status, headers = response.get_wsgi_response(environ)
start_response(status, headers)
return app_iter
def GenerateRedirectApp():
redirect_app = flask.Flask(__name__)
def PreCheckHandler():
# Should not redirect away from monorail if param set.
r = flask.request
no_redirect = 'no_tracker_redirect' in r.args
if no_redirect:
flask.abort(404)
redirect_app.before_request(PreCheckHandler)
def IssueList(project_name):
redirect_url = redirect_utils.GetRedirectURL(project_name)
if redirect_url:
query_string = redirect_utils.GetSearchQuery(
project_name, flask.request.args)
return flask.redirect(redirect_url + '/issues?' + query_string)
flask.abort(404)
redirect_app.route('/p/<string:project_name>/')(IssueList)
redirect_app.route('/p/<string:project_name>/issues/')(IssueList)
redirect_app.route('/p/<string:project_name>/issues/list')(IssueList)
redirect_app.route('/p/<string:project_name>/issues/list_new')(IssueList)
def IssueDetail(project_name):
local_id = flask.request.args.get('id', type=int)
if not local_id:
flask.abort(404)
redirect_url = _GenerateIssueDetailRedirectURL(local_id, project_name)
if redirect_url:
return flask.render_template('redirect.html', base_url=redirect_url)
flask.abort(404)
redirect_app.route('/p/<string:project_name>/issues/detail')(IssueDetail)
def IssueCreate(project_name):
redirect_url = redirect_utils.GetRedirectURL(project_name)
if redirect_url:
query_string = redirect_utils.GetNewIssueParams(
flask.request.args, project_name)
return flask.redirect(redirect_url + '/new?' + query_string)
flask.abort(404)
redirect_app.route('/p/<string:project_name>/issues/entry')(IssueCreate)
redirect_app.route('/p/<string:project_name>/issues/entry_new')(IssueCreate)
return redirect_app
def _GenerateIssueDetailRedirectURL(local_id, project_name):
redirect_base_url = redirect_utils.GetRedirectURL(project_name)
if not redirect_base_url:
return None
if local_id > redirect_utils.MAX_MONORAIL_ISSUE_ID:
return redirect_base_url + '/' + str(local_id)
tracker_id = redirectissue.RedirectIssue.Get(project_name, local_id)
if tracker_id:
return redirect_base_url + '/' + tracker_id
return None