Fix HTTP scheme when behind a reverse proxy

This commit is contained in:
Scott Wallace 2022-03-25 12:51:36 +00:00
parent d5f35d23bc
commit 39c917fcd0
Signed by: scott
GPG key ID: AA742FDC5AFE2A72
2 changed files with 32 additions and 2 deletions

View file

@ -3,10 +3,12 @@ Main Flask-based app for Slinky
""" """
from flask import Flask, Response, render_template from flask import Flask, Response, render_template
from flask_bootstrap import Bootstrap # type: ignore[import] from flask_bootstrap import Bootstrap # type: ignore[import]
from werkzeug.middleware.proxy_fix import ProxyFix
from slinky.web import protect, slinky_webapp from slinky.web import protect, slinky_webapp
app = Flask(__name__) app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1) # type: ignore[assignment]
app.register_blueprint(slinky_webapp) app.register_blueprint(slinky_webapp)
Bootstrap(app) Bootstrap(app)

View file

@ -3,6 +3,7 @@ Web component
""" """
import logging import logging
import os
from datetime import datetime from datetime import datetime
from functools import wraps from functools import wraps
from typing import Any, Callable from typing import Any, Callable
@ -13,6 +14,7 @@ from flask_wtf import FlaskForm # type: ignore[import]
from wtforms import HiddenField # type: ignore[import] from wtforms import HiddenField # type: ignore[import]
from wtforms import DateTimeLocalField, IntegerField, StringField from wtforms import DateTimeLocalField, IntegerField, StringField
from wtforms.validators import DataRequired, Length # type: ignore[import] from wtforms.validators import DataRequired, Length # type: ignore[import]
from slinky import Slinky from slinky import Slinky
slinky_webapp = Blueprint('webapp', __name__, template_folder='templates') slinky_webapp = Blueprint('webapp', __name__, template_folder='templates')
@ -82,7 +84,10 @@ def protect(func: Callable[..., Response]) -> Callable[..., Response]:
@wraps(func) @wraps(func)
def check_ip(*args: Any, **kwargs: Any) -> Response: def check_ip(*args: Any, **kwargs: Any) -> Response:
if request.headers['X-Forwarded-For'] not in cfg['allowed_ips']: if (
os.environ.get('FLASK_ENV', '') != 'development'
and request.headers['X-Forwarded-For'] not in cfg['allowed_ips']
):
print(f'Protected URL access attempt from {request.remote_addr}') print(f'Protected URL access attempt from {request.remote_addr}')
return Response('Not found', 404) return Response('Not found', 404)
return func(*args, **kwargs) return func(*args, **kwargs)
@ -112,7 +117,9 @@ def try_path_as_shortcode(path: str) -> Response:
should_redirect = False should_redirect = False
if should_redirect: if should_redirect:
return Response('Redirecting...', status=302, headers={'location': shortcode.url}) return Response(
'Redirecting...', status=302, headers={'location': shortcode.url}
)
return Response('Not found', 404) return Response('Not found', 404)
@ -172,3 +179,24 @@ def lister() -> Response:
render_template('list.html', form=form, shortcodes=slinky.get_all()), render_template('list.html', form=form, shortcodes=slinky.get_all()),
200, 200,
) )
@slinky_webapp.route('/_/edit/<int:id>', methods=['GET', 'POST'])
@protect
def edit(id: int) -> Response:
"""
Edit the shortcode.
Returns:
Response: HTTP response
"""
form = DelForm(meta={'csrf': False})
slinky = Slinky(cfg['db'])
if form.is_submitted():
slinky.delete_by_shortcode(form.delete.data.strip())
return Response(
render_template('edit.html', form=form, shortcodes=slinky.get_all()),
200,
)