diff --git a/env b/env index 33b81643d..9fe97684c 100644 --- a/env +++ b/env @@ -4,10 +4,6 @@ SITE_ID=TheMotte SITE_TITLE=The Motte ENFORCE_PRODUCTION=True GIPHY_KEY=blahblahblah -DISCORD_SERVER_ID=blahblahblah -DISCORD_CLIENT_ID=blahblahblah -DISCORD_CLIENT_SECRET=blahblahblah -DISCORD_BOT_TOKEN=blahblahblah HCAPTCHA_SECRET=blahblahblah YOUTUBE_KEY=blahblahblah PUSHER_ID=blahblahblah diff --git a/files/classes/__init__.py b/files/classes/__init__.py index 88c9fbec2..603843864 100644 --- a/files/classes/__init__.py +++ b/files/classes/__init__.py @@ -90,6 +90,5 @@ from files.helpers.lazy import * from files.helpers.security import * # Then the specific stuff we don't want stomped on -from files.helpers.discord import remove_user from files.helpers.lazy import lazy from files.__main__ import Base, app, cache diff --git a/files/classes/user.py b/files/classes/user.py index fe70140b2..4efbf44ee 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -1,7 +1,6 @@ from sqlalchemy.orm import deferred, aliased from secrets import token_hex import pyotp -from files.helpers.discord import remove_user from files.helpers.images import * from files.helpers.const import * from .alts import Alt @@ -33,7 +32,6 @@ class User(Base): __tablename__ = "users" __table_args__ = ( UniqueConstraint('bannerurl', name='one_banner'), - UniqueConstraint('discord_id', name='one_discord_account'), UniqueConstraint('id', name='uid_unique'), UniqueConstraint('original_username', name='users_original_username_key'), UniqueConstraint('username', name='users_username_key'), @@ -108,7 +106,6 @@ class User(Base): defaulttime = Column(String, default=defaulttimefilter, nullable=False) is_nofollow = Column(Boolean, default=False, nullable=False) custom_filter_list = Column(String) - discord_id = Column(String) ban_evade = Column(Integer, default=0, nullable=False) original_username = deferred(Column(String)) referred_by = Column(Integer, ForeignKey("users.id")) @@ -127,7 +124,6 @@ class User(Base): postgresql_ops={'description':'gin_trgm_ops'} ) - Index('discord_id_idx', discord_id) Index('fki_user_referrer_fkey', referred_by) Index('user_banned_idx', is_banned) Index('user_private_idx', is_private) @@ -602,7 +598,6 @@ class User(Base): if days: self.unban_utc = int(time.time()) + (days * 86400) g.db.add(self) - elif self.discord_id: remove_user(self) self.is_banned = admin.id if admin else AUTOJANNY_ID if reason: self.ban_reason = reason diff --git a/files/helpers/discord.py b/files/helpers/discord.py deleted file mode 100644 index 2ff345913..000000000 --- a/files/helpers/discord.py +++ /dev/null @@ -1,66 +0,0 @@ -from os import environ -import requests -import threading -from .const import * - -SERVER_ID = environ.get("DISCORD_SERVER_ID",'').strip() -CLIENT_ID = environ.get("DISCORD_CLIENT_ID",'').strip() -CLIENT_SECRET = environ.get("DISCORD_CLIENT_SECRET",'').strip() -BOT_TOKEN = environ.get("DISCORD_BOT_TOKEN",'').strip() -AUTH = environ.get("DISCORD_AUTH",'').strip() - -def discord_wrap(f): - - def wrapper(*args, **kwargs): - - user=args[0] - if not user.discord_id: - return - - - thread=threading.Thread(target=f, args=args, kwargs=kwargs) - thread.start() - - wrapper.__name__=f.__name__ - return wrapper - - - -@discord_wrap -def add_role(user, role_name): - role_id = ROLES[role_name] - url = f"https://discordapp.com/api/guilds/{SERVER_ID}/members/{user.discord_id}/roles/{role_id}" - headers = {"Authorization": f"Bot {BOT_TOKEN}"} - requests.put(url, headers=headers, timeout=5) - -@discord_wrap -def remove_role(user, role_name): - role_id = ROLES[role_name] - url = f"https://discordapp.com/api/guilds/{SERVER_ID}/members/{user.discord_id}/roles/{role_id}" - headers = {"Authorization": f"Bot {BOT_TOKEN}"} - requests.delete(url, headers=headers, timeout=5) - -@discord_wrap -def remove_user(user): - url=f"https://discordapp.com/api/guilds/{SERVER_ID}/members/{user.discord_id}" - headers = {"Authorization": f"Bot {BOT_TOKEN}"} - requests.delete(url, headers=headers, timeout=5) - -@discord_wrap -def set_nick(user, nick): - url=f"https://discordapp.com/api/guilds/{SERVER_ID}/members/{user.discord_id}" - headers = {"Authorization": f"Bot {BOT_TOKEN}"} - data={"nick": nick} - requests.patch(url, headers=headers, json=data, timeout=5) - -def send_discord_message(message): - headers = {"Authorization": f"Bot {BOT_TOKEN}"} - data={"content": message} - requests.post("https://discordapp.com/api/channels/924485611715452940/messages", headers=headers, data=data, timeout=5) - requests.post("https://discordapp.com/api/channels/924486091795484732/messages", headers=headers, data=data, timeout=5) - - -def send_cringetopia_message(message): - headers = {"Authorization": f"Bot {BOT_TOKEN}"} - data={"content": message} - requests.post("https://discordapp.com/api/channels/965264044531527740/messages", headers=headers, data=data, timeout=5) diff --git a/files/routes/__init__.py b/files/routes/__init__.py index 3488be0b0..c704a199b 100644 --- a/files/routes/__init__.py +++ b/files/routes/__init__.py @@ -1,6 +1,5 @@ from .admin import * from .comments import * -from .discord import * from .errors import * from .reporting import * from .front import * diff --git a/files/routes/admin.py b/files/routes/admin.py index 3bea2e27c..d5c5cac2f 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -14,7 +14,6 @@ from flask import * from files.__main__ import app, cache, limiter from .front import frontlist from files.routes.comments import comment_on_publish -from files.helpers.discord import add_role from datetime import datetime import requests from urllib.parse import quote, urlencode diff --git a/files/routes/awards.py b/files/routes/awards.py index ac148b847..de26e41dc 100644 --- a/files/routes/awards.py +++ b/files/routes/awards.py @@ -3,7 +3,6 @@ from files.helpers.wrappers import * from files.helpers.alerts import * from files.helpers.get import * from files.helpers.const import * -from files.helpers.discord import * from files.classes.award import * from .front import frontlist from flask import g, request @@ -204,7 +203,6 @@ def award_post(pid, v): if author.patron_utc: author.patron_utc += 2629746 else: author.patron_utc = int(time.time()) + 2629746 author.procoins += 2500 - if author.discord_id: add_role(author, "1") if not v.has_badge(103): badge = Badge(user_id=v.id, badge_id=103) g.db.add(badge) @@ -304,7 +302,6 @@ def award_comment(cid, v): if author.patron_utc: author.patron_utc += 2629746 else: author.patron_utc = int(time.time()) + 2629746 author.procoins += 2500 - if author.discord_id: add_role(author, "1") if not v.has_badge(103): badge = Badge(user_id=v.id, badge_id=103) g.db.add(badge) diff --git a/files/routes/discord.py b/files/routes/discord.py deleted file mode 100644 index d03497f0e..000000000 --- a/files/routes/discord.py +++ /dev/null @@ -1,138 +0,0 @@ -from files.helpers.wrappers import * -from files.helpers.security import * -from files.helpers.discord import add_role -from files.__main__ import app -import requests - -SERVER_ID = environ.get("DISCORD_SERVER_ID",'').strip() -CLIENT_ID = environ.get("DISCORD_CLIENT_ID",'').strip() -CLIENT_SECRET = environ.get("DISCORD_CLIENT_SECRET",'').strip() -BOT_TOKEN = environ.get("DISCORD_BOT_TOKEN").strip() -DISCORD_ENDPOINT = "https://discordapp.com/api/v6" -WELCOME_CHANNEL="846509313941700618" - -@app.get("/discord") -@is_not_permabanned -def join_discord(v): - - if v.shadowbanned: return {"error": "Internal server error"} - - now=int(time.time()) - - state=generate_hash(f"{now}+{v.id}+discord") - - state=f"{now}.{state}" - - return redirect(f"https://discord.com/api/oauth2/authorize?client_id={CLIENT_ID}&redirect_uri=https%3A%2F%2F{app.config['SERVER_NAME']}%2Fdiscord_redirect&response_type=code&scope=identify%20guilds.join&state={state}") - - -@app.get("/discord_redirect") -@auth_required -def discord_redirect(v): - - - now=int(time.time()) - state=request.values.get('state','').split('.') - - timestamp=state[0] - - state=state[1] - - if int(timestamp) < now-600: - abort(400) - - if not validate_hash(f"{timestamp}+{v.id}+discord", state): - abort(400) - - code = request.values.get("code","") - if not code: - abort(400) - - data={ - "client_id":CLIENT_ID, - 'client_secret': CLIENT_SECRET, - 'grant_type': 'authorization_code', - 'code': code, - 'redirect_uri': f"https://{app.config['SERVER_NAME']}/discord_redirect", - 'scope': 'identify guilds.join' - } - headers={ - 'Content-Type': 'application/x-www-form-urlencoded' - } - url="https://discord.com/api/oauth2/token" - - x=requests.post(url, headers=headers, data=data, timeout=5) - - x=x.json() - - - token=x["access_token"] - - - url="https://discord.com/api/users/@me" - headers={ - 'Authorization': f"Bearer {token}" - } - x=requests.get(url, headers=headers, timeout=5) - - x=x.json() - - - - headers={ - 'Authorization': f"Bot {BOT_TOKEN}", - 'Content-Type': "application/json" - } - - if v.discord_id and v.discord_id != x['id']: - url=f"https://discord.com/api/guilds/{SERVER_ID}/members/{v.discord_id}" - requests.delete(url, headers=headers, timeout=5) - - if g.db.query(User).filter(User.id!=v.id, User.discord_id==x["id"]).one_or_none(): - return render_template("message.html", title="Discord account already linked.", error="That Discord account is already in use by another user.", v=v) - - v.discord_id=x["id"] - g.db.add(v) - - url=f"https://discord.com/api/guilds/{SERVER_ID}/members/{x['id']}" - - name=v.username - - data={ - "access_token":token, - "nick":name, - } - - x=requests.put(url, headers=headers, json=data, timeout=5) - - if x.status_code in {201, 204}: - - if v.admin_level > 2: - add_role(v, "owner") - time.sleep(0.1) - - if v.admin_level > 1: add_role(v, "admin") - - time.sleep(0.1) - add_role(v, "linked") - - if v.patron: - time.sleep(0.1) - add_role(v, str(v.patron)) - - else: - return x.json() - - - if x.status_code==204: - - url=f"https://discord.com/api/guilds/{SERVER_ID}/members/{v.discord_id}" - data={ - "nick": name - } - - requests.patch(url, headers=headers, json=data, timeout=5) - - g.db.commit() - - return redirect(f"https://discord.com/channels/{SERVER_ID}/{WELCOME_CHANNEL}") diff --git a/files/routes/front.py b/files/routes/front.py index f606c9c01..850c9b29f 100644 --- a/files/routes/front.py +++ b/files/routes/front.py @@ -1,6 +1,5 @@ from files.helpers.wrappers import * from files.helpers.get import * -from files.helpers.discord import * from files.__main__ import app, cache, limiter from files.classes.submission import Submission @@ -214,7 +213,6 @@ def front_all(v, sub=None, subdomain=None): v.patron = 0 v.patron_utc = 0 send_repeatable_notification(v.id, "Your paypig status has expired!") - if v.discord_id: remove_role(v, "1") g.db.add(v) g.db.commit() if v.unban_utc and v.unban_utc < time.time(): diff --git a/files/routes/posts.py b/files/routes/posts.py index 464345d0a..13d5ebd1c 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -4,7 +4,6 @@ from files.helpers.wrappers import * from files.helpers.sanitize import * from files.helpers.strings import sql_ilike_clean from files.helpers.alerts import * -from files.helpers.discord import send_discord_message, send_cringetopia_message from files.helpers.const import * from files.classes import * from flask import * @@ -106,7 +105,6 @@ def publish(pid, v): cache.delete_memoized(User.userpagelisting) if v.admin_level > 0 and ("[changelog]" in post.title.lower() or "(changelog)" in post.title.lower()): - send_discord_message(post.permalink) cache.delete_memoized(changeloglist) return redirect(post.permalink) @@ -1007,7 +1005,6 @@ def submit_post(v, sub=None): cache.delete_memoized(User.userpagelisting) if v.admin_level > 0 and ("[changelog]" in post.title.lower() or "(changelog)" in post.title.lower()) and not post.private: - send_discord_message(post.permalink) cache.delete_memoized(changeloglist) if request.headers.get("Authorization"): return post.json diff --git a/files/routes/settings.py b/files/routes/settings.py index 95e2a6ec3..5efae29d7 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals from files.helpers.alerts import * from files.helpers.sanitize import * -from files.helpers.discord import remove_user, set_nick from files.helpers.const import * from files.mail import * from files.__main__ import app, cache, limiter @@ -10,7 +9,6 @@ from .front import frontlist import os from files.helpers.sanitize import filter_emojis_only from files.helpers.strings import sql_ilike_clean -from files.helpers.discord import add_role from shutil import copyfile import requests @@ -604,28 +602,11 @@ def settings_unblock_user(v): @app.get("/settings/apps") @auth_required def settings_apps(v): - return render_template("settings_apps.html", v=v) - -@app.post("/settings/remove_discord") -@limiter.limit("1/second;30/minute;200/hour;1000/day") -@auth_required -def settings_remove_discord(v): - - remove_user(v) - - v.discord_id=None - g.db.add(v) - - g.db.commit() - - return redirect("/settings/profile") - @app.get("/settings/content") @auth_required def settings_content_get(v): - return render_template("settings_filters.html", v=v) @app.post("/settings/name_change") @@ -663,11 +644,7 @@ def settings_name_change(v): v.username=new_name v.name_changed_utc=int(time.time()) - - set_nick(v, new_name) - g.db.add(v) - g.db.commit() return redirect("/settings/profile") diff --git a/migrations/versions/2022_11_21_17_52_32_b23ec080ecb7_remove_discord_user_properties.py b/migrations/versions/2022_11_21_17_52_32_b23ec080ecb7_remove_discord_user_properties.py new file mode 100644 index 000000000..51fc6eff6 --- /dev/null +++ b/migrations/versions/2022_11_21_17_52_32_b23ec080ecb7_remove_discord_user_properties.py @@ -0,0 +1,32 @@ +"""remove discord user properties + +Revision ID: b23ec080ecb7 +Revises: 0d4c7cf3da6d +Create Date: 2022-11-21 17:52:32.623111+00:00 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'b23ec080ecb7' +down_revision = '0d4c7cf3da6d' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index('discord_id_idx', table_name='users') + op.drop_constraint('one_discord_account', 'users', type_='unique') + op.drop_column('users', 'discord_id') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('users', sa.Column('discord_id', sa.VARCHAR(length=64), autoincrement=False, nullable=True)) + op.create_unique_constraint('one_discord_account', 'users', ['discord_id']) + op.create_index('discord_id_idx', 'users', ['discord_id'], unique=False) + # ### end Alembic commands ###