def controlList(h): user = request.cookies.get('Username') main = ddbb.query( "SELECT acls.mac, acls.name FROM acls, user WHERE acls.user=user.id AND user.username=%s ORDER BY name", user) secondary = ddbb.query( "SELECT acls.mac, acls.name FROM acls, share, user WHERE share.user=user.id AND share.mac=acls.mac AND user.username=%s", user) response = {'own': [], 'share': []} for r in main: status = ddbb.broker.mretrieve(r[0], 0) action = ddbb.broker.mretrieve(r[0], 1) version = ddbb.broker.mretrieve(r[0], 2) response['own'].append({ 'mac': r[0], 'name': r[1], 'status': status, 'action': action, 'version': version }) for r in secondary: status = ddbb.broker.mretrieve(r[0], 0) action = ddbb.broker.mretrieve(r[0], 1) version = ddbb.broker.mretrieve(r[0], 2) response['share'].append({ 'mac': r[0], 'name': r[1], 'status': status, 'action': action, 'version': version }) return response
def recoverChange(): if not limiter.check(): return "409 (Conflict)", 409 limiter.count(login=True) user = request.headers.get('Username') confirm = request.headers.get('Confirm') pw = request.headers.get('Password') if user is None or confirm is None or len(confirm) != 64: return "400 (Bad request)", 400 if pw is None: return "400 (Bad request)", 400 user = base64.b64decode(user).decode('utf-8') pw = base64.b64decode(pw).decode('utf-8') if len(pw) < 8 or len(pw) > 20 or not pw.isalnum(): return "400 (Bad request)", 400 q = ddbb.query( "SELECT confirmType, confirmValid FROM user WHERE confirm=%s AND username=%s", confirm, user) if len(q) == 0 or q[0][0] != 'password': return "404 (Not Found)", 404 valid = q[0][1] + timedelta(hours=1) valid = valid.timestamp() if (valid - time.time()) < 0: return "410 (Gone)", 410 ddbb.query( "UPDATE user SET confirm=NULL, confirmType=NULL, confirmData=NULL, confirmValid=NULL, pw=%s WHERE username=%s", password.createHash(pw), user) return "done"
def recoverAdd(): if not limiter.check(): return "409 (Conflict)", 409 limiter.count(login=True) user = request.headers.get('Username') if user is None: return "400 (Bad request)", 400 user = base64.b64decode(user).decode('utf-8') q = ddbb.query( "SELECT confirm, confirmType, confirmValid, pw FROM user WHERE username=%s", user) if len(q) == 0: return "404 (Not Found)", 404 if q[0][2] != None: valid = q[0][2] + timedelta(hours=1) valid = valid.timestamp() if q[0][1] == 'password' and (valid - time.time()) > 0: return "done" confirm = ''.join([ random.choice(string.ascii_letters + string.digits) for _ in range(64) ]) ddbb.query( "UPDATE user SET confirm=%s, confirmType='password', confirmData=NULL, confirmValid=now() WHERE username=%s", confirm, user) email.passwordRecovery(user, confirm) return "done"
def managerChangeName(h): user = request.cookies.get('Username') mac = h.get('mac').upper() if not ddbb.inAcls(user, mac): return "403 (Forbidden)", 403 name = h.get('name') if not re.match("^[A-Za-z0-9_-]*$", name) or len(name) > 15: return "400 (Bad request)", 400 ddbb.query( "UPDATE acls SET name=%s WHERE user=(SELECT id FROM user WHERE username=%s) AND mac=%s", name, user, mac) return {'done': True}
def managerAdd(h): user = request.cookies.get('Username') mac = h.get('mac') if not isinstance(mac, str): return "400 (Bad request)", 400 mac = mac.upper() name = h.get('name') if not re.match("^[A-Za-z0-9_-]*$", name) or len(name) > 15: return "400 (Bad request)", 400 ddbb.query( "INSERT INTO acls (mac, user, name) VALUES (%s, (SELECT id FROM user WHERE username=%s), %s)", mac, user, name) return {'done': True}
def settingsPassword(h): user = request.cookies.get('Username') new = h.get('new') old = h.get('old') if new is None or old is None: return "400 (Bad request)", 400 if len(new) < 8 or len(new) > 20 or not new.isalnum(): return "400 (Bad request)", 400 if not ddbb.checkPW(user, old): return "401 (Unauthorized)", 401 ddbb.query("UPDATE user SET pw=%s WHERE username=%s", password.createHash(new), user) ddbb.broker.muser(user) ddbb.broker.macls(user) return "done"
def managerList(h): user = request.cookies.get('Username') main = ddbb.query( "SELECT acls.mac, acls.name, (SELECT user.username FROM share, user WHERE share.user=user.id AND share.mac=acls.mac) FROM acls WHERE acls.user=(SELECT id FROM user WHERE username=%s)", user) secondary = ddbb.query( "SELECT acls.mac, acls.name, user.username FROM acls, share, user WHERE share.mac=acls.mac AND user.id=share.owner AND share.user=(SELECT id FROM user WHERE username=%s)", user) response = {'own': [], 'share': []} for r in main: response['own'].append({'mac': r[0], 'name': r[1], 'shareWith': r[2]}) for r in secondary: response['share'].append({'mac': r[0], 'name': r[1], 'shareBy': r[2]}) return response
def controlUpdate(h): user = request.cookies.get('Username') main = ddbb.query( "(SELECT mac FROM acls WHERE user=(SELECT id FROM user WHERE username=%s)) UNION (SELECT acls.mac FROM acls, share WHERE share.user=(SELECT id FROM user WHERE username=%s) AND share.mac=acls.mac)", user, user) response = [] for r in main: status = ddbb.broker.mretrieve(r[0], 0) action = ddbb.broker.mretrieve(r[0], 1) response.append({'mac': r[0], 'status': status, 'action': action}) return response
def settingsEmail(h): user = request.cookies.get('Username') new = h.get('email') pw = h.get('pw') if new is None or pw is None: return "400 (Bad request)", 400 if not ddbb.checkPW(user, pw): return "401 (Unauthorized)", 401 if not re.match( "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", new): return "400 (Bad request)", 400 q = ddbb.query("SELECT id FROM user WHERE username=%s", new) if len(q): return "418 (I'm a teapot)", 418 confirm = ''.join([ random.choice(string.ascii_letters + string.digits) for _ in range(64) ]) ddbb.query( "UPDATE user SET confirm=%s, confirmType='email', confirmData=%s, confirmValid=now() WHERE username=%s", confirm, new, user) email.emailConfirm(new, user, confirm) return "done"
def check(): user = request.cookies.get('Username') hash = request.cookies.get('Session') if user is None or hash is None or len(hash) > 150 or len(user) > 50: return False session = ddbb.query("SELECT session FROM user WHERE username=%s", user) if len(session) > 0: session = session[0][0] else: session = None if session == hash: return True limiter.count() return False
def logout(): if not limiter.check(): return "409 (Conflict)", 409 user = request.headers.get('Username') hash = request.headers.get('Session') if user is None or hash is None: return "400 (Bad request)", 400 session = ddbb.query("SELECT session FROM user WHERE username=%s", user) if len(session) > 0: session = session[0][0] else: session = None if session != hash: return "401 (Unauthorized)", 401 ddbb.query("UPDATE user SET session=NULL WHERE username=%s", user) with lsid: sids = sid.get(user) try: del sid[user] except Exception: pass if sids is not None: socketio.start_background_task(disconnect_user, sids) return """{'done':1}"""
def managerRemove(h): user = request.cookies.get('Username') mac = h.get('mac') if not isinstance(mac, str): return "400 (Bad request)", 400 mac = mac.upper() if not ddbb.inAcls(user, mac): return "403 (Forbidden)", 403 affected = ddbb.query( "SELECT username FROM user WHERE id=(SELECT user FROM share WHERE mac=%s) OR id=(SELECT user FROM acls WHERE mac=%s)", mac, mac) ddbb.query( "DELETE FROM share WHERE user=(SELECT id FROM user WHERE username=%s) AND mac=%s", user, mac) ddbb.query( "DELETE FROM share WHERE owner=(SELECT id FROM user WHERE username=%s) AND mac=%s", user, mac) ddbb.query( "DELETE FROM acls WHERE user=(SELECT id FROM user WHERE username=%s) AND mac=%s", user, mac) for u in affected: ddbb.broker.macls(u[0]) return {'done': True}
def registerConfirm(): if not limiter.check(): return "409 (Conflict)", 409 limiter.count(login=True) user = request.headers.get('Username') confirm = request.headers.get('Confirm') if user is None or confirm is None: return "400 (Bad request)", 400 user = base64.b64decode(user).decode('utf-8') q = ddbb.query( "SELECT confirmType, confirmData, confirmValid FROM user WHERE confirm=%s AND username=%s", confirm, user) if len(q) == 0 or (q[0][0] != 'register' and q[0][0] != 'email'): return "404 (Not Found)", 404 valid = q[0][2] + timedelta(hours=1) valid = valid.timestamp() if (valid - time.time()) < 0: return "410 (Gone)", 410 if q[0][0] == 'register': data = q[0][1].split(';') ddbb.query( "INSERT INTO acls (mac, user, name) SELECT %s, id, 'Unnamed' FROM user WHERE username=%s", data[1], user) ddbb.query( "UPDATE user SET pw=%s, confirm=NULL, confirmType=NULL, confirmData=NULL, confirmValid=NULL WHERE username=%s", data[0], user) if q[0][0] == 'email': ddbb.query( "UPDATE user SET username=confirmData, confirm=NULL, confirmType=NULL, confirmData=NULL, confirmValid=NULL WHERE username=%s", user) ddbb.broker.muser(user) ddbb.broker.macls(user) return "done"
def settingsDestroy(h): user = request.cookies.get('Username') email = h.get('email') pw = h.get('pw') if email is None or pw is None: return "400 (Bad request)", 400 if email != user: return "401 (Unauthorized)", 401 if not ddbb.checkPW(user, pw): return "401 (Unauthorized)", 401 ddbb.query( "DELETE FROM share WHERE owner=(SELECT id FROM user WHERE username=%s) OR user=(SELECT id FROM user WHERE username=%s)", user, user) ddbb.query( "DELETE FROM acls WHERE user=(SELECT id FROM user WHERE username=%s)", user) ddbb.query("DELETE FROM user WHERE username=%s", user) ddbb.broker.muser(user) ddbb.broker.macls(user) return "done"
def register(): if not limiter.check(): return "409 (Conflict)", 409 limiter.count(login=True) user = request.headers.get('Username') pw = request.headers.get('Password') mac = request.headers.get('MAC') if user is None or mac is None or pw is None: return "400 (Bad request)", 400 user = base64.b64decode(user).decode('utf-8').lower() pw = base64.b64decode(pw).decode('utf-8') mac = base64.b64decode(mac).decode('utf-8').upper() if len(pw) < 8 or len(pw) > 20 or not pw.isalnum(): return "400 (Bad request)", 400 if not re.match( "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", user): return "400 (Bad request)", 400 q = ddbb.query( "SELECT b.mac, a.mac FROM boards AS b LEFT JOIN acls AS a ON b.mac=a.mac WHERE b.mac=%s", mac) if len(q) == 0 or q[0][1] != None: return "404 (Not Found)", 404 q = ddbb.query("SELECT pw FROM user WHERE username=%s", user) if len(q) > 0 and len(q[0][0]) > 0: return "404 (Not Found)", 404 q = ddbb.query( "SELECT confirm, confirmType, confirmValid, confirmData FROM user WHERE username=%s", user) if len(q) > 0 and q[0][2] != None: valid = q[0][2] + timedelta(hours=1) valid = valid.timestamp() if q[0][1] == 'register' and (valid - time.time()) > 0: return "done" q2 = ddbb.query( "SELECT id FROM user WHERE date_add(NOW(), INTERVAL -1 HOUR) > confirmValid AND pw=''" ) confirm = ''.join([ random.choice(string.ascii_letters + string.digits) for _ in range(64) ]) data = password.createHash(pw) + ";" + mac if len(q) > 0: ddbb.query( "UPDATE user SET confirm=%s, confirmType='register', confirmData=%s, confirmValid=now() WHERE username=%s", confirm, data, user) elif len(q2) > 0: ddbb.query("DELETE FROM share WHERE user=%s", q2[0][0]) ddbb.query( "UPDATE user SET username=%s, confirm=%s, confirmType='register', confirmData=%s, confirmValid=now() WHERE id=%s", user, confirm, data, q2[0][0]) else: ddbb.query( "INSERT INTO user (username, pw, confirm, confirmType, confirmData, confirmValid) VALUES (%s, '', %s, 'register', %s, now())", user, confirm, data) email.registerConfirm(user, confirm) return "done"
def start(user): hash = base64.urlsafe_b64encode( bytearray(os.urandom(random.randint(40, 60)))).decode('utf-8') ddbb.query("UPDATE user SET session=%s WHERE username=%s", hash, user) return hash
def managerChangeShare(h): user = request.cookies.get('Username') mac = h.get('mac') if not isinstance(mac, str): return "400 (Bad request)", 400 mac = mac.upper() if not ddbb.inAcls(user, mac): return "403 (Forbidden)", 403 receiver = h.get("email") if not isinstance(receiver, str): return "400 (Bad request)", 400 receiver = receiver.lower() affected = ddbb.query( "SELECT username FROM user WHERE id=(SELECT user FROM share WHERE mac=%s)", mac) ddbb.query("DELETE FROM share WHERE share.mac=%s", mac) if re.match( "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", receiver): if receiver == user: return {'done': True} new = ddbb.query( "SELECT id, pw, confirmValid FROM user WHERE username=%s", receiver) if len(new) == 0: reuse = ddbb.query( "SELECT id FROM user WHERE date_add(NOW(), INTERVAL -1 HOUR) > confirmValid AND pw=''" ) confirm = ''.join([ random.choice(string.ascii_letters + string.digits) for _ in range(64) ]) if len(reuse) > 0: reuse = reuse[0][0] ddbb.query( "UPDATE user SET username=%s, confirm=%s, confirmType='password', confirmData=NULL, confirmValid=now() WHERE id=%s", receiver, confirm, reuse) new = reuse else: new = ddbb.insert( "INSERT INTO user (username, pw, confirm, confirmType, confirmData, confirmValid) VALUES (%s, '', %s, 'password', NULL, now())", receiver, confirm) registerShare(user, receiver, confirm) receiver = new else: receiver = new[0][0] if new[0][1] == "": valid = new[0][2] + timedelta(hours=1) valid = valid.timestamp() if (valid - time.time()) <= 0: confirm = ''.join([ random.choice(string.ascii_letters + string.digits) for _ in range(64) ]) ddbb.query( "UPDATE user SET confirm=%s, confirmType='password', confirmData=NULL, confirmValid=now() WHERE id=%s", confirm, new[0][0]) registerShare(user, '*****@*****.**', confirm) ddbb.query( "INSERT INTO share (owner, user, mac) VALUES ((SELECT id FROM user WHERE username=%s), %s, %s)", user, receiver, mac) for u in affected: ddbb.broker.macls(u[0]) return {'done': True}