Create separate templates and static folder, and make the web app use both of these. Yay, now we have real static resources

This commit is contained in:
Micah Lee 2018-03-06 02:54:12 -08:00
parent baede53632
commit ce852fc60a
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
12 changed files with 39 additions and 66 deletions

View File

@ -4,7 +4,8 @@ include BUILD.md
include share/* include share/*
include share/images/* include share/images/*
include share/locale/* include share/locale/*
include share/html/* include share/templates/*
include share/static/*
include install/onionshare.desktop include install/onionshare.desktop
include install/onionshare.appdata.xml include install/onionshare.appdata.xml
include install/onionshare80.xpm include install/onionshare80.xpm

View File

@ -20,7 +20,8 @@ a = Analysis(
('../share/torrc_template-windows', 'share'), ('../share/torrc_template-windows', 'share'),
('../share/images/*', 'share/images'), ('../share/images/*', 'share/images'),
('../share/locale/*', 'share/locale'), ('../share/locale/*', 'share/locale'),
('../share/html/*', 'share/html') ('../share/templates/*', 'share/templates'),
('../share/static/*', 'share/static')
], ],
hiddenimports=[], hiddenimports=[],
hookspath=[], hookspath=[],

View File

@ -26,12 +26,11 @@ import queue
import socket import socket
import sys import sys
import tempfile import tempfile
import base64
from distutils.version import LooseVersion as Version from distutils.version import LooseVersion as Version
from urllib.request import urlopen from urllib.request import urlopen
from flask import ( from flask import (
Flask, Response, request, render_template_string, abort, make_response, Flask, Response, request, render_template, abort, make_response,
__version__ as flask_version __version__ as flask_version
) )
@ -43,7 +42,9 @@ class Web(object):
""" """
def __init__(self, debug, stay_open, gui_mode, receive_mode=False): def __init__(self, debug, stay_open, gui_mode, receive_mode=False):
# The flask app # The flask app
self.app = Flask(__name__) self.app = Flask(__name__,
static_folder=common.get_resource_path('static'),
template_folder=common.get_resource_path('templates'))
# Debug mode? # Debug mode?
if debug: if debug:
@ -88,12 +89,6 @@ class Web(object):
self.REQUEST_RATE_LIMIT = 5 self.REQUEST_RATE_LIMIT = 5
self.q = queue.Queue() self.q = queue.Queue()
# Load and base64 encode images to pass into templates
self.favicon_b64 = self.base64_image('favicon.ico')
self.logo_b64 = self.base64_image('logo.png')
self.folder_b64 = self.base64_image('web_folder.png')
self.file_b64 = self.base64_image('web_file.png')
self.slug = None self.slug = None
self.download_count = 0 self.download_count = 0
@ -137,29 +132,18 @@ class Web(object):
# currently a download # currently a download
deny_download = not self.stay_open and self.download_in_progress deny_download = not self.stay_open and self.download_in_progress
if deny_download: if deny_download:
r = make_response(render_template_string( r = make_response(render_template('denied.html'))
open(common.get_resource_path('html/denied.html')).read(), return self.add_security_headers(r)
favicon_b64=self.favicon_b64
))
for header, value in self.security_headers:
r.headers.set(header, value)
return r
# If download is allowed to continue, serve download page # If download is allowed to continue, serve download page
r = make_response(render_template_string( r = make_response(render_template(
open(common.get_resource_path('html/send.html')).read(), 'send.html',
favicon_b64=self.favicon_b64,
logo_b64=self.logo_b64,
folder_b64=self.folder_b64,
file_b64=self.file_b64,
slug=self.slug, slug=self.slug,
file_info=self.file_info, file_info=self.file_info,
filename=os.path.basename(self.zip_filename), filename=os.path.basename(self.zip_filename),
filesize=self.zip_filesize, filesize=self.zip_filesize,
filesize_human=common.human_readable_filesize(self.zip_filesize))) filesize_human=common.human_readable_filesize(self.zip_filesize)))
for header, value in self.security_headers: return self.add_security_headers(r)
r.headers.set(header, value)
return r
@self.app.route("/<slug_candidate>/download") @self.app.route("/<slug_candidate>/download")
def download(slug_candidate): def download(slug_candidate):
@ -172,13 +156,8 @@ class Web(object):
# currently a download # currently a download
deny_download = not self.stay_open and self.download_in_progress deny_download = not self.stay_open and self.download_in_progress
if deny_download: if deny_download:
r = make_response(render_template_string( r = make_response(render_template('denied.html'))
open(common.get_resource_path('html/denied.html')).read(), return self.add_security_headers(r)
favicon_b64=self.favicon_b64
))
for header,value in self.security_headers:
r.headers.set(header, value)
return r
# each download has a unique id # each download has a unique id
download_id = self.download_count download_id = self.download_count
@ -261,8 +240,7 @@ class Web(object):
r = Response(generate()) r = Response(generate())
r.headers.set('Content-Length', self.zip_filesize) r.headers.set('Content-Length', self.zip_filesize)
r.headers.set('Content-Disposition', 'attachment', filename=basename) r.headers.set('Content-Disposition', 'attachment', filename=basename)
for header,value in self.security_headers: r = self.add_security_headers(r)
r.headers.set(header, value)
# guess content type # guess content type
(content_type, _) = mimetypes.guess_type(basename, strict=False) (content_type, _) = mimetypes.guess_type(basename, strict=False)
if content_type is not None: if content_type is not None:
@ -278,15 +256,10 @@ class Web(object):
self.check_slug_candidate(slug_candidate) self.check_slug_candidate(slug_candidate)
# If download is allowed to continue, serve download page # If download is allowed to continue, serve download page
r = make_response(render_template_string( r = make_response(render_template(
open(common.get_resource_path('html/receive.html')).read(), 'receive.html',
favicon_b64=self.favicon_b64,
logo_b64=self.logo_b64,
slug=self.slug)) slug=self.slug))
for header, value in self.security_headers: return self.add_security_headers(r)
r.headers.set(header, value)
return r
def common_routes(self): def common_routes(self):
""" """
@ -306,13 +279,8 @@ class Web(object):
self.force_shutdown() self.force_shutdown()
print(strings._('error_rate_limit')) print(strings._('error_rate_limit'))
r = make_response(render_template_string( r = make_response(render_template('404.html'), 404)
open(common.get_resource_path('html/404.html')).read(), return self.add_security_headers(r)
favicon_b64=self.favicon_b64
), 404)
for header, value in self.security_headers:
r.headers.set(header, value)
return r
@self.app.route("/<slug_candidate>/shutdown") @self.app.route("/<slug_candidate>/shutdown")
def shutdown(slug_candidate): def shutdown(slug_candidate):
@ -323,6 +291,14 @@ class Web(object):
self.force_shutdown() self.force_shutdown()
return "" return ""
def add_security_headers(self, r):
"""
Add security headers to a request
"""
for header, value in self.security_headers:
r.headers.set(header, value)
return r
def set_file_info(self, filenames, processed_size_callback=None): def set_file_info(self, filenames, processed_size_callback=None):
""" """
Using the list of filenames being shared, fill in details that the web Using the list of filenames being shared, fill in details that the web
@ -362,12 +338,6 @@ class Web(object):
return True return True
return filename.endswith(('.html', '.htm', '.xml', '.xhtml')) return filename.endswith(('.html', '.htm', '.xml', '.xhtml'))
def base64_image(self, filename):
"""
Base64-encode an image file to use data URIs in the web app
"""
return base64.b64encode(open(common.get_resource_path('images/{}'.format(filename)), 'rb').read()).decode()
def add_request(self, request_type, path, data=None): def add_request(self, request_type, path, data=None):
""" """
Add a request to the queue, to communicate with the GUI. Add a request to the queue, to communicate with the GUI.

View File

@ -52,7 +52,8 @@ data_files=[
(os.path.join(sys.prefix, 'share/onionshare'), file_list('share')), (os.path.join(sys.prefix, 'share/onionshare'), file_list('share')),
(os.path.join(sys.prefix, 'share/onionshare/images'), file_list('share/images')), (os.path.join(sys.prefix, 'share/onionshare/images'), file_list('share/images')),
(os.path.join(sys.prefix, 'share/onionshare/locale'), file_list('share/locale')), (os.path.join(sys.prefix, 'share/onionshare/locale'), file_list('share/locale')),
(os.path.join(sys.prefix, 'share/onionshare/html'), file_list('share/html')), (os.path.join(sys.prefix, 'share/onionshare/templates'), file_list('share/templates')),
(os.path.join(sys.prefix, 'share/onionshare/static'), file_list('share/static'))
] ]
if platform.system() != 'OpenBSD': if platform.system() != 'OpenBSD':
data_files.append(('/usr/share/nautilus-python/extensions/', ['install/scripts/onionshare-nautilus.py'])) data_files.append(('/usr/share/nautilus-python/extensions/', ['install/scripts/onionshare-nautilus.py']))

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
share/static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 251 B

After

Width:  |  Height:  |  Size: 251 B

View File

Before

Width:  |  Height:  |  Size: 338 B

After

Width:  |  Height:  |  Size: 338 B

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<title>Error 404</title> <title>Error 404</title>
<link href="data:image/x-icon;base64,{{favicon_b64}}" rel="icon" type="image/x-icon" /> <link href="/static/favicon.ico" rel="icon" type="image/x-icon" />
<style type="text/css"> <style type="text/css">
body { body {
background-color: #FFC4D5; background-color: #FFC4D5;

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<title>OnionShare</title> <title>OnionShare</title>
<link href="data:image/x-icon;base64,{{favicon_b64}}" rel="icon" type="image/x-icon" /> <link href="/static/favicon.ico" rel="icon" type="image/x-icon" />
<style> <style>
body { body {
background-color: #222222; background-color: #222222;

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<title>OnionShare</title> <title>OnionShare</title>
<link href="data:image/x-icon;base64,{{favicon_b64}}" rel="icon" type="image/x-icon" /> <link href="/static/favicon.ico" rel="icon" type="image/x-icon" />
<style type="text/css"> <style type="text/css">
.clearfix:after { .clearfix:after {
content: "."; content: ".";
@ -97,7 +97,7 @@
<body> <body>
<header class="clearfix"> <header class="clearfix">
<img class="logo" src="data:image/png;base64,{{logo_b64}}" title="OnionShare"> <img class="logo" src="/static/logo.png" title="OnionShare">
<h1>OnionShare</h1> <h1>OnionShare</h1>
</header> </header>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<title>OnionShare</title> <title>OnionShare</title>
<link href="data:image/x-icon;base64,{{favicon_b64}}" rel="icon" type="image/x-icon" /> <link href="/static/favicon.ico" rel="icon" type="image/x-icon" />
<style type="text/css"> <style type="text/css">
.clearfix:after { .clearfix:after {
content: "."; content: ".";
@ -105,7 +105,7 @@
<li><a class="button" href='/{{ slug }}/download'>Download Files</a></li> <li><a class="button" href='/{{ slug }}/download'>Download Files</a></li>
</ul> </ul>
</div> </div>
<img class="logo" src="data:image/png;base64,{{logo_b64}}" title="OnionShare"> <img class="logo" src="/static/logo.png" title="OnionShare">
<h1>OnionShare</h1> <h1>OnionShare</h1>
</header> </header>
@ -118,7 +118,7 @@
{% for info in file_info.dirs %} {% for info in file_info.dirs %}
<tr> <tr>
<td> <td>
<img width="30" height="30" title="" alt="" src="data:image/png;base64,{{ folder_b64 }}" /> <img width="30" height="30" title="" alt="" src="/static/web_folder.png" />
{{ info.basename }} {{ info.basename }}
</td> </td>
<td>{{ info.size_human }}</td> <td>{{ info.size_human }}</td>
@ -128,7 +128,7 @@
{% for info in file_info.files %} {% for info in file_info.files %}
<tr> <tr>
<td> <td>
<img width="30" height="30" title="" alt="" src="data:image/png;base64,{{ file_b64 }}" /> <img width="30" height="30" title="" alt="" src="/static/web_file.png" />
{{ info.basename }} {{ info.basename }}
</td> </td>
<td>{{ info.size_human }}</td> <td>{{ info.size_human }}</td>