integrate docker to wallet creation and connection

mm-logging
lza_menace 4 years ago
parent e260b8f269
commit 1cecd043e4

@ -6,6 +6,7 @@ from wowstash.blueprints.auth import auth_bp
from wowstash.forms import Register, Login
from wowstash.models import User
from wowstash.factory import db, bcrypt
from wowstash.library.docker import docker
@auth_bp.route("/register", methods=["GET", "POST"])
@ -69,7 +70,7 @@ def login():
@auth_bp.route("/logout")
def logout():
if current_user.is_authenticated:
current_user.kill_wallet()
docker.stop_container(current_user.wallet_container)
current_user.clear_wallet_data()
logout_user()
return redirect(url_for('meta.index'))

@ -1,4 +1,4 @@
import subprocess
from time import sleep
from io import BytesIO
from base64 import b64encode
from qrcode import make as qrcode_make
@ -9,6 +9,7 @@ from flask_login import login_required, current_user
from socket import socket
from datetime import datetime
from wowstash.blueprints.wallet import wallet_bp
from wowstash.library.docker import docker
from wowstash.library.jsonrpc import Wallet, to_atomic
from wowstash.library.cache import cache
from wowstash.forms import Send
@ -21,6 +22,7 @@ from wowstash import config
@login_required
def loading():
if current_user.wallet_connected and current_user.wallet_created:
sleep(1)
return redirect(url_for('wallet.dashboard'))
return render_template('wallet/loading.html')
@ -46,7 +48,7 @@ def dashboard():
for tx in transfers[type]:
all_transfers.append(tx)
balances = wallet.get_balances()
qr_uri = f'wownero:{address}?tx_description="{current_user.email}"'
qr_uri = f'wownero:{address}?tx_description={current_user.email}'
address_qr = qrcode_make(qr_uri).save(_address_qr)
qrcode = b64encode(_address_qr.getvalue()).decode()
return render_template(
@ -63,42 +65,33 @@ def dashboard():
@login_required
def connect():
if current_user.wallet_connected is False:
tcp = socket()
tcp.bind(('', 0))
_, port = tcp.getsockname()
tcp.close()
command = f"""wownero-wallet-rpc \
--detach \
--non-interactive \
--rpc-bind-port {port} \
--wallet-file {config.WALLET_DIR}/{current_user.id}.wallet \
--rpc-login {current_user.id}:{current_user.wallet_password} \
--password {current_user.wallet_password} \
--daemon-address {config.DAEMON_PROTO}://{config.DAEMON_HOST}:{config.DAEMON_PORT} \
--daemon-login {config.DAEMON_USER}:{config.DAEMON_PASS} \
--log-file {config.WALLET_DIR}/{current_user.id}.log
"""
proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
outs, errs = proc.communicate()
# print(outs)
if proc.returncode == 0:
print(f'Successfully started RPC for {current_user}!')
current_user.wallet_connected = True
current_user.wallet_port = port
current_user.wallet_pid = proc.pid
current_user.wallet_connect_date = datetime.now()
db.session.commit()
return "ok"
wallet = docker.start_wallet(current_user.id)
port = docker.get_port(wallet)
current_user.wallet_connected = docker.container_exists(wallet)
current_user.wallet_port = port
current_user.wallet_container = wallet
db.session.commit()
return 'ok'
@wallet_bp.route('/wallet/create')
@login_required
def create():
if current_user.wallet_created is False:
docker.create_wallet(current_user.id)
current_user.wallet_created = True
db.session.commit()
return 'ok'
@wallet_bp.route('/wallet/status')
@login_required
def status():
data = {
"created": current_user.wallet_created,
"connected": current_user.wallet_connected,
"port": current_user.wallet_port,
"date": current_user.wallet_connect_date
'created': current_user.wallet_created,
'connected': current_user.wallet_connected,
'port': current_user.wallet_port,
'container': current_user.wallet_container
}
return jsonify(data)

@ -57,6 +57,7 @@ def create_app():
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'auth.login'
login_manager.logout_view = 'auth.logout'
@login_manager.user_loader
def load_user(user_id):
@ -73,7 +74,16 @@ def create_app():
@app.template_filter('from_atomic')
def from_atomic(a):
from wowstash.library.jsonrpc import from_atomic
return from_atomic(a)
atomic = from_atomic(a)
if atomic == 0:
return 0
else:
return float(atomic)
@app.cli.command('clean_containers')
def clean_containers():
from wowstash.library.docker import docker
docker.cleanup()
# Routes
from wowstash.blueprints.auth import auth_bp

@ -9,7 +9,7 @@ class Docker(object):
def __init__(self):
self.client = from_env()
self.wownero_image = getattr(config, 'WOWNERO_IMAGE', 'lalanza808/wownero')
self.wallet_dir = getattr(config, 'WALLET_DIR', './data/wallets')
self.wallet_dir = getattr(config, 'WALLET_DIR', '/tmp/wallets')
self.listen_port = 34569
def create_wallet(self, user_id):
@ -45,6 +45,8 @@ class Docker(object):
command = f"""wownero-wallet-rpc \
--non-interactive \
--rpc-bind-port {self.listen_port} \
--rpc-bind-ip 0.0.0.0 \
--confirm-external-bind \
--wallet-file /wallet/{u.id}.wallet \
--rpc-login {u.id}:{u.wallet_password} \
--password {u.wallet_password} \
@ -60,7 +62,7 @@ class Docker(object):
remove=True,
detach=True,
ports={
f'{self.listen_port}/tcp': None
f'{self.listen_port}/tcp': ('127.0.0.1', None)
},
volumes={
f'{self.wallet_dir}/{u.id}': {
@ -83,3 +85,18 @@ class Docker(object):
return True
except NotFound:
return False
def stop_container(self, container_id):
if self.container_exists(container_id):
c = self.client.containers.get(container_id)
c.stop()
def cleanup(self):
users = User.query.all()
for u in users:
if u.wallet_container:
if not self.container_exists(u.wallet_container):
u.clear_wallet_data()
docker = Docker()

@ -18,8 +18,7 @@ class User(db.Model):
wallet_created = db.Column(db.Boolean, default=False)
wallet_connected = db.Column(db.Boolean, default=False)
wallet_port = db.Column(db.Integer, nullable=True)
wallet_pid = db.Column(db.Integer, nullable=True)
wallet_connect_date = db.Column(db.DateTime, nullable=True)
wallet_container = db.Column(db.String(30), nullable=True)
@property
def is_authenticated(self):
@ -40,17 +39,10 @@ class User(db.Model):
def get_id(self):
return self.id
def kill_wallet(self):
try:
kill(self.wallet_pid, 9)
except Exception as e:
print('could kill:', e)
def clear_wallet_data(self):
self.wallet_connected = False
self.wallet_port = None
self.wallet_pid = None
self.wallet_connect_date = None
self.wallet_container = None
db.session.commit()
def __repr__(self):

@ -41,7 +41,7 @@
xhr.send();
}
{% if current_user.wallet_connected == False %}
{% if current_user.wallet_connected == False and current_user.wallet_created == True %}
document.addEventListener("DOMContentLoaded", function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', '{{ url_for("wallet.connect") }}');
@ -49,6 +49,14 @@
});
{% endif %}
{% if current_user.wallet_connected == False and current_user.wallet_created == False %}
document.addEventListener("DOMContentLoaded", function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', '{{ url_for("wallet.create") }}');
xhr.send();
});
{% endif %}
window.setInterval(function(){
{% if current_user.wallet_connected == False %}
check_wallet_status('connected');