154 lines
6.1 KiB
Python
154 lines
6.1 KiB
Python
import requests
|
|
import urllib.parse
|
|
from threading import Thread
|
|
|
|
import os
|
|
import ssl
|
|
import socketio
|
|
import logging, traceback
|
|
import json
|
|
import time
|
|
|
|
from libs.app.common.paths import ROOT_DIR
|
|
from libs.app.common.logging import get_logger
|
|
from libs.app.common.network_utils import check_url
|
|
from libs.app.common.process import new_python_process
|
|
from libs.noSys.noSysModule import NoSysModule
|
|
from libs.noSys.users import User
|
|
from .lockboxService import UserData
|
|
|
|
logger = get_logger()
|
|
|
|
class LockboxClient(NoSysModule):
|
|
def __init__(self, nosys_core):
|
|
super().__init__(nosys_core)
|
|
|
|
self.api_host = self.config.get("server").get("host")
|
|
self.api_port = self.config.get("server").get("port")
|
|
self.service_url = f'{self.api_host}:{self.api_port}'
|
|
self.session = requests.Session()
|
|
certs_path = os.path.join(ROOT_DIR, "libs", "api", "certs")
|
|
ca_path = os.path.join(certs_path, "ca.pem")
|
|
self.session.verify = ca_path
|
|
session_socketio = requests.Session()
|
|
session_socketio.verify = ca_path
|
|
self.socketio = socketio.Client(http_session=session_socketio)
|
|
self.sio_events()
|
|
|
|
self.users = {} # UserData
|
|
self.user_tokens = {}
|
|
self.signature_requests = {} # request_id | callback
|
|
|
|
def setup(self):
|
|
self.nosys_core.modules.pmc = self
|
|
|
|
def on_nosys_ready(self, event):
|
|
logger.debug("LOCKBOX READY")
|
|
self.starts_lockbox_service()
|
|
self.connect()
|
|
# TODO Remove it
|
|
# self.add("I0x1Y2FzR2FicmllbFZhekRvc1NhbnRvc0luYWNpbyE=", UserData(proof_of_work="eYnU*@"))
|
|
self.users = self.user_list()
|
|
for user in self.users:
|
|
u = User(user)
|
|
self.nosys_core.users.add_user(u)
|
|
|
|
def starts_lockbox_service(self):
|
|
try:
|
|
health_check_url = f"{self.service_url}/healthCheck"
|
|
if not check_url(health_check_url, timeout=3):
|
|
logger.debug(f"Starting lockbox Service in a new process")
|
|
process_pid = new_python_process("libs/lockbox/lockboxService.py", args=[self.api_port], new_console=True)
|
|
logger.debug(f"Lockbox process PID {process_pid}")
|
|
else:
|
|
logger.debug(f"Lockbox service already running in {health_check_url}")
|
|
except Exception:
|
|
logger.exception("ERROR")
|
|
|
|
def add(self, password, data = UserData()):
|
|
add_url = f"{self.service_url}/users"
|
|
body = {'password': password, 'data':data.__dict__}
|
|
result = self.session.post(add_url, json = body)
|
|
content = result.json()
|
|
user_token = content["token"]
|
|
verifying_key = content["verifying_key"]
|
|
# self.users[verifying_key] = data
|
|
self.user_tokens[verifying_key] = user_token
|
|
return (verifying_key, user_token)
|
|
|
|
def user_list(self):
|
|
users_list_url = f"{self.service_url}/users"
|
|
result = self.session.get(users_list_url)
|
|
for user in result.json():
|
|
print("LOGGED", user["logged"])
|
|
if user["logged"]:
|
|
verifying_key = user["id"]
|
|
self.users[verifying_key] = UserData(id=user["id"],proof_of_work=user["proof_of_work"], time_to_live=user["time_to_live"], added_at=user["added_at"], logged=user["logged"])
|
|
return self.users
|
|
|
|
def set_authorization_header(self, user, headers={}):
|
|
if user in self.user_tokens:
|
|
headers["Authorization"] = f'Bearer {self.user_tokens[user]}'
|
|
return headers
|
|
|
|
def get(self, user):
|
|
# users_data_url = f"{self.service_url}/users/{urllib.parse.quote(user, safe='')}"
|
|
# headers = self.set_authorization_header(user)
|
|
# result = self.session.get(users_data_url, headers=headers)
|
|
# content = result.json()
|
|
# data = UserData(proof_of_work=content["proof_of_work"])
|
|
data = self.users[user]
|
|
return data
|
|
|
|
def sign(self, data, user, callback, info=None):
|
|
sign_url = f"{self.service_url}/users/{urllib.parse.quote(user, safe='')}/signatures"
|
|
headers = self.set_authorization_header(user)
|
|
body = {'data': data, "info":info}
|
|
result = self.session.post(sign_url, json = body, headers=headers)
|
|
request_id = result.json()["requestId"]
|
|
self.signature_requests[request_id] = callback
|
|
return request_id
|
|
|
|
def connect(self):
|
|
while True:
|
|
try:
|
|
logger.debug(f"Trying to connect to lockbox service {self.service_url}")
|
|
self.socketio.connect(self.service_url, wait=True ,wait_timeout=60, transports=["websocket"])
|
|
logger.debug(f"Lockbox service connected {self.service_url}")
|
|
break
|
|
except Exception:
|
|
logger.exception(f"Failed to connect to lockbox service {self.service_url} - Retrying in 10 seconds")
|
|
time.sleep(10)
|
|
# self.socketio.emit('message', {'from': 'client'})
|
|
|
|
|
|
def sio_events(self):
|
|
@self.socketio.on('message')
|
|
def message(*args, **kwargs):
|
|
logger.debug("Message",args, kwargs)
|
|
|
|
@self.socketio.on("userAdded")
|
|
def on_user_added(*args, **kwargs):
|
|
user_id = args[0]
|
|
logger.debug(f"User added {user_id}")
|
|
self.user_list()
|
|
if user_id in self.users:
|
|
u = User(user_id)
|
|
self.nosys_core.users.add_user(u)
|
|
|
|
@self.socketio.on("signatureWaiting")
|
|
def on_signature_waiting(*args, **kwargs):
|
|
logger.debug(f"Signature Waiting {args[0]}")
|
|
|
|
@self.socketio.on("signatureResponse")
|
|
def on_signature_response(*args, **kwargs):
|
|
logger.debug(f"Signature response {args[0]}")
|
|
request_id = args[0]["requestId"]
|
|
signature = args[0]["signature"]
|
|
if request_id in self.signature_requests:
|
|
self.signature_requests[request_id](request_id, signature)
|
|
# signature = result.json()["signature"]
|
|
# if signature:
|
|
# return signature
|
|
# else:
|
|
# raise Exception("Sign data failed") |