This commit is contained in:
Iliyan Angelov
2025-09-14 23:24:25 +03:00
commit c67067a2a4
71311 changed files with 6800714 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
import requests
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.urls import reverse
from django.utils.http import urlencode
from allauth.socialaccount.adapter import get_adapter
from allauth.socialaccount.providers.openid.provider import (
OpenIDAccount,
OpenIDProvider,
)
if "allauth.socialaccount.providers.openid" not in settings.INSTALLED_APPS:
raise ImproperlyConfigured(
"The steam provider requires 'allauth.socialaccount.providers.openid' to be installed"
)
class SteamAccount(OpenIDAccount):
def to_str(self):
dflt = super(SteamAccount, self).to_str()
return self.account.extra_data.get("personaname", dflt)
def get_profile_url(self):
return self.account.extra_data.get("profileurl")
def get_avatar_url(self):
return (
self.account.extra_data.get("avatarfull")
or self.account.extra_data.get("avatarmedium")
or self.account.extra_data.get("avatar")
)
def extract_steam_id(url):
return url.lstrip("https://steamcommunity.com/openid/id/")
def request_steam_account_summary(api_key, steam_id):
api_base = "https://api.steampowered.com/"
method = "ISteamUser/GetPlayerSummaries/v0002/"
params = {"key": api_key, "steamids": steam_id}
resp = requests.get(api_base + method, params)
resp.raise_for_status()
data = resp.json()
playerlist = data.get("response", {}).get("players", [])
return playerlist[0] if playerlist else {"steamid": steam_id}
class SteamOpenIDProvider(OpenIDProvider):
id = "steam"
name = "Steam"
account_class = SteamAccount
uses_apps = True
def __init__(self, request, app=None):
if app is None:
app = get_adapter().get_app(request, self.id)
super().__init__(request, app=app)
def get_login_url(self, request, **kwargs):
url = reverse("steam_login")
if kwargs:
url += "?" + urlencode(kwargs)
return url
def sociallogin_from_response(self, request, response):
steam_id = extract_steam_id(response.identity_url)
steam_api_key = self.app.secret
response._extra = request_steam_account_summary(steam_api_key, steam_id)
return super(SteamOpenIDProvider, self).sociallogin_from_response(
request, response
)
def extract_uid(self, response):
return response._extra["steamid"]
def extract_extra_data(self, response):
return response._extra.copy()
def extract_common_fields(self, response):
full_name = response._extra.get("realname", "").strip()
if full_name.count(" ") == 1:
first_name, last_name = full_name.split()
else:
first_name, last_name = full_name, ""
username = response._extra.get("personaname", "")
return {
"username": username or response._extra["steamid"],
"first_name": first_name,
"last_name": last_name,
"full_name": full_name,
}
provider_classes = [SteamOpenIDProvider]

View File

@@ -0,0 +1,9 @@
from django.urls import path
from . import views
urlpatterns = [
path("steam/login/", views.steam_login, name="steam_login"),
path("steam/callback/", views.steam_callback, name="steam_callback"),
]

View File

@@ -0,0 +1,45 @@
"""
OpenID Adapter for Steam
The Steam login API is simple OpenID but requires extra API calls
for basic resources such as usernames.
Resources:
* Steam Web API Documentation
https://steamcommunity.com/dev
* Steam Partner API documentation
https://partner.steamgames.com/doc/features/auth#website
"""
from django.urls import reverse
from allauth.socialaccount.providers.openid.views import (
OpenIDCallbackView,
OpenIDLoginView,
)
from .provider import SteamOpenIDProvider
STEAM_OPENID_URL = "https://steamcommunity.com/openid"
class SteamOpenIDLoginView(OpenIDLoginView):
provider = SteamOpenIDProvider
def get_form(self):
items = dict(list(self.request.GET.items()) + list(self.request.POST.items()))
items["openid"] = STEAM_OPENID_URL
return self.form_class(items)
def get_callback_url(self):
return reverse(steam_callback)
class SteamOpenIDCallbackView(OpenIDCallbackView):
provider = SteamOpenIDProvider
steam_login = SteamOpenIDLoginView.as_view()
steam_callback = SteamOpenIDCallbackView.as_view()