Completed guild dashbaord and database fixes

This commit is contained in:
Jeremy Zhang 2017-03-26 01:04:15 -07:00
parent 3e884fa2fa
commit ea362dd45f
6 changed files with 186 additions and 25 deletions

View File

@ -129,11 +129,6 @@ def create_unauthenticated_user():
status = {'banned': True} status = {'banned': True}
return jsonify(status=status) return jsonify(status=status)
@api.route("/new_guild", methods=["POST"])
@discord_users_only(api=True)
def post_new_guild():
pass
@api.route("/query_guild", methods=["GET"]) @api.route("/query_guild", methods=["GET"])
@valid_session_required(api=True) @valid_session_required(api=True)
def query_guild(): def query_guild():

View File

@ -54,8 +54,6 @@ def get_user_guilds():
def get_user_managed_servers(): def get_user_managed_servers():
guilds = get_user_guilds() guilds = get_user_guilds()
if guilds.status_code != 200: if guilds.status_code != 200:
print(guilds.text)
print(guilds.headers)
abort(guilds.status_code) abort(guilds.status_code)
guilds = guilds.json() guilds = guilds.json()
filtered = [] filtered = []
@ -87,7 +85,7 @@ def check_user_permission(guild_id, id):
guilds = get_user_managed_servers_safe() guilds = get_user_managed_servers_safe()
for guild in guilds: for guild in guilds:
if guild['id'] == guild_id: if guild['id'] == guild_id:
return user_has_permission(guild['permissions'], id) return user_has_permission(guild['permissions'], id) or guild['owner']
return False return False
def generate_avatar_url(id, av): def generate_avatar_url(id, av):
@ -174,13 +172,32 @@ def administrate_guild(guild_id):
permissions.append("Ban Members") permissions.append("Ban Members")
if check_user_permission(guild_id, 1): if check_user_permission(guild_id, 1):
permissions.append("Kick Members") permissions.append("Kick Members")
all_members = db.session.query(UnauthenticatedUsers).filter(UnauthenticatedUsers.guild_id == guild_id).all() all_members = db.session.query(UnauthenticatedUsers).filter(UnauthenticatedUsers.guild_id == guild_id).order_by(UnauthenticatedUsers.last_timestamp).all()
all_bans = db.session.query(UnauthenticatedBans).filter(UnauthenticatedBans.guild_id == guild_id).all() all_bans = db.session.query(UnauthenticatedBans).filter(UnauthenticatedBans.guild_id == guild_id).all()
users = prepare_guild_members_list(all_members, all_bans) users = prepare_guild_members_list(all_members, all_bans)
users.reverse() users.reverse()
dbguild_dict = {"unauth_users": db_guild.unauth_users} dbguild_dict = {"unauth_users": db_guild.unauth_users}
return render_template("administrate_guild.html.j2", guild=guild['content'], dbguild=dbguild_dict, members=users, permissions=permissions) return render_template("administrate_guild.html.j2", guild=guild['content'], dbguild=dbguild_dict, members=users, permissions=permissions)
@user.route("/administrate_guild/<guild_id>", methods=["POST"])
@discord_users_only()
def update_administrate_guild(guild_id):
if not check_user_can_administrate_guild(guild_id):
abort(403)
guild = discord_api.get_guild(guild_id)
if guild['code'] != 200:
abort(guild['code'])
db_guild = db.session.query(Guilds).filter(Guilds.guild_id == guild_id).first()
if db_guild is None:
abort(400)
db_guild.unauth_users = request.form.get("unauth_users", db_guild.unauth_users) in ["true", True]
db.session.commit()
return jsonify(
id=db_guild.id,
guild_id=db_guild.guild_id,
unauth_users=db_guild.unauth_users,
)
@user.route('/me') @user.route('/me')
@discord_users_only() @discord_users_only()
def me(): def me():
@ -213,3 +230,67 @@ def prepare_guild_members_list(members, bans):
continue continue
all_users.append(user) all_users.append(user)
return all_users return all_users
@user.route("/ban", methods=["POST"])
@discord_users_only(api=True)
def ban_unauthenticated_user():
guild_id = request.form.get("guild_id", None)
user_id = request.form.get("user_id", None)
reason = request.form.get("reason", None)
if reason is not None:
reason = reason.strip()
if reason == "":
reason = None
if not guild_id or not user_id:
abort(400)
if not check_user_permission(guild_id, 2):
abort(401)
db_user = db.session.query(UnauthenticatedUsers).filter(UnauthenticatedUsers.guild_id == guild_id, UnauthenticatedUsers.id == user_id).order_by(UnauthenticatedUsers.id.desc()).first()
if db_user is None:
abort(404)
db_ban = db.session.query(UnauthenticatedBans).filter(UnauthenticatedBans.guild_id == guild_id, UnauthenticatedBans.ip_address == db_user.ip_address).first()
if db_ban is not None:
if db_ban.lifter_id is None:
abort(409)
db.session.delete(db_ban)
db_ban = UnauthenticatedBans(guild_id, db_user.ip_address, db_user.username, db_user.discriminator, reason, session["user_id"])
db.session.add(db_ban)
db.session.commit()
return ('', 204)
@user.route("/ban", methods=["DELETE"])
@discord_users_only(api=True)
def unban_unauthenticated_user():
guild_id = request.args.get("guild_id", None)
user_id = request.args.get("user_id", None)
if not guild_id or not user_id:
abort(400)
if not check_user_permission(guild_id, 2):
abort(401)
db_user = db.session.query(UnauthenticatedUsers).filter(UnauthenticatedUsers.guild_id == guild_id, UnauthenticatedUsers.id == user_id).order_by(UnauthenticatedUsers.id.desc()).first()
if db_user is None:
abort(404)
db_ban = db.session.query(UnauthenticatedBans).filter(UnauthenticatedBans.guild_id == guild_id, UnauthenticatedBans.ip_address == db_user.ip_address).first()
if db_ban is None:
abort(404)
if db_ban.lifter_id is not None:
abort(409)
db_ban.liftBan(session["user_id"])
return ('', 204)
@user.route("/revoke", methods=["POST"])
@discord_users_only(api=True)
def revoke_unauthenticated_user():
guild_id = request.args.get("guild_id", None)
user_id = request.args.get("user_id", None)
if not guild_id or not user_id:
abort(400)
if not check_user_permission(guild_id, 1):
abort(401)
db_user = db.session.query(UnauthenticatedUsers).filter(UnauthenticatedUsers.guild_id == guild_id, UnauthenticatedUsers.id == user_id).order_by(UnauthenticatedUsers.id.desc()).first()
if db_user is None:
abort(404)
if db_user.isRevoked():
abort(409)
db_user.revokeUser()
return ('', 204)

