2017-05-09 05:44:12 +02:00
from titanembeds . database import db , Guilds , UnauthenticatedUsers , UnauthenticatedBans , AuthenticatedUsers , KeyValueProperties , GuildMembers , Messages , get_channel_messages , list_all_guild_members
2017-03-25 08:52:56 +01:00
from titanembeds . decorators import valid_session_required , discord_users_only
2017-06-09 06:22:33 +02:00
from titanembeds . utils import check_guild_existance , guild_accepts_visitors , guild_query_unauth_users_bool , get_client_ipaddr , discord_api , rate_limiter , channel_ratelimit_key , guild_ratelimit_key
2017-04-05 06:00:44 +02:00
from titanembeds . oauth import user_has_permission , generate_avatar_url , check_user_can_administrate_guild
2017-07-22 04:06:45 +02:00
from titanembeds . database import get_administrators_list
2017-07-01 08:52:21 +02:00
from flask import Blueprint , abort , jsonify , session , request , url_for
2017-02-10 06:10:44 +01:00
from sqlalchemy import and_
import random
import requests
import json
2017-03-27 04:46:06 +02:00
import datetime
2017-04-10 01:40:11 +02:00
import re
2017-02-10 06:10:44 +01:00
from config import config
api = Blueprint ( " api " , __name__ )
def user_unauthenticated ( ) :
2017-03-15 02:18:57 +01:00
if ' unauthenticated ' in session :
return session [ ' unauthenticated ' ]
return True
2017-02-10 06:10:44 +01:00
def checkUserRevoke ( guild_id , user_key = None ) :
revoked = True #guilty until proven not revoked
if user_unauthenticated ( ) :
dbUser = UnauthenticatedUsers . query . filter ( and_ ( UnauthenticatedUsers . guild_id == guild_id , UnauthenticatedUsers . user_key == user_key ) ) . first ( )
revoked = dbUser . isRevoked ( )
else :
2017-03-26 11:23:30 +02:00
banned = checkUserBanned ( guild_id )
if banned :
return revoked
2017-05-07 03:19:20 +02:00
dbUser = GuildMembers . query . filter ( GuildMembers . guild_id == guild_id ) . filter ( GuildMembers . user_id == session [ " user_id " ] ) . first ( )
2017-05-14 23:05:51 +02:00
revoked = not dbUser or not dbUser . active
2017-02-10 06:10:44 +01:00
return revoked
def checkUserBanned ( guild_id , ip_address = None ) :
banned = True
if user_unauthenticated ( ) :
dbUser = UnauthenticatedBans . query . filter ( and_ ( UnauthenticatedBans . guild_id == guild_id , UnauthenticatedBans . ip_address == ip_address ) ) . all ( )
if not dbUser :
banned = False
else :
for usr in dbUser :
if usr . lifter_id is not None :
banned = False
else :
2017-03-26 11:13:08 +02:00
banned = False
2017-05-07 03:19:20 +02:00
dbUser = GuildMembers . query . filter ( GuildMembers . guild_id == guild_id ) . filter ( GuildMembers . user_id == session [ " user_id " ] ) . first ( )
2017-05-11 21:02:22 +02:00
if not dbUser :
banned = False
else :
banned = dbUser . banned
2017-02-10 06:10:44 +01:00
return banned
def update_user_status ( guild_id , username , user_key = None ) :
if user_unauthenticated ( ) :
ip_address = get_client_ipaddr ( )
status = {
2017-04-04 21:16:21 +02:00
' authenticated ' : False ,
' avatar ' : None ,
2017-04-05 06:00:44 +02:00
' manage_embed ' : False ,
2017-02-10 06:10:44 +01:00
' ip_address ' : ip_address ,
' username ' : username ,
' user_key ' : user_key ,
' guild_id ' : guild_id ,
2017-04-04 21:16:21 +02:00
' user_id ' : session [ ' user_id ' ] ,
2017-02-10 06:10:44 +01:00
' banned ' : checkUserBanned ( guild_id , ip_address ) ,
' revoked ' : checkUserRevoke ( guild_id , user_key ) ,
}
if status [ ' banned ' ] or status [ ' revoked ' ] :
2017-04-06 05:18:07 +02:00
session [ ' user_keys ' ] . pop ( guild_id , None )
2017-02-10 06:10:44 +01:00
return status
dbUser = UnauthenticatedUsers . query . filter ( and_ ( UnauthenticatedUsers . guild_id == guild_id , UnauthenticatedUsers . user_key == user_key ) ) . first ( )
dbUser . bumpTimestamp ( )
if dbUser . username != username or dbUser . ip_address != ip_address :
dbUser . username = username
dbUser . ip_address = ip_address
db . session . commit ( )
else :
2017-03-27 01:37:27 +02:00
status = {
2017-04-04 21:16:21 +02:00
' authenticated ' : True ,
' avatar ' : session [ " avatar " ] ,
2017-04-05 06:00:44 +02:00
' manage_embed ' : check_user_can_administrate_guild ( guild_id ) ,
2017-03-27 01:37:27 +02:00
' username ' : username ,
2017-04-12 15:15:05 +02:00
' discriminator ' : session [ ' discriminator ' ] ,
2017-03-27 01:37:27 +02:00
' guild_id ' : guild_id ,
' user_id ' : session [ ' user_id ' ] ,
' banned ' : checkUserBanned ( guild_id ) ,
' revoked ' : checkUserRevoke ( guild_id )
}
if status [ ' banned ' ] or status [ ' revoked ' ] :
return status
2017-04-04 07:53:27 +02:00
dbUser = db . session . query ( AuthenticatedUsers ) . filter ( and_ ( AuthenticatedUsers . guild_id == guild_id , AuthenticatedUsers . client_id == status [ ' user_id ' ] ) ) . first ( )
2017-03-27 01:37:27 +02:00
dbUser . bumpTimestamp ( )
2017-02-10 06:10:44 +01:00
return status
2017-03-27 04:46:06 +02:00
def check_user_in_guild ( guild_id ) :
if user_unauthenticated ( ) :
return guild_id in session [ ' user_keys ' ]
else :
2017-04-05 20:43:59 +02:00
dbUser = db . session . query ( AuthenticatedUsers ) . filter ( and_ ( AuthenticatedUsers . guild_id == guild_id , AuthenticatedUsers . client_id == session [ ' user_id ' ] ) ) . first ( )
2017-05-11 21:02:22 +02:00
return dbUser is not None and not checkUserRevoke ( guild_id )
2017-03-27 04:46:06 +02:00
2017-05-29 23:35:51 +02:00
def parse_emoji ( textToParse , guild_id ) :
2017-05-30 00:29:16 +02:00
guild_emojis = get_guild_emojis ( guild_id )
for gemoji in guild_emojis :
emoji_name = gemoji [ " name " ]
emoji_id = gemoji [ " id " ]
2017-06-10 05:43:23 +02:00
textToParse = textToParse . replace ( " : {} : " . format ( emoji_name ) , " <: {} : {} > " . format ( emoji_name , emoji_id ) )
return textToParse
2017-05-29 23:35:51 +02:00
2017-07-01 08:52:21 +02:00
def format_post_content ( guild_id , channel_id , message ) :
2017-05-09 03:39:22 +02:00
illegal_post = False
illegal_reasons = [ ]
2017-04-09 00:45:03 +02:00
message = message . replace ( " < " , " \ < " )
2017-04-10 01:40:11 +02:00
message = message . replace ( " > " , " \ > " )
2017-05-30 00:29:16 +02:00
message = parse_emoji ( message , guild_id )
2017-04-10 01:40:11 +02:00
2017-05-09 03:39:22 +02:00
dbguild = db . session . query ( Guilds ) . filter ( Guilds . guild_id == guild_id ) . first ( )
links = re . findall ( ' http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!* \ ( \ ),]|(?: % [0-9a-fA-F][0-9a-fA-F]))+ ' , message )
if not dbguild . chat_links and len ( links ) > 0 :
illegal_post = True
illegal_reasons . append ( " Links is not allowed. " )
elif dbguild . chat_links and not dbguild . bracket_links :
for link in links :
newlink = " < " + link + " > "
message = message . replace ( link , newlink )
mention_pattern = re . compile ( r ' \ [@[0-9]+ \ ] ' )
all_mentions = re . findall ( mention_pattern , message )
if dbguild . mentions_limit != - 1 and len ( all_mentions ) > dbguild . mentions_limit :
illegal_post = True
illegal_reasons . append ( " Mentions is capped at the following limit: " + str ( dbguild . mentions_limit ) )
for match in all_mentions :
2017-04-10 01:40:11 +02:00
mention = " <@ " + match [ 2 : len ( match ) - 1 ] + " > "
message = message . replace ( match , mention , 1 )
2017-07-01 08:52:21 +02:00
if not get_channel_webhook_url ( guild_id , channel_id ) :
if ( session [ ' unauthenticated ' ] ) :
message = u " **[ {} # {} ]** {} " . format ( session [ ' username ' ] , session [ ' user_id ' ] , message )
else :
message = u " **< {} # {} >** {} " . format ( session [ ' username ' ] , session [ ' discriminator ' ] , message ) # I would like to do a @ mention, but i am worried about notif spam
2017-05-09 03:39:22 +02:00
return ( message , illegal_post , illegal_reasons )
2017-04-05 08:25:07 +02:00
2017-05-10 10:56:37 +02:00
def format_everyone_mention ( channel , content ) :
2017-05-10 11:01:36 +02:00
if not channel [ " mention_everyone " ] :
if " @everyone " in content :
content = content . replace ( " @everyone " , u " @ \u200B everyone " )
if " @here " in content :
content = content . replace ( " @here " , u " @ \u200B here " )
2017-05-10 10:56:37 +02:00
return content
2017-05-07 03:19:20 +02:00
def get_member_roles ( guild_id , user_id ) :
q = db . session . query ( GuildMembers ) . filter ( GuildMembers . guild_id == guild_id ) . filter ( GuildMembers . user_id == user_id ) . first ( )
return json . loads ( q . roles )
def get_dbguild_channels ( guild_id ) :
q = db . session . query ( Guilds ) . filter ( Guilds . guild_id == guild_id ) . first ( )
return json . loads ( q . channels )
2017-06-09 06:22:33 +02:00
def get_guild_channels ( guild_id , force_everyone = False ) :
if user_unauthenticated ( ) or force_everyone :
2017-04-08 09:34:17 +02:00
member_roles = [ guild_id ] #equivilant to @everyone role
2017-03-27 04:46:06 +02:00
else :
2017-05-07 03:19:20 +02:00
member_roles = get_member_roles ( guild_id , session [ ' user_id ' ] )
2017-04-08 20:36:18 +02:00
if guild_id not in member_roles :
member_roles . append ( guild_id )
2017-05-07 03:19:20 +02:00
dbguild = db . session . query ( Guilds ) . filter ( Guilds . guild_id == guild_id ) . first ( )
guild_channels = json . loads ( dbguild . channels )
guild_roles = json . loads ( dbguild . roles )
2017-05-09 10:45:27 +02:00
guild_owner = str ( dbguild . owner_id )
2017-03-27 04:46:06 +02:00
result_channels = [ ]
for channel in guild_channels :
2017-05-07 03:19:20 +02:00
if channel [ ' type ' ] == " text " :
2017-05-10 10:56:37 +02:00
result = { " channel " : channel , " read " : False , " write " : False , " mention_everyone " : False }
2017-06-09 06:22:33 +02:00
if guild_owner == session . get ( " user_id " ) :
2017-04-08 09:34:17 +02:00
result [ " read " ] = True
result [ " write " ] = True
2017-05-10 10:56:37 +02:00
result [ " mention_everyone " ] = True
2017-04-08 09:34:17 +02:00
result_channels . append ( result )
2017-03-27 04:46:06 +02:00
continue
2017-04-08 09:34:17 +02:00
channel_perm = 0
# @everyone
for role in guild_roles :
if role [ " id " ] == guild_id :
channel_perm | = role [ " permissions " ]
continue
# User Guild Roles
for m_role in member_roles :
for g_role in guild_roles :
if g_role [ " id " ] == m_role :
channel_perm | = g_role [ " permissions " ]
continue
# If has server administrator permission
if user_has_permission ( channel_perm , 3 ) :
result [ " read " ] = True
result [ " write " ] = True
2017-05-10 10:56:37 +02:00
result [ " mention_everyone " ] = True
2017-04-08 09:34:17 +02:00
result_channels . append ( result )
continue
denies = 0
allows = 0
# channel specific
for overwrite in channel [ " permission_overwrites " ] :
if overwrite [ " type " ] == " role " and overwrite [ " id " ] in member_roles :
denies | = overwrite [ " deny " ]
allows | = overwrite [ " allow " ]
channel_perm = ( channel_perm & ~ denies ) | allows
# member specific
for overwrite in channel [ " permission_overwrites " ] :
2017-06-09 06:22:33 +02:00
if overwrite [ " type " ] == " member " and overwrite [ " id " ] == session . get ( " user_id " ) :
2017-04-08 09:34:17 +02:00
channel_perm = ( channel_perm & ~ overwrite [ ' deny ' ] ) | overwrite [ ' allow ' ]
break
result [ " read " ] = user_has_permission ( channel_perm , 10 )
result [ " write " ] = user_has_permission ( channel_perm , 11 )
2017-05-10 10:56:37 +02:00
result [ " mention_everyone " ] = user_has_permission ( channel_perm , 17 )
2017-04-08 09:34:17 +02:00
# If default channel, you can read
if channel [ " id " ] == guild_id :
result [ " read " ] = True
# If you cant read channel, you cant write in it
if not user_has_permission ( channel_perm , 10 ) :
result [ " read " ] = False
result [ " write " ] = False
2017-05-10 10:56:37 +02:00
result [ " mention_everyone " ] = False
2017-04-08 09:34:17 +02:00
2017-04-14 08:12:42 +02:00
result_channels . append ( result )
2017-04-09 21:26:09 +02:00
return sorted ( result_channels , key = lambda k : k [ ' channel ' ] [ ' position ' ] )
2017-03-27 04:46:06 +02:00
2017-06-09 06:22:33 +02:00
def filter_guild_channel ( guild_id , channel_id , force_everyone = False ) :
channels = get_guild_channels ( guild_id , force_everyone )
2017-04-08 09:34:17 +02:00
for chan in channels :
2017-05-07 03:19:20 +02:00
if chan [ " channel " ] [ " id " ] == channel_id :
2017-04-08 09:34:17 +02:00
return chan
return None
2017-05-24 05:41:12 +02:00
def get_online_discord_users ( guild_id , embed ) :
2017-05-07 03:19:20 +02:00
apimembers = list_all_guild_members ( guild_id )
2017-04-14 08:10:13 +02:00
apimembers_filtered = { }
for member in apimembers :
apimembers_filtered [ member [ " user " ] [ " id " ] ] = member
2017-05-07 03:19:20 +02:00
guild_roles = json . loads ( db . session . query ( Guilds ) . filter ( Guilds . guild_id == guild_id ) . first ( ) . roles )
2017-04-14 08:10:13 +02:00
guildroles_filtered = { }
for role in guild_roles :
guildroles_filtered [ role [ " id " ] ] = role
for member in embed [ ' members ' ] :
apimem = apimembers_filtered . get ( member [ " id " ] )
member [ " hoist-role " ] = None
member [ " color " ] = None
if apimem :
for roleid in reversed ( apimem [ " roles " ] ) :
2017-07-28 07:30:59 +02:00
role = guildroles_filtered . get ( roleid )
if not role :
continue
2017-04-14 08:10:13 +02:00
if role [ " color " ] != 0 :
member [ " color " ] = ' {0:02x} ' . format ( role [ " color " ] ) #int to hex
if role [ " hoist " ] :
member [ " hoist-role " ] = { }
member [ " hoist-role " ] [ " name " ] = role [ " name " ]
member [ " hoist-role " ] [ " id " ] = role [ " id " ]
member [ " hoist-role " ] [ " position " ] = role [ " position " ]
2017-03-27 04:46:06 +02:00
return embed [ ' members ' ]
def get_online_embed_users ( guild_id ) :
2017-04-09 21:26:09 +02:00
time_past = ( datetime . datetime . now ( ) - datetime . timedelta ( seconds = 60 ) ) . strftime ( ' % Y- % m- %d % H: % M: % S ' )
2017-04-08 12:35:30 +02:00
unauths = db . session . query ( UnauthenticatedUsers ) . filter ( UnauthenticatedUsers . last_timestamp > time_past , UnauthenticatedUsers . revoked == False , UnauthenticatedUsers . guild_id == guild_id ) . all ( )
auths = db . session . query ( AuthenticatedUsers ) . filter ( AuthenticatedUsers . last_timestamp > time_past , AuthenticatedUsers . guild_id == guild_id ) . all ( )
2017-03-27 04:46:06 +02:00
users = { ' unauthenticated ' : [ ] , ' authenticated ' : [ ] }
for user in unauths :
meta = {
' username ' : user . username ,
' discriminator ' : user . discriminator ,
}
users [ ' unauthenticated ' ] . append ( meta )
for user in auths :
client_id = user . client_id
2017-05-07 03:19:20 +02:00
usrdb = db . session . query ( GuildMembers ) . filter ( GuildMembers . guild_id == guild_id ) . filter ( GuildMembers . user_id == client_id ) . first ( )
2017-03-27 04:46:06 +02:00
meta = {
2017-05-07 03:19:20 +02:00
' id ' : usrdb . user_id ,
' username ' : usrdb . username ,
' discriminator ' : usrdb . discriminator ,
' avatar_url ' : generate_avatar_url ( usrdb . user_id , usrdb . avatar ) ,
2017-03-27 04:46:06 +02:00
}
users [ ' authenticated ' ] . append ( meta )
return users
2017-05-30 00:29:16 +02:00
def get_guild_emojis ( guild_id ) :
dbguild = db . session . query ( Guilds ) . filter ( Guilds . guild_id == guild_id ) . first ( )
return json . loads ( dbguild . emojis )
2017-07-01 08:52:21 +02:00
# Returns webhook url if exists and can post w/webhooks, otherwise None
def get_channel_webhook_url ( guild_id , channel_id ) :
dbguild = db . session . query ( Guilds ) . filter ( Guilds . guild_id == guild_id ) . first ( )
guild_webhooks = json . loads ( dbguild . webhooks )
for webhook in guild_webhooks :
if channel_id == webhook [ " channel_id " ] and ( webhook [ " name " ] . lower ( ) . startswith ( " titan " ) or webhook [ " name " ] . lower ( ) . startswith ( " [titan] " ) ) :
return {
" id " : webhook [ " id " ] ,
" token " : webhook [ " token " ]
}
return None
2017-02-10 06:10:44 +01:00
@api.route ( " /fetch " , methods = [ " GET " ] )
2017-03-15 02:18:57 +01:00
@valid_session_required ( api = True )
2017-04-11 02:34:21 +02:00
@rate_limiter.limit ( " 2 per 2 second " , key_func = channel_ratelimit_key )
2017-02-10 06:10:44 +01:00
def fetch ( ) :
2017-04-05 07:10:20 +02:00
guild_id = request . args . get ( " guild_id " )
2017-02-10 06:10:44 +01:00
channel_id = request . args . get ( ' channel_id ' )
after_snowflake = request . args . get ( ' after ' , None , type = int )
if user_unauthenticated ( ) :
2017-04-05 08:29:57 +02:00
key = session [ ' user_keys ' ] [ guild_id ]
2017-02-10 06:10:44 +01:00
else :
key = None
2017-04-05 07:10:20 +02:00
status = update_user_status ( guild_id , session [ ' username ' ] , key )
2017-04-08 09:34:17 +02:00
messages = { }
2017-02-10 06:10:44 +01:00
if status [ ' banned ' ] or status [ ' revoked ' ] :
2017-04-05 07:10:20 +02:00
status_code = 403
2017-05-27 18:39:38 +02:00
if user_unauthenticated ( ) :
session [ ' user_keys ' ] . pop ( guild_id , None )
2017-02-10 06:10:44 +01:00
else :
2017-04-08 09:34:17 +02:00
chan = filter_guild_channel ( guild_id , channel_id )
if not chan . get ( " read " ) :
status_code = 401
else :
2017-05-07 02:19:12 +02:00
messages = get_channel_messages ( channel_id , after_snowflake )
2017-05-14 11:26:29 +02:00
status_code = 200
2017-05-07 02:19:12 +02:00
response = jsonify ( messages = messages , status = status )
2017-05-14 11:26:29 +02:00
response . status_code = status_code
2017-03-27 01:37:27 +02:00
return response
2017-02-10 06:10:44 +01:00
2017-06-09 06:22:33 +02:00
@api.route ( " /fetch_visitor " , methods = [ " GET " ] )
@rate_limiter.limit ( " 2 per 2 second " , key_func = channel_ratelimit_key )
def fetch_visitor ( ) :
guild_id = request . args . get ( " guild_id " )
channel_id = request . args . get ( ' channel_id ' )
after_snowflake = request . args . get ( ' after ' , None , type = int )
if not guild_accepts_visitors ( guild_id ) :
abort ( 403 )
messages = { }
chan = filter_guild_channel ( guild_id , channel_id , True )
if not chan . get ( " read " ) :
status_code = 401
else :
messages = get_channel_messages ( channel_id , after_snowflake )
status_code = 200
response = jsonify ( messages = messages )
response . status_code = status_code
return response
2017-02-10 06:10:44 +01:00
@api.route ( " /post " , methods = [ " POST " ] )
2017-03-15 02:18:57 +01:00
@valid_session_required ( api = True )
2017-04-06 04:29:42 +02:00
@rate_limiter.limit ( " 1 per 10 second " , key_func = channel_ratelimit_key )
2017-02-10 06:10:44 +01:00
def post ( ) :
2017-04-05 08:25:07 +02:00
guild_id = request . form . get ( " guild_id " )
2017-02-10 06:10:44 +01:00
channel_id = request . form . get ( ' channel_id ' )
content = request . form . get ( ' content ' )
2017-07-01 08:52:21 +02:00
content , illegal_post , illegal_reasons = format_post_content ( guild_id , channel_id , content )
2017-02-10 06:10:44 +01:00
if user_unauthenticated ( ) :
2017-04-06 06:32:38 +02:00
key = session [ ' user_keys ' ] [ guild_id ]
2017-02-10 06:10:44 +01:00
else :
key = None
2017-04-05 07:10:20 +02:00
status = update_user_status ( guild_id , session [ ' username ' ] , key )
2017-04-08 09:34:17 +02:00
message = { }
2017-05-09 03:39:22 +02:00
if illegal_post :
status_code = 417
2017-02-10 06:10:44 +01:00
if status [ ' banned ' ] or status [ ' revoked ' ] :
2017-03-27 01:37:27 +02:00
status_code = 401
else :
2017-04-08 09:34:17 +02:00
chan = filter_guild_channel ( guild_id , channel_id )
if not chan . get ( " write " ) :
status_code = 401
2017-05-09 03:39:22 +02:00
elif not illegal_post :
2017-07-06 19:18:15 +02:00
userid = session [ " user_id " ]
2017-05-10 10:56:37 +02:00
content = format_everyone_mention ( chan , content )
2017-07-01 08:52:21 +02:00
webhook = get_channel_webhook_url ( guild_id , channel_id )
2017-07-22 04:06:45 +02:00
if userid in get_administrators_list ( ) :
2017-07-06 19:18:15 +02:00
oldcontent = content
content = " (Titan Dev) " + oldcontent
2017-07-01 08:52:21 +02:00
if webhook :
if ( session [ ' unauthenticated ' ] ) :
username = session [ " username " ] + " # " + str ( session [ " user_id " ] )
avatar = url_for ( ' static ' , filename = ' img/titanembeds_round.png ' , _external = True )
else :
2017-07-06 19:18:15 +02:00
username = session [ " username " ]
if content . startswith ( " (Titan Dev) " ) :
content = content [ 12 : ]
username = " (Titan Dev) " + username
else :
username = username + " # " + str ( session [ ' discriminator ' ] )
2017-07-01 08:52:21 +02:00
avatar = session [ ' avatar ' ]
message = discord_api . execute_webhook ( webhook . get ( " id " ) , webhook . get ( " token " ) , username , avatar , content )
else :
message = discord_api . create_message ( channel_id , content )
2017-04-08 09:34:17 +02:00
status_code = message [ ' code ' ]
2017-05-09 03:39:22 +02:00
response = jsonify ( message = message . get ( ' content ' , message ) , status = status , illegal_reasons = illegal_reasons )
2017-03-27 01:37:27 +02:00
response . status_code = status_code
return response
2017-02-10 06:10:44 +01:00
@api.route ( " /create_unauthenticated_user " , methods = [ " POST " ] )
2017-04-06 04:29:42 +02:00
@rate_limiter.limit ( " 1 per 15 minute " , key_func = guild_ratelimit_key )
2017-02-10 06:10:44 +01:00
def create_unauthenticated_user ( ) :
session [ ' unauthenticated ' ] = True
username = request . form [ ' username ' ]
guild_id = request . form [ ' guild_id ' ]
ip_address = get_client_ipaddr ( )
2017-04-08 23:53:58 +02:00
username = username . strip ( )
2017-04-04 07:57:51 +02:00
if len ( username ) < 2 or len ( username ) > 32 :
abort ( 406 )
2017-04-14 08:12:42 +02:00
if not all ( x . isalnum ( ) or x . isspace ( ) or " - " == x or " _ " == x for x in username ) :
2017-04-08 23:53:58 +02:00
abort ( 406 )
2017-03-15 02:49:59 +01:00
if not check_guild_existance ( guild_id ) :
2017-03-27 04:46:06 +02:00
abort ( 404 )
2017-03-27 17:58:47 +02:00
if not guild_query_unauth_users_bool ( guild_id ) :
abort ( 401 )
2017-02-10 06:10:44 +01:00
if not checkUserBanned ( guild_id , ip_address ) :
session [ ' username ' ] = username
2017-04-15 09:54:57 +02:00
if ' user_id ' not in session or len ( str ( session [ " user_id " ] ) ) > 4 :
2017-02-10 06:10:44 +01:00
session [ ' user_id ' ] = random . randint ( 0 , 9999 )
user = UnauthenticatedUsers ( guild_id , username , session [ ' user_id ' ] , ip_address )
db . session . add ( user )
db . session . commit ( )
key = user . user_key
if ' user_keys ' not in session :
session [ ' user_keys ' ] = { guild_id : key }
else :
session [ ' user_keys ' ] [ guild_id ] = key
status = update_user_status ( guild_id , username , key )
return jsonify ( status = status )
else :
status = { ' banned ' : True }
2017-03-27 18:12:54 +02:00
response = jsonify ( status = status )
response . status_code = 403
return response
2017-03-15 02:18:57 +01:00
2017-06-09 06:22:33 +02:00
def process_query_guild ( guild_id , visitor = False ) :
widget = discord_api . get_widget ( guild_id )
channels = get_guild_channels ( guild_id , visitor )
discordmembers = get_online_discord_users ( guild_id , widget )
embedmembers = get_online_embed_users ( guild_id )
emojis = get_guild_emojis ( guild_id )
if visitor :
for channel in channels :
channel [ " write " ] = False
return jsonify ( channels = channels , discordmembers = discordmembers , embedmembers = embedmembers , emojis = emojis , instant_invite = widget . get ( " instant_invite " ) )
2017-03-15 02:18:57 +01:00
@api.route ( " /query_guild " , methods = [ " GET " ] )
@valid_session_required ( api = True )
def query_guild ( ) :
guild_id = request . args . get ( ' guild_id ' )
2017-03-27 04:46:06 +02:00
if check_guild_existance ( guild_id ) :
if check_user_in_guild ( guild_id ) :
2017-06-09 06:22:33 +02:00
return process_query_guild ( guild_id )
2017-03-27 17:58:47 +02:00
abort ( 403 )
abort ( 404 )
2017-03-25 08:52:56 +01:00
2017-06-09 06:22:33 +02:00
@api.route ( " /query_guild_visitor " , methods = [ " GET " ] )
def query_guild_visitor ( ) :
guild_id = request . args . get ( ' guild_id ' )
if check_guild_existance ( guild_id ) :
if not guild_accepts_visitors ( guild_id ) :
abort ( 403 )
return process_query_guild ( guild_id , True )
abort ( 404 )
2017-03-27 04:46:06 +02:00
@api.route ( " /create_authenticated_user " , methods = [ " POST " ] )
2017-03-25 08:52:56 +01:00
@discord_users_only ( api = True )
2017-03-27 04:46:06 +02:00
def create_authenticated_user ( ) :
guild_id = request . form . get ( ' guild_id ' )
if session [ ' unauthenticated ' ] :
response = jsonify ( error = True )
response . status_code = 401
return response
2017-03-25 08:52:56 +01:00
else :
2017-03-27 04:46:06 +02:00
if not check_guild_existance ( guild_id ) :
abort ( 404 )
if not checkUserBanned ( guild_id ) :
2017-05-13 23:27:47 +02:00
if not check_user_in_guild ( guild_id ) :
discord_api . add_guild_member ( guild_id , session [ ' user_id ' ] , session [ ' user_keys ' ] [ ' access_token ' ] )
2017-04-04 07:53:27 +02:00
db_user = db . session . query ( AuthenticatedUsers ) . filter ( and_ ( AuthenticatedUsers . guild_id == guild_id , AuthenticatedUsers . client_id == session [ ' user_id ' ] ) ) . first ( )
2017-03-27 04:46:06 +02:00
if not db_user :
db_user = AuthenticatedUsers ( guild_id , session [ ' user_id ' ] )
db . session . add ( db_user )
db . session . commit ( )
status = update_user_status ( guild_id , session [ ' username ' ] )
2017-04-04 07:53:27 +02:00
return jsonify ( status = status )
2017-03-27 04:46:06 +02:00
else :
status = { ' banned ' : True }
response = jsonify ( status = status )
response . status_code = 403
return response
2017-04-27 00:59:10 +02:00
2017-05-09 05:44:12 +02:00
@api.route ( " /cleanup-db " , methods = [ " DELETE " ] )
2017-04-27 00:59:10 +02:00
def cleanup_keyval_db ( ) :
if request . form . get ( " secret " , None ) == config [ " app-secret " ] :
2017-06-24 21:50:55 +02:00
db . session . query ( KeyValueProperties ) . filter ( KeyValueProperties . expiration < datetime . datetime . now ( ) ) . delete ( )
db . session . commit ( )
2017-05-09 05:44:12 +02:00
guilds = Guilds . query . all ( )
for guild in guilds :
2017-06-24 21:50:55 +02:00
try :
channelsjson = json . loads ( guild . channels )
except :
continue
2017-05-09 05:44:12 +02:00
for channel in channelsjson :
chanid = channel [ " id " ]
2017-06-24 22:03:54 +02:00
msgs = db . session . query ( Messages ) . filter ( Messages . channel_id == chanid ) . order_by ( Messages . timestamp . desc ( ) ) . offset ( 50 ) . all ( )
for msg in msgs :
db . session . delete ( msg )
2017-06-24 21:50:55 +02:00
db . session . commit ( )
2017-04-27 00:59:10 +02:00
return ( ' ' , 204 )
2017-05-07 02:19:12 +02:00
abort ( 401 )