Added files (v0.1)
Added the Python files so now the repository actually has something. This will probably become v0.1 without any changes.
This commit is contained in:
		
							
								
								
									
										139
									
								
								configtest.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								configtest.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| import os | ||||
| import settings as settings | ||||
|  | ||||
|  | ||||
| # Default settings | ||||
| defaults = { | ||||
|     "UPLOAD_FOLDER": "/var/www/img", | ||||
|     "ALLOWED_EXTENSIONS": [".png", ".jpg", ".jpeg", ".svg", ".bmp", ".gif", ".ico",  ".webp"], | ||||
|     "ROOTURL": "https://img.bbaovanc.com/", | ||||
|     "SAVELOG": "savelog.log", | ||||
|     "SAVELOG_CHMOD": "0o644", | ||||
|     "UPLOADKEYS_CHMOD": "0o400", | ||||
|     "SAVELOG_KEYPREFIX": 4, | ||||
| } | ||||
|  | ||||
| deftypes = { | ||||
|     "UPLOAD_FOLDER": str, | ||||
|     "ALLOWED_EXTENSIONS": list, | ||||
|     "ROOTURL": str, | ||||
|     "SAVELOG": str, | ||||
|     "SAVELOG_CHMOD": int, | ||||
|     "UPLOADKEYS_CHMOD": int, | ||||
|     "SAVELOG_KEYPREFIX": int, | ||||
| } | ||||
|  | ||||
|  | ||||
| # Check for unset settings | ||||
| checksettings = list(defaults.keys()) | ||||
| unset_settings = [i for i in defaults.keys() if i not in dir(settings)] | ||||
| if len(unset_settings) > 0: | ||||
|     for unset in unset_settings: | ||||
|         checksettings.remove(unset) | ||||
|         print("[!] {0} is unset. The default value is type {1} with value {2}".format(unset, deftypes[unset].__name__, defaults[unset])) | ||||
| else: | ||||
|     print("[" + u"\u2713" + "] Found all required settings!") | ||||
|  | ||||
|  | ||||
| # Check if types of settings are correct | ||||
| typesgood = True | ||||
| typeswrong = [] | ||||
| for testtype in checksettings: | ||||
|     if type(getattr(settings, testtype)) is not deftypes[testtype]: | ||||
|         print("[!] {0} requires {1}, but is {2}".format(testtype, deftypes[testtype].__name__, type(getattr(settings, testtype)).__name__)) | ||||
|         typeswrong.append(testtype) | ||||
|         typesgood = False | ||||
|  | ||||
| if typesgood: | ||||
|     print("[" + u"\u2713" + "] Types are good!") | ||||
|  | ||||
|  | ||||
| # Check if allowed extensions all start with a . | ||||
| invalid_exts = [] | ||||
| if "ALLOWED_EXTENSIONS" in checksettings: | ||||
|     for e in settings.ALLOWED_EXTENSIONS: | ||||
|         if not e.startswith("."): | ||||
|             invalid_exts.append(e) | ||||
|  | ||||
|     if len(invalid_exts) > 0: | ||||
|         print("[!] The following extensions listed in ALLOWED_EXTENSIONS are invalid:") | ||||
|         for e in invalid_exts: | ||||
|             print("    {0} is listed in ALLOWED_EXTENSIONS, but doesn't start with a .".format(e)) | ||||
|     else: | ||||
|         print("[" + u"\u2713" + "] ALLOWED_EXTENSIONS is good!") | ||||
|  | ||||
|  | ||||
| # Check if UPLOAD_FOLDER exists | ||||
| uploadfolder_exists = True | ||||
| if "UPLOAD_FOLDER" in checksettings: | ||||
|     if not os.path.isdir(settings.UPLOAD_FOLDER): | ||||
|         uploadfolder_exists = False | ||||
|         print("[!] The directory set in UPLOAD_FOLDER ('{0}') doesn't exist!".format(settings.UPLOAD_FOLDER)) | ||||
|     else: | ||||
|         print("[" + u"\u2713" + "] UPLOAD_FOLDER exists!") | ||||
|  | ||||
|  | ||||
| # Check if ROOTURL starts with http(s):// and ends with / | ||||
| rooturl_good = True | ||||
| if "ROOTURL" in checksettings: | ||||
|     if settings.ROOTURL.startswith("http://") or settings.ROOTURL.startswith("https://"): | ||||
|         pass | ||||
|     else: | ||||
|         rooturl_good = False | ||||
|         print(settings.ROOTURL) | ||||
|         print(settings.ROOTURL.startswith("https://")) | ||||
|         print("[!] ROOTURL does not start with `http://` or `https://`! This may cause issues!") | ||||
|     if not settings.ROOTURL.endswith("/"): | ||||
|         rooturl_good = False | ||||
|         print("[!] ROOTURL does not end with a `/`. This WILL cause issues!") | ||||
|  | ||||
|     if not rooturl_good: | ||||
|         print("    With your current settings, this is what a generated url would look like:") | ||||
|         print("    {0}example.png".format(settings.ROOTURL)) | ||||
|     else: | ||||
|         print("[" + u"\u2713" + "] ROOTURL is good!") | ||||
|  | ||||
|  | ||||
| # Ask the user if SAVELOG is the intended filename | ||||
| if "SAVELOG" in checksettings: | ||||
|     print("[*] SAVELOG was interpreted to be {0}".format(settings.SAVELOG)) | ||||
|     print("[*] If this is not the intended filename, please fix it.") | ||||
|  | ||||
|  | ||||
| # Show summary | ||||
| print() | ||||
| print("----- SUMMARY -----") | ||||
| summarygood = True | ||||
| if len(unset_settings) > 0: | ||||
|     summarygood = False | ||||
|     print("Unset settings:") | ||||
|     for unset in unset_settings: | ||||
|         print("    {0}".format(unset)) | ||||
|  | ||||
| if len(typeswrong) > 0: | ||||
|     summarygood = False | ||||
|     print("Incorrect types:") | ||||
|     for wtype in typeswrong: | ||||
|         print("    {0}".format(wtype)) | ||||
|  | ||||
| if len(invalid_exts) > 0: | ||||
|     summarygood = False | ||||
|     print("Invalid extensions:") | ||||
|     for wext in invalid_exts: | ||||
|         print("    '{0}'".format(wext)) | ||||
|  | ||||
| if not uploadfolder_exists: | ||||
|     summarygood = False | ||||
|     print("UPLOAD_FOLDER ({0}) does not exist!".format(settings.UPLOAD_FOLDER)) | ||||
|  | ||||
| if not rooturl_good: | ||||
|     summarygood = False | ||||
|     print("ROOTURL may cause issues!") | ||||
|     print("With current settings, this is what a generated URL would look like:") | ||||
|     print("{0}example.png".format(settings.ROOTURL)) | ||||
|  | ||||
| if "SAVELOG" in checksettings: | ||||
|     print("[*] SAVELOG is {0}".format(settings.SAVELOG)) | ||||
|  | ||||
| if summarygood: | ||||
|     print("[" + u"\u2713" + "] This configuration passes all tests!") | ||||
							
								
								
									
										114
									
								
								imgupload.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								imgupload.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| from flask import Flask, request, jsonify, abort, Response | ||||