View File

@ -1,5 +1,6 @@
from titanembeds.database import db from titanembeds.database import db
import datetime import datetime
import time
class UnauthenticatedBans(db.Model): class UnauthenticatedBans(db.Model):
__tablename__ = "unauthenticated_bans" __tablename__ = "unauthenticated_bans"
@ -18,9 +19,9 @@ class UnauthenticatedBans(db.Model):
self.ip_address = ip_address self.ip_address = ip_address
self.last_username = last_username self.last_username = last_username
self.last_discriminator = last_discriminator self.last_discriminator = last_discriminator
self.timestamp = datetime.datetime.now self.timestamp = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
self.reason = reason self.reason = reason
self.lifter_id = null self.lifter_id = None
self.placer_id = placer_id self.placer_id = placer_id
def liftBan(self, lifter_id): def liftBan(self, lifter_id):

View File

@ -0,0 +1,77 @@
$('#unauth_users').change(function() {
var pathname = window.location.pathname;
var checked = $(this).is(':checked')
var payload = {"unauth_users": checked}
$.post(pathname, payload, function(data) {
Materialize.toast('Updated guest users setting!', 2000)
});
});
function initiate_ban(guild_id, user_id) {
var reason = prompt("Please enter your reason for ban");
var payload = {
"reason": reason,
"guild_id": guild_id,
"user_id": user_id,
}
var pathname = document.location.origin + "/user/ban"
if (reason != null) {
$.post(pathname, payload)
.done(function(){
location.reload();
})
.fail(function(xhr, status, error) {
if (error == "CONFLICT") {
Materialize.toast('User is already banned!', 2000)
} else {
Materialize.toast('An error has occured!', 2000)
}
});
}
}
function remove_ban(guild_id, user_id) {
var payload = {
"guild_id": guild_id,
"user_id": user_id,
}
var pathname = document.location.origin + "/user/ban"
$.ajax({
url: pathname + '?' + $.param(payload),
type: 'DELETE',
success: function() {
location.reload();
},
error: function(jqxhr, status, error) {
if (error == "CONFLICT") {
Materialize.toast('User is already pardoned!', 2000)
} else {
Materialize.toast('An error has occured!', 2000)
}
}
});
}
function revoke_user(guild_id, user_id) {
var payload = {
"guild_id": guild_id,
"user_id": user_id,
}
var confirmation = confirm("Are you sure that you want to kick user?")
var pathname = document.location.origin + "/user/revoke"
if (confirmation) {
$.post(pathname, payload)
.done(function(){
location.reload();
})
.fail(function(xhr, status, error) {
if (error == "CONFLICT") {
Materialize.toast('User is already revoked!', 2000)
} else {
Materialize.toast('An error has occured!', 2000)
}
});
}
}

