M src/api/userapi.py => src/api/userapi.py +34 -2
@@ 1,6 1,6 @@
-from flask import Blueprint, jsonify
+from flask import Blueprint, jsonify, request
-from utils.dbutils import get_uuid_from_username
+from utils.dbutils import get_uuid_from_username, register_user
user_api = Blueprint("user_api", __name__)
@@ 10,3 10,35 @@ user_api = Blueprint("user_api", __name__)
def userapi_profiles_minecraft(username: str):
uuid = get_uuid_from_username(username)
return jsonify({"uuid": uuid, "username": username})
+
+
+# NONSTANDARD FOR MOJANG API AS YOU CAN'T REGISTER FROM LAUNCHER
+@user_api.post("/api/v1/register")
+def api_v1_register():
+ data = request.json
+
+ if not data:
+ return jsonify({"status": "ko", "err": "No data"})
+
+ username = data.get("username")
+ password = data.get("password")
+
+ if not username or not password:
+ return jsonify({"status": "ko", "err": "No data"})
+
+ if (
+ len(username) < 3
+ or len(username) > 255
+ or len(password) < 8
+ or len(password) > 255
+ ):
+ return jsonify({"status": "ko", "err": "Invalid data was provided"})
+
+ uuid = register_user(username, password)
+
+ if not uuid:
+ return jsonify(
+ {"status": "ko", "err": "User already exists or an error happened"}
+ )
+
+ return jsonify({"status": "ok", "uuid": uuid})
M src/utils/db.py => src/utils/db.py +1 -3
@@ 19,7 19,6 @@ class BaseModel(Model):
class Users(BaseModel):
- id = IntegerField(primary_key=True)
username = CharField(null=False)
password = CharField(null=True) # NULL TRUE = IN CASE OF SSO LOGIN/REGISTER
uuid = CharField(null=False)
@@ 29,10 28,9 @@ class Users(BaseModel):
class UsernameHistory(BaseModel):
- id = IntegerField(primary_key=True)
username = CharField(null=False)
changed_on = DateTimeField(null=False)
- uuid = ForeignKeyField(Users, backref="uuid")
+ uuid = ForeignKeyField(model=Users, column_name="uuid")
def get_object(model, **kwargs):
M src/utils/dbutils.py => src/utils/dbutils.py +39 -1
@@ 1,7 1,10 @@
from datetime import datetime, timedelta
+from uuid import uuid4
+
+from bcrypt import gensalt, hashpw
from utils.redisutil import cache_val, get_val
-from utils.db import get_object, Users
+from utils.db import get_object, Users, UsernameHistory
def get_uuid_from_username(username: str):
@@ 46,3 49,38 @@ def get_all_users_count():
cache_val(cachekey, number_all_users, expiration=3600)
return number_all_users
+
+
+def hash_password(password: str):
+ salt = gensalt()
+ hashed = hashpw(str.encode(password), salt)
+
+ return hashed.decode()
+
+
+def register_user(username: str, password: str):
+ # USER CHECK
+ existing_user = Users.select().where(Users.username == username).count()
+ if existing_user > 0:
+ return None
+
+ # DO REGISTRATION
+ hashed_pass = hash_password(password)
+ uuid = str(uuid4())
+ register_date = datetime.now()
+
+ user = Users.create(
+ username=username,
+ password=hash_password,
+ uuid=uuid,
+ registered_on=register_date,
+ )
+
+ uh = UsernameHistory.create(
+ username=username, changed_on=register_date, uuid=user.uuid
+ )
+
+ user.save()
+ uh.save()
+
+ return uuid