diff --git a/Vagrantfile b/Vagrantfile index 6a97d6a..0afe04a 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -13,6 +13,7 @@ Vagrant.configure(2) do |config| config.vm.synced_folder "scripts", "/home/vagrant/scripts" config.vm.synced_folder "web", "/srv/http/ctf" + config.vm.provision :shell, path: "/vagrant/deploy", run: "always", privileged: false config.vm.provision :shell, :path => "scripts/setup.sh" config.ssh.forward_agent = true diff --git a/server/api/user.py b/server/api/user.py index c9af129..87fe1f4 100644 --- a/server/api/user.py +++ b/server/api/user.py @@ -1,4 +1,5 @@ from flask import Blueprint, make_response, session, request, redirect, url_for, send_file +from werkzeug import secure_filename from flask import current_app as app from voluptuous import Schema, Length, Required @@ -8,11 +9,14 @@ from schemas import verify_to_schema, check import datetime import logger +import os import re import requests import team import utils +from PIL import Image + ############### # USER ROUTES # ############### @@ -185,6 +189,46 @@ def user_avatar(uid): return send_file("pfp/%d.png" % uid, mimetype="image/png") return abort(404) +@blueprint.route("/avatar/upload", methods=["POST"]) +@api_wrapper +def user_avatar_upload(): + logged_in = is_logged_in() + if not logged_in: + raise WebException("You're not logged in.") + + _user = get_user().first() + f = request.files["file"] + if f is None: + raise WebException("Please upload something.") + + fname = "/tmp/" + secure_filename(utils.generate_string()) + f.save(fname) + + try: + pfp = "pfp/%d.png" % _user.uid + os.remove(pfp) + im = Image.open(fname) + im = im.resize((256, 256), Image.ANTIALIAS) + im.save(open(pfp, "w"), "PNG") + return { "success": 1, "message": "Uploaded!" } + except Exception, e: + raise WebException(str(e)) + +@blueprint.route("/avatar/remove", methods=["POST"]) +@api_wrapper +def user_avatar_remove(): + logged_in = is_logged_in() + if not logged_in: + raise WebException("You're not logged in.") + _user = get_user().first() + + try: + pfp = "pfp/%d.png" % _user.uid + os.remove(pfp) + return { "success": 1, "message": "Removed!" } + except Exception, e: + raise WebException(str(e)) + ################## # USER FUNCTIONS # ################## diff --git a/web/js/easyctf.js b/web/js/easyctf.js index f6dfda3..69cad28 100644 --- a/web/js/easyctf.js +++ b/web/js/easyctf.js @@ -77,6 +77,7 @@ app.config(function($routeProvider, $locationProvider) { app.controller("mainController", ["$scope", "$http", function($scope, $http) { $scope.config = { navbar: { } }; + $scope.timestamp = Date.now(); $.get("/api/user/status", function(result) { if (result["success"] == 1) { delete result["success"]; @@ -192,7 +193,6 @@ app.controller("settingsController", ["$controller", "$scope", "$http", function $controller("mainController", { $scope: $scope }); $.get("/api/user/info", {}, function(result) { if (result["success"] == 1) { - console.log(result["user"]); $scope.user = result["user"]; } $scope.$apply(); @@ -204,7 +204,7 @@ function display_message(containerId, alertType, message, callback) { $("#" + containerId).hide().slideDown("fast", "swing", function() { window.setTimeout(function () { $("#" + containerId).slideUp("fast", "swing", callback); - }, message.length * 75); + }, message.length * 55); }); }; @@ -402,3 +402,13 @@ var accept_invitation_request = function(uid) { } }); }; + +// settings page + +var remove_profile_picture = function() { + api_call("POST", "/api/user/avatar/remove", { }, function(result) { + if (result["success"] == 1) { + location.reload(true); + } + }); +}; \ No newline at end of file diff --git a/web/pages/profile.html b/web/pages/profile.html index fb98766..64e191b 100644 --- a/web/pages/profile.html +++ b/web/pages/profile.html @@ -4,7 +4,7 @@
- + Edit Picture

{{ user.name }}

diff --git a/web/pages/settings.html b/web/pages/settings.html index 00dcc7e..d2bc0fe 100644 --- a/web/pages/settings.html +++ b/web/pages/settings.html @@ -1,3 +1,24 @@ + +
@@ -21,16 +42,23 @@
- +
-

- Upload new picture - Remove profile picture -

-

- If you remove your picture, an automatically generated identicon will be used. -

+
+
+
+ Upload new picture + +
+ + Remove profile picture + +
+
+
+

If you remove your picture, an automatically generated identicon will be used.

+
@@ -82,4 +110,83 @@ offset: $("#navbar").outerHeight(), updateURL: false }); + var dataURItoBlob = function(dataURI) { + var byteString = atob(dataURI.split(",")[1]); + var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]; + var ab = new ArrayBuffer(byteString.length); + var ia = new Uint8Array(ab); + for (var i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i); + } + var blob = new Blob([ ab ], { type: mimeString }); + return blob; + } + var MAX_SIZE = 256; + var uploadListener = function(e) { + try { + $("#file_upload").attr("disabled", "disabled"); + $("#file_upload").html(" Uploading..."); + var file = e.target.files[0]; + var reader = new FileReader(); + reader.onload = (function(_file) { + return function(progress) { + var img = document.createElement("img"); + img.src = progress.target.result; + var width = img.width; + var height = img.height; + + if (width > height) { + if (width > MAX_SIZE) { + height *= MAX_SIZE / width; + width = MAX_SIZE; + } + } else { + if (height > MAX_SIZE) { + width *= MAX_SIZE / height; + height = MAX_SIZE; + } + } + img.cwidth = width; + img.cheight = height; + + var data = new FormData(); + data.append("file", dataURItoBlob(img.src)); + data.append("csrf_token", $.cookie("csrf_token")); + $.ajax({ + type: "POST", + url: "/api/user/avatar/upload", + data: data, + processData: false, + contentType: false, + }).done(function(result) { + if (result["success"] == 1) { + $("#file_upload").removeClass("btn-primary"); + $("#file_upload").addClass("btn-success"); + $("#file_upload").html(" Done! Reloading..."); + location.reload(true); + } + }).fail(function() { + $("#file_upload").removeClass("btn-primary"); + $("#file_upload").addClass("btn-danger"); + $("#file_upload").html(" Error. Reloading..."); + location.reload(true); + }); + }; + })(file); + reader.readAsDataURL(file); + } catch (e) { + console.log(e); + $("#file_upload").removeClass("btn-primary"); + $("#file_upload").addClass("btn-danger"); + $("#file_upload").html(" Error. Reloading..."); + location.reload(true); + } + }; + $(document).ready(function() { + if (!(window.File && window.FileReader && window.FileList && window.Blob)) { + console.log("Your browser doesn't support file upload."); + } else { + document.getElementById("file").addEventListener("change", uploadListener, false); + }; + }); \ No newline at end of file