You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.7 KiB

  1. import requests
  2. from django.conf import settings
  3. from social_core.backends.azuread_tenant import AzureADTenantOAuth2
  4. from social_core.backends.github import GithubOAuth2
  5. from social_core.backends.okta import OktaOAuth2
  6. from social_core.backends.okta_openidconnect import OktaOpenIdConnect
  7. # noinspection PyUnusedLocal
  8. def fetch_github_permissions(strategy, details, user=None, is_new=False, *args, **kwargs):
  9. org_name = getattr(settings, 'GITHUB_ADMIN_ORG_NAME', '')
  10. team_name = getattr(settings, 'GITHUB_ADMIN_TEAM_NAME', '')
  11. if not user or not isinstance(kwargs['backend'], GithubOAuth2) or not org_name or not team_name:
  12. return
  13. response = requests.post(
  14. url='https://api.github.com/graphql',
  15. headers={
  16. 'Authorization': 'Bearer {}'.format(kwargs['response']['access_token']),
  17. },
  18. json={
  19. 'query': '''
  20. query($userName: String!, $orgName: String!, $teamName: String!) {
  21. organization(login: $orgName) {
  22. teams(query: $teamName, userLogins: [$userName], first: 1) {
  23. nodes {
  24. name
  25. }
  26. }
  27. }
  28. }
  29. ''',
  30. 'variables': {
  31. 'userName': details['username'],
  32. 'orgName': org_name,
  33. 'teamName': team_name,
  34. }
  35. }
  36. )
  37. response.raise_for_status()
  38. response = response.json()
  39. is_superuser = {'name': team_name} in response['data']['organization']['teams']['nodes']
  40. if user.is_superuser != is_superuser:
  41. user.is_superuser = is_superuser
  42. user.save()
  43. # noinspection PyUnusedLocal
  44. def fetch_azuread_permissions(strategy, details, user=None, is_new=False, *args, **kwargs):
  45. group_id = getattr(settings, 'AZUREAD_ADMIN_GROUP_ID', '')
  46. if not user or not isinstance(kwargs['backend'], AzureADTenantOAuth2) or not group_id:
  47. return
  48. response = requests.post(
  49. url='https://graph.microsoft.com/v1.0/me/checkMemberGroups',
  50. headers={
  51. 'Authorization': 'Bearer {}'.format(kwargs['response']['access_token']),
  52. },
  53. json={
  54. 'groupIds': [group_id]
  55. }
  56. )
  57. response.raise_for_status()
  58. response = response.json()
  59. is_superuser = group_id in response['value']
  60. if user.is_superuser != is_superuser:
  61. user.is_superuser = is_superuser
  62. user.save()
  63. # noinspection PyUnusedLocal
  64. def fetch_okta_oauth2_permissions(strategy, details, user=None, is_new=False, *args, **kwargs):
  65. org_url = getattr(settings, 'SOCIAL_AUTH_OKTA_OAUTH2_API_URL', '')
  66. admin_group_name = getattr(settings, "OKTA_OAUTH2_ADMIN_GROUP_NAME", "")
  67. if not user or not isinstance(kwargs['backend'], OktaOAuth2):
  68. return
  69. # OktaOpenIdConnect inherits `OktaOAuth2`, so we have to explicitly skip OAuth2 trying
  70. # to fetch permissions when using OIDC backend.
  71. if isinstance(kwargs['backend'], OktaOpenIdConnect):
  72. return
  73. response = requests.post(
  74. url=f"{org_url}/v1/userinfo",
  75. headers={
  76. 'Authorization': 'Bearer {}'.format(kwargs['response']['access_token']),
  77. },
  78. )
  79. response.raise_for_status()
  80. response = response.json()
  81. is_superuser = admin_group_name in response.get("groups", [])
  82. is_staff = admin_group_name in response.get("groups", [])
  83. user_changed = False
  84. if user.is_superuser != is_superuser:
  85. user.is_superuser = is_superuser
  86. user_changed = user_changed or True
  87. if user.is_staff != is_staff:
  88. user.is_staff = is_staff
  89. user_changed = user_changed or True
  90. if user_changed:
  91. user.save()
  92. # noinspection PyUnusedLocal
  93. def fetch_okta_openidconnect_permissions(strategy, details, user=None, is_new=False, *args, **kwargs):
  94. org_url = getattr(settings, 'SOCIAL_AUTH_OKTA_OPENIDCONNECT_API_URL', '')
  95. admin_group_name = getattr(settings, "OKTA_OPENIDCONNECT_ADMIN_GROUP_NAME", "")
  96. if not user or not isinstance(kwargs['backend'], OktaOpenIdConnect):
  97. return
  98. response = requests.post(
  99. url=f"{org_url}/v1/userinfo",
  100. headers={
  101. 'Authorization': 'Bearer {}'.format(kwargs['response']['access_token']),
  102. },
  103. )
  104. response.raise_for_status()
  105. response = response.json()
  106. is_superuser = admin_group_name in response.get("groups", [])
  107. is_staff = admin_group_name in response.get("groups", [])
  108. user_changed = False
  109. if user.is_superuser != is_superuser:
  110. user.is_superuser = is_superuser
  111. user_changed = user_changed or True
  112. if user.is_staff != is_staff:
  113. user.is_staff = is_staff
  114. user_changed = user_changed or True
  115. if user_changed:
  116. user.save()