add web
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
"""
|
||||
All routes inside here is used to communicate internally with our Discord Bot.
|
||||
"""
|
||||
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash, make_response, jsonify, abort
|
||||
from app.extensions import csrf, redis_controller, get_remote_address
|
||||
from sqlalchemy import func
|
||||
from config import Config
|
||||
from app.models.user import User
|
||||
from app.models.asset import Asset
|
||||
from app.models.linked_discord import LinkedDiscord
|
||||
from app.models.asset_rap import AssetRap
|
||||
from app.models.placeserver_players import PlaceServerPlayer
|
||||
from app.enums.MembershipType import MembershipType
|
||||
from app.services.economy import GetAssetRap
|
||||
from app.util.membership import GetUserMembership, GiveUserMembership
|
||||
import datetime
|
||||
import time
|
||||
import logging
|
||||
|
||||
DiscordInternal = Blueprint('discord_internal', __name__, url_prefix='/internal/discord_bot')
|
||||
|
||||
@DiscordInternal.before_request
|
||||
def before_request():
|
||||
AuthorizationToken = request.headers.get("InternalAuthorizationKey", default=None, type=str)
|
||||
if AuthorizationToken != Config.DISCORD_BOT_AUTHTOKEN:
|
||||
logging.warning(f"Discord Bot Internal API: Unauthorized request from {get_remote_address()}, invalid auth token")
|
||||
return abort(404)
|
||||
UserAgent = request.headers.get("User-Agent", default=None, type=str)
|
||||
if UserAgent != "SyntaxBot/1.0":
|
||||
logging.warning(f"Discord Bot Internal API: Unauthorized request from {get_remote_address()}, invalid user agent")
|
||||
return abort(404)
|
||||
RequesterAddress = get_remote_address()
|
||||
if RequesterAddress not in Config.DISCORD_BOT_AUTHORISED_IPS:
|
||||
logging.warning(f"Discord Bot Internal API: Unauthorized request from {RequesterAddress}, not in authorised IP list")
|
||||
return abort(404)
|
||||
|
||||
def GetUserFromId( UserObj : User | int ) -> User | None:
|
||||
"""
|
||||
Returns a User object from a User ID.
|
||||
"""
|
||||
if isinstance(UserObj, User):
|
||||
return UserObj
|
||||
else:
|
||||
TargetUser : User | None = User.query.filter_by(id=UserObj).first()
|
||||
if TargetUser is None:
|
||||
raise Exception("User does not exist.")
|
||||
return TargetUser
|
||||
|
||||
def ReturnUserObject( UserObj : User ) -> dict:
|
||||
return {
|
||||
"id": UserObj.id,
|
||||
"username": UserObj.username,
|
||||
"last_online": time.mktime(UserObj.lastonline.timetuple()),
|
||||
"created_at": time.mktime(UserObj.created.timetuple()),
|
||||
"description": UserObj.description,
|
||||
"membership": GetUserMembership(UserObj, changeToString=True)
|
||||
}
|
||||
|
||||
def ReturnItemObject( AssetObj : Asset ) -> dict:
|
||||
return {
|
||||
"id": AssetObj.id,
|
||||
"name": AssetObj.name,
|
||||
"description": AssetObj.description,
|
||||
"asset_type": AssetObj.asset_type.name,
|
||||
"creator": ReturnUserObject(GetUserFromId(AssetObj.creator_id)) if AssetObj.creator_type == 0 else None,
|
||||
"creator_type": AssetObj.creator_type,
|
||||
"created_at": time.mktime(AssetObj.created_at.timetuple()),
|
||||
"updated_at": time.mktime(AssetObj.updated_at.timetuple()),
|
||||
"is_limited": AssetObj.is_limited,
|
||||
"is_limited_unique": AssetObj.is_limited_unique,
|
||||
"is_for_sale": AssetObj.is_for_sale,
|
||||
"asset_rap": GetAssetRap(AssetObj.id) if AssetObj.is_limited and not AssetObj.is_for_sale else None,
|
||||
"price_robux": AssetObj.price_robux,
|
||||
"price_tickets": AssetObj.price_tix,
|
||||
"sales": AssetObj.sale_count
|
||||
}
|
||||
|
||||
@DiscordInternal.route("/UsernameLookup", methods=['GET'])
|
||||
def UsernameLookup():
|
||||
Username = request.args.get("username", default=None, type=str)
|
||||
if Username is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Invalid username"
|
||||
})
|
||||
UserObject : User = User.query.filter(func.lower(User.username) == func.lower(Username)).first()
|
||||
if UserObject is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User not found"
|
||||
})
|
||||
if UserObject.accountstatus in [3,4]:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User not found"
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "",
|
||||
"data": ReturnUserObject(UserObject)
|
||||
})
|
||||
|
||||
@DiscordInternal.route("/UseridLookup", methods=['GET'])
|
||||
def UseridLookup():
|
||||
Userid = request.args.get("userid", default=None, type=int)
|
||||
if Userid is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Invalid userid"
|
||||
})
|
||||
UserObject : User = User.query.filter_by(id=Userid).first()
|
||||
if UserObject is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User not found"
|
||||
})
|
||||
if UserObject.accountstatus in [3,4]:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User not found"
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "",
|
||||
"data": ReturnUserObject(UserObject)
|
||||
})
|
||||
|
||||
@DiscordInternal.route("/ItemLookup", methods=['GET'])
|
||||
def ItemLookup():
|
||||
AssetId = request.args.get("itemid", default=None, type=int)
|
||||
if AssetId is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Invalid itemid"
|
||||
})
|
||||
AssetObject : Asset = Asset.query.filter_by(id=AssetId).first()
|
||||
if AssetObject is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Item not found"
|
||||
})
|
||||
if AssetObject.asset_type.value not in [2, 8, 11, 12, 17, 18, 19, 27, 28, 29, 30, 31, 32, 41, 42, 43, 44, 45, 46, 47]:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Item not found"
|
||||
})
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "",
|
||||
"data": ReturnItemObject(AssetObject)
|
||||
})
|
||||
|
||||
@DiscordInternal.route("/UserLookupByDiscordId", methods=['GET'])
|
||||
def UserLookupByDiscordId():
|
||||
DiscordId = request.args.get("discordid", default=None, type=int)
|
||||
if DiscordId is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Invalid discordid"
|
||||
})
|
||||
LinkedDiscordObject : LinkedDiscord = LinkedDiscord.query.filter_by(discord_id=DiscordId).first()
|
||||
if LinkedDiscordObject is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User does not have an account linked to their discord account"
|
||||
})
|
||||
UserObject : User = User.query.filter_by(id=LinkedDiscordObject.user_id).first()
|
||||
if UserObject is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User not found"
|
||||
})
|
||||
if UserObject.accountstatus in [3,4]:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User not found"
|
||||
})
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "",
|
||||
"data": ReturnUserObject(UserObject)
|
||||
})
|
||||
|
||||
@DiscordInternal.route("/AwardUserTurbo", methods=['POST'])
|
||||
@csrf.exempt
|
||||
def AwardUserTurbo():
|
||||
DiscordId = request.args.get("discordid", default=None, type=int)
|
||||
if DiscordId is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Invalid discordid"
|
||||
})
|
||||
LinkedDiscordObject : LinkedDiscord = LinkedDiscord.query.filter_by(discord_id=DiscordId).first()
|
||||
if LinkedDiscordObject is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User does not have an account linked to their discord account"
|
||||
})
|
||||
UserObject : User = User.query.filter_by(id=LinkedDiscordObject.user_id).first()
|
||||
if UserObject is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User not found"
|
||||
})
|
||||
if UserObject.accountstatus in [3,4]:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User is currently moderated"
|
||||
})
|
||||
UserMembershipStatus : MembershipType = GetUserMembership(UserObject)
|
||||
if UserMembershipStatus == MembershipType.TurboBuildersClub:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User already has Turbo Builders Club"
|
||||
})
|
||||
if UserMembershipStatus == MembershipType.OutrageousBuildersClub:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "User has Outrageous Builders Club"
|
||||
})
|
||||
|
||||
if redis_controller.get(f"discord_bot_award_turbo_{UserObject.id}") is not None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Discord user has recenetly been awarded Turbo Builders Club"
|
||||
})
|
||||
GiveUserMembership(UserObject, MembershipType.TurboBuildersClub, expiration=datetime.timedelta(days=14))
|
||||
redis_controller.set(f"discord_bot_award_turbo_{UserObject.id}", "1", ex=60*60*24*14)
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": ""
|
||||
})
|
||||
|
||||
@DiscordInternal.route("/Ping", methods=['GET'])
|
||||
def Ping():
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "Pong!"
|
||||
})
|
||||
|
||||
@DiscordInternal.route("/VerifyOBCUsers", methods=["POST"])
|
||||
@csrf.exempt
|
||||
def VerifyOBCUsers():
|
||||
JSONPayload = request.get_json()
|
||||
if JSONPayload is None:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Invalid JSON payload"
|
||||
})
|
||||
if "users" not in JSONPayload:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": "Invalid JSON payload"
|
||||
})
|
||||
|
||||
BadUsersIds : list[int] = []
|
||||
for UserId in JSONPayload["users"]:
|
||||
LinkedDiscordObj : LinkedDiscord = LinkedDiscord.query.filter_by(discord_id=UserId).first()
|
||||
if LinkedDiscordObj is None:
|
||||
BadUsersIds.append(UserId)
|
||||
continue
|
||||
|
||||
UserObj : User = User.query.filter_by(id=LinkedDiscordObj.user_id).first()
|
||||
if UserObj is None:
|
||||
BadUsersIds.append(UserId)
|
||||
continue
|
||||
|
||||
UserMembershipType : MembershipType = GetUserMembership(UserObj)
|
||||
if UserMembershipType != MembershipType.OutrageousBuildersClub:
|
||||
BadUsersIds.append(UserId)
|
||||
continue
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "",
|
||||
"bad_users": BadUsersIds
|
||||
})
|
||||
|
||||
@DiscordInternal.route("/GetSiteStats", methods=["GET"])
|
||||
def SiteStats():
|
||||
UsersOnline = User.query.filter(User.lastonline > (datetime.datetime.utcnow() - datetime.timedelta(minutes=1))).count()
|
||||
UsersIngame = PlaceServerPlayer.query.count()
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "",
|
||||
"data": {
|
||||
"users_online": UsersOnline,
|
||||
"users_ingame": UsersIngame
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user