add user wallet deletion

mm-logging
lza_menace 4 years ago
parent 86fd1ecbcc
commit c379ae9bc9

@ -1,9 +1,8 @@
from os import kill
from flask import request, render_template, session, redirect, url_for, flash
from flask_login import login_user, logout_user, current_user
from secrets import token_urlsafe
from flask_login import login_user, logout_user, current_user, login_required
from wowstash.blueprints.auth import auth_bp
from wowstash.forms import Register, Login
from wowstash.forms import Register, Login, Delete
from wowstash.models import User
from wowstash.factory import db, bcrypt
from wowstash.library.docker import docker
@ -28,7 +27,6 @@ def register():
user = User(
email=form.email.data,
password=bcrypt.generate_password_hash(form.password.data).decode('utf8'),
wallet_password=token_urlsafe(16),
)
db.session.add(user)
db.session.commit()
@ -76,6 +74,22 @@ def logout():
docker.stop_container(current_user.wallet_container)
send_es({'type': 'stop_container', 'user': current_user.email})
current_user.clear_wallet_data()
send_es({'type': 'logout', 'user': current_user.email})
logout_user()
send_es({'type': 'logout', 'user': current_user.email})
logout_user()
return redirect(url_for('meta.index'))
@auth_bp.route("/delete", methods=["GET", "POST"])
@login_required
def delete():
form = Delete()
if form.validate_on_submit():
docker.stop_container(current_user.wallet_container)
send_es({'type': 'stop_container', 'user': current_user.email})
docker.delete_wallet_data(current_user.id)
send_es({'type': 'delete_wallet', 'user': current_user.email})
current_user.clear_wallet_data(reset_password=True, reset_wallet=True)
flash('Successfully deleted wallet data')
return redirect(url_for('meta.index'))
else:
flash('Please confirm deletion of the account')
return redirect(url_for('wallet.dashboard'))

