68 lines
2.0 KiB
Python
68 lines
2.0 KiB
Python
from collections.abc import Mapping
|
|
from typing import Any
|
|
|
|
from flask import Blueprint, current_app, jsonify, render_template, request
|
|
|
|
from .binding import BindingService
|
|
from .bitrix import BitrixClient
|
|
|
|
|
|
class SiteInputError(ValueError):
|
|
pass
|
|
|
|
|
|
def _field(payload: Mapping[str, Any], name: str) -> str:
|
|
"""Проверка существования обязательного поля с именем name."""
|
|
for key in (name, name.lower(), name.upper()):
|
|
value = payload.get(key)
|
|
if value is not None and str(value).strip():
|
|
return str(value).strip()
|
|
raise SiteInputError(f"Не передано поле {name}")
|
|
|
|
|
|
def create_blueprint(
|
|
bindings: BindingService,
|
|
bitrix: BitrixClient,
|
|
) -> Blueprint:
|
|
blueprint = Blueprint("site", __name__)
|
|
|
|
@blueprint.get("/")
|
|
def index():
|
|
return jsonify(
|
|
service="bitrix-telegram-binding",
|
|
public_url=current_app.config["PUBLIC_BASE_URL"],
|
|
)
|
|
|
|
@blueprint.get("/health")
|
|
def health():
|
|
database = current_app.extensions["database"]
|
|
try:
|
|
available = database.ping()
|
|
except Exception:
|
|
available = False
|
|
status = "ok" if available else "error"
|
|
return jsonify(status=status), 200 if available else 503
|
|
|
|
@blueprint.post("/bitrix/bind")
|
|
def bind():
|
|
payload = request.get_json(silent=True) or request.form
|
|
refresh_token = _field(payload, "REFRESH_ID")
|
|
|
|
# OAuth-ответ дает доверенные ID портала и пользователя.
|
|
auth = bitrix.authorize(refresh_token)
|
|
link = bindings.issue(
|
|
auth.member_id,
|
|
auth.domain,
|
|
auth.user.id,
|
|
auth.access_token,
|
|
auth.refresh_token,
|
|
auth.expires_in,
|
|
)
|
|
return render_template(
|
|
"binding.html",
|
|
user=auth.user,
|
|
link=link,
|
|
)
|
|
|
|
return blueprint
|