## hosts photocosm web server via flask # external libraries from flask import Blueprint, Flask, request, redirect, render_template, jsonify, flash, url_for, send_from_directory from flask_login import current_user, login_required # core libraries import os.path # internal code from . import db main = Blueprint('main', __name__) # main page # GET = get main page @main.route("/", methods=['GET']) def home(): return render_template("home.html", collections=db.get_collection_list()) # editor page @main.route("/editor", methods=['GET']) def editor(): collection_id = request.args.get("collection") if request.method == "GET": collection = db.get_collection(collection_id) if not collection: flash("No such collection exists!") return redirect(url_for('main.home')) if not current_user.is_authenticated: flash("You must be logged in to edit collections!") return redirect(url_for('auth.login')) if not db.validate_user(collection_id, current_user.email): flash("You do not have permission to edit this collection!") return redirect(url_for('main.home')) return render_template("editor.html", collection_id=collection_id) # get latest collection data (in editor) @main.route("/editorgetlatestinfo", methods=["POST"]) @login_required def editor_request_update(): content = request.get_json() if not content or ("collection" not in content) or ("last_updated" not in content): return jsonify({"status" : "ERROR: Invalid request."}) collection_id = content["collection"] client_last_update = content["last_updated"] collection = db.get_collection(collection_id) if not collection: return jsonify({"status" : "ERROR: No such collection."}) if not current_user.is_authenticated: return jsonify({"status" : "ERROR: You must be logged in to edit collections."}) if not db.validate_user(collection_id, current_user.email): return jsonify({"status" : "ERROR: You do not have permission to edit this collection."}) if collection["last_edited"] > client_last_update: data = {"status" : "OK", "update" : True, "collection" : collection} return jsonify(data) return jsonify({"status" : "OK", "update" : False}) # upload media to collection from editor @main.route("/editormediaupload", methods=['POST']) @login_required def file_upload(): collection_id = request.form.get('collection_id') if not db.validate_user(collection_id, current_user.email): return jsonify({"STATUS" : "PERMISSION DENIED"}) files = request.files.getlist("files") db.add_media_bulk(collection_id ,files) return jsonify({"STATUS" : "OK"}) @main.route("/editoreditmedia", methods=['POST']) @login_required def edit_media(): content = request.get_json() if not content or ("collection" not in content): return jsonify({"status" : "ERROR: Invalid request."}) collection_id = content["collection"] collection = db.get_collection(collection_id) if not collection: return jsonify({"status" : "ERROR: No such collection."}) if not current_user.is_authenticated: return jsonify({"status" : "ERROR: You must be logged in to edit collections."}) if not db.validate_user(collection_id, current_user.email): return jsonify({"status" : "ERROR: You do not have permission to edit this collection."}) for edit in content["edits"]: db.edit_media(collection_id, edit["media_id"], edit["changes"]) return jsonify({"status" : "OK", "update" : False}) @main.route("/editorshare", methods=['POST']) @login_required def share(): content = request.get_json() if not content or ("collection" not in content): return jsonify({"status" : "ERROR: Invalid request."}) collection_id = content["collection"] collection = db.get_collection(collection_id) if not collection: return jsonify({"status" : "ERROR: No such collection."}) if not current_user.is_authenticated: return jsonify({"status" : "ERROR: You must be logged in to edit collections."}) if not db.validate_user(collection_id, current_user.email): return jsonify({"status" : "ERROR: You do not have permission to edit this collection."}) if "user_email" in content: db.set_user_permissions(collection_id, content["user_email"], content["perm"]) if "public" in content: db.set_collection_public(collection_id, content["public"]) return jsonify({"status" : "OK", "update" : False}) @main.route("/editorcollectioninfo", methods=['POST']) @login_required def edit_collection_info(): content = request.get_json() if not content or ("collection" not in content) or ("edits" not in content): return jsonify({"status" : "ERROR: Invalid request."}) collection_id = content["collection"] collection = db.get_collection(collection_id) if not collection: return jsonify({"status" : "ERROR: No such collection."}) if not current_user.is_authenticated: return jsonify({"status" : "ERROR: You must be logged in to edit collections."}) if not db.validate_user(collection_id, current_user.email): return jsonify({"status" : "ERROR: You do not have permission to edit this collection."}) db.set_collection_info(collection_id, content["edits"]) return jsonify({"status" : "OK", "update" : False}) @main.route("/editordeletemedia", methods=['POST']) @login_required def delete_media(): content = request.get_json() print(content) if not content or ("collection" not in content): return jsonify({"status" : "ERROR: Invalid request."}) collection_id = content["collection"] collection = db.get_collection(collection_id) if not collection: return jsonify({"status" : "ERROR: No such collection."}) if not current_user.is_authenticated: return jsonify({"status" : "ERROR: You must be logged in to edit collections."}) if not db.validate_user(collection_id, current_user.email): return jsonify({"status" : "ERROR: You do not have permission to edit this collection."}) for media_id in content["to_be_removed"]: print(db.delete_media(collection_id, media_id)) return jsonify({"status" : "OK", "update" : False}) # access media content @main.route('/content/') def send_content(path): # Using request args for path will expose you to directory traversal attacks return send_from_directory('content', path)