diff --git a/html/src/auth.js b/html/src/auth.js index 41d2f0c..7b6d2db 100755 --- a/html/src/auth.js +++ b/html/src/auth.js @@ -26,12 +26,12 @@ export function authClient(rawClient) { } this.clidata = (data)=>{ - // const session = utils.getCookie('session') - // if(session != ''){ - // this.rawClient.send('reauth', { - // session: session - // }) - // } + const session = utils.getCookie('session') + if(session != ''){ + this.rawClient.send('reauth', { + session: session + }) + } } this.loginSuccess = (data)=>{ @@ -45,7 +45,9 @@ export function authClient(rawClient) { } this.reauth = (data)=>{ - utils.popupSuccess('Connection', 'Successfully logged in!') + if(window.location.pathname == "/login"){ + utils.popupSuccess('Connection', 'Successfully logged in!') + } utils.iconauth() } diff --git a/html/src/main.js b/html/src/main.js index 43c0914..a9b7baa 100755 --- a/html/src/main.js +++ b/html/src/main.js @@ -21,4 +21,24 @@ window.authClient = client window.authLogin = client.login window.sendAuth = client.send window.sendRaw = rawClient.send -window.addRawTypeListener = rawClient.addRawTypeListener \ No newline at end of file +window.addListener = rawClient.addRawTypeListener + +window.addListener('popupInfo', (data)=>{ + window.utils.popupInfo(data.data.title, data.data.msg) +}) + +window.addListener('popupSuccess', (data)=>{ + window.utils.popupSuccess(data.data.title, data.data.msg) +}) + +window.addListener('popupWarning', (data)=>{ + window.utils.popupWarning(data.data.title, data.data.msg) +}) + +window.addListener('popupError', (data)=>{ + window.utils.popupError(data.data.title, data.data.msg) +}) + +window.addListener('popupColor', (data)=>{ + window.utils.addPopup(data.data.color, data.data.isDark, data.data.title, data.data.msg) +}) \ No newline at end of file diff --git a/html/src/packets.js b/html/src/packets.js index 30204f9..de4782a 100755 --- a/html/src/packets.js +++ b/html/src/packets.js @@ -11,6 +11,7 @@ function getErrorDesc(error){ case 'invalidLogin': return 'Invalid username or password' case 'invalidLoginRequest': + utils.setCookie('session', '') return 'Some part of the login request is invalid, please try again' case 'prelogin': return 'You are already logged in' diff --git a/html/src/style.css b/html/src/style.css index 31e2e96..a96af1b 100755 --- a/html/src/style.css +++ b/html/src/style.css @@ -202,6 +202,7 @@ li::marker { width: var(--popupBoxWidth); height: calc(100% - var(--topnavheight) - 10px); + pointer-events:none; bottom: 0; right: 20px; overflow: auto; @@ -224,6 +225,8 @@ li::marker { padding: 0; background-color: inherit; + pointer-events:all; + left: 0; margin: 0; margin-bottom: 20px; diff --git a/html/src/utils.js b/html/src/utils.js index aa2c2fc..07e15ba 100755 --- a/html/src/utils.js +++ b/html/src/utils.js @@ -64,7 +64,7 @@ export function iconauth() { // } -function addPopup(bgcolor, isDark, title, content) { +export function addPopup(bgcolor, isDark, title, content) { const elem = document.getElementById('popupBox') let header let textColor @@ -105,6 +105,7 @@ export function popupError(title, text){ addPopup('#500000', true, title, text) } + export function getUnixTime() { return (+ new Date()) } diff --git a/main.py b/main.py index 1baf077..6a682db 100755 --- a/main.py +++ b/main.py @@ -6,6 +6,7 @@ from sys import argv webserv = web.webserv() moduleMaster = modules.moduleMaster() + def main(): if not utils.pathExists('data'): @@ -24,8 +25,9 @@ def main(): if not utils.pathExists('data/selfsign.crt'): utils.genCert(utils.getRoot('data/')) + moduleMaster.addModules(webserv) + webserv.init() moduleMaster.initModules(webserv) - webserv.start() moduleMaster.runModules() diff --git a/modules/main/main.py b/modules/main/main.py index d6fcf34..fa1eb15 100644 --- a/modules/main/main.py +++ b/modules/main/main.py @@ -1,10 +1,14 @@ from modules.main import test as test -def test1(ac, data): - print(ac) - print(data) +mm = None -def main(mm): - # mm.addAuthEventListener('test1', test1) - print(mm.rawServer.addEventListener('test1', test1)) - #mm.rawServer.addEventListener('login', test1) \ No newline at end of file +def test1(ac, data): + mm.sendPopupColor(ac.rawClient, 'test!', 'test!', '#600060', True) + +def init(moduleMaster): + global mm + mm = moduleMaster + mm.addAuthEventListener('test1', test1) + +def main(): + pass \ No newline at end of file diff --git a/src/auth.py b/src/auth.py index 79fbea8..c508127 100755 --- a/src/auth.py +++ b/src/auth.py @@ -29,12 +29,18 @@ class authClient: self.rawClient.send(type, data) class authServer: - def __init__(self): + def __init__(self, webserv): self.rawServer = None self.app = None self.clients = [] self.users = [] + self.webserv = webserv + + self.reloadUsers() + self.rawServer = webserv.rawServer + self.initRawServer() + def login(self, c, data): if c.clientid != data['cid']: c.send('error', 'invalidLoginRequest') @@ -69,7 +75,7 @@ class authServer: c.send('loginSuccess', { 'username': ac.username, 'session': ac.session, - 'redir': f'/{self.app.defaultTab}/{self.app.defaultPage}', + 'redir': f'/{self.webserv.defaultTab}/{self.webserv.defaultPage}', 'timeout': ac.timeout }) @@ -78,17 +84,22 @@ class authServer: c.send('error', 'invalidLogin') return + def validAc(self, ac): + if ac == None: + return False + if ac.rawClient.address != request.remote_addr: + return False + if utils.getUnixTime() > ac.timeout: + return False + + return True + def reauth(self, c, data): session = data['data']['session'] + ac = utils.getatribinarr(self.clients, 'session', session) - if ac == None: - c.send('error', 'invalidLoginRequest') - return - if ac.rawClient.address != request.remote_addr: - c.send('error', 'invalidLoginRequest') - return - if utils.getUnixTime() > ac.timeout: + if not self.validAc(ac): c.send('error', 'invalidLoginRequest') return @@ -106,18 +117,12 @@ class authServer: ac = utils.getatribinarr(self.clients, 'session', session) - if ac == None: - return False - if ac.rawClient.address != request.remote_addr: - return False - if utils.getUnixTime() > ac.timeout: - return False + return self.validAc(ac) - return True def initRawServer(self): - self.app.rawServer.addEventListener('login', self.login) - self.app.rawServer.addEventListener('reauth', self.reauth) + self.rawServer.addEventListener('login', self.login) + self.rawServer.addEventListener('reauth', self.reauth) def reloadUsers(self): data = json.loads(utils.readFile(utils.getRoot('data/')+'creds.json')) @@ -129,14 +134,4 @@ class authServer: user.username = acc['username'] user.sha256passwordhash = acc['sha256passwordhash'] user.permGroups = acc['permGroups'] - self.users.append(user) - -def startAuthListener(app): - global authServer - authServer = authServer() - authServer.app = app - authServer.reloadUsers() - packets.startRawListener(app) - authServer.initRawServer() - - return authServer + self.users.append(user) \ No newline at end of file diff --git a/src/modules.py b/src/modules.py index 7c25549..ece8362 100644 --- a/src/modules.py +++ b/src/modules.py @@ -12,25 +12,30 @@ class module(): self.rootdir = None self.tabs = [] - def initSelf(self): + def add(self): spec = importlib.util.spec_from_file_location(self.name, utils.getRoot(self.entrypoint)) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) self.module = module - - def run(self, moduleMaster): - self.module.main(moduleMaster) + + def init(self, moduleMaster): + self.module.init(moduleMaster) + + def run(self): + self.module.main() + class moduleMaster(): def __init__(self): self.modules = [] + self.webserv = None - self.app = None self.rawServer = None self.authServer = None + # self.addRawEventListener('test1', test1) - def initModules(self, webserv): + def addModules(self, webserv): self.webserv = webserv mdirs = utils.listSubdirs(utils.getRoot('modules/')) @@ -75,37 +80,93 @@ class moduleMaster(): self.webserv.webtabs.append(mtab) - m.initSelf() + m.add() self.modules.append(m) for tab in webserv.webtabs: tab.addHtml() - def runModules(self): - self.app = self.webserv.app - self.rawServer = self.app.rawServer - self.authServer = self.app.authServer + + + def initModules(self, webserv): + self.webserv = webserv + self.app = webserv.app + self.rawServer = webserv.rawServer + self.authServer = webserv.authServer for module in self.modules: - module.run(self) - + module.init(self) + + def runModules(self): + for module in self.modules: + module.run() + + + + def getRawClients(self): return self.rawServer.clients - - def addRawEventListener(self, eventName, func): - self.rawServer.addEventListener(eventName, func) - + def getAuthClients(self): return self.authServer.clients + + def addRawEventListener(self, eventName, func): + self.rawServer.eventListeners.append({ + 'type': eventName, + 'func': func + }) def addAuthEventListener(self, eventName, func): - def tmpfunc(self, c, data): + def tmpfunc(c, data): if not c in self.rawServer.clients: return ac = utils.getatribinarr(self.authServer.clients, 'rawClient', c) if ac == None: return + if not self.authServer.validAc(ac): + return func(ac, data) - self.rawServer.addEventListener(eventName, tmpfunc) \ No newline at end of file + self.rawServer.addEventListener(eventName, tmpfunc) + + def getRawClientByID(self, ID): + return utils.getatribinarr(self.rawServer.clients, 'clientid', ID) + + def getAuthClientByID(self, ID): + c = utils.getatribinarr(self.rawServer.clients, 'clientid', ID) + if c == None: + return None + return utils.getatribinarr(self.authServer.clients, 'rawClient', c) + + def sendPopupInfo(self, c, title, msg): + c.send('popupInfo', { + 'title': title, + 'msg': msg + }) + + def sendPopupSuccess(self, c, title, msg): + c.send('popupSuccess', { + 'title': title, + 'msg': msg + }) + + def sendPopupWarning(self, c, title, msg): + c.send('popupWarning', { + 'title': title, + 'msg': msg + }) + + def sendPopupError(self, c, title, msg): + c.send('popupError', { + 'title': title, + 'msg': msg + }) + + def sendPopupColor(self, c, title, msg, color, isDark): + c.send('popupColor', { + 'title': title, + 'msg': msg, + 'color': color, + 'isDark': isDark + }) \ No newline at end of file diff --git a/src/packets.py b/src/packets.py index 66d8279..8eecf1f 100755 --- a/src/packets.py +++ b/src/packets.py @@ -10,13 +10,13 @@ import src.utils as utils import queue class rawClient: - def __init__(self, app): + def __init__(self, rawServer): self.clientid = utils.randID(32) self.messages = queue.Queue() - self.app = app + self.rawServer = rawServer self.address = None def send(self, type, msg): - self.app.rawServer.sendClient(self, jsonpack.pack({ + self.rawServer.sendClient(self, jsonpack.pack({ 'type': type, 'data': msg, 'cid': self.clientid @@ -25,14 +25,15 @@ class rawClient: #Credit to https://github.com/MaxHalford/flask-sse-no-deps class rawServer: - def __init__(self, app): + def __init__(self, webserv): self.eventListeners = [] self.clients = [] - self.app = app - app.rawServer = self.app + self.webserv = webserv + self.app = webserv.app + # self.app = app def listen(self): - c = rawClient(self.app) + c = rawClient(self) self.clients.append(c) return self.clients[-1] @@ -60,11 +61,10 @@ class rawServer: def addEventListener(self, eventName, func): self.eventListeners.append({ - 'name': eventName, + 'type': eventName, 'func': func }) - def format_sse(data: str, event=None) -> str: #Formats a string and an event name in order to follow the event stream convention. msg = f'data: {data}\n\n' @@ -73,15 +73,16 @@ def format_sse(data: str, event=None) -> str: return msg -def startRawListener(app): - app.rawServer = rawServer(app) +def startRawListener(webserv): + server = rawServer(webserv) + # app.rawServer = server - @app.route('/listen', methods=['GET', 'POST']) + @webserv.app.route('/listen', methods=['GET', 'POST']) def listen(): if request.method == 'GET': - c = app.rawServer.listen() # returns a queue.Queue + c = server.listen() # returns a queue.Queue c.address = request.remote_addr c.send('clidata', { 'cid': c.clientid @@ -99,14 +100,14 @@ def startRawListener(app): if data['cid'] == None: return {}, 400 - c = utils.getatribinarr(app.rawServer.clients, 'clientid', data['cid']) + c = utils.getatribinarr(server.clients, 'clientid', data['cid']) if c == None: return {}, 400 - for event in app.rawServer.eventListeners: - if event['name'] == data['type']: + for event in server.eventListeners: + if event['type'] == data['type']: event['func'](c, data) return {}, 200 - #return rawServer \ No newline at end of file + return server \ No newline at end of file diff --git a/src/web.py b/src/web.py index 84d9edc..7542ac6 100755 --- a/src/web.py +++ b/src/web.py @@ -6,6 +6,7 @@ from flask import Flask, render_template, Response from flask import request, redirect, url_for, make_response import src.jsonpack as jsonpack +import src.packets as packets import src.auth as auth webroot = utils.getRoot('html/') @@ -55,22 +56,22 @@ class webpage(): @app.route('/') def index(): - isValid = app.authServer.cookieLogin(request) + isValid = app.webserv.authServer.cookieLogin(request) if not isValid: return redirect("/login", code=302) else: - return redirect(f'/{app.defaultTab}/{app.defaultPage}', code=302) + return redirect(f'/{app.webserv.defaultTab}/{app.webserv.defaultPage}', code=302) @app.route('/login') def loginPage(): - isValid = app.authServer.cookieLogin(request) + isValid = app.webserv.authServer.cookieLogin(request) if isValid: - return redirect(f'/{app.defaultTab}/{app.defaultPage}', code=302) + return redirect(f'/{app.webserv.defaultTab}/{app.webserv.defaultPage}', code=302) return make_response(open(f'{webroot}nav.html', 'r').read() .replace('', open(f'{webroot}login.html', 'r').read()) .replace('', 'Login') - .replace('', app.title) + .replace('', app.webserv.title) .replace('', '/login')) def recursivePageLocationFinder(pagename, objs): @@ -88,21 +89,21 @@ def recursivePageLocationFinder(pagename, objs): @app.route('//') def page(tabname, pagename): - isValid = app.authServer.cookieLogin(request) + isValid = app.webserv.authServer.cookieLogin(request) if not isValid: return redirect("/login", code=302) try: - tab = utils.getatribinarr(app.webtabs, 'name', tabname) + tab = utils.getatribinarr(app.webserv.webtabs, 'name', tabname) pageloc = recursivePageLocationFinder(pagename, tab.pages) return make_response(open(utils.getRoot('html/nav.html'), 'r').read() .replace('', open(utils.getRoot(pageloc), 'r').read()) - .replace('', app.tabHtml) + .replace('', app.webserv.tabHtml) .replace('', tab.html) - .replace('', app.title) - .replace('', f'/{app.defaultTab}/{app.defaultPage}')) + .replace('', app.webserv.title) + .replace('', f'/{app.webserv.defaultTab}/{app.webserv.defaultPage}')) except: return redirect("/login", code=302) @@ -114,6 +115,7 @@ def src(file): def err404(err): return redirect("/", code=302) + class webserv(): def __init__(self): self.title = 'Modulator' @@ -128,7 +130,7 @@ class webserv(): self.app = None - def start(self): + def init(self): if not self.verbose: import logging log = logging.getLogger('werkzeug') @@ -140,8 +142,6 @@ class webserv(): else: sslcontext = None - self.proc = mupr.Process(target=app.run, kwargs=dict(debug=self.verbose, port=self.port, host=self.host, ssl_context=sslcontext)) - def tabHtml(path, name): return f'{name}' @@ -150,16 +150,22 @@ class webserv(): if tab.name == self.defaultTab: self.defaultPage = tab.defaultPage - app.authServer = auth.startAuthListener(app) + def testfunc1(ac, data): + print(ac) + print(data) - app.defaultTab = self.defaultTab - app.defaultPage = self.defaultPage - app.webtabs = self.webtabs - app.tabHtml = self.tabHtml - app.title = self.title + app.webserv = self self.app = app + self.rawServer = packets.startRawListener(self) + self.authServer = auth.authServer(self) + self.proc = mupr.Process(target=app.run, kwargs=dict(debug=self.verbose, port=self.port, host=self.host, ssl_context=sslcontext)) + + + def start(self): self.proc.start() + + # return self.rawServer def stop(self): self.proc.terminate()