From 09409b80a7d75047744583560666b57a65fe7eeb Mon Sep 17 00:00:00 2001 From: lza_menace Date: Sun, 13 Dec 2020 22:28:23 -0800 Subject: [PATCH] revamp logging and auditing with webhook events --- suchwow/app.py | 52 +++++++++------------------------------ suchwow/config.example.py | 8 ++++++ suchwow/discord.py | 23 +++++++++-------- suchwow/routes/post.py | 29 +++++++++++++++------- suchwow/utils/helpers.py | 23 +++++++++++++++-- 5 files changed, 73 insertions(+), 62 deletions(-) diff --git a/suchwow/app.py b/suchwow/app.py index 5b03fd7..a42ff29 100644 --- a/suchwow/app.py +++ b/suchwow/app.py @@ -10,6 +10,7 @@ from suchwow import config from suchwow.models import Post, Profile, Comment, Notification, db, Moderator from suchwow.routes import auth, comment, post, profile, leaderboard from suchwow.utils.decorators import login_required, moderator_required +from suchwow.utils.helpers import post_webhook from suchwow.reddit import make_post from suchwow.discord import post_discord_webhook from suchwow import wownero @@ -76,57 +77,24 @@ def create_accounts(): account = wallet.new_account() print(f"Created account {account}") -@app.cli.command("post_new_memes") -def post_new_memes(): - # run every 5 mins - all_posts = Post.select().order_by(Post.timestamp.desc()).where( - (Post.to_reddit == False) | (Post.to_discord == False) - ) - for post in all_posts: - diff = datetime.now() - post.timestamp - recent_post = diff < timedelta(hours=2) - if recent_post: - if not post.to_reddit: - make_post(post) - if not post.to_discord: - post_discord_webhook(post) - return - -@app.cli.command("post_meme") -@click.argument("post_id") -def post_meme(post_id): - post = Post.get(id=post_id) - make_post(post) - post_discord_webhook(post) - return - -@app.cli.command("reddit_random") -def reddit_random(): - # run every 8 hours - all_posts = Post.select().where(Post.reddit_url == None) - post = choice(all_posts) - make_post(post) - @app.cli.command("payout_users") def payout_users(): wallet = wownero.Wallet() + _fa = wownero.from_atomic + _aw = wownero.as_wownero for post in Post.select(): submitter = Profile.get(username=post.submitter) balances = wallet.balances(post.account_index) + url = url_for('post.read', id=post.id, _external=True) if balances[1] > 0: print(f"Post #{post.id} has {balances[1]} funds unlocked and ready to send. Sweeping all funds to user's address ({submitter.address}).") sweep = wallet.sweep_all(account=post.account_index, dest_address=submitter.address) print(sweep) - -@app.cli.command("delete_post") -@click.argument("post_id") -def _delete_post(post_id): - post = Post.get(id=post_id) - save_path_base = path.join(app.config["DATA_FOLDER"], "uploads") - save_path = path.join(save_path_base, post.image_name) - post.delete_instance() - remove(save_path) - print(f"Deleted post {post_id} and image {save_path}") + if "tx_hash_list" in sweep: + amount = 0 + for amt in sweep["amount_list"]: + amount += int(amt) + post_webhook(f"Paid out :moneybag: {_aw(_fa(amount))} WOW to `{post.submitter}` for post [{post.id}]({url})") @app.cli.command("add_admin") @click.argument("username") @@ -135,6 +103,7 @@ def add_admin(username): m = Moderator(username=username) m.save() print(f"Added {username}") + post_webhook(f"Moderator `{username}` added :ship_it_parrot: by console :black_flag:") else: print("That moderator already exists") @@ -145,6 +114,7 @@ def remove_admin(username): if m: m.delete_instance() print(f"Deleted {username}") + post_webhook(f"Moderator `{username}` removed :excuseme: by console :black_flag:") else: print("That moderator doesn't exist") diff --git a/suchwow/config.example.py b/suchwow/config.example.py index a35c03d..426f6d1 100644 --- a/suchwow/config.example.py +++ b/suchwow/config.example.py @@ -1,3 +1,6 @@ +from os import getenv + + OIDC_URL = 'https://login.wownero.com/auth/realms/master/protocol/openid-connect', OIDC_CLIENT_ID = 'suchwowxxx', OIDC_CLIENT_SECRET = 'xxxxxxxxxx', @@ -20,3 +23,8 @@ PRAW_PASSWORD = 'xxxxxxxx' SERVER_NAME = 'localhost' DISCORD_URL = 'xxxxxxx' BANNED_USERS = {'username': 'reason for the ban'} + +MM_ICON = getenv('MM_ICON', 'https://funding.wownero.com/static/wowdoge-a.jpg') +MM_CHANNEL = getenv('MM_CHANNEL', 'suchwow') +MM_USERNAME = getenv('MM_USERNAME', 'SuchWow!') +MM_ENDPOINT = getenv('MM_ENDPOINT', 'ppppppppppppppppppppppppp') diff --git a/suchwow/discord.py b/suchwow/discord.py index 7be2b82..725bd93 100644 --- a/suchwow/discord.py +++ b/suchwow/discord.py @@ -10,13 +10,16 @@ insults = ["fart sacks", "dick lips", "shit stains", "chodes", "dipshits", "dick def post_discord_webhook(post): - wallet = wownero.Wallet() - post_wow_address = wallet.get_address(account=post.account_index) - content = f"{choice(intro)} {choice(insults)}, new SuchWow post #{post.id} by {post.submitter} is up! Tip WOW to `{post_wow_address}` to show support! {url_for('post.uploaded_file', filename=post.image_name, _external=True)}" - msg = {"content": content} - discord_webhook_url = config.DISCORD_URL - r = requests.post(discord_webhook_url, data=msg) - r.raise_for_status() - post.to_discord = True - post.save() - print(f"Posted #{post.id} to Discord") + try: + wallet = wownero.Wallet() + post_wow_address = wallet.get_address(account=post.account_index) + content = f"{choice(intro)} {choice(insults)}, new SuchWow post #{post.id} by {post.submitter} is up! Tip WOW to `{post_wow_address}` to show support! {url_for('post.uploaded_file', filename=post.image_name, _external=True)}" + msg = {"content": content} + discord_webhook_url = config.DISCORD_URL + r = requests.post(discord_webhook_url, data=msg) + r.raise_for_status() + post.to_discord = True + post.save() + return True + except: + return False diff --git a/suchwow/routes/post.py b/suchwow/routes/post.py index 2546698..6d89958 100644 --- a/suchwow/routes/post.py +++ b/suchwow/routes/post.py @@ -7,7 +7,7 @@ from suchwow import wownero from suchwow import config from suchwow.models import Post, Comment from suchwow.utils.decorators import login_required, profile_required, moderator_required -from suchwow.utils.helpers import allowed_file, is_moderator, get_session_user +from suchwow.utils.helpers import allowed_file, is_moderator, get_session_user, post_webhook from suchwow.reddit import make_post from suchwow.discord import post_discord_webhook @@ -100,21 +100,31 @@ def create(): address_index=0 ) post.save() - return redirect(url_for("post.read", id=post.id)) + url = url_for('post.read', id=post.id, _external=True) + post_webhook(f"New post :doge2: [{post.id}]({url}) by `{submitter}` :neckbeard:") + return redirect(url) return render_template("post/create.html") @bp.route("/post//approve") @moderator_required def approve(id): post = Post.get(id=id) + url = url_for('post.read', id=post.id, _external=True) if post: - post.approved = True - post.save() - if not post.to_reddit: - make_post(post) - if not post.to_discord: - post_discord_webhook(post) - flash("Approved") + if not post.approved: + post.approved = True + post.save() + post_webhook(f"Post [{post.id}]({url}) approved :white_check_mark: by `{get_session_user()}` :fieri_parrot:") + flash("Approved") + if current_app.config["DEBUG"] is False: + if not post.to_reddit: + _r = make_post(post) + if not post.to_discord: + _d = post_discord_webhook(post) + if _r and _d: + post_webhook(f"Post [{post.id}]({url}) submitted :dab_parrot: to Reddit and Discord.") + else: + post_webhook(f"Post [{post.id}]({url}) failed :this-is-fine-fire: to post to socials...Reddit: {_r} - Discord: {_d}") return redirect(url_for("mod_queue")) else: flash("You can't approve this") @@ -133,6 +143,7 @@ def delete(id): save_path = path.join(save_path_base, post.image_name) remove(save_path) post.delete_instance() + post_webhook(f"Post {post.id} deleted :dumpsterfire: by `{user}` :godmode:") flash("Deleted that shit, brah!") if is_mod: return redirect(url_for("mod_queue")) diff --git a/suchwow/utils/helpers.py b/suchwow/utils/helpers.py index edbff4e..a014d95 100644 --- a/suchwow/utils/helpers.py +++ b/suchwow/utils/helpers.py @@ -1,10 +1,13 @@ -from flask import current_app, session +from requests import post as r_post +from json import dumps +from flask import session, current_app from suchwow.models import Moderator +from suchwow import config def allowed_file(filename): return "." in filename and \ - filename.rsplit(".", 1)[1].lower() in current_app.config["ALLOWED_EXTENSIONS"] + filename.rsplit(".", 1)[1].lower() in config.ALLOWED_EXTENSIONS def is_moderator(username): m = Moderator.filter(username=username) @@ -17,3 +20,19 @@ def get_session_user(): if "auth" not in session or not session["auth"]: return None return session["auth"]["preferred_username"] + +def post_webhook(msg): + try: + if current_app.config["DEBUG"]: + msg = "[DEBUG] " + msg + data = { + "text": msg, + "channel": config.MM_CHANNEL, + "username": config.MM_USERNAME, + "icon_url": config.MM_ICON + } + res = r_post(config.MM_ENDPOINT, data=dumps(data)) + res.raise_for_status() + return True + except: + return False