66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
from app.core.models.keys import KnownKey
|
|
from datetime import datetime
|
|
from base58 import b58encode, b58decode
|
|
from hashlib import sha256
|
|
from app.core.logger import make_log
|
|
import os
|
|
|
|
|
|
# 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(f"[Auth] User {user_id} created new {token_type} key {new_key.id}")
|
|
return {
|
|
"key": new_key,
|
|
"auth_v1_token": new_key.seed
|
|
}
|