mirror of
https://github.com/wowlikon/LiB.git
synced 2026-02-04 12:31:09 +00:00
79 lines
2.0 KiB
Python
79 lines
2.0 KiB
Python
"""Модуль TOTP 2FA"""
|
|
|
|
import base64
|
|
import os
|
|
|
|
import pyotp
|
|
import qrcode
|
|
|
|
|
|
# Настройкт из переменных окружения
|
|
TOTP_ISSUER = os.getenv("TOTP_ISSUER", "LiB")
|
|
TOTP_VALID_WINDOW = int(os.getenv("TOTP_VALID_WINDOW", "1"))
|
|
|
|
|
|
def generate_secret() -> str:
|
|
"""Генерация нового TOTP секрета"""
|
|
return pyotp.random_base32()
|
|
|
|
|
|
def get_provisioning_uri(secret: str, username: str) -> str:
|
|
"""Получение URI для QR-кода"""
|
|
totp = pyotp.TOTP(secret)
|
|
return totp.provisioning_uri(name=username, issuer_name=TOTP_ISSUER)
|
|
|
|
|
|
def verify_totp_code(secret: str, code: str) -> bool:
|
|
"""Проверка TOTP кода"""
|
|
if not secret or not code:
|
|
return False
|
|
totp = pyotp.TOTP(secret)
|
|
return totp.verify(code, valid_window=TOTP_VALID_WINDOW)
|
|
|
|
|
|
def qr_to_bitmap_b64(data: str) -> dict:
|
|
"""Конвертирует данные в QR-код и возвращает как base64 bitmap"""
|
|
qr = qrcode.QRCode(
|
|
version=1,
|
|
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
|
box_size=1,
|
|
border=0,
|
|
)
|
|
qr.add_data(data)
|
|
qr.make(fit=True)
|
|
|
|
matrix = qr.get_matrix()
|
|
size = len(matrix)
|
|
|
|
bits = []
|
|
for row in matrix:
|
|
for cell in row:
|
|
bits.append(0 if cell else 1)
|
|
|
|
padding = (8 - len(bits) % 8) % 8
|
|
bits.extend([0] * padding)
|
|
|
|
bytes_array = bytearray()
|
|
for i in range(0, len(bits), 8):
|
|
byte = 0
|
|
for j in range(8):
|
|
byte = (byte << 1) | bits[i + j]
|
|
bytes_array.append(byte)
|
|
|
|
b64 = base64.b64encode(bytes_array).decode("ascii")
|
|
return {"size": size, "padding": padding, "bitmap_b64": b64}
|
|
|
|
|
|
def generate_totp_setup(username: str) -> dict:
|
|
"""Генерация данных для настройки TOTP"""
|
|
secret = generate_secret()
|
|
uri = get_provisioning_uri(secret, username)
|
|
bitmap_data = qr_to_bitmap_b64(uri)
|
|
|
|
return {
|
|
"secret": secret,
|
|
"username": username,
|
|
"issuer": TOTP_ISSUER,
|
|
**bitmap_data,
|
|
}
|