Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions firebase_admin/_auth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,8 @@ def get_oidc_provider_config(self, provider_id):
return self._provider_manager.get_oidc_provider_config(provider_id)

def create_oidc_provider_config(
self, provider_id, client_id, issuer, display_name=None, enabled=None):
self, provider_id, client_id, issuer, display_name=None, enabled=None,
client_secret=None, id_token_response_type=None, code_response_type=None):
"""Creates a new OIDC provider config from the given parameters.

OIDC provider support requires Google Cloud's Identity Platform (GCIP). To learn more about
Expand All @@ -530,10 +531,11 @@ def create_oidc_provider_config(
"""
return self._provider_manager.create_oidc_provider_config(
provider_id, client_id=client_id, issuer=issuer, display_name=display_name,
enabled=enabled)
enabled=enabled, client_secret=client_secret,
id_token_response_type=id_token_response_type, code_response_type=code_response_type)

def update_oidc_provider_config(
self, provider_id, client_id=None, issuer=None, display_name=None, enabled=None):
self, provider_id, client_id=None, issuer=None, display_name=None, enabled=None, client_secret=None, id_token_response_type=None, code_response_type=None):
"""Updates an existing OIDC provider config with the given parameters.

Args:
Expand All @@ -554,7 +556,8 @@ def update_oidc_provider_config(
"""
return self._provider_manager.update_oidc_provider_config(
provider_id, client_id=client_id, issuer=issuer, display_name=display_name,
enabled=enabled)
enabled=enabled, client_secret=client_secret,
id_token_response_type=id_token_response_type, code_response_type=code_response_type)

def delete_oidc_provider_config(self, provider_id):
"""Deletes the ``OIDCProviderConfig`` with the given ID.
Expand Down
59 changes: 57 additions & 2 deletions firebase_admin/_auth_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ def issuer(self):
def client_id(self):
return self._data['clientId']

@property
def client_secret(self):
return self._data.get('clientSecret')

@property
def id_token_response_type(self):
return self._data.get('responseType', {}).get('idToken', False)

@property
def code_response_type(self):
return self._data.get('responseType', {}).get('code', False)


class SAMLProviderConfig(ProviderConfig):
"""Represents he SAML auth provider configuration.
Expand Down Expand Up @@ -179,7 +191,8 @@ def get_oidc_provider_config(self, provider_id):
return OIDCProviderConfig(body)

