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 @@
# Create your models here.

View File

@@ -0,0 +1,51 @@
from __future__ import unicode_literals
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider
class AzureAccount(ProviderAccount):
# TODO:
# - avatar_url:
# https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/profilephoto_get # noqa
def get_username(self):
return self.account.extra_data["email"]
def to_str(self):
name = "{0} {1}".format(
self.account.extra_data.get("first_name", ""),
self.account.extra_data.get("last_name", ""),
)
if name.strip() != "":
return name
return super(AzureAccount, self).to_str()
class AzureProvider(OAuth2Provider):
id = str("azure")
name = "Azure"
account_class = AzureAccount
def get_default_scope(self):
"""
Doc on scopes available at
https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-scopes # noqa
"""
return ["User.Read", "openid"]
def extract_uid(self, data):
return str(data["id"])
def extract_common_fields(self, data):
email = data.get("mail")
if not email and "userPrincipalName" in data:
email = data.get("userPrincipalName")
return dict(
email=email,
username=email,
last_name=data.get("surname"),
first_name=data.get("givenName"),
)
provider_classes = [AzureProvider]

View File

@@ -0,0 +1,23 @@
from allauth.socialaccount.tests import OAuth2TestsMixin
from allauth.tests import MockedResponse, TestCase
from .provider import AzureProvider
class AzureTests(OAuth2TestsMixin, TestCase):
provider_id = AzureProvider.id
def get_mocked_response(self):
return MockedResponse(
200,
"""
{"displayName": "John Smith", "mobilePhone": null,
"preferredLanguage": "en-US", "jobTitle": "Director",
"userPrincipalName": "john@smith.com",
"@odata.context":
"https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"officeLocation": "Paris", "businessPhones": [],
"mail": "john@smith.com", "surname": "Smith",
"givenName": "John", "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"}
""",
)

View File

@@ -0,0 +1,6 @@
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
from .provider import AzureProvider
urlpatterns = default_urlpatterns(AzureProvider)

View File

@@ -0,0 +1,62 @@
from __future__ import unicode_literals
import requests
from allauth.socialaccount.providers.oauth2.views import (
OAuth2Adapter,
OAuth2CallbackView,
OAuth2LoginView,
)
from .provider import AzureProvider
LOGIN_URL = "https://login.microsoftonline.com/common/oauth2/v2.0"
GRAPH_URL = "https://graph.microsoft.com/v1.0"
class AzureOAuth2Adapter(OAuth2Adapter):
"""
Docs available at:
https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols
"""
provider_id = AzureProvider.id
access_token_url = LOGIN_URL + "/token"
authorize_url = LOGIN_URL + "/authorize"
profile_url = "https://graph.microsoft.com/v1.0/me"
# Can be used later to obtain group data. Needs 'Group.Read.All' or
# similar.
#
# See https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/user_list_memberof # noqa
groups_url = GRAPH_URL + "/me/memberOf?$select=displayName"
def complete_login(self, request, app, token, **kwargs):
headers = {"Authorization": "Bearer {0}".format(token.token)}
extra_data = {}
resp = requests.get(self.profile_url, headers=headers)
# See:
#
# https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/user_get # noqa
#
# example of what's returned (in python format)
#
# {u'displayName': u'John Smith', u'mobilePhone': None,
# u'preferredLanguage': u'en-US', u'jobTitle': u'Director',
# u'userPrincipalName': u'john@smith.com',
# u'@odata.context':
# u'https://graph.microsoft.com/v1.0/$metadata#users/$entity',
# u'officeLocation': u'Paris', u'businessPhones': [],
# u'mail': u'john@smith.com', u'surname': u'Smith',
# u'givenName': u'John', u'id': u'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'}
profile_data = resp.json()
extra_data.update(profile_data)
return self.get_provider().sociallogin_from_response(request, extra_data)
oauth2_login = OAuth2LoginView.adapter_view(AzureOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(AzureOAuth2Adapter)