~jae/dn0magik-mc

26ac5531625dd8b4aa46a81ba45a02e2e6efce1c — Jae Lo Presti (DN0) 2 years ago d5e2d34
API: add working way of registering for an account

New endpoint: /api/v1/register [POST]
3 files changed, 74 insertions(+), 6 deletions(-)

M src/api/userapi.py
M src/utils/db.py
M src/utils/dbutils.py
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