def create_oidc_provider_config(
self, provider_id, client_id, issuer, display_name=None, enabled=None):
self, provider_id, client_id, issuer, display_name=None, enabled=None,
client_secret=None, id_token_response_type=None, code_response_type=None):
"""Creates a new OIDC provider config from the given parameters."""
_validate_oidc_provider_id(provider_id)
req = {
Expand All @@ -190,13 +203,35 @@ def create_oidc_provider_config(
req['displayName'] = _auth_utils.validate_string(display_name, 'display_name')
if enabled is not None:
req['enabled'] = _auth_utils.validate_boolean(enabled, 'enabled')
if id_token_response_type is not None or code_response_type is not None:
req['responseType'] = {}
if id_token_response_type is not None:
req['responseType']['idToken'] = _auth_utils.validate_boolean(id_token_response_type, 'id_token_response_type')
if code_response_type is not None:
req['responseType']['code'] = _auth_utils.validate_boolean(code_response_type, 'code_response_type')
if code_response_type:
req['clientSecret'] = _validate_non_empty_string(client_secret, 'client_secret')

response_type = {}
if id_token_response_type is False and code_response_type is False:
raise ValueError("At least one response type must be returned.")
if id_token_response_type is not None:
response_type['idToken'] = _auth_utils.validate_boolean(id_token_response_type, 'id_token_response_type')
if code_response_type is not None:
response_type['code'] = _auth_utils.validate_boolean(code_response_type, 'code_response_type')
if code_response_type:
req['clientSecret'] = _validate_non_empty_string(client_secret, 'client_secret')
if response_type:
req['responseType'] = response_type

params = 'oauthIdpConfigId={0}'.format(provider_id)
body = self._make_request('post', '/oauthIdpConfigs', json=req, params=params)
return OIDCProviderConfig(body)

def update_oidc_provider_config(
self, provider_id, client_id=None, issuer=None, display_name=None, enabled=None):
self, provider_id, client_id=None, issuer=None, display_name=None,
enabled=None, client_secret=None, id_token_response_type=None,
code_response_type=None):
"""Updates an existing OIDC provider config with the given parameters."""
_validate_oidc_provider_id(provider_id)
req = {}
Expand All @@ -211,6 +246,26 @@ def update_oidc_provider_config(
req['clientId'] = _validate_non_empty_string(client_id, 'client_id')
if issuer:
req['issuer'] = _validate_url(issuer, 'issuer')
if id_token_response_type is not None or code_response_type is not None:
req['responseType'] = {}
if id_token_response_type is not None:
req['responseType']['idToken'] = _auth_utils.validate_boolean(id_token_response_type, 'id_token_response_type')
if code_response_type is not None:
if code_response_type:
req['clientSecret'] = _validate_non_empty_string(client_secret, 'client_secret')
req['responseType']['code'] = _auth_utils.validate_boolean(code_response_type, 'code_response_type')

response_type = {}
if id_token_response_type is False and code_response_type is False:
raise ValueError("At least one response type must be returned.")
if id_token_response_type is not None:
response_type['idToken'] = _auth_utils.validate_boolean(id_token_response_type, 'id_token_response_type')
if code_response_type is not None:
response_type['code'] = _auth_utils.validate_boolean(code_response_type, 'code_response_type')
if code_response_type:
req['clientSecret'] = _validate_non_empty_string(client_secret, 'client_secret')
if response_type:
req['responseType'] = response_type

if not req:
raise ValueError('At least one parameter must be specified for update.')
Expand Down
10 changes: 6 additions & 4 deletions firebase_admin/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ def get_oidc_provider_config(provider_id, app=None):
return client.get_oidc_provider_config(provider_id)

def create_oidc_provider_config(
provider_id, client_id, issuer, display_name=None, enabled=None, app=None):
provider_id, client_id, issuer, display_name=None, enabled=None, client_secret=None, id_token_response_type=None, code_response_type=None, app=None):
"""Creates a new OIDC provider config from the given parameters.

OIDC provider support requires Google Cloud's Identity Platform (GCIP). To learn more about
Expand All @@ -671,11 +671,12 @@ def create_oidc_provider_config(
client = _get_client(app)
return client.create_oidc_provider_config(
provider_id, client_id=client_id, issuer=issuer, display_name=display_name,
enabled=enabled)
enabled=enabled, client_secret=client_secret, id_token_response_type=id_token_response_type,
code_response_type=code_response_type)


def update_oidc_provider_config(
provider_id, client_id=None, issuer=None, display_name=None, enabled=None, app=None):
provider_id, client_id=None, issuer=None, display_name=None, enabled=None, client_secret=None, id_token_response_type=None, code_response_type=None, app=None):
"""Updates an existing OIDC provider config with the given parameters.

Args:
Expand All @@ -698,7 +699,8 @@ def update_oidc_provider_config(
client = _get_client(app)
return client.update_oidc_provider_config(
provider_id, client_id=client_id, issuer=issuer, display_name=display_name,
enabled=enabled)
enabled=enabled, client_secret=client_secret, id_token_response_type=id_token_response_type,
code_response_type=code_response_type)


def delete_oidc_provider_config(provider_id, app=None):
Expand Down
18 changes: 16 additions & 2 deletions integration/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,9 @@ def test_create_oidc_provider_config(oidc_provider):
assert oidc_provider.issuer == 'https://oidc.com/issuer'
assert oidc_provider.display_name == 'OIDC_DISPLAY_NAME'
assert oidc_provider.enabled is True
assert oidc_provider.response_type.id_token is True
assert oidc_provider.response_type.code is False
assert oidc_provider.client_secret is None


def test_get_oidc_provider_config(oidc_provider):
Expand All @@ -702,6 +705,9 @@ def test_get_oidc_provider_config(oidc_provider):
assert provider_config.issuer == 'https://oidc.com/issuer'
assert provider_config.display_name == 'OIDC_DISPLAY_NAME'
assert provider_config.enabled is True
assert provider_config.response_type.id_token is True
assert provider_config.response_type.code is False
assert provider_config.client_secret is None


def test_list_oidc_provider_configs(oidc_provider):
Expand All @@ -723,11 +729,17 @@ def test_update_oidc_provider_config():
client_id='UPDATED_OIDC_CLIENT_ID',
issuer='https://oidc.com/updated_issuer',
display_name='UPDATED_OIDC_DISPLAY_NAME',
enabled=False)
enabled=False,
client_secret='CLIENT_SECRET',
id_token_response_type=False,
code_response_type=True)
assert provider_config.client_id == 'UPDATED_OIDC_CLIENT_ID'
assert provider_config.issuer == 'https://oidc.com/updated_issuer'
assert provider_config.display_name == 'UPDATED_OIDC_DISPLAY_NAME'
assert provider_config.enabled is False
assert provider_config.response_type.id_token is False
assert provider_config.response_type.code is True
assert provider_config.client_secret == 'CLIENT_SECRET'
finally:
auth.delete_oidc_provider_config(provider_config.provider_id)

