Files
wgfrontend/src/webapp.py

134 lines
5.2 KiB
Python
Raw Normal View History

2020-11-19 21:55:45 +01:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cherrypy
import jinja2
import os
import random
import string
import pwdtools
import wgcfg
class WebApp():
def __init__(self, cfg):
"""Instance initialization"""
self.cfg = cfg
2020-11-26 23:21:14 +01:00
self.jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')))
2020-11-19 21:55:45 +01:00
self.wg = wgcfg.WGCfg(self.cfg.wg_configfile, self.cfg.libdir)
@cherrypy.expose
def index(self, action=None, id=None, description=None):
if (action == 'delete') and id:
peer, peerdata = self.wg.get_peer_byid(id)
self.wg.delete_peer(peer)
peers = self.wg.get_peers()
tmpl = self.jinja_env.get_template('index.html')
2020-11-26 23:21:14 +01:00
return tmpl.render(sessiondata=cherrypy.session, peers=peers)
2020-11-19 21:55:45 +01:00
@cherrypy.expose
2020-11-26 23:21:14 +01:00
def config(self, action=None, id=None, description=None):
peerdata = None
if (action == 'save') and id:
peer, peerdata = self.wg.get_peer_byid(id)
peerdata = self.wg.update_peer(peer, description)
if (action == 'save') and not id:
peer = self.wg.create_peer(description)
peerdata = self.wg.get_peer(peer)
if not peerdata:
peer, peerdata = self.wg.get_peer_byid(id)
2020-11-19 21:55:45 +01:00
tmpl = self.jinja_env.get_template('config.html')
2020-11-26 23:21:14 +01:00
return tmpl.render(sessiondata=cherrypy.session, peerdata=peerdata)
2020-11-19 21:55:45 +01:00
@cherrypy.expose
def edit(self, action='edit', id=None, description=None):
if id: # existing client
peer, peerdata = self.wg.get_peer_byid(id)
if description:
peerdata = self.wg.update_peer(peer, description)
else:
if not description:
description = 'My new client'
if action == 'new': # default values for new client
peerdata = { 'Description': description, 'Id': '' }
else: # save changes
2020-11-26 23:21:14 +01:00
raise ValueError()
2020-11-19 21:55:45 +01:00
tmpl = self.jinja_env.get_template('edit.html')
2020-11-26 23:21:14 +01:00
return tmpl.render(sessiondata=cherrypy.session, peerdata=peerdata)
2020-11-19 21:55:45 +01:00
@cherrypy.expose
def download(self, id):
2020-11-26 23:21:14 +01:00
"""Provide the WireGuard config for the client with the given identifier for download"""
2020-11-19 21:55:45 +01:00
peer, peerdata = self.wg.get_peer_byid(id)
config, peerdata = self.wg.get_peerconfig(peer)
cherrypy.response.headers['Content-Disposition'] = f'attachment; filename=wg_{id}.conf'
cherrypy.response.headers['Content-Type'] = 'text/plain' # 'application/x-download' 'application/octet-stream'
return config.encode('utf-8')
2020-11-26 23:21:14 +01:00
def check_username_and_password(self, username, password):
"""Check whether provided username and password are valid when authenticating"""
if (username in self.cfg.users) and (pwdtools.verify_password(self.cfg.users[username], password)):
return
return 'invalid username/password'
def login_screen(self, from_page='..', username='', error_msg='', **kwargs):
"""Shows a login form"""
tmpl = self.jinja_env.get_template('login.html')
return tmpl.render(from_page=from_page, username=username, error_msg=error_msg).encode('utf-8')
2020-11-19 21:55:45 +01:00
@cherrypy.expose
def logout(self):
2020-11-26 23:21:14 +01:00
username = cherrypy.session['username']
cherrypy.session.clear()
cherrypy.response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
cherrypy.response.headers['Pragma'] = 'no-cache'
cherrypy.response.headers['Expires'] = '0'
raise cherrypy.HTTPRedirect('/', 302)
return '"{0}" has been logged out'.format(username)
2020-11-19 21:55:45 +01:00
def run_webapp(cfg):
2020-11-26 23:21:14 +01:00
"""Runs the CherryPy web application with the provided configuration data"""
2020-11-19 21:55:45 +01:00
script_path = os.path.dirname(os.path.abspath(__file__))
2020-11-26 23:21:14 +01:00
app = WebApp(cfg)
app_conf = {
2020-11-19 21:55:45 +01:00
'/': {
'tools.sessions.on': True,
'tools.staticdir.root': os.path.join(script_path, 'webroot'),
2020-11-26 23:21:14 +01:00
'tools.session_auth.on': True,
'tools.session_auth.login_screen': app.login_screen,
'tools.session_auth.check_username_and_password': app.check_username_and_password,
2020-11-19 21:55:45 +01:00
},
'/configs': {
'tools.staticdir.on': True,
'tools.staticdir.root': None,
'tools.staticdir.dir': cfg.libdir
},
'/static': {
2020-11-26 23:21:14 +01:00
'tools.session_auth.on': False,
2020-11-19 21:55:45 +01:00
'tools.staticdir.on': True,
'tools.staticdir.dir': 'static'
},
'/favicon.ico':
{
2020-11-26 23:21:14 +01:00
'tools.session_auth.on': False,
2020-11-19 21:55:45 +01:00
'tools.staticfile.on': True,
'tools.staticfile.filename': os.path.join(script_path, 'webroot', 'static', 'favicon.ico')
}
}
if os.path.exists(cfg.sslcertfile) and os.path.exists(cfg.sslkeyfile):
cherrypy.server.ssl_module = 'builtin'
cherrypy.server.ssl_certificate = cfg.sslcertfile
cherrypy.server.ssl_private_key = cfg.sslkeyfile
cherrypy.config.update({'server.socket_host': '0.0.0.0',
'server.socket_port': 8080,
})
2020-11-26 23:21:14 +01:00
cherrypy.quickstart(app, '/', app_conf)
2020-11-19 21:55:45 +01:00
if __name__ == '__main__':
pass