diff --git a/docker-compose.yaml b/docker-compose.yaml index 4470664..8cce076 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,8 +1,10 @@ version: '3' +volumes: + grafana: services: db: image: postgres:9.6.15-alpine - container_name: db + container_name: wowstash_db ports: - 5433:5432 environment: @@ -13,6 +15,27 @@ services: - ./data/postgresql:/var/lib/postgresql/data cache: image: redis:latest - container_name: cache + container_name: wowstash_cache ports: - 6379:6379 + kibana: + image: docker.elastic.co/kibana/kibana:7.1.0 + ports: + - 5601:5601 + environment: + ELASTICSEARCH_HOSTS: http://elasticsearch:9200 + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:7.1.0 + environment: + - discovery.type=single-node + - node.name=elasticsearch + - cluster.name=es-docker-cluster + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ulimits: + memlock: + soft: -1 + hard: -1 + volumes: + - ./data/elasticsearch:/usr/share/elasticsearch/data + ports: + - 9200:9200 diff --git a/requirements.txt b/requirements.txt index cadbf53..040b815 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,5 @@ flask-bcrypt flask-login qrcode Pillow -git+https://github.com/lalanza808/MoneroPy docker +elasticsearch diff --git a/wowstash/blueprints/auth/routes.py b/wowstash/blueprints/auth/routes.py index 1ec6d42..bd8f409 100644 --- a/wowstash/blueprints/auth/routes.py +++ b/wowstash/blueprints/auth/routes.py @@ -7,6 +7,7 @@ from wowstash.forms import Register, Login from wowstash.models import User from wowstash.factory import db, bcrypt from wowstash.library.docker import docker +from wowstash.library.elasticsearch import send_es @auth_bp.route("/register", methods=["GET", "POST"]) @@ -32,7 +33,8 @@ def register(): db.session.add(user) db.session.commit() - # Login user and redirect to wallet page + # Capture event, login user and redirect to wallet page + send_es({'type': 'register', 'user': user.email}) login_user(user) return redirect(url_for('wallet.dashboard')) @@ -61,7 +63,8 @@ def login(): flash('Invalid username or password.') return redirect(url_for('auth.login')) - # Login user and redirect to wallet page + # Capture event, login user, and redirect to wallet page + send_es({'type': 'login', 'user': user.email}) login_user(user) return redirect(url_for('wallet.dashboard')) @@ -71,6 +74,8 @@ def login(): def logout(): if current_user.is_authenticated: 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() return redirect(url_for('meta.index')) diff --git a/wowstash/blueprints/wallet/routes.py b/wowstash/blueprints/wallet/routes.py index 4afc858..8d1fc36 100644 --- a/wowstash/blueprints/wallet/routes.py +++ b/wowstash/blueprints/wallet/routes.py @@ -10,6 +10,7 @@ from socket import socket from datetime import datetime from wowstash.blueprints.wallet import wallet_bp 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 @@ -58,6 +59,7 @@ def dashboard(): seed = wallet.seed() spend_key = wallet.spend_key() view_key = wallet.view_key() + send_es({'type': 'load_dashboard', 'user': current_user.email}) return render_template( 'wallet/dashboard.html', transfers=all_transfers, @@ -124,11 +126,13 @@ def send(): # Check if Wownero wallet is available if wallet.connected is False: flash('Wallet RPC interface is unavailable at this time. Try again later.') + send_es({'type': 'tx_fail_rpc_unavailable', 'user': user.email}) return redirect(redirect_url) # Quick n dirty check to see if address is WOW if len(address) not in [97, 108]: flash('Invalid Wownero address provided.') + send_es({'type': 'tx_fail_address_invalid', 'user': user.email}) return redirect(redirect_url) # Check if we're sweeping or not @@ -140,6 +144,7 @@ def send(): amount = to_atomic(Decimal(send_form.amount.data)) except: flash('Invalid Wownero amount specified.') + send_es({'type': 'tx_fail_amount_invalid', 'user': user.email}) return redirect(redirect_url) # Send transfer @@ -148,9 +153,12 @@ def send(): # Inform user of result and redirect if 'message' in tx: msg = tx['message'].capitalize() + msg_lower = tx['message'].replace(' ', '_').lower() flash(f'There was a problem sending the transaction: {msg}') + send_es({'type': f'tx_fail_{msg_lower}', 'user': user.email}) else: flash('Successfully sent transfer.') + send_es({'type': 'tx_success', 'user': user.email}) return redirect(redirect_url) else: diff --git a/wowstash/library/docker.py b/wowstash/library/docker.py index 6f5c674..a7c5694 100644 --- a/wowstash/library/docker.py +++ b/wowstash/library/docker.py @@ -4,6 +4,8 @@ from socket import socket from wowstash import config from wowstash.models import User from wowstash.library.jsonrpc import daemon +from wowstash.library.elasticsearch import send_es + class Docker(object): def __init__(self): @@ -38,6 +40,7 @@ class Docker(object): } } ) + send_es({'type': 'create_wallet', 'user': u.email}) return container.short_id def start_wallet(self, user_id): @@ -73,6 +76,7 @@ class Docker(object): } } ) + send_es({'type': 'start_wallet', 'user': u.email}) return container.short_id except APIError as e: if str(e).startswith('409'): diff --git a/wowstash/library/elasticsearch.py b/wowstash/library/elasticsearch.py new file mode 100644 index 0000000..d3ce5a6 --- /dev/null +++ b/wowstash/library/elasticsearch.py @@ -0,0 +1,21 @@ +from datetime import datetime +from elasticsearch import Elasticsearch +from wowstash import config + + +def send_es(data): + try: + es = Elasticsearch( + [getattr(config, 'ELASTICSEARCH_HOST', 'localhost')] + ) + now = datetime.utcnow() + index_ts = now.strftime('%Y%m%d') + data['datetime'] = now + es.index( + index="{}-{}".format( + getattr(config, 'ELASTICSEARCH_INDEX_NAME', 'wowstash'), + index_ts + ), body=data) + except Exception as e: + print('Could not capture event in Elasticsearch: ', e) + pass # I don't really care if this logs... diff --git a/wowstash/templates/meta/privacy.html b/wowstash/templates/meta/privacy.html index 0aec61c..41916fb 100644 --- a/wowstash/templates/meta/privacy.html +++ b/wowstash/templates/meta/privacy.html @@ -17,9 +17,9 @@ -

I don't actively track or monitor any of this though. I might check logs for troubleshooting purposes. I don't even know what a privacy policy is supposed to be for, to be honest. Just trying to be legit.

-

None of this data is shared with any third parties because I'm not a fucking lame.

+

I check logs and capture events for troubleshooting purposes only. None of this data is shared with any third parties because I'm not a fucking lame.