mirror of
https://git.wownero.com/lza_menace/wowstash.git
synced 2024-08-15 00:33:15 +00:00
add user wallet deletion
This commit is contained in:
parent
86fd1ecbcc
commit
c379ae9bc9
7 changed files with 72 additions and 21 deletions
|
@ -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' %}
|
||||
|
|
Loading…
Reference in a new issue