Commit af5a897d authored by OzzieIsaacs's avatar OzzieIsaacs

Added SSL Options (#416)

parent a8b3da24
......@@ -30,11 +30,19 @@ if __name__ == '__main__':
else:
web.app.logger.info('Falling back to Tornado')
# Max Buffersize set to 200MB
http_server = HTTPServer(WSGIContainer(web.app),max_buffer_size = 209700000)
if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile():
ssl={"certfile": web.ub.config.get_config_certfile(),
"keyfile": web.ub.config.get_config_keyfile()}
else:
ssl=None
http_server = HTTPServer(WSGIContainer(web.app),
max_buffer_size = 209700000,
ssl_options=ssl)
http_server.listen(web.ub.config.config_port)
IOLoop.instance().start()
IOLoop.instance().close(True)
if web.helper.global_task == 0:
web.app.logger.info("Performing restart of Calibre-web")
os.execl(sys.executable, sys.executable, *sys.argv)
......
......@@ -3,11 +3,14 @@
import argparse
import os
import sys
parser = argparse.ArgumentParser(description='Calibre Web is a web app'
' providing a interface for browsing, reading and downloading eBooks\n', prog='cps.py')
parser.add_argument('-p', metavar='path', help='path and name to settings db, e.g. /opt/cw.db')
parser.add_argument('-g', metavar='path', help='path and name to gdrive db, e.g. /opt/gd.db')
parser.add_argument('-c', metavar='path', help='path and name to SSL certfile, e.g. /opt/test.cert, works only in combination with keyfile')
parser.add_argument('-k', metavar='path', help='path and name to SSL keyfile, e.g. /opt/test.key, works only in combination with certfile')
args = parser.parse_args()
generalPath = os.path.normpath(os.getenv("CALIBRE_DBPATH",
......@@ -22,3 +25,24 @@ if args.g:
else:
gdpath = os.path.join(generalPath, "gdrive.db")
certfilepath = None
keyfilepath = None
if args.c:
if os.path.isfile(args.c):
certfilepath = args.c
else:
print("Certfilepath is invalid. Exiting...")
sys.exit(1)
if args.c is "":
certfilepath = ""
if args.k:
if os.path.isfile(args.k):
keyfilepath = args.k
else:
print("Keyfilepath is invalid. Exiting...")
sys.exit(1)
if args.k is "":
keyfilepath = ""
......@@ -52,6 +52,14 @@
<label for="config_port">{{_('Server Port')}}</label>
<input type="number" min="1" max="65535" class="form-control" name="config_port" id="config_port" value="{% if content.config_port != None %}{{ content.config_port }}{% endif %}" autocomplete="off" required>
</div>
<div class="form-group">
<label for="config_certfile">{{_('SSL certfile location (leave it empty for non-SSL Servers)')}}</label>
<input type="text" class="form-control" name="config_certfile" id="config_certfile" value="{% if content.config_certfile != None %}{{ content.config_certfile }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_keyfile">{{_('SSL Keyfile location (leave it empty for non-SSL Servers)')}}</label>
<input type="text" class="form-control" name="config_keyfile" id="config_keyfile" value="{% if content.config_keyfile != None %}{{ content.config_keyfile }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_calibre_web_title">{{_('Title')}}</label>
<input type="text" class="form-control" name="config_calibre_web_title" id="config_calibre_web_title" value="{% if content.config_calibre_web_title != None %}{{ content.config_calibre_web_title }}{% endif %}" autocomplete="off" required>
......
......@@ -100,8 +100,8 @@
{% endfor %}
<div id="loader" hidden="true">
<center>
<h3>Uploading...</h3>
<span>please don't refresh the page</span>.
<h3>_('Uploading...')</h3>
<span>_('please don't refresh the page')</span>.
<br />
<img src="{{ url_for('static', filename='img/loader.gif') }}">
</center>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -272,6 +272,8 @@ class Settings(Base):
mail_from = Column(String)
config_calibre_dir = Column(String)
config_port = Column(Integer, default=DEFAULT_PORT)
config_certfile = Column(String)
config_keyfile = Column(String)
config_calibre_web_title = Column(String, default=u'Calibre-web')
config_books_per_page = Column(Integer, default=60)
config_random_books = Column(Integer, default=4)
......@@ -328,8 +330,11 @@ class Config:
def loadSettings(self):
data = session.query(Settings).first() # type: Settings
self.config_calibre_dir = data.config_calibre_dir
self.config_port = data.config_port
self.config_certfile = data.config_certfile
self.config_keyfile = data.config_keyfile
self.config_calibre_web_title = data.config_calibre_web_title
self.config_books_per_page = data.config_books_per_page
self.config_random_books = data.config_random_books
......@@ -365,6 +370,24 @@ class Config:
def get_main_dir(self):
return self.config_main_dir
def get_config_certfile(self):
if cli.certfilepath:
return cli.certfilepath
else:
if cli.certfilepath is "":
return None
else:
return self.config_certfile
def get_config_keyfile(self):
if cli.keyfilepath:
return cli.keyfilepath
else:
if cli.certfilepath is "":
return None
else:
return self.config_keyfile
def get_config_logfile(self):
if not self.config_logfile:
return os.path.join(self.get_main_dir, "calibre-web.log")
......@@ -608,6 +631,14 @@ def migrate_Database():
conn = engine.connect()
conn.execute("ALTER TABLE Settings ADD column `config_logfile` String DEFAULT ''")
session.commit()
try:
session.query(exists().where(Settings.config_certfile)).scalar()
session.commit()
except exc.OperationalError: # Database is not compatible, some rows are missing
conn = engine.connect()
conn.execute("ALTER TABLE Settings ADD column `config_certfile` String DEFAULT ''")
conn.execute("ALTER TABLE Settings ADD column `config_keyfile` String DEFAULT ''")
session.commit()
def clean_database():
......
......@@ -2522,6 +2522,28 @@ def configuration_helper(origin):
if content.config_port != int(to_save["config_port"]):
content.config_port = int(to_save["config_port"])
reboot_required = True
if "config_keyfile" in to_save:
if content.config_keyfile != to_save["config_keyfile"]:
if os.path.isfile(to_save["config_keyfile"]) or to_save["config_keyfile"] is u"":
content.config_keyfile = to_save["config_keyfile"]
reboot_required = True
else:
ub.session.commit()
flash(_(u'Keyfile location is not valid, please enter correct path'), category="error")
return render_title_template("config_edit.html", content=config, origin=origin,
gdrive=gdrive_support,
goodreads=goodreads_support, title=_(u"Basic Configuration"))
if "config_certfile" in to_save:
if content.config_certfile != to_save["config_certfile"]:
if os.path.isfile(to_save["config_certfile"]) or to_save["config_certfile"] is u"":
content.config_certfile = to_save["config_certfile"]
reboot_required = True
else:
ub.session.commit()
flash(_(u'Certfile location is not valid, please enter correct path'), category="error")
return render_title_template("config_edit.html", content=config, origin=origin,
gdrive=gdrive_support,
goodreads=goodreads_support, title=_(u"Basic Configuration"))
if "config_calibre_web_title" in to_save:
content.config_calibre_web_title = to_save["config_calibre_web_title"]
if "config_columns_to_ignore" in to_save:
......@@ -3309,11 +3331,21 @@ def start_gevent():
from gevent.wsgi import WSGIServer
global gevent_server
try:
gevent_server = WSGIServer(('', ub.config.config_port), app)
if ub.config.get_config_certfile() and ub.get_config_keyfile():
keyfile = ub.config.get_config_certfile()
certfile = ub.config.get_config_keyfile()
else:
keyfile = None
certfile = None
gevent_server = WSGIServer(('', ub.config.config_port), app,
keyfile = keyfile,
certfile = certfile)
gevent_server.serve_forever()
except SocketError:
app.logger.info('Unable to listen on \'\', trying on IPv4 only...')
gevent_server = WSGIServer(('0.0.0.0', ub.config.config_port), app)
gevent_server = WSGIServer(('0.0.0.0', ub.config.config_port), app,
keyfile = keyfile,
certfile = certfile)
gevent_server.serve_forever()
except:
pass
This diff is collapsed.
......@@ -155,6 +155,14 @@ Listen 443
</VirtualHost>
```
## (Optional) SSL Configuration
For configuration of calibre-web as SSL Server go to the Config page in the Admin section. Enter the certfile- and keyfile-location, optionally change port to 443 and press submit.
Afterwards the server can only be accessed via SSL. In case of a misconfiguration (wrong/invalid files) both files can be overridden via command line options
-c [certfile location] -k [keyfile location]
By using "" as file locations the server runs as non SSL server again. The correct file path can than be entered on the Config page. After the next restart without command line options the changed file paths are applied.
## Start Calibre-Web as service under Linux
Create a file "cps.service" as root in the folder /etc/systemd/system with the following content:
......@@ -183,5 +191,6 @@ Starting the script with `-h` lists all supported command line options
Currently supported are 2 options, which are both useful for running multiple instances of Calibre-Web
`"-p path"` allows to specify the location of the settings database
`"-p path"` allows to specify the location of the google-drive database
`"-g path"` allows to specify the location of the google-drive database
`"-c path"` allows to specify the location of SSL certfile, works only in combination with keyfile
`"-k path"` allows to specify the location of SSL keyfile, works only in combination with certfile
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment