Files
HospitalAssistantBackend/src/apps/esia/sign.py
Miwory c3fcd2021d
All checks were successful
Build And Push / publish (push) Successful in 7m20s
Добавлена возможность пробрасывать есиа через прокси
2025-09-30 16:44:47 +03:00

81 lines
2.1 KiB
Python

import base64
import secrets
import subprocess # noqa: S404
import tempfile
import uuid
from datetime import UTC, datetime
from pathlib import Path
from typing import Any
from urllib.parse import urlencode
from apps.esia.scopes import SCOPES
from core.config import settings
ACCESS_TYPE = 'online'
RESPONSE_CODE = 'code'
def csp_sign(data: str):
with tempfile.TemporaryDirectory() as tmp_dir:
tmp_file_name = secrets.token_hex(8)
source_path = Path(tmp_dir) / f'{tmp_file_name}.txt'
destination_path = source_path.with_suffix('.txt.sgn')
with open(source_path, 'w', encoding='utf-8') as f:
f.write(data)
cmd = [
'cryptcp',
'-signf',
'-norev',
'-nochain',
'-der',
'-strict',
'-cert',
'-detached',
'-thumbprint',
settings.ESIA_CONTAINER_THUMBPRINT,
'-pin',
settings.ESIA_CONTAINER_PASSWORD,
'-dir',
tmp_dir,
str(source_path),
]
subprocess.run( # noqa: S603
cmd, input=b'y\n', capture_output=True, check=True, text=False
)
signed_message = destination_path.read_bytes()
return signed_message
def sign_params(params: dict[str, Any]):
plaintext = (
params.get('scope', '')
+ params.get('timestamp', '')
+ params.get('client_id', '')
+ params.get('state', '')
)
client_secret = csp_sign(plaintext)
return base64.urlsafe_b64encode(client_secret).decode('utf-8')
def get_url():
timestamp = datetime.now(UTC).strftime('%Y.%m.%d %H:%M:%S %z').strip()
state = str(uuid.uuid4())
params = {
'client_id': settings.ESIA_CLIENT_ID,
'client_secret': '',
'redirect_uri': settings.ESIA_REDIRECT_URI,
'response_type': RESPONSE_CODE,
'state': state,
'timestamp': timestamp,
'access_type': ACCESS_TYPE,
'scope': ' '.join(SCOPES),
}
params['client_secret'] = sign_params(params)
return f'{settings.ESIA_BASE_URL}/aas/oauth2/ac?{urlencode(params)}'