Skip to content

Commit

Permalink
feat: support Auth0 OAuth2 (#2171)
Browse files Browse the repository at this point in the history
* feat: support Auth0 OAuth2

* lint
  • Loading branch information
dpgaspar authored Nov 24, 2023
1 parent ba63c5c commit 59db85d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 4 deletions.
16 changes: 15 additions & 1 deletion docs/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,21 @@ Specify a list of OAUTH_PROVIDERS in **config.py** that you want to allow for yo
"client_kwargs": {"scope": "openid profile email groups"},
"access_token_url": "https://OKTA_DOMAIN.okta.com/oauth2/v1/token",
"authorize_url": "https://OKTA_DOMAIN.okta.com/oauth2/v1/authorize",
"server_metadata_url": f"https://OKTA_DOMAIN.okta.com/.well-known/openid-configuration",
"server_metadata_url": "https://OKTA_DOMAIN.okta.com/.well-known/openid-configuration",
},
},
{
"name": "auth0",
"icon": "fa-shield-halved",
"token_key": "access_token",
"remote_app": {
"client_id": "AUTH0_KEY",
"client_secret": "AUTH0_SECRET",
"api_base_url": "https://AUTH0_DOMAIN/oauth2/v1/",
"client_kwargs": {"scope": "openid profile email groups"},
"access_token_url": "https://AUTH0_DOMAIN/oauth/token",
"authorize_url": "https://AUTH0_DOMAIN/authorize",
"server_metadata_url": "https://AUTH0_DOMAIN/.well-known/openid-configuration",
},
},
{
Expand Down
15 changes: 13 additions & 2 deletions flask_appbuilder/security/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,10 +649,21 @@ def get_oauth_user_info(
data = me.json()
log.debug("User info from Okta: %s", data)
return {
"username": "okta_" + data.get("sub", ""),
"username": f"{provider}_{data['sub']}",
"first_name": data.get("given_name", ""),
"last_name": data.get("family_name", ""),
"email": data.get("email", ""),
"email": data["email"],
"role_keys": data.get("groups", []),
}
# for Auth0
if provider == "auth0":
data = self.appbuilder.sm.oauth_remotes[provider].userinfo()
log.debug("User info from Auth0: %s", data)
return {
"username": f"{provider}_{data['sub']}",
"first_name": data.get("given_name", ""),
"last_name": data.get("family_name", ""),
"email": data["email"],
"role_keys": data.get("groups", []),
}
# for Keycloak
Expand Down
45 changes: 44 additions & 1 deletion tests/security/test_auth_oauth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import os
import unittest
from unittest.mock import MagicMock

from flask import Flask
from flask_appbuilder import AppBuilder, SQLA
Expand Down Expand Up @@ -47,7 +48,22 @@ def setUp(self):
"AZURE_APPLICATION_ID/"
"oauth2/authorize",
},
}
},
{
"name": "auth0",
"icon": "fa-shield-halved",
"token_key": "access_token",
"remote_app": {
"client_id": "AUTH0_KEY",
"client_secret": "AUTH0_SECRET",
"api_base_url": "https://AUTH0_DOMAIN/oauth2/v1/",
"client_kwargs": {"scope": "openid profile email groups"},
"access_token_url": "https://AUTH0_DOMAIN/oauth/token",
"authorize_url": "https://AUTH0_DOMAIN/authorize",
"server_metadata_url": "https://AUTH0_DOMAIN/.well-known/"
"openid-configuration",
},
},
]

# start Database
Expand Down Expand Up @@ -652,3 +668,30 @@ def test_oauth_user_info_azure_with_jwt_validation(self):
"username": "b1a54a40-8dfa-4a6d-a2b8-f90b84d4b1df",
},
)

def test_oauth_user_info_auth0(self):
self.appbuilder = AppBuilder(self.app, self.db.session)

self.appbuilder.sm.oauth_remotes["auth0"].userinfo = MagicMock(
return_value={
"email": "[email protected]",
"given_name": "test",
"family_name": "user",
"role_keys": [],
"sub": "test-sub",
}
)

user_info = self.appbuilder.sm.get_oauth_user_info(
"auth0", {"access_token": "", "id_token": ""}
)
self.assertEqual(
user_info,
{
"email": "[email protected]",
"first_name": "test",
"last_name": "user",
"role_keys": [],
"username": "auth0_test-sub",
},
)

0 comments on commit 59db85d

Please sign in to comment.