Expand Down Expand Up @@ -819,7 +831,9 @@ def _create_oidc_provider_config():
client_id='OIDC_CLIENT_ID',
issuer='https://oidc.com/issuer',
display_name='OIDC_DISPLAY_NAME',
enabled=True)
enabled=True,
id_token_response_type=True,
code_response_type=False)


def _create_saml_provider_config():
Expand Down
89 changes: 89 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Welcome to Firebase Hosting</title>

<!-- update the version number as needed -->
<script defer src="/__/firebase/8.4.3/firebase-app.js"></script>
<!-- include only the Firebase features as you need -->
<script defer src="/__/firebase/8.4.3/firebase-auth.js"></script>
<script defer src="/__/firebase/8.4.3/firebase-database.js"></script>
<script defer src="/__/firebase/8.4.3/firebase-firestore.js"></script>
<script defer src="/__/firebase/8.4.3/firebase-functions.js"></script>
<script defer src="/__/firebase/8.4.3/firebase-messaging.js"></script>
<script defer src="/__/firebase/8.4.3/firebase-storage.js"></script>
<script defer src="/__/firebase/8.4.3/firebase-analytics.js"></script>
<script defer src="/__/firebase/8.4.3/firebase-remote-config.js"></script>
<script defer src="/__/firebase/8.4.3/firebase-performance.js"></script>
<!--
initialize the SDK after all desired features are loaded, set useEmulator to false
to avoid connecting the SDK to running emulators.
-->
<script defer src="/__/firebase/init.js?useEmulator=true"></script>

<style media="screen">
body { background: #ECEFF1; color: rgba(0,0,0,0.87); font-family: Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 0; }
#message { background: white; max-width: 360px; margin: 100px auto 16px; padding: 32px 24px; border-radius: 3px; }
#message h2 { color: #ffa100; font-weight: bold; font-size: 16px; margin: 0 0 8px; }
#message h1 { font-size: 22px; font-weight: 300; color: rgba(0,0,0,0.6); margin: 0 0 16px;}
#message p { line-height: 140%; margin: 16px 0 24px; font-size: 14px; }
#message a { display: block; text-align: center; background: #039be5; text-transform: uppercase; text-decoration: none; color: white; padding: 16px; border-radius: 4px; }
#message, #message a { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); }
#load { color: rgba(0,0,0,0.4); text-align: center; font-size: 13px; }
@media (max-width: 600px) {
body, #message { margin-top: 0; background: white; box-shadow: none; }
body { border-top: 16px solid #ffa100; }
}
</style>
</head>
<body>
<div id="message">
<h2>Welcome</h2>
<h1>Firebase Hosting Setup Complete</h1>
<p>You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!</p>
<a target="_blank" href="https://firebase.google.com/docs/hosting/">Open Hosting Documentation</a>
</div>
<p id="load">Firebase SDK Loading&hellip;</p>

<script>
document.addEventListener('DOMContentLoaded', function() {
const loadEl = document.querySelector('#load');
// // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
// // The Firebase SDK is initialized and available here!
//
// firebase.auth().onAuthStateChanged(user => { });
// firebase.database().ref('/path/to/ref').on('value', snapshot => { });
// firebase.firestore().doc('/foo/bar').get().then(() => { });
// firebase.functions().httpsCallable('yourFunction')().then(() => { });
// firebase.messaging().requestPermission().then(() => { });
// firebase.storage().ref('/path/to/ref').getDownloadURL().then(() => { });
// firebase.analytics(); // call to activate
// firebase.analytics().logEvent('tutorial_completed');
// firebase.performance(); // call to activate
//
// // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥

try {
let app = firebase.app();
let features = [
'auth',
'database',
'firestore',
'functions',
'messaging',
'storage',
'analytics',
'remoteConfig',
'performance',
].filter(feature => typeof app[feature] === 'function');
loadEl.textContent = `Firebase SDK loaded with ${features.join(', ')}`;
} catch (e) {
console.error(e);
loadEl.textContent = 'Error loading the Firebase SDK, check the console.';
}
});
</script>
</body>
</html>
Loading