Update werkzeug and stopusing routes with the same path. (#2861)

This commit is contained in:
Jason Robbins 2023-03-27 13:54:05 -07:00 коммит произвёл GitHub
Родитель f33576a5f3
Коммит 52328f8d90
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 65 добавлений и 62 удалений

Просмотреть файл

@ -554,38 +554,44 @@ class SPAHandler(FlaskHandler):
TEMPLATE_PATH = 'spa.html'
def get_template_data(self, **defaults):
# Check if the page requires user to sign in
if defaults.get('require_signin') and not self.get_current_user():
return flask.redirect(settings.LOGIN_PAGE_URL), self.get_headers()
# Check if the page requires create feature permission
if defaults.get('require_create_feature'):
redirect_resp = permissions.validate_feature_create_permission(self)
if redirect_resp:
return redirect_resp
# Validate the user has edit permissions and redirect if needed.
if defaults.get('require_edit_feature'):
feature_id = defaults.get('feature_id')
if not feature_id:
self.abort(500, msg='Cannot get feature ID from the URL')
redirect_resp = permissions.validate_feature_edit_permission(
self, feature_id)
if redirect_resp:
return redirect_resp
# Validate the user has admin permissions and redirect if needed.
if defaults.get('require_admin_site'):
user = self.get_current_user()
# Should have already done the require_signin check.
# If for reason, we don't let's treat it as the main 403 case.
if (not user
or not permissions.can_admin_site(user)):
self.abort(403, msg='Cannot perform admin actions')
return {} # no handler_data needed to be returned
return get_spa_template_data(self, defaults)
def FlaskApplication(import_name, routes, post_routes, pattern_base='', debug=False):
def get_spa_template_data(handler_obj, defaults):
"""Check permissions then let spa.html do its thing."""
# Check if the page requires user to sign in
if defaults.get('require_signin') and not handler_obj.get_current_user():
return flask.redirect(settings.LOGIN_PAGE_URL), handler_obj.get_headers()
# Check if the page requires create feature permission
if defaults.get('require_create_feature'):
redirect_resp = permissions.validate_feature_create_permission(handler_obj)
if redirect_resp:
return redirect_resp
# Validate the user has edit permissions and redirect if needed.
if defaults.get('require_edit_feature'):
feature_id = defaults.get('feature_id')
if not feature_id:
handler_obj.abort(500, msg='Cannot get feature ID from the URL')
redirect_resp = permissions.validate_feature_edit_permission(
handler_obj, feature_id)
if redirect_resp:
return redirect_resp
# Validate the user has admin permissions and redirect if needed.
if defaults.get('require_admin_site'):
user = handler_obj.get_current_user()
# Should have already done the require_signin check.
# If for reason, we don't let's treat it as the main 403 case.
if not user or not permissions.can_admin_site(user):
handler_obj.abort(403, msg='Cannot perform admin actions')
return {} # no handler_data needed to be returned
def FlaskApplication(import_name, routes, pattern_base='', debug=False):
"""Make a Flask app and add routes and handlers that work like webapp2."""
app = flask.Flask(import_name,
@ -599,19 +605,11 @@ def FlaskApplication(import_name, routes, post_routes, pattern_base='', debug=Fa
app.secret_key = secrets.get_session_secret() # For flask.session
app.permanent_session_lifetime = xsrf.REFRESH_TOKEN_TIMEOUT_SEC
for i, route in enumerate(post_routes):
classname = route.handler_class.__name__
app.add_url_rule(
pattern_base + route.path,
endpoint=f'{classname}{i}', # We don't use it, but it must be unique.
view_func=route.handler_class.as_view(classname),
methods=["POST"])
for i, route in enumerate(routes):
classname = route.handler_class.__name__
app.add_url_rule(
pattern_base + route.path,
endpoint=f'{classname}{i + len(post_routes)}', # We don't use it, but it must be unique.
endpoint=f'{classname}{i}', # We don't use it, but it must be unique.
view_func=route.handler_class.as_view(classname),
defaults=route.defaults)

Просмотреть файл

@ -74,7 +74,6 @@ test_app = basehandlers.FlaskApplication(
Route('/ui/density.json', basehandlers.ConstHandler,
{'UI density': ['default', 'comfortable', 'compact']}),
],
[], # POST routes
debug=True)

Просмотреть файл

@ -47,7 +47,6 @@ test_app = basehandlers.FlaskApplication(
__name__,
[Route('/path', MockHandler),
],
[], # POST routes
debug=True)

32
main.py
Просмотреть файл

@ -152,27 +152,31 @@ api_routes: list[Route] = [
# (f'{API_BASE}/metrics/<str:kind>/<int:bucket_id>', TODO),
]
# The Routes below that have no handler specified use SPAHandler.
# The guide.* handlers each call get_spa_template_data().
spa_page_routes = [
Route('/'),
Route('/roadmap'),
Route('/myfeatures', defaults={'require_signin': True}),
Route('/newfeatures'),
Route('/feature/<int:feature_id>'),
Route('/guide/new',
Route('/guide/new', guide.FeatureCreateHandler,
defaults={'require_create_feature': True}),
Route('/guide/enterprise/new',
Route('/guide/enterprise/new', guide.EnterpriseFeatureCreateHandler,
defaults={'require_create_feature': True}),
Route('/guide/edit/<int:feature_id>',
Route('/guide/edit/<int:feature_id>', guide.FeatureEditHandler,
defaults={'require_edit_feature': True}),
Route('/guide/stage/<int:feature_id>/<int:stage_id>/<int:intent_stage>',
Route('/guide/stage/<int:feature_id>/<int:intent_stage>/<int:stage_id>',
guide.FeatureEditHandler,
defaults={'require_edit_feature': True}),
Route('/guide/stage/<int:feature_id>/<int:stage_id>',
guide.FeatureEditHandler,
defaults={'require_edit_feature': True}),
Route('/guide/edit/<int:feature_id>/<int:stage_id>',
Route('/guide/edit/<int:feature_id>/<int:stage_id>', guide.FeatureEditHandler,
defaults={'require_edit_feature': True}),
Route('/guide/editall/<int:feature_id>',
Route('/guide/editall/<int:feature_id>', guide.FeatureEditHandler,
defaults={'require_edit_feature': True}),
Route('/guide/verify_accuracy/<int:feature_id>',
Route('/guide/verify_accuracy/<int:feature_id>', guide.FeatureEditHandler,
defaults={'require_edit_feature': True}),
Route('/guide/stage/<int:feature_id>/metadata',
defaults={'require_edit_feature': True}),
@ -193,18 +197,6 @@ spa_page_routes = [
Route('/admin/blink', defaults={'require_admin_site': True, 'require_signin': True}),
]
spa_page_post_routes: list[Route] = [
Route('/guide/new', guide.FeatureCreateHandler),
Route('/guide/enterprise/new', guide.EnterpriseFeatureCreateHandler),
Route('/guide/edit/<int:feature_id>', guide.FeatureEditHandler),
Route('/guide/stage/<int:feature_id>/<int:intent_stage>',
guide.FeatureEditHandler),
Route('/guide/stage/<int:feature_id>/<int:intent_stage>/<int:stage_id>/',
guide.FeatureEditHandler),
Route('/guide/editall/<int:feature_id>', guide.FeatureEditHandler),
Route('/guide/verify_accuracy/<int:feature_id>', guide.FeatureEditHandler),
]
mpa_page_routes: list[Route] = [
Route('/admin/subscribers', blink_handler.SubscribersHandler),
Route('/admin/users/new', users.UserListHandler),
@ -270,7 +262,7 @@ if settings.DEV_MODE:
app = basehandlers.FlaskApplication(
__name__,
(metrics_chart_routes + api_routes + mpa_page_routes + spa_page_routes +
internals_routes + dev_routes), spa_page_post_routes)
internals_routes + dev_routes))
# TODO(jrobbins): Make the CSP handler be a class like our others.
app.add_url_rule(

Просмотреть файл

@ -40,6 +40,11 @@ DEVREL_EMAIL = 'devrel-chromestatus-all@google.com'
class FeatureCreateHandler(basehandlers.FlaskHandler):
TEMPLATE_PATH = 'spa.html'
def get_template_data(self, **defaults):
return basehandlers.get_spa_template_data(self, defaults)
@permissions.require_create_feature
def process_post_data(self, **kwargs):
owners = self.split_emails('owner')
@ -131,6 +136,11 @@ class FeatureCreateHandler(basehandlers.FlaskHandler):
class EnterpriseFeatureCreateHandler(FeatureCreateHandler):
TEMPLATE_PATH = 'spa.html'
def get_template_data(self, **defaults):
return basehandlers.get_spa_template_data(self, defaults)
@permissions.require_create_feature
def process_post_data(self, **kwargs):
owners = self.split_emails('owner')
@ -195,6 +205,11 @@ class EnterpriseFeatureCreateHandler(FeatureCreateHandler):
class FeatureEditHandler(basehandlers.FlaskHandler):
TEMPLATE_PATH = 'spa.html'
def get_template_data(self, **defaults):
return basehandlers.get_spa_template_data(self, defaults)
# Field name, data type
EXISTING_FIELDS: list[tuple[str, str]] = [
# impl_status_chrome and intent_stage handled separately.

Просмотреть файл

@ -23,7 +23,7 @@ flask-cors==3.0.10
funcsigs==1.0.2
Jinja2==3.1.2
MarkupSafe==2.1.1
Werkzeug==2.1.2
Werkzeug==2.2.3
click==8.1.3
itsdangerous==2.1.2