#!/usr/bin/env python3 from os import environ from typing import Optional, Tuple from datetime import datetime from redis import Redis from hashlib import sha256 from functools import reduce s = datetime.now() NO_REMOTE_IDENTITY_MSG = """User identity hash not available. In MeshChat: use the fingerprint button in the top right to send the identification information. In NomadNet: Save node, click on it, go to and select "Identify when connecting".""" FORBIDDEN_INPUT = [ "[", "`", "\n" ] ADMIN_IDENTITIES = [ "e6c72573bb91d48338dbcc57d0223b81", "70c9608c9a0f4ae895f7fab406554e1c" ] BGCOLOR = "`F333`BDDD" def is_admin() -> bool: remote_identity = environ.get("remote_identity", None) if remote_identity is None: return False return remote_identity in ADMIN_IDENTITIES def sanitize_input(text: str) -> str: return reduce(lambda a, b: a.replace(b, ""), FORBIDDEN_INPUT, text) def check_password(password: str) -> bool: expected = '34a77e61000b2ba1f56201332ef64d93f9cdc60e63ab48bc255102586ef7e592' gotten = sha256(f"hswrosalt{password}".encode('utf-8'), usedforsecurity=True).hexdigest() return expected == gotten def check_name(username: str) -> bool: if len(username) >= 16: return False return all(map(lambda c: c.isalnum(), username)) def get_login_info() -> Tuple[Optional[str], Optional[str]]: """Returns [login_name, error]""" remote_identity = environ.get("remote_identity", None) if remote_identity is None: return (None, NO_REMOTE_IDENTITY_MSG) r = Redis(host='localhost', port=6379, db=0) login = r.get(f'login_info_{remote_identity}') if login is None: return (None, None) return (login.decode('utf-8'), None) def login(username: str) -> Optional[str]: """Returns err""" remote_identity = environ.get("remote_identity", None) if remote_identity is None: return NO_REMOTE_IDENTITY_MSG if not check_name(username): return "Username should only contain alphanumeric characters and have at most 16 characters." r = Redis(host='localhost', port=6379, db=0) r.set(f'login_info_{remote_identity}', username) return None def logout(): remote_identity = environ.get("remote_identity", None) if remote_identity is None: return r = Redis(host='localhost', port=6379, db=0) r.delete(f'login_info_{remote_identity}') def login_button() -> str: l = get_login_info() if l[0] is None: return "[`[Identify`:/page/login.mu`]]" else: return f"Welcome, {l[0]} | [`[Forget`:/page/logout.mu`]]" def header(title: Optional[str] = None): if title is None: title = "" else: title = ": `i" + title print(f"""`F000`BFB1 `c -*abc `r {login_button()} `l `!Hackerspace`!Wrocław{title} `a -_ `a `` `FEEE`B333 `c `l `[Home`:/page/index.mu]` | `[Status`:/page/status.mu]` | `[Shoutbox`:/page/chat.mu]` `a `` {BGCOLOR} """) def reset_colors() -> str: print(BGCOLOR) def footer(): print(f"{BGCOLOR}`r Rendered in: {(datetime.now()-s).total_seconds()}s") print(f"{datetime.now()}") if __name__ == "__main__": pass