View File

@ -20,9 +20,9 @@
<div class="card-stacked"> <div class="card-stacked">
<div class="card-content"> <div class="card-content">
<p class="flow-text">Direct Link</p> <p class="flow-text">Direct Link</p>
<input disabled value="{{ url_for("embed.guild_embed", guild_id=guild['id'], _external=True) }}" id="disabled" type="text"> <!-- Switch to url_for later --> <input readonly value="{{ url_for("embed.guild_embed", guild_id=guild['id'], _external=True) }}" id="disabled" type="text" onClick="this.setSelectionRange(0, this.value.length)">
<p class="flow-text">iFrame Embed</p> <p class="flow-text">iFrame Embed</p>
<input disabled value=" &lt;iframe src=&quot;{{ url_for("embed.guild_embed", guild_id=guild['id'], _external=True) }}&quot; height=&quot;200&quot; width=&quot;300&quot; /&gt; " id="disabled" type="text"> <!-- Switch to url_for later --> <input readonly value=" &lt;iframe src=&quot;{{ url_for("embed.guild_embed", guild_id=guild['id'], _external=True) }}&quot; height=&quot;200&quot; width=&quot;300&quot; /&gt; " id="disabled" type="text" onClick="this.setSelectionRange(0, this.value.length)">
</div> </div>
</div> </div>
</div> </div>
@ -35,7 +35,6 @@
<div class="card-stacked"> <div class="card-stacked">
<div class="card-content"> <div class="card-content">
<p class="flow-text">Unauthenticated (Guest) Users</p> <p class="flow-text">Unauthenticated (Guest) Users</p>
<form action="#">
<div class="switch"> <div class="switch">
<label> <label>
Disable Disable
@ -44,7 +43,6 @@
Enable Enable
</label> </label>
</div> </div>
</form>
</div> </div>
</div> </div>
</div> </div>
@ -76,8 +74,12 @@
<tbody> <tbody>
{% for member in members %} {% for member in members %}
<tr> <tr>
<td><a class="waves-effect waves-light btn orange" {% if "Kick Members" not in permissions %}disabled{% endif %} >Kick</a></td> <td><a class="waves-effect waves-light btn orange" {% if "Kick Members" not in permissions or member["kicked"] %}disabled{% endif %} >Kick</a></td>
<td><a class="waves-effect waves-light btn red" {% if "Ban Members" not in permissions %}disabled{% endif %} >Ban</a></td> {% if not member["banned"] %}
<td><a class="waves-effect waves-light btn red" {% if "Ban Members" not in permissions %}disabled{% endif %} {% if "Ban Members" in permissions %} onclick='initiate_ban( "{{ guild['id'] }}" , {{ member['id'] }} )' {% endif %} >Ban</a></td>
{% else %}
<td><a class="waves-effect waves-light btn red lighten-2" {% if "Ban Members" not in permissions %}disabled{% endif %} {% if "Ban Members" in permissions %} onclick='remove_ban( "{{ guild['id'] }}" , {{ member['id'] }} )' {% endif %} >Lift</a></td>
{% endif %}
<td>{{ member['username'] }}</td> <td>{{ member['username'] }}</td>
<td>{{ member['discrim'] }}</td> <td>{{ member['discrim'] }}</td>
<td>{{ member['last_visit'] }}</td> <td>{{ member['last_visit'] }}</td>
@ -90,6 +92,7 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<p>Note that all bans are by IP. Seeing duplicates? It is because users are generated a unique session on each browser load.</p>
</div> </div>
</div> </div>
</div> </div>
@ -98,3 +101,6 @@
</div> </div>
{% endblock %} {% endblock %}
{% block script %}
<script type="text/javascript" src="{{ url_for('static', filename='js/administrate_guild.js') }}"></script>
{% endblock %}

View File

@ -51,5 +51,6 @@
<!--Import jQuery before materialize.js--> <!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.1/js/materialize.min.js" integrity="sha256-ToPQhpo/E89yaCd7+V8LUCjobNRkjilRXfho6x3twLU=" crossorigin="anonymous"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.1/js/materialize.min.js" integrity="sha256-ToPQhpo/E89yaCd7+V8LUCjobNRkjilRXfho6x3twLU=" crossorigin="anonymous"></script>
{% block script %}{% endblock %}
</body> </body>
</html> </html>