Skip to content

Commit

Permalink
Add option to read user admin status from AAD
Browse files Browse the repository at this point in the history
  • Loading branch information
c-w committed May 20, 2019
1 parent f47b79e commit d5c891a
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 0 deletions.
6 changes: 6 additions & 0 deletions app/app/settings.py
Expand Up @@ -129,6 +129,11 @@
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY = env('OAUTH_AAD_KEY', None)
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET = env('OAUTH_AAD_SECRET', None)
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID = env('OAUTH_AAD_TENANT', None)
AZUREAD_ADMIN_GROUP_ID = env('AZUREAD_ADMIN_GROUP_ID', None)

if AZUREAD_ADMIN_GROUP_ID:
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_RESOURCE = 'https://graph.microsoft.com/'
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SCOPE = ['Directory.Read.All']

SOCIAL_AUTH_PIPELINE = [
'social_core.pipeline.social_auth.social_details',
Expand All @@ -142,6 +147,7 @@
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
'server.social_auth.fetch_github_permissions',
'server.social_auth.fetch_azuread_permissions',
]

# Database
Expand Down
26 changes: 26 additions & 0 deletions app/server/social_auth.py
@@ -1,5 +1,6 @@
import requests
from django.conf import settings
from social_core.backends.azuread_tenant import AzureADTenantOAuth2
from social_core.backends.github import GithubOAuth2


Expand Down Expand Up @@ -42,3 +43,28 @@ def fetch_github_permissions(strategy, details, user=None, is_new=False, *args,
if user.is_superuser != is_superuser:
user.is_superuser = is_superuser
user.save()


# noinspection PyUnusedLocal
def fetch_azuread_permissions(strategy, details, user=None, is_new=False, *args, **kwargs):
group_id = getattr(settings, 'AZUREAD_ADMIN_GROUP_ID', '')
if not user or not isinstance(kwargs['backend'], AzureADTenantOAuth2) or not group_id:
return

response = requests.post(
url='https://graph.microsoft.com/v1.0/me/checkMemberGroups',
headers={
'Authorization': 'Bearer {}'.format(kwargs['response']['access_token']),
},
json={
'groupIds': [group_id]
}
)
response.raise_for_status()
response = response.json()

is_superuser = group_id in response['value']

if user.is_superuser != is_superuser:
user.is_superuser = is_superuser
user.save()
@@ -0,0 +1,52 @@
interactions:
- request:
body: '{"groupIds": ["dddddddd-dddd-dddd-dddd-dddddddddddd"]}'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '54'
Content-Type:
- application/json
User-Agent:
- python-requests/2.21.0
method: POST
uri: https://graph.microsoft.com/v1.0/me/checkMemberGroups
response:
body:
string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#Collection(Edm.String)","value":["dddddddd-dddd-dddd-dddd-dddddddddddd"]}'
headers:
Cache-Control:
- private
Content-Type:
- application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8
Date:
- Mon, 20 May 2019 19:34:27 GMT
Duration:
- '89.2611'
Location:
- https://graph.microsoft.com
OData-Version:
- '4.0'
Strict-Transport-Security:
- max-age=31536000
Transfer-Encoding:
- chunked
Vary:
- Accept-Encoding
client-request-id:
- 78c55087-ba07-4e80-8498-8b23b1901356
content-length:
- '135'
request-id:
- 78c55087-ba07-4e80-8498-8b23b1901356
x-ms-ags-diagnostic:
- '{"ServerInfo":{"DataCenter":"East US","Slice":"SliceC","Ring":"2","ScaleUnit":"000","RoleInstance":"AGSFE_IN_51","ADSiteName":"EUS"}}'
status:
code: 200
message: OK
version: 1
@@ -0,0 +1,52 @@
interactions:
- request:
body: '{"groupIds": ["eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee"]}'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '54'
Content-Type:
- application/json
User-Agent:
- python-requests/2.21.0
method: POST
uri: https://graph.microsoft.com/v1.0/me/checkMemberGroups
response:
body:
string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#Collection(Edm.String)","value":[]}'
headers:
Cache-Control:
- private
Content-Type:
- application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8
Date:
- Mon, 20 May 2019 19:34:52 GMT
Duration:
- '84.3986'
Location:
- https://graph.microsoft.com
OData-Version:
- '4.0'
Strict-Transport-Security:
- max-age=31536000
Transfer-Encoding:
- chunked
Vary:
- Accept-Encoding
client-request-id:
- 69bf4728-ae4e-47ef-afd0-7d2c31129b83
content-length:
- '97'
request-id:
- 69bf4728-ae4e-47ef-afd0-7d2c31129b83
x-ms-ags-diagnostic:
- '{"ServerInfo":{"DataCenter":"East US","Slice":"SliceC","Ring":"2","ScaleUnit":"000","RoleInstance":"AGSFE_IN_5","ADSiteName":"EUS"}}'
status:
code: 200
message: OK
version: 1
38 changes: 38 additions & 0 deletions app/server/tests/test_social_auth.py
@@ -1,5 +1,6 @@
from django.contrib.auth import get_user_model
from django.test import TestCase, override_settings
from social_core.backends.azuread_tenant import AzureADTenantOAuth2
from social_core.backends.github import GithubOAuth2
from vcr_unittest import VCRMixin

Expand Down Expand Up @@ -55,3 +56,40 @@ def test_fetch_permissions_not_admin(self):
)

self.assertFalse(user.is_superuser)


@override_settings(SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY='aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa')
@override_settings(SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=')
@override_settings(SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT='cccccccc-cccc-cccc-cccc-cccccccccccc')
class TestAzureADTenantSocialAuth(VCRTestCase):
strategy = None
backend = AzureADTenantOAuth2(strategy=strategy)
access_token = 'censored'

@override_settings(AZUREAD_ADMIN_GROUP_ID='dddddddd-dddd-dddd-dddd-dddddddddddd')
def test_fetch_permissions_is_admin(self):
user = User()

social_auth.fetch_azuread_permissions(
strategy=self.strategy,
details={},
user=user,
backend=self.backend,
response={'access_token': self.access_token},
)

self.assertTrue(user.is_superuser)

@override_settings(AZUREAD_ADMIN_GROUP_ID='eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee')
def test_fetch_permissions_not_admin(self):
user = User()

social_auth.fetch_azuread_permissions(
strategy=self.strategy,
details={},
user=user,
backend=self.backend,
response={'access_token': self.access_token},
)

self.assertFalse(user.is_superuser)

0 comments on commit d5c891a

Please sign in to comment.