Files
GNX-mailEnterprise/venv/lib/python3.12/site-packages/allauth/socialaccount/providers/telegram/views.py
Iliyan Angelov c67067a2a4 Mail
2025-09-14 23:24:25 +03:00

79 lines
2.5 KiB
Python

import base64
import hashlib
import hmac
import json
import time
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.http import urlencode
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from allauth.socialaccount.adapter import get_adapter
from allauth.socialaccount.helpers import (
complete_social_login,
render_authentication_error,
)
from .provider import TelegramProvider
class LoginView(View):
def dispatch(self, request):
provider = get_adapter().get_provider(request, TelegramProvider.id)
return_to = request.build_absolute_uri(
reverse("telegram_callback") + "?" + request.GET.urlencode()
)
url = "https://oauth.telegram.org/auth?" + urlencode(
{
"origin": request.build_absolute_uri("/"),
"bot_id": provider.app.client_id,
"request_access": "write",
"embed": "0",
"return_to": return_to,
}
)
return HttpResponseRedirect(url)
login = LoginView.as_view()
@method_decorator(csrf_exempt, name="dispatch")
class CallbackView(View):
def get(self, request):
return render(request, "telegram/callback.html")
def post(self, request):
result = request.POST.get("tgAuthResult")
padding = "=" * (4 - (len(result) % 4))
data = json.loads(base64.b64decode(result + padding))
adapter = get_adapter()
provider = adapter.get_provider(request, TelegramProvider.id)
hash = data.pop("hash")
payload = "\n".join(sorted(["{}={}".format(k, v) for k, v in data.items()]))
token = provider.app.secret
token_sha256 = hashlib.sha256(token.encode()).digest()
expected_hash = hmac.new(
token_sha256, payload.encode(), hashlib.sha256
).hexdigest()
auth_date = int(data.pop("auth_date"))
auth_date_validity = provider.get_auth_date_validity()
if hash != expected_hash or time.time() - auth_date > auth_date_validity:
return render_authentication_error(
request, provider_id=provider.id, extra_context={"response": data}
)
login = provider.sociallogin_from_response(request, data)
process = request.GET.get("process")
if process:
login.state["process"] = process
return complete_social_login(request, login)
callback = CallbackView.as_view()