@ -13,7 +13,7 @@ from wowstash.library.docker import docker
from wowstash.library.elasticsearch import send_es
from wowstash.library.jsonrpc import Wallet, to_atomic
from wowstash.library.cache import cache
from wowstash.forms import Send
from wowstash.forms import Send, Delete
from wowstash.factory import db
from wowstash.models import User
from wowstash import config
@ -31,6 +31,7 @@ def loading():
@login_required
def dashboard():
send_form = Send()
delete_form = Delete()
_address_qr = BytesIO()
all_transfers = list()
wallet = Wallet(
@ -67,6 +68,7 @@ def dashboard():
address=address,
qrcode=qrcode,
send_form=send_form,
delete_form=delete_form,
user=current_user,
seed=seed,
spend_key=spend_key,

@ -17,3 +17,6 @@ class Login(FlaskForm):
class Send(FlaskForm):
address = StringField('Destination Address:', validators=[DataRequired()], render_kw={"placeholder": "Wownero address", "class": "form-control"})
amount = StringField('Amount:', validators=[DataRequired()], render_kw={"placeholder": "Amount to send or \"all\"", "class": "form-control"})
class Delete(FlaskForm):
confirm = BooleanField('Confirm Account and Wallet Deletion:', validators=[DataRequired()], render_kw={"class": "form-control-span"})

@ -1,8 +1,12 @@
from docker import from_env, APIClient
from docker.errors import NotFound, NullResource, APIError
from socket import socket
from shutil import rmtree
from os.path import expanduser
from secrets import token_urlsafe
from wowstash import config
from wowstash.models import User
from wowstash.factory import db
from wowstash.library.jsonrpc import daemon
from wowstash.library.elasticsearch import send_es
@ -11,11 +15,13 @@ 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', '/tmp/wallets')
self.listen_port = 34569
self.wallet_dir = expanduser(getattr(config, 'WALLET_DIR', '~/data/wallets'))
self.listen_port = 8888
def create_wallet(self, user_id):
u = User.query.get(user_id)
u.wallet_password = token_urlsafe(12)
db.session.commit()
command = f"""wownero-wallet-cli \
--generate-new-wallet /wallet/{u.id}.wallet \
--restore-height {daemon.info()['height']} \
@ -103,6 +109,11 @@ class Docker(object):
c = self.client.containers.get(container_id)
c.stop()
def delete_wallet_data(self, user_id):
user_dir = f'{self.wallet_dir}/{user_id}'
res = rmtree(user_dir)
return res
def cleanup(self):
users = User.query.all()
for u in users:

@ -14,7 +14,7 @@ class User(db.Model):
email = db.Column(db.String(50), unique=True, index=True)
password = db.Column(db.String(120))
register_date = db.Column(db.DateTime, server_default=func.now())
wallet_password = db.Column(db.String(120))
wallet_password = db.Column(db.String(120), nullable=True)
wallet_created = db.Column(db.Boolean, default=False)
wallet_connected = db.Column(db.Boolean, default=False)
wallet_port = db.Column(db.Integer, nullable=True)
@ -39,10 +39,14 @@ class User(db.Model):
def get_id(self):
return self.id
def clear_wallet_data(self):
def clear_wallet_data(self, reset_password=False, reset_wallet=False):
self.wallet_connected = False
self.wallet_port = None
self.wallet_container = None
if reset_password:
self.wallet_password = None
if reset_wallet:
self.wallet_created = False
db.session.commit()
def __repr__(self):

@ -14,7 +14,7 @@
<div class="header-content mx-auto">
<h1 class="mb-5">Manage your Wownero funds securely and anonymously.</h1>
{% if current_user.is_authenticated %}
<a href="{{ url_for('wallet.dashboard') }}" class="btn btn-outline btn-xl">Wallet Dashboard</a>
<a href="{{ url_for('wallet.dashboard') }}" class="btn btn-outline btn-xl">{% if current_user.wallet_created %}Wallet Dashboard{% else %}Create Wallet{% endif %}</a>
{% else %}
<a href="{{ url_for('auth.register') }}" class="btn btn-outline btn-xl">Register</a>
<a href="{{ url_for('auth.login') }}" class="btn btn-outline btn-xl">Login</a>

@ -69,14 +69,6 @@
<div class="container-slim">
<div class="section-heading text-center">
<h2>Send</h2>
{% if current_user.funds_locked %}
<p>Sending funds is currently locked due to a transfer already in progress. Please try again in a few minutes. Pending transfers:</p>
<ul>
{% for tx in txs_queued %}
<li class="slim small">{{ tx.amount | from_atomic }} - {{ tx.address }}</li>
{% endfor %}
</ul>
{% else %}
<form method="POST" action="{{ url_for('wallet.send') }}" class="send-form">
{{ send_form.csrf_token }}
{% for f in send_form %}
@ -94,7 +86,6 @@
</ul>
<input type="submit" value="Send" class="btn btn-link btn-outline btn-xl">
</form>
{% endif %}
</div>
</div>
</section>
@ -117,6 +108,32 @@
</div>
</section>
<section class="section2" id="send">
<div class="container-slim">
<div class="section-heading text-center">
<h2>Delete Account</h2>
<p>You can and should delete your wallet from the server. Please ensure you have copied the mnemonic seed from the secrets above if there are still funds associated with the keys.</p>
<form method="POST" action="{{ url_for('auth.delete') }}" class="send-form">
{{ delete_form.csrf_token }}
{% for f in delete_form %}
{% if f.name != 'csrf_token' %}
<div class="form-group">
{{ f.label }}
{{ f }}
</div>
{% endif %}
{% endfor %}
<ul>
{% for field, errors in delete_form.errors.items() %}
<li>{{ send_form[field].label }}: {{ ', '.join(errors) }}</li>
{% endfor %}
</ul>
<input type="submit" value="Delete" class="btn btn-link btn-outline btn-xl">
</form>
</div>
</div>
</section>
{% include 'footer.html' %}
{% include 'scripts.html' %}