uploader-bot/app/core/auth_v1.py

68 lines
2.2 KiB
Python

import os
from datetime import datetime
from hashlib import sha256
from base58 import b58encode
from app.core.logger import make_log
from app.core.models.keys import KnownKey
# Auth v1 specs
## Private key (57 bytes)
# 1. int8 token version
# 2. int128 users.id
# 3. int64 init_ts
# 4. int256 of os.urandom
## Public key (72 bytes)
# 1. int256 of sha256 of private key
# 2. int256 of sha256 of users.id
# 3. int64 init_ts
class AuthenticationMixin:
async def create_api_token_v1(self, db_session, token_type) -> dict:
user_id = self.id
randpart = os.urandom(32)
assert type(user_id) == int, "User ID must be an integer"
init_ts = int(datetime.now().timestamp())
new_seed = (bytes([1]) # token version
+ user_id.to_bytes(16, 'big')
+ init_ts.to_bytes(8, 'big')
+ randpart)
assert len(new_seed) == 57, "Invalid seed length"
new_seed_hash_bin = sha256(new_seed).digest()
new_seed_hash = b58encode(new_seed_hash_bin).decode()
user_id_hash_bin = sha256(user_id.to_bytes(16, 'big')).digest()
public_key = (
new_seed_hash_bin
+ user_id_hash_bin
+ init_ts.to_bytes(8, 'big')
)
assert len(public_key) == 72, "Invalid public key length"
public_key_hash_bin = sha256(public_key).digest()
public_key_hash = b58encode(public_key_hash_bin).decode()
new_key = KnownKey(
type=token_type,
seed=b58encode(new_seed).decode(),
seed_hash=new_seed_hash,
public_key=b58encode(public_key).decode(),
public_key_hash=public_key_hash,
algo='CX_URANDOM_SHA256',
meta={
'I_user_id': user_id
},
created=datetime.fromtimestamp(init_ts)
)
db_session.add(new_key)
db_session.commit()
new_key = db_session.query(KnownKey).filter(KnownKey.seed_hash == new_key.seed_hash).first()
assert new_key, "Key not created"
make_log("auth", f"[new-K] User {user_id} created new {token_type} key {new_key.id}")
return {
"key": new_key,
"auth_v1_token": new_key.seed
}