2023-12-14 12:39:23 +01:00
|
|
|
from config import disallowedMimeTypes, Errors, Config
|
2023-12-26 20:16:58 +01:00
|
|
|
from app.models import User
|
|
|
|
from app import bcrypt
|
2023-12-14 12:39:23 +01:00
|
|
|
import secrets
|
|
|
|
import datetime
|
|
|
|
import random
|
|
|
|
import time
|
|
|
|
import os
|
|
|
|
|
|
|
|
def uploadFile(file, ip, userid, filename, id, retention):
|
|
|
|
|
|
|
|
# Is the MIME and file size good?
|
|
|
|
if file.content_type not in disallowedMimeTypes:
|
|
|
|
if file.content_length <= Config.maxFileSize:
|
|
|
|
# We're going to check whether the id variable has been filled
|
|
|
|
|
|
|
|
while True: # Loop to find an available file ID
|
|
|
|
id = randomHex() # Prevent conflicts if 2 of the same get made
|
|
|
|
if Config.files.find_one({'id': id}) is None:
|
2023-12-29 20:47:28 +01:00
|
|
|
filename=id
|
2023-12-14 12:39:23 +01:00
|
|
|
break
|
|
|
|
|
|
|
|
if userid == None:
|
|
|
|
userid = 0
|
|
|
|
elif Config.users.find_one({'userid': userid}) == None:
|
|
|
|
userid = 0
|
|
|
|
|
|
|
|
# Calculate retention before the file is written, we'll grab the filesize here as it's needed for the equation.
|
2024-01-03 09:51:31 +01:00
|
|
|
file.seek(0, os.SEEK_END)
|
|
|
|
fileSize = round(float(file.tell()) / 1024, 2)
|
2024-01-04 19:58:42 +01:00
|
|
|
|
|
|
|
# Set the position back to 0
|
|
|
|
file.seek(0)
|
2023-12-14 12:39:23 +01:00
|
|
|
|
|
|
|
if retention == None:
|
|
|
|
retention = (Config.minretention+(-Config.maxretention + Config.minretention)*pow((fileSize / Config.maxFileSize -1), 3))
|
|
|
|
elif retention > (Config.minretention+(-Config.maxretention + Config.minretention)*pow((fileSize / Config.maxFileSize -1), 3)):
|
|
|
|
retention = (Config.minretention+(-Config.maxretention + Config.minretention)*pow((fileSize / Config.maxFileSize -1), 3))
|
2023-12-29 20:47:28 +01:00
|
|
|
else:
|
|
|
|
retention = retention
|
2023-12-14 12:39:23 +01:00
|
|
|
|
2023-12-21 17:19:22 +01:00
|
|
|
|
2023-12-14 12:39:23 +01:00
|
|
|
# Create the file
|
|
|
|
with open(f"{os.path.abspath(Config.fileDir)}/{filename}", "wb") as f:
|
|
|
|
f.write(file.read())
|
|
|
|
|
|
|
|
date = time.mktime(datetime.datetime.now().timetuple())
|
|
|
|
|
|
|
|
# Create the dictionary that we'll insert into the db
|
|
|
|
data = {
|
|
|
|
'id': id,
|
|
|
|
'filename': filename,
|
|
|
|
'filesize': fileSize,
|
|
|
|
'retention': round(retention * 86400), # Convert to seconds
|
|
|
|
'userid': userid,
|
|
|
|
'ip': ip,
|
|
|
|
'date': date,
|
|
|
|
'expiry': date + round(retention * 86400)
|
|
|
|
}
|
|
|
|
|
|
|
|
# Add the data and verify its there.
|
|
|
|
Config.files.insert_one(data)
|
|
|
|
print(Config.files.find_one({"id": id}))
|
|
|
|
|
2024-01-04 19:58:42 +01:00
|
|
|
return f"https://xygt.cc/{id}", 200
|
2023-12-14 12:39:23 +01:00
|
|
|
else:
|
|
|
|
return random.choice(Errors.fileTooLarge), 400
|
|
|
|
else:
|
|
|
|
return random.choice(Errors.fileTypeNotAllowed), 400
|
|
|
|
|
|
|
|
def shortenURL(url, ip, userid, id, retention):
|
|
|
|
# We're going to check whether the id variable has been filled
|
|
|
|
# If not then we'll generate one. (The ID variable will be the same as the filename if not rejected earlier.)
|
|
|
|
if id == None:
|
|
|
|
while True: # Loop to find an available file ID
|
|
|
|
id = randomHex() # Prevent conflicts if 2 of the same get made
|
|
|
|
if Config.files.find_one({'id': id}) is None:
|
|
|
|
break
|
|
|
|
|
|
|
|
if userid == None:
|
|
|
|
userid = 0
|
|
|
|
elif Config.users.find_one({'userid': userid}) == None:
|
|
|
|
userid = 0
|
|
|
|
|
|
|
|
if retention == None:
|
|
|
|
retention = 14
|
|
|
|
elif retention > 365:
|
|
|
|
retention = 365
|
|
|
|
|
|
|
|
data = {
|
|
|
|
"id": id,
|
|
|
|
"url": url,
|
|
|
|
"userid": userid,
|
|
|
|
"retention": retention,
|
|
|
|
"ip": ip
|
|
|
|
}
|
|
|
|
|
|
|
|
Config.url.insert_one(data)
|
|
|
|
print(Config.url.find_one({"id": data["id"]}))
|
|
|
|
|
2024-01-04 19:58:42 +01:00
|
|
|
return f"https://xygt.cc/{id}", 200
|
2023-12-14 12:39:23 +01:00
|
|
|
|
|
|
|
def idInfo(id):
|
|
|
|
# Check files and url for the ID
|
|
|
|
if Config.files.find_one({"id": id}) is not None:
|
2023-12-22 22:16:10 +01:00
|
|
|
check = Config.files.find_one({"id": id}, {'_id': False, "ip": False})
|
2023-12-14 12:39:23 +01:00
|
|
|
# "ip": False removes the IP from the returned data.
|
|
|
|
# If it's not there then check url
|
|
|
|
elif Config.url.find_one({"id": id}) is not None:
|
2023-12-22 22:16:10 +01:00
|
|
|
check = Config.url.find_one({"id": id}, {'_id': False, "ip": False})
|
2023-12-14 12:39:23 +01:00
|
|
|
|
|
|
|
# Return the mongodb info about the file, removing IP if its present
|
|
|
|
return check
|
|
|
|
|
|
|
|
def randomHex():
|
|
|
|
hexRand = ''.join(secrets.choice('0123456789abcdef') for _ in range(6))
|
|
|
|
return hexRand
|
2023-12-26 20:16:58 +01:00
|
|
|
|
|
|
|
def registerUser(username, password):
|
|
|
|
# Initialise some values
|
|
|
|
try:
|
|
|
|
level = 1
|
2024-01-04 19:58:42 +01:00
|
|
|
while True:
|
|
|
|
userid = randomHex()
|
|
|
|
if Config.users.find_one({"userid": userid}) is None:
|
|
|
|
break
|
|
|
|
idpass = bcrypt.generate_password_hash(randomHex()).decode("utf-8") # The user will not know this, they'll need to generate a new one.
|
2023-12-26 20:16:58 +01:00
|
|
|
password = bcrypt.generate_password_hash(password).decode("utf-8")
|
|
|
|
user = User(username, userid, password, idpass, level)
|
|
|
|
Config.users.insert_one(user.__dict__)
|
|
|
|
|
|
|
|
return True
|
2024-01-04 19:58:42 +01:00
|
|
|
except:
|
|
|
|
return False
|
|
|
|
|
|
|
|
def resetIDPass(userid):
|
|
|
|
try:
|
|
|
|
idpass = randomHex(8)
|
|
|
|
hashedPass = bcrypt.generate_password_hash(idpass).decode("utf-8")
|
|
|
|
Config.users.update_one({"userid": userid}, {"$set": {"idpass": hashedPass}})
|
|
|
|
return idpass
|
2023-12-26 20:16:58 +01:00
|
|
|
except:
|
|
|
|
return False
|