| from flask_api import status | ||||
| from pathlib import Path | ||||
| import string | ||||
| import random | ||||
| import os | ||||
| import datetime | ||||
|  | ||||
| import settings  # app settings (such as allowed extensions) | ||||
|  | ||||
|  | ||||
| ALPHANUMERIC = string.ascii_letters + string.digits  # uppercase, lowercase, and numbers | ||||
|  | ||||
| app = Flask(__name__)  # app is the app | ||||
|  | ||||
|  | ||||
| def allowed_extension(testext): | ||||
|     if testext in settings.ALLOWED_EXTENSIONS: | ||||
|         return True | ||||
|     else: | ||||
|         return False | ||||
|  | ||||
|  | ||||
| def generate_name(extension): | ||||
|     namefound = False | ||||
|     while not namefound: | ||||
|         fname = ''.join((random.choice(ALPHANUMERIC) for i in range(8))) + str(extension) | ||||
|         if not Path(fname).is_file(): | ||||
|             namefound = True | ||||
|     return fname | ||||
|  | ||||
|  | ||||
| def log_savelog(key, ip, savedname): | ||||
|     if settings.SAVELOG_KEYPREFIX > 0: | ||||
|         with open(settings.SAVELOG, "a+") as slogf: | ||||
|             slogf.write("[{0}] {1}: {2} - {3}\n".format(datetime.datetime.now(), key[:settings.SAVELOG_KEYPREFIX], ip, savedname)) | ||||
|         os.chmod(settings.SAVELOG, settings.SAVELOG_CHMOD) | ||||
|     else: | ||||
|         with open(settings.SAVELOG, "a+") as slogf: | ||||
|             slogf.write("[{0}] {1} - {2}\n".format(datetime.datetime.now(), ip, savedname)) | ||||
|         os.chmod(settings.SAVELOG, settings.SAVELOG_CHMOD) | ||||
|  | ||||
|  | ||||
| @app.route("/upload", methods = ["POST"]) | ||||
| def upload(): | ||||
|     if request.method == "POST":  # sanity check: make sure it's a POST request | ||||
|         print("Request method was POST!") | ||||
|  | ||||
|         os.chmod("uploadkeys", settings.UPLOADKEYS_CHMOD) | ||||
|         print("Changed permissions of `uploadkeys`") | ||||
|         with open("uploadkeys", "r") as keyfile:  # load valid keys | ||||
|             validkeys = keyfile.readlines() | ||||
|         validkeys = [x.strip("\n") for x in validkeys] | ||||
|         while "" in validkeys: | ||||
|             validkeys.remove("") | ||||
|             print("removed blank key") | ||||
|         print("Valid keys: {0}".format(validkeys)) | ||||
|         print("Loaded validkeys") | ||||
|  | ||||
|         if "uploadKey" in request.form:  # if an uploadKey was provided | ||||
|             if request.form["uploadKey"] in validkeys:  # check if uploadKey is valid | ||||
|                 print("Key is valid!") | ||||
|  | ||||
|                 if "imageUpload" in request.files:  # check if image to upload was provided | ||||
|                     f = request.files["imageUpload"]  # f is the image to upload | ||||
|                     print("Found uploaded image") | ||||
|                 else: | ||||
|                     print("No image upload was found!") | ||||
|                     return jsonify({'status': 'error', 'error': 'NO_IMAGE_UPLOADED'}), status.HTTP_400_BAD_REQUEST | ||||
|  | ||||
|                 if f.filename == "":  # make sure the filename isn't blank | ||||
|                     print("Filename is blank") | ||||
|                     return jsonify({'status': 'error', 'error': 'FILENAME_BLANK'}), status.HTTP_400_BAD_REQUEST | ||||
|  | ||||
|                 fext = Path(f.filename).suffix  # get the uploaded extension | ||||
|                 print("Uploaded file extensions is {0}".format(fext)) | ||||
|                 if allowed_extension(fext):  # if the extension is allowed | ||||
|                     fname = generate_name(fext)  # generate file name | ||||
|                     print("Generated name: {0}".format(fname)) | ||||
|  | ||||
|                     if f:  # if the uploaded image exists | ||||
|                         print("Uploaded image exists, obviously.") | ||||
|                         f.save(os.path.join(settings.UPLOAD_FOLDER, fname))  # save the image | ||||
|                         print("Saved to {0}".format(fname)) | ||||
|                         url = settings.ROOTURL + fname  # construct the url to the image | ||||
|                         if settings.SAVELOG != "/dev/null": | ||||
|                             log_savelog(request.form["uploadKey"], request.remote_addr, fname) | ||||
|                             print("Logged message to savelog") | ||||
|                         print("Returning json response") | ||||
|                         return jsonify({'status': 'success', 'url': url, 'name': fname, 'uploadedName': f.filename}), status.HTTP_201_CREATED | ||||
|                     else:  # this shouldn't happen | ||||
|                         print("Um... uploaded image is nonexistent..? Please report this error!") | ||||
|                         return jsonify({'status': 'error', 'error': 'UPLOADED_IMAGE_FAILED_SANITY_CHECK_1'}), status.HTTP_400_BAD_REQUEST | ||||
|  | ||||
|                 else:  # if the extension was invalid | ||||
|                     print("Uploaded extension is invalid!") | ||||
|                     abort(415) | ||||
|  | ||||
|             else:  # if the key was not valid | ||||
|                 print("Key is invalid!") | ||||
|                 print("Request key: {0}".format(request.form["uploadKey"])) | ||||
|                 abort(401) | ||||
|  | ||||
|         else:  # if uploadKey was not found in request body | ||||
|             print("No uploadKey found in request!") | ||||
|             abort(401) | ||||
|  | ||||
|  | ||||
|     else:  # if the request method wasn't post | ||||
|         print("Request method was not POST!") | ||||
|         abort(405) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     print("Run with `flask` or a WSGI server!") | ||||
							
								
								
									
										7
									
								
								settings.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								settings.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| UPLOAD_FOLDER = "/var/www/img" | ||||
| ALLOWED_EXTENSIONS = [".png", ".jpg", ".jpeg", ".svg", ".bmp", ".gif", ".ico",  ".webp"] | ||||
| ROOTURL = "https://img.bbaovanc.com/" | ||||
| SAVELOG = "savelog.log" | ||||
| SAVELOG_CHMOD = 0o644 | ||||
| UPLOADKEYS_CHMOD = 0o600 | ||||
| SAVELOG_KEYPREFIX = 4 | ||||
		Reference in New Issue
	
	Block a user