mirror of
https://github.com/TitanEmbeds/Titan.git
synced 2024-11-15 02:21:21 +01:00
Basic websockets authentication handling
This commit is contained in:
parent
72649f069e
commit
4ed2d14bc3
@ -23,4 +23,13 @@ class SocketIOInterface:
|
|||||||
"mentions": get_message_mentions(message.mentions),
|
"mentions": get_message_mentions(message.mentions),
|
||||||
"attachments": message.attachments,
|
"attachments": message.attachments,
|
||||||
}
|
}
|
||||||
await self.io.emit('MESSAGE_CREATE', data=msg, room=message.server.id, namespace='/gateway')
|
nickname = None
|
||||||
|
if hasattr(message.author, 'nick') and message.author.nick:
|
||||||
|
nickname = message.author.nick
|
||||||
|
msg["author"]["nickname"] = nickname
|
||||||
|
for mention in msg["mentions"]:
|
||||||
|
mention["nickname"] = None
|
||||||
|
member = message.server.get_member(mention["id"])
|
||||||
|
if member:
|
||||||
|
mention["nickname"] = member.nick
|
||||||
|
await self.io.emit('MESSAGE_CREATE', data=msg, room=str("CHANNEL_"+message.channel.id), namespace='/gateway')
|
@ -2,11 +2,10 @@ from titanembeds.database import db, Guilds, UnauthenticatedUsers, Unauthenticat
|
|||||||
from titanembeds.decorators import valid_session_required, discord_users_only
|
from titanembeds.decorators import valid_session_required, discord_users_only
|
||||||
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
|
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
|
||||||
from titanembeds.oauth import user_has_permission, generate_avatar_url, check_user_can_administrate_guild
|
from titanembeds.oauth import user_has_permission, generate_avatar_url, check_user_can_administrate_guild
|
||||||
from titanembeds.database import get_administrators_list
|
from titanembeds.userbookkeeping import user_unauthenticated, checkUserRevoke, checkUserBanned, update_user_status, check_user_in_guild, get_guild_channels
|
||||||
from flask import Blueprint, abort, jsonify, session, request, url_for
|
from flask import Blueprint, abort, jsonify, session, request, url_for
|
||||||
from sqlalchemy import and_
|
from sqlalchemy import and_
|
||||||
import random
|
import random
|
||||||
import requests
|
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
@ -14,97 +13,6 @@ from config import config
|
|||||||
|
|
||||||
api = Blueprint("api", __name__)
|
api = Blueprint("api", __name__)
|
||||||
|
|
||||||
def user_unauthenticated():
|
|
||||||
if 'unauthenticated' in session:
|
|
||||||
return session['unauthenticated']
|
|
||||||
return True
|
|
||||||
|
|
||||||
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:
|
|
||||||
banned = checkUserBanned(guild_id)
|
|
||||||
if banned:
|
|
||||||
return revoked
|
|
||||||
dbUser = GuildMembers.query.filter(GuildMembers.guild_id == guild_id).filter(GuildMembers.user_id == session["user_id"]).first()
|
|
||||||
revoked = not dbUser or not dbUser.active
|
|
||||||
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:
|
|
||||||
banned = False
|
|
||||||
dbUser = GuildMembers.query.filter(GuildMembers.guild_id == guild_id).filter(GuildMembers.user_id == session["user_id"]).first()
|
|
||||||
if not dbUser:
|
|
||||||
banned = False
|
|
||||||
else:
|
|
||||||
banned = dbUser.banned
|
|
||||||
return banned
|
|
||||||
|
|
||||||
def update_user_status(guild_id, username, user_key=None):
|
|
||||||
if user_unauthenticated():
|
|
||||||
ip_address = get_client_ipaddr()
|
|
||||||
status = {
|
|
||||||
'authenticated': False,
|
|
||||||
'avatar': None,
|
|
||||||
'manage_embed': False,
|
|
||||||
'ip_address': ip_address,
|
|
||||||
'username': username,
|
|
||||||
'nickname': None,
|
|
||||||
'user_key': user_key,
|
|
||||||
'guild_id': guild_id,
|
|
||||||
'user_id': session['user_id'],
|
|
||||||
'banned': checkUserBanned(guild_id, ip_address),
|
|
||||||
'revoked': checkUserRevoke(guild_id, user_key),
|
|
||||||
}
|
|
||||||
if status['banned'] or status['revoked']:
|
|
||||||
session['user_keys'].pop(guild_id, None)
|
|
||||||
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:
|
|
||||||
status = {
|
|
||||||
'authenticated': True,
|
|
||||||
'avatar': session["avatar"],
|
|
||||||
'manage_embed': check_user_can_administrate_guild(guild_id),
|
|
||||||
'username': username,
|
|
||||||
'nickname': None,
|
|
||||||
'discriminator': session['discriminator'],
|
|
||||||
'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
|
|
||||||
dbMember = get_guild_member(guild_id, status["user_id"])
|
|
||||||
if dbMember:
|
|
||||||
status["nickname"] = dbMember.nickname
|
|
||||||
dbUser = db.session.query(AuthenticatedUsers).filter(and_(AuthenticatedUsers.guild_id == guild_id, AuthenticatedUsers.client_id == status['user_id'])).first()
|
|
||||||
dbUser.bumpTimestamp()
|
|
||||||
return status
|
|
||||||
|
|
||||||
def check_user_in_guild(guild_id):
|
|
||||||
if user_unauthenticated():
|
|
||||||
return guild_id in session['user_keys']
|
|
||||||
else:
|
|
||||||
dbUser = db.session.query(AuthenticatedUsers).filter(and_(AuthenticatedUsers.guild_id == guild_id, AuthenticatedUsers.client_id == session['user_id'])).first()
|
|
||||||
return dbUser is not None and not checkUserRevoke(guild_id)
|
|
||||||
|
|
||||||
def parse_emoji(textToParse, guild_id):
|
def parse_emoji(textToParse, guild_id):
|
||||||
guild_emojis = get_guild_emojis(guild_id)
|
guild_emojis = get_guild_emojis(guild_id)
|
||||||
for gemoji in guild_emojis:
|
for gemoji in guild_emojis:
|
||||||
@ -160,92 +68,6 @@ def format_everyone_mention(channel, content):
|
|||||||
content = content.replace("@here", u"@\u200Bhere")
|
content = content.replace("@here", u"@\u200Bhere")
|
||||||
return content
|
return content
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
def get_guild_channels(guild_id, force_everyone=False):
|
|
||||||
if user_unauthenticated() or force_everyone:
|
|
||||||
member_roles = [guild_id] #equivilant to @everyone role
|
|
||||||
else:
|
|
||||||
member_roles = get_member_roles(guild_id, session['user_id'])
|
|
||||||
if guild_id not in member_roles:
|
|
||||||
member_roles.append(guild_id)
|
|
||||||
dbguild = db.session.query(Guilds).filter(Guilds.guild_id == guild_id).first()
|
|
||||||
guild_channels = json.loads(dbguild.channels)
|
|
||||||
guild_roles = json.loads(dbguild.roles)
|
|
||||||
guild_owner = str(dbguild.owner_id)
|
|
||||||
result_channels = []
|
|
||||||
for channel in guild_channels:
|
|
||||||
if channel['type'] == "text":
|
|
||||||
result = {"channel": channel, "read": False, "write": False, "mention_everyone": False}
|
|
||||||
if guild_owner == session.get("user_id"):
|
|
||||||
result["read"] = True
|
|
||||||
result["write"] = True
|
|
||||||
result["mention_everyone"] = True
|
|
||||||
result_channels.append(result)
|
|
||||||
continue
|
|
||||||
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
|
|
||||||
result["mention_everyone"] = True
|
|
||||||
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"]:
|
|
||||||
if overwrite["type"] == "member" and overwrite["id"] == session.get("user_id"):
|
|
||||||
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)
|
|
||||||
result["mention_everyone"] = user_has_permission(channel_perm, 17)
|
|
||||||
|
|
||||||
# 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
|
|
||||||
result["mention_everyone"] = False
|
|
||||||
|
|
||||||
result_channels.append(result)
|
|
||||||
return sorted(result_channels, key=lambda k: k['channel']['position'])
|
|
||||||
|
|
||||||
def filter_guild_channel(guild_id, channel_id, force_everyone=False):
|
def filter_guild_channel(guild_id, channel_id, force_everyone=False):
|
||||||
channels = get_guild_channels(guild_id, force_everyone)
|
channels = get_guild_channels(guild_id, force_everyone)
|
||||||
for chan in channels:
|
for chan in channels:
|
||||||
@ -341,6 +163,7 @@ def fetch():
|
|||||||
status_code = 403
|
status_code = 403
|
||||||
if user_unauthenticated():
|
if user_unauthenticated():
|
||||||
session['user_keys'].pop(guild_id, None)
|
session['user_keys'].pop(guild_id, None)
|
||||||
|
session.modified = True
|
||||||
else:
|
else:
|
||||||
chan = filter_guild_channel(guild_id, channel_id)
|
chan = filter_guild_channel(guild_id, channel_id)
|
||||||
if not chan:
|
if not chan:
|
||||||
|
@ -1,22 +1,43 @@
|
|||||||
from titanembeds.utils import socketio
|
from titanembeds.utils import socketio, guild_accepts_visitors, get_client_ipaddr
|
||||||
|
from titanembeds.userbookkeeping import check_user_in_guild, get_guild_channels, update_user_status
|
||||||
from flask_socketio import Namespace, emit, disconnect, join_room
|
from flask_socketio import Namespace, emit, disconnect, join_room
|
||||||
import functools
|
import functools
|
||||||
from flask import request, session
|
from flask import request, session
|
||||||
|
import time
|
||||||
def authenticated_only(f):
|
|
||||||
@functools.wraps(f)
|
|
||||||
def wrapped(*args, **kwargs):
|
|
||||||
if False:
|
|
||||||
pass
|
|
||||||
#disconnect()
|
|
||||||
else:
|
|
||||||
return f(*args, **kwargs)
|
|
||||||
return wrapped
|
|
||||||
|
|
||||||
class Gateway(Namespace):
|
class Gateway(Namespace):
|
||||||
def on_connect(self):
|
def on_connect(self):
|
||||||
emit('hello')
|
emit('hello')
|
||||||
|
|
||||||
def on_identify(self, data):
|
def on_identify(self, data):
|
||||||
room = data["guild_id"]
|
guild_id = data["guild_id"]
|
||||||
join_room(room)
|
if not guild_accepts_visitors(guild_id) and not check_user_in_guild(guild_id):
|
||||||
|
disconnect()
|
||||||
|
return
|
||||||
|
channels = []
|
||||||
|
if guild_accepts_visitors(guild_id) and not check_user_in_guild(guild_id):
|
||||||
|
channels = get_guild_channels(guild_id, force_everyone=True)
|
||||||
|
else:
|
||||||
|
channels = get_guild_channels(guild_id)
|
||||||
|
join_room("GUILD_"+guild_id)
|
||||||
|
for chan in channels:
|
||||||
|
if chan["read"]:
|
||||||
|
join_room("CHANNEL_"+chan["channel"]["id"])
|
||||||
|
if session.get("unauthenticated", True) and guild_id in session.get("user_keys", {}):
|
||||||
|
join_room("IP_"+get_client_ipaddr())
|
||||||
|
elif not session.get("unauthenticated", True):
|
||||||
|
join_room("USER_"+session["user_id"])
|
||||||
|
emit("identified")
|
||||||
|
|
||||||
|
def on_heartbeat(self, data):
|
||||||
|
guild_id = data["guild_id"]
|
||||||
|
visitor_mode = data["visitor_mode"]
|
||||||
|
if not visitor_mode:
|
||||||
|
status = update_user_status(guild_id, session["username"], session["user_keys"][guild_id])
|
||||||
|
if status["revoked"] or status["banned"]:
|
||||||
|
emit("revoke")
|
||||||
|
time.sleep(1000)
|
||||||
|
disconnect()
|
||||||
|
else:
|
||||||
|
if not guild_accepts_visitors(guild_id):
|
||||||
|
disconnect()
|
@ -17,17 +17,13 @@
|
|||||||
var has_already_been_focused = false; // keep track of if the embed has initially been focused.
|
var has_already_been_focused = false; // keep track of if the embed has initially been focused.
|
||||||
var has_already_been_initially_resized = false; // keep track if the embed initially been resized
|
var has_already_been_initially_resized = false; // keep track if the embed initially been resized
|
||||||
var logintimer; // timer to keep track of user inactivity after hitting login
|
var logintimer; // timer to keep track of user inactivity after hitting login
|
||||||
var fetchtimeout; // fetch routine timer
|
|
||||||
var currently_fetching; // fetch lock- if true, do not fetch
|
|
||||||
var last_message_id; // last message tracked
|
var last_message_id; // last message tracked
|
||||||
var selected_channel = null; // user selected channel
|
var selected_channel = null; // user selected channel
|
||||||
var guild_channels = {}; // all server channels used to highlight channels in messages
|
var guild_channels = {}; // all server channels used to highlight channels in messages
|
||||||
var emoji_store = {}; // all server emojis
|
var emoji_store = {}; // all server emojis
|
||||||
var times_fetched = 0; // kept track of how many times that it has fetched
|
|
||||||
var fetch_error_count = 0; // Number of errors fetch has encountered
|
|
||||||
var priority_query_guild = false; // So you have selected a channel? Let's populate it.
|
|
||||||
var current_username_discrim; // Current username/discrim pair, eg EndenDraogn#4151
|
var current_username_discrim; // Current username/discrim pair, eg EndenDraogn#4151
|
||||||
var visitor_mode = false; // Keep track of if using the visitor mode or authenticate mode
|
var visitor_mode = false; // Keep track of if using the visitor mode or authenticate mode
|
||||||
|
var socket = null; // Socket.io object
|
||||||
|
|
||||||
function element_in_view(element, fullyInView) {
|
function element_in_view(element, fullyInView) {
|
||||||
var pageTop = $(window).scrollTop();
|
var pageTop = $(window).scrollTop();
|
||||||
@ -249,6 +245,8 @@
|
|||||||
} else {
|
} else {
|
||||||
primeEmbed();
|
primeEmbed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setInterval(send_socket_heartbeat, 5000);
|
||||||
});
|
});
|
||||||
|
|
||||||
function changeTheme(theme=null, keep_custom_css=true) {
|
function changeTheme(theme=null, keep_custom_css=true) {
|
||||||
@ -339,6 +337,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initialize_embed(guildobj) {
|
function initialize_embed(guildobj) {
|
||||||
|
if (socket) {
|
||||||
|
socket.disconnect();
|
||||||
|
}
|
||||||
if (guildobj === undefined) {
|
if (guildobj === undefined) {
|
||||||
var guild = query_guild();
|
var guild = query_guild();
|
||||||
guild.done(function(data) {
|
guild.done(function(data) {
|
||||||
@ -379,6 +380,7 @@
|
|||||||
fill_unauthenticated_users(guildobj.embedmembers.unauthenticated);
|
fill_unauthenticated_users(guildobj.embedmembers.unauthenticated);
|
||||||
$("#instant-inv").attr("href", guildobj.instant_invite);
|
$("#instant-inv").attr("href", guildobj.instant_invite);
|
||||||
run_fetch_routine();
|
run_fetch_routine();
|
||||||
|
initiate_websockets();
|
||||||
}
|
}
|
||||||
|
|
||||||
function fill_channels(channels) {
|
function fill_channels(channels) {
|
||||||
@ -559,8 +561,6 @@
|
|||||||
last_message_id = null;
|
last_message_id = null;
|
||||||
$("#channels-list > li.active").removeClass("active");
|
$("#channels-list > li.active").removeClass("active");
|
||||||
$("#channel-"+selected_channel).parent().addClass("active");
|
$("#channel-"+selected_channel).parent().addClass("active");
|
||||||
priority_query_guild = true;
|
|
||||||
clearTimeout(fetchtimeout);
|
|
||||||
run_fetch_routine();
|
run_fetch_routine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -718,11 +718,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function run_fetch_routine() {
|
function run_fetch_routine() {
|
||||||
if (currently_fetching) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
currently_fetching = true;
|
|
||||||
times_fetched += 1;
|
|
||||||
var channel_id = selected_channel;
|
var channel_id = selected_channel;
|
||||||
var fet;
|
var fet;
|
||||||
var jumpscroll;
|
var jumpscroll;
|
||||||
@ -752,13 +747,11 @@
|
|||||||
}
|
}
|
||||||
var guild = query_guild();
|
var guild = query_guild();
|
||||||
guild.done(function(guildobj) {
|
guild.done(function(guildobj) {
|
||||||
priority_query_guild = false;
|
|
||||||
fill_channels(guildobj.channels);
|
fill_channels(guildobj.channels);
|
||||||
fill_discord_members(guildobj.discordmembers);
|
fill_discord_members(guildobj.discordmembers);
|
||||||
fill_authenticated_users(guildobj.embedmembers.authenticated);
|
fill_authenticated_users(guildobj.embedmembers.authenticated);
|
||||||
fill_unauthenticated_users(guildobj.embedmembers.unauthenticated);
|
fill_unauthenticated_users(guildobj.embedmembers.unauthenticated);
|
||||||
$("#instant-inv").attr("href", guildobj.instant_invite);
|
$("#instant-inv").attr("href", guildobj.instant_invite);
|
||||||
initiate_websockets();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
fet.fail(function(data) {
|
fet.fail(function(data) {
|
||||||
@ -769,25 +762,9 @@
|
|||||||
$('#loginmodal').modal('open');
|
$('#loginmodal').modal('open');
|
||||||
Materialize.toast('Session expired! You have been logged out.', 10000);
|
Materialize.toast('Session expired! You have been logged out.', 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.status != 429) {
|
|
||||||
setVisitorMode(true);
|
setVisitorMode(true);
|
||||||
if (visitor_mode) {
|
|
||||||
fetchtimeout = setTimeout(run_fetch_routine, 5000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
fet.catch(function(data) {
|
|
||||||
if (500 <= data.status && data.status < 600) {
|
|
||||||
if (fetch_error_count % 5 == 0) {
|
|
||||||
Materialize.toast('Fetching messages error! EndenDragon probably broke something. Sorry =(', 10000);
|
|
||||||
}
|
|
||||||
fetch_error_count += 1;
|
|
||||||
fetchtimeout = setTimeout(run_fetch_routine, 10000);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
fet.always(function() {
|
fet.always(function() {
|
||||||
currently_fetching = false;
|
|
||||||
$("#fetching-indicator").fadeOut(800);
|
$("#fetching-indicator").fadeOut(800);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -870,8 +847,6 @@
|
|||||||
var usr = change_unauthenticated_username($(this).val());
|
var usr = change_unauthenticated_username($(this).val());
|
||||||
usr.done(function(data) {
|
usr.done(function(data) {
|
||||||
Materialize.toast('Username changed successfully!', 10000);
|
Materialize.toast('Username changed successfully!', 10000);
|
||||||
priority_query_guild = true;
|
|
||||||
clearTimeout(fetchtimeout);
|
|
||||||
run_fetch_routine();
|
run_fetch_routine();
|
||||||
});
|
});
|
||||||
usr.fail(function(data) {
|
usr.fail(function(data) {
|
||||||
@ -900,8 +875,6 @@
|
|||||||
var funct = post(selected_channel, $(this).val());
|
var funct = post(selected_channel, $(this).val());
|
||||||
funct.done(function(data) {
|
funct.done(function(data) {
|
||||||
$("#messagebox").val("");
|
$("#messagebox").val("");
|
||||||
clearTimeout(fetchtimeout);
|
|
||||||
run_fetch_routine();
|
|
||||||
});
|
});
|
||||||
funct.fail(function(data) {
|
funct.fail(function(data) {
|
||||||
Materialize.toast('Failed to send message.', 10000);
|
Materialize.toast('Failed to send message.', 10000);
|
||||||
@ -945,13 +918,40 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
function initiate_websockets() {
|
function initiate_websockets() {
|
||||||
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + "/gateway", {path: '/gateway', transports: ['websocket']});
|
if (socket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + "/gateway", {path: '/gateway', transports: ['websocket']});
|
||||||
socket.on('connect', function () {
|
socket.on('connect', function () {
|
||||||
socket.emit('identify', {"guild_id": guild_id});
|
socket.emit('identify', {"guild_id": guild_id});
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('MESSAGE_CREATE', function(msg) {
|
socket.on("disconnect", function () {
|
||||||
console.log(msg);
|
socket = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("revoke", function () {
|
||||||
|
$('#loginmodal').modal('open');
|
||||||
|
setVisitorMode(true);
|
||||||
|
primeEmbed();
|
||||||
|
Materialize.toast('Authentication error! You have been disconnected by the server.', 10000);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("MESSAGE_CREATE", function (msg) {
|
||||||
|
var thismsgchan = msg.channel_id;
|
||||||
|
if (selected_channel != thismsgchan) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var jumpscroll = element_in_view($('#discordmessage_'+last_message_id), true);
|
||||||
|
last_message_id = fill_discord_messages([msg], jumpscroll);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function send_socket_heartbeat() {
|
||||||
|
if (!socket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
socket.emit("heartbeat", {"guild_id": guild_id, "visitor_mode": visitor_mode});
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
179
webapp/titanembeds/userbookkeeping.py
Normal file
179
webapp/titanembeds/userbookkeeping.py
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, AuthenticatedUsers, GuildMembers, get_guild_member
|
||||||
|
from titanembeds.utils import guild_accepts_visitors, guild_query_unauth_users_bool, get_client_ipaddr
|
||||||
|
from titanembeds.oauth import check_user_can_administrate_guild, user_has_permission
|
||||||
|
from flask import session
|
||||||
|
from sqlalchemy import and_
|
||||||
|
import json
|
||||||
|
|
||||||
|
def user_unauthenticated():
|
||||||
|
if 'unauthenticated' in session:
|
||||||
|
return session['unauthenticated']
|
||||||
|
return True
|
||||||
|
|
||||||
|
def checkUserRevoke(guild_id, user_key=None):
|
||||||
|
revoked = True #guilty until proven not revoked
|
||||||
|
if user_unauthenticated():
|
||||||
|
dbUser = db.session.query(UnauthenticatedUsers).filter(UnauthenticatedUsers.guild_id == guild_id, UnauthenticatedUsers.user_key == user_key).first()
|
||||||
|
revoked = dbUser.isRevoked()
|
||||||
|
else:
|
||||||
|
banned = checkUserBanned(guild_id)
|
||||||
|
if banned:
|
||||||
|
return revoked
|
||||||
|
dbUser = GuildMembers.query.filter(GuildMembers.guild_id == guild_id).filter(GuildMembers.user_id == session["user_id"]).first()
|
||||||
|
revoked = not dbUser or not dbUser.active
|
||||||
|
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:
|
||||||
|
banned = False
|
||||||
|
dbUser = GuildMembers.query.filter(GuildMembers.guild_id == guild_id).filter(GuildMembers.user_id == session["user_id"]).first()
|
||||||
|
if not dbUser:
|
||||||
|
banned = False
|
||||||
|
else:
|
||||||
|
banned = dbUser.banned
|
||||||
|
return banned
|
||||||
|
|
||||||
|
def update_user_status(guild_id, username, user_key=None):
|
||||||
|
if user_unauthenticated():
|
||||||
|
ip_address = get_client_ipaddr()
|
||||||
|
status = {
|
||||||
|
'authenticated': False,
|
||||||
|
'avatar': None,
|
||||||
|
'manage_embed': False,
|
||||||
|
'ip_address': ip_address,
|
||||||
|
'username': username,
|
||||||
|
'nickname': None,
|
||||||
|
'user_key': user_key,
|
||||||
|
'guild_id': guild_id,
|
||||||
|
'user_id': session['user_id'],
|
||||||
|
'banned': checkUserBanned(guild_id, ip_address),
|
||||||
|
'revoked': checkUserRevoke(guild_id, user_key),
|
||||||
|
}
|
||||||
|
if status['banned'] or status['revoked']:
|
||||||
|
session['user_keys'].pop(guild_id, None)
|
||||||
|
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:
|
||||||
|
status = {
|
||||||
|
'authenticated': True,
|
||||||
|
'avatar': session["avatar"],
|
||||||
|
'manage_embed': check_user_can_administrate_guild(guild_id),
|
||||||
|
'username': username,
|
||||||
|
'nickname': None,
|
||||||
|
'discriminator': session['discriminator'],
|
||||||
|
'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
|
||||||
|
dbMember = get_guild_member(guild_id, status["user_id"])
|
||||||
|
if dbMember:
|
||||||
|
status["nickname"] = dbMember.nickname
|
||||||
|
dbUser = db.session.query(AuthenticatedUsers).filter(and_(AuthenticatedUsers.guild_id == guild_id, AuthenticatedUsers.client_id == status['user_id'])).first()
|
||||||
|
dbUser.bumpTimestamp()
|
||||||
|
return status
|
||||||
|
|
||||||
|
def check_user_in_guild(guild_id):
|
||||||
|
if user_unauthenticated():
|
||||||
|
return guild_id in session.get("user_keys", {})
|
||||||
|
else:
|
||||||
|
dbUser = db.session.query(AuthenticatedUsers).filter(and_(AuthenticatedUsers.guild_id == guild_id, AuthenticatedUsers.client_id == session['user_id'])).first()
|
||||||
|
return dbUser is not None and not checkUserRevoke(guild_id)
|
||||||
|
|
||||||
|
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_guild_channels(guild_id, force_everyone=False):
|
||||||
|
if user_unauthenticated() or force_everyone:
|
||||||
|
member_roles = [guild_id] #equivilant to @everyone role
|
||||||
|
else:
|
||||||
|
member_roles = get_member_roles(guild_id, session['user_id'])
|
||||||
|
if guild_id not in member_roles:
|
||||||
|
member_roles.append(guild_id)
|
||||||
|
dbguild = db.session.query(Guilds).filter(Guilds.guild_id == guild_id).first()
|
||||||
|
guild_channels = json.loads(dbguild.channels)
|
||||||
|
guild_roles = json.loads(dbguild.roles)
|
||||||
|
guild_owner = str(dbguild.owner_id)
|
||||||
|
result_channels = []
|
||||||
|
for channel in guild_channels:
|
||||||
|
if channel['type'] == "text":
|
||||||
|
result = {"channel": channel, "read": False, "write": False, "mention_everyone": False}
|
||||||
|
if guild_owner == session.get("user_id"):
|
||||||
|
result["read"] = True
|
||||||
|
result["write"] = True
|
||||||
|
result["mention_everyone"] = True
|
||||||
|
result_channels.append(result)
|
||||||
|
continue
|
||||||
|
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
|
||||||
|
result["mention_everyone"] = True
|
||||||
|
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"]:
|
||||||
|
if overwrite["type"] == "member" and overwrite["id"] == session.get("user_id"):
|
||||||
|
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)
|
||||||
|
result["mention_everyone"] = user_has_permission(channel_perm, 17)
|
||||||
|
|
||||||
|
# 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
|
||||||
|
result["mention_everyone"] = False
|
||||||
|
|
||||||
|
result_channels.append(result)
|
||||||
|
return sorted(result_channels, key=lambda k: k['channel']['position'])
|
Loading…
Reference in New Issue
Block a user