Merged in feature/HTTPASTE-46/view (pull request #50)
Feature/HTTPASTE-46/view
This commit is contained in:
commit
389571522f
16 changed files with 145 additions and 23 deletions
|
|
@ -14,7 +14,7 @@ WORKDIR /usr/local/src/httpaste
|
|||
COPY . .
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y libffi-dev gcc && \
|
||||
apt-get install -y libffi-dev gcc fontconfig && \
|
||||
python3 -m pip install pipenv && \
|
||||
python3 -m pipenv install --deploy --system --verbose && \
|
||||
python3 setup.py install && \
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ services:
|
|||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
-
|
||||
type: volume
|
||||
|
|
@ -30,11 +31,13 @@ services:
|
|||
volume:
|
||||
nocopy: true
|
||||
- ./httpd/usr/local/apache2/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf
|
||||
- ./httpd/usr/local/apache2/ssl:/usr/local/apache2/ssl
|
||||
tor:
|
||||
build:
|
||||
context: ./tor
|
||||
dockerfile: Dockerfile
|
||||
volumes:
|
||||
- ./tor/etc/tor/torrc:/etc/tor/torrc
|
||||
- ./tor/var/lib/tor/hidden_service:./tor/var/lib/tor/hidden_service
|
||||
volumes:
|
||||
system-shared:
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ LoadModule unixd_module modules/mod_unixd.so
|
|||
LoadModule access_compat_module modules/mod_access_compat.so
|
||||
LoadModule security2_module /usr/lib/apache2/modules/mod_security2.so
|
||||
LoadModule evasive20_module /usr/lib/apache2/modules/mod_evasive20.so
|
||||
|
||||
LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so
|
||||
|
||||
<IfModule unixd_module>
|
||||
User www-data
|
||||
|
|
@ -88,3 +88,20 @@ ServerName 127.0.0.1
|
|||
SetEnv proxy-sendchunks
|
||||
ProxyPass "/" "unix:/shared/uwsgi.sock|uwsgi://localhost/"
|
||||
</VirtualHost>
|
||||
|
||||
<IfFile 'ssl/private.key'>
|
||||
Listen 0.0.0.0:443
|
||||
|
||||
|
||||
<VirtualHost 0.0.0.0:443>
|
||||
#ProxyPreserveHost On
|
||||
ServerName httpaste.it
|
||||
ServerAlias localhost
|
||||
SSLEngine on
|
||||
SSLCertificateFile "ssl/certificate.crt"
|
||||
SSLCertificateChainFile "ssl/ca_bundle.crt"
|
||||
SSLCertificateKeyFile "ssl/private.key"
|
||||
SetEnv proxy-sendchunks
|
||||
ProxyPass "/" "unix:/shared/uwsgi.sock|uwsgi://localhost/"
|
||||
</VirtualHost>
|
||||
</IfFile>
|
||||
|
|
|
|||
2
samples/httpaste.it/httpd/usr/local/apache2/ssl/.gitignore
vendored
Normal file
2
samples/httpaste.it/httpd/usr/local/apache2/ssl/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*.key
|
||||
*.crt
|
||||
|
|
@ -0,0 +1 @@
|
|||
*
|
||||
|
|
@ -152,6 +152,7 @@ from httpaste.model import Config as ModelConfig
|
|||
from httpaste.backend import get_backend_config
|
||||
from httpaste.backend import Config as BackendConfig
|
||||
from httpaste.helper.config import get_configparser, CONFIGPATH_ENVIRON
|
||||
from httpaste.helper.url import url_upgrade_to_https
|
||||
from httpaste.helper.http import (
|
||||
BadRequestError,
|
||||
ForbiddenError,
|
||||
|
|
@ -201,8 +202,6 @@ def get_flask_app(config: Config) -> FlaskApp:
|
|||
"""get a flask app object
|
||||
"""
|
||||
|
||||
print(config.server.swagger_ui)
|
||||
|
||||
options = {"swagger_ui": config.server.swagger_ui}
|
||||
|
||||
#context manager returns a pathlib.Path object
|
||||
|
|
@ -238,6 +237,20 @@ def get_flask_app(config: Config) -> FlaskApp:
|
|||
response.headers['WWW-Authenticate'] = 'Basic realm="private"'
|
||||
return response
|
||||
|
||||
@application.app.before_request
|
||||
def before_request_func():
|
||||
from flask import request
|
||||
|
||||
request._view = {}
|
||||
|
||||
if config.server.request_ssl:
|
||||
|
||||
https_url = url_upgrade_to_https(request.url, config.server.ssl_port)
|
||||
|
||||
if https_url != request.url:
|
||||
|
||||
request._view['before_request__ssl_url'] = https_url
|
||||
|
||||
return application
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
from httpaste.helper.template import views
|
||||
from httpaste.helper.template import views, render_template_with_context
|
||||
from httpaste import __doc__ as man_page
|
||||
|
||||
from flask import current_app
|
||||
|
||||
def search(**kwargs):
|
||||
|
||||
template = views.get_template("viewport/ui/search.html")
|
||||
|
|
@ -13,4 +15,7 @@ def search(**kwargs):
|
|||
'delete_session_url': '/ui/user/session/delete'
|
||||
}
|
||||
|
||||
return template.render(**variables), 200
|
||||
with current_app.app_context():
|
||||
view_render = render_template_with_context(template, **variables)
|
||||
|
||||
return view_render, 200
|
||||
|
|
@ -2,8 +2,9 @@ from io import BytesIO
|
|||
from base64 import b64encode
|
||||
|
||||
from connexion import request
|
||||
from flask import current_app
|
||||
|
||||
from httpaste.helper.template import views
|
||||
from httpaste.helper.template import views, render_template_with_context
|
||||
from httpaste.helper.url import url_query_string, url_append_query_param
|
||||
from httpaste.helper.syntax import syntax_shortnames, format_shortnames
|
||||
from httpaste.helper.http import mime_types
|
||||
|
|
@ -23,7 +24,10 @@ def search(**kwargs):
|
|||
'delete_session_url': '/ui/user/session/delete'
|
||||
}
|
||||
|
||||
return template.render(**variables), 200
|
||||
with current_app.app_context():
|
||||
view_render = render_template_with_context(template, **variables)
|
||||
|
||||
return view_render, 200
|
||||
|
||||
|
||||
def post(**kwargs):
|
||||
|
|
@ -93,4 +97,7 @@ def get(**kwargs):
|
|||
'mime_types': mime_types()
|
||||
}
|
||||
|
||||
return template.render(**variables)
|
||||
with current_app.app_context():
|
||||
view_render = render_template_with_context(template, **variables)
|
||||
|
||||
return view_render, 200
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
from httpaste.helper.template import views
|
||||
from flask import current_app
|
||||
|
||||
from httpaste.helper.template import views, render_template_with_context
|
||||
from httpaste.controller.ui.paste import post as post_proxy
|
||||
from httpaste.controller.ui.paste import get as get_proxy
|
||||
|
||||
|
|
@ -8,10 +10,12 @@ def search(**kwargs):
|
|||
|
||||
variables = {
|
||||
'paste_form_url': '/ui/paste/private',
|
||||
'user': kwargs.get('user')
|
||||
}
|
||||
|
||||
return template.render(**variables), 200
|
||||
with current_app.app_context():
|
||||
view_render = render_template_with_context(template, **variables)
|
||||
|
||||
return view_render, 200
|
||||
|
||||
|
||||
def post(**kwargs):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
from httpaste.helper.template import views
|
||||
from flask import current_app
|
||||
|
||||
from httpaste.helper.template import views, render_template_with_context
|
||||
from httpaste.controller.ui.paste import post as post_proxy
|
||||
from httpaste.controller.ui.paste import get as get_proxy
|
||||
|
||||
|
|
@ -10,7 +12,10 @@ def search(**kwargs):
|
|||
'paste_form_url': '/ui/paste/public'
|
||||
}
|
||||
|
||||
return template.render(**variables), 200
|
||||
with current_app.app_context():
|
||||
view_render = render_template_with_context(template, **variables)
|
||||
|
||||
return view_render, 200
|
||||
|
||||
|
||||
def post(**kwargs):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from httpaste.helper.template import views
|
||||
from httpaste import __doc__ as man_page
|
||||
from flask import current_app
|
||||
|
||||
from httpaste.helper.template import views, render_template_with_context
|
||||
|
||||
def search(**kwargs):
|
||||
|
||||
|
|
@ -9,4 +10,7 @@ def search(**kwargs):
|
|||
'delete_session_url': '/ui/user/session/delete'
|
||||
}
|
||||
|
||||
return template.render(**variables), 200
|
||||
with current_app.app_context():
|
||||
view_render = render_template_with_context(template, **variables)
|
||||
|
||||
return view_render, 200
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from httpaste.helper.template import views
|
||||
from httpaste.helper.template import views, render_template_with_context
|
||||
from httpaste.controller.user.session import delete as raw_delete
|
||||
|
||||
from connexion import request
|
||||
|
|
@ -7,11 +7,12 @@ def search(**kwargs):
|
|||
|
||||
template = views.get_template("viewport/ui/user/session/search.html")
|
||||
|
||||
print(request.path)
|
||||
|
||||
variables = {'session_delete_url': request.path + '/delete'}
|
||||
|
||||
return template.render(**variables), 200
|
||||
with current_app.app_context():
|
||||
view_render = render_template_with_context(template, **variables)
|
||||
|
||||
return view_render, 200
|
||||
|
||||
|
||||
def delete(**kwargs):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,25 @@
|
|||
from jinja2 import Environment, PackageLoader, select_autoescape
|
||||
from collections import namedtuple
|
||||
|
||||
views = Environment(
|
||||
loader=PackageLoader("httpaste", "view"),
|
||||
autoescape=select_autoescape()
|
||||
)
|
||||
|
||||
|
||||
def render_template_with_context(template: object, **kwargs):
|
||||
"""render a template with global context variables
|
||||
|
||||
the definition of a global context is abstract, it does neither apply
|
||||
to Flask, nor to Jinja2 and only acts as a bridge for passing
|
||||
variables from flask to jinja2, without having to define them within
|
||||
each controller.
|
||||
|
||||
:param template: jinja2 template object
|
||||
"""
|
||||
|
||||
from flask import request
|
||||
|
||||
return template.render(**{**kwargs, **{
|
||||
'flask': namedtuple('Flask', request._view.keys())(**request._view)
|
||||
}})
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
from typing import Optional
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
||||
|
||||
|
|
@ -18,3 +19,22 @@ def url_append_query_param(url:str, name: str, value:str):
|
|||
|
||||
return urlcomps._replace(query=qs).geturl()
|
||||
|
||||
|
||||
def url_upgrade_to_https(url: str, port: Optional[int] = 443):
|
||||
|
||||
urlcomps = urlparse(url)
|
||||
|
||||
urlcomps = urlcomps._replace(scheme='https')
|
||||
|
||||
if url != urlcomps.geturl():
|
||||
|
||||
hostname = urlcomps.netloc.rsplit(':', 1)[0]
|
||||
|
||||
if port != 443:
|
||||
netloc = ':'.join((hostname, str(port)))
|
||||
else:
|
||||
netloc = hostname
|
||||
|
||||
urlcomps = urlcomps._replace(netloc=netloc)
|
||||
|
||||
return urlcomps.geturl()
|
||||
|
|
@ -10,6 +10,8 @@ class Config(NamedTuple):
|
|||
"""
|
||||
swagger_ui: bool = True
|
||||
bind_address: str = None
|
||||
request_ssl: bool = True
|
||||
ssl_port: int = 443
|
||||
|
||||
|
||||
def get_server_config(configIni: ConfigParser) -> Config:
|
||||
|
|
|
|||
|
|
@ -15,10 +15,29 @@
|
|||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.blinking{
|
||||
animation:blinkingText 1.0s infinite;
|
||||
animation-timing-function: step-start;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: red;
|
||||
}
|
||||
|
||||
@keyframes blinkingText {
|
||||
0%{ color: red; }
|
||||
50%{ color: transparent; }
|
||||
100%{ color: red; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
{% if flask.before_request__ssl_url is defined %}
|
||||
<p>
|
||||
<strong class="blinking warning">WARNING:</strong> Communication not encrypted - SSL/TLS will not be enforced. Visit <a href="{{ flask.before_request__ssl_url }}">{{ flask.before_request__ssl_url }}</a>, for SSL/TLS encryption.
|
||||
</p>
|
||||
{% endif %}
|
||||
{% block header %}{% endblock %}
|
||||
</header>
|
||||
<hr/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue