From fd79c1bacd8498a305e903d5684f693115fcb1da Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Fri, 30 Apr 2021 07:48:37 -0700 Subject: [PATCH 01/11] fix(auth): Enable OIDC auth code flow --- firebase_admin/_auth_client.py | 11 ++-- firebase_admin/_auth_providers.py | 23 +++++++- firebase_admin/auth.py | 10 ++-- integration/test_auth.py | 21 +++++++- public/index.html | 89 +++++++++++++++++++++++++++++++ tests/test_auth_providers.py | 34 ++++++++++-- 6 files changed, 172 insertions(+), 16 deletions(-) create mode 100644 public/index.html diff --git a/firebase_admin/_auth_client.py b/firebase_admin/_auth_client.py index 2f6713d41..3bcf16ad0 100644 --- a/firebase_admin/_auth_client.py +++ b/firebase_admin/_auth_client.py @@ -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 @@ -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: @@ -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. diff --git a/firebase_admin/_auth_providers.py b/firebase_admin/_auth_providers.py index 5126c862c..4ae58d7d6 100644 --- a/firebase_admin/_auth_providers.py +++ b/firebase_admin/_auth_providers.py @@ -179,7 +179,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 = { @@ -190,13 +191,23 @@ 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') 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 = {} @@ -211,6 +222,14 @@ 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') if not req: raise ValueError('At least one parameter must be specified for update.') diff --git a/firebase_admin/auth.py b/firebase_admin/auth.py index 5154bb495..cd9d5f2a6 100644 --- a/firebase_admin/auth.py +++ b/firebase_admin/auth.py @@ -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 @@ -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: @@ -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): diff --git a/integration/test_auth.py b/integration/test_auth.py index 16ae52a86..3f47ed16a 100644 --- a/integration/test_auth.py +++ b/integration/test_auth.py @@ -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 == False + assert oidc_provider.response_type.code == False + assert oidc_provider.client_secret == None def test_get_oidc_provider_config(oidc_provider): @@ -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 oidc_provider.response_type.id_token == False + assert oidc_provider.response_type.code == False + assert oidc_provider.client_secret == None def test_list_oidc_provider_configs(oidc_provider): @@ -723,11 +729,20 @@ 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.code == True + assert provider_config.response_type.id_token == True + assert provider_config.client_secret == True + assert oidc_provider.response_type.id_token == False + assert oidc_provider.response_type.code == True + assert oidc_provider.client_secret == 'CLIENT_SECRET' finally: auth.delete_oidc_provider_config(provider_config.provider_id) @@ -819,7 +834,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(): diff --git a/public/index.html b/public/index.html new file mode 100644 index 000000000..f053deb17 --- /dev/null +++ b/public/index.html @@ -0,0 +1,89 @@ + + + + + + Welcome to Firebase Hosting + + + + + + + + + + + + + + + + + + + +
+

Welcome

+

Firebase Hosting Setup Complete

+

You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!

+ Open Hosting Documentation +
+

Firebase SDK Loading…

+ + + + diff --git a/tests/test_auth_providers.py b/tests/test_auth_providers.py index 0947c77ae..e24b395b7 100644 --- a/tests/test_auth_providers.py +++ b/tests/test_auth_providers.py @@ -79,13 +79,21 @@ class TestOIDCProviderConfig: 'issuer': 'https://oidc.com/issuer', 'display_name': 'oidcProviderName', 'enabled': True, + 'id_token_response_type': True, + 'code_response_type': True, + 'client_secret': 'CLIENT_SECRET', } OIDC_CONFIG_REQUEST = { 'displayName': 'oidcProviderName', 'enabled': True, 'clientId': 'CLIENT_ID', + 'clientSecret': 'CLIENT_SECRET', 'issuer': 'https://oidc.com/issuer', + 'responseType': { + 'code': True, + 'idToken': True, + }, } @pytest.mark.parametrize('provider_id', INVALID_PROVIDER_IDS + ['saml.provider']) @@ -112,6 +120,9 @@ def test_get(self, user_mgt_app): {'issuer': None}, {'issuer': ''}, {'issuer': 'not a url'}, {'display_name': True}, {'enabled': 'true'}, + {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, + {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, + {'code_response_type': True, 'client_secret': None}, ]) def test_create_invalid_args(self, user_mgt_app, invalid_opts): options = dict(self.VALID_CREATE_OPTIONS) @@ -139,9 +150,14 @@ def test_create_minimal(self, user_mgt_app): options = dict(self.VALID_CREATE_OPTIONS) del options['display_name'] del options['enabled'] + del options['client_secret'] + del options['id_token_response_type'] + del options['code_response_type'] want = dict(self.OIDC_CONFIG_REQUEST) del want['displayName'] del want['enabled'] + del want['clientSecret'] + del want['responseType'] provider_config = auth.create_oidc_provider_config(**options, app=user_mgt_app) @@ -159,9 +175,16 @@ def test_create_empty_values(self, user_mgt_app): options = dict(self.VALID_CREATE_OPTIONS) options['display_name'] = '' options['enabled'] = False + options['code_response_type'] = False + options['id_token_response_type'] = False want = dict(self.OIDC_CONFIG_REQUEST) want['displayName'] = '' want['enabled'] = False + want['responseType'] = { + 'code': False, + 'idToken': False, + } + del want['clientSecret'] provider_config = auth.create_oidc_provider_config(**options, app=user_mgt_app) @@ -181,6 +204,9 @@ def test_create_empty_values(self, user_mgt_app): {'issuer': ''}, {'issuer': 'not a url'}, {'display_name': True}, {'enabled': 'true'}, + {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, + {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, + {'code_response_type': True, 'client_secret': None}, ]) def test_update_invalid_args(self, user_mgt_app, invalid_opts): options = {'provider_id': 'oidc.provider'} @@ -198,7 +224,7 @@ def test_update(self, user_mgt_app): assert len(recorder) == 1 req = recorder[0] assert req.method == 'PATCH' - mask = ['clientId', 'displayName', 'enabled', 'issuer'] + mask = ['clientId', 'clientSecret', 'displayName', 'enabled', 'issuer', 'responseType.code', 'responseType.idToken'] assert req.url == '{0}/oauthIdpConfigs/oidc.provider?updateMask={1}'.format( USER_MGT_URLS['PREFIX'], ','.join(mask)) got = json.loads(req.body.decode()) @@ -223,17 +249,17 @@ def test_update_empty_values(self, user_mgt_app): recorder = _instrument_provider_mgt(user_mgt_app, 200, OIDC_PROVIDER_CONFIG_RESPONSE) provider_config = auth.update_oidc_provider_config( - 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, app=user_mgt_app) + 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, id_token_response_type=False, code_response_type=False, app=user_mgt_app) self._assert_provider_config(provider_config) assert len(recorder) == 1 req = recorder[0] assert req.method == 'PATCH' - mask = ['displayName', 'enabled'] + mask = ['displayName', 'enabled', 'responseType.code', 'responseType.idToken'] assert req.url == '{0}/oauthIdpConfigs/oidc.provider?updateMask={1}'.format( USER_MGT_URLS['PREFIX'], ','.join(mask)) got = json.loads(req.body.decode()) - assert got == {'displayName': None, 'enabled': False} + assert got == {'displayName': None, 'enabled': False, 'responseType': {'code': False, 'idToken': False}} @pytest.mark.parametrize('provider_id', INVALID_PROVIDER_IDS + ['saml.provider']) def test_delete_invalid_provider_id(self, user_mgt_app, provider_id): From 226f36bed34adb80ce102663971c0f45940d69bf Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Fri, 30 Apr 2021 07:48:37 -0700 Subject: [PATCH 02/11] fix(auth): Enable OIDC auth code flow --- firebase_admin/_auth_client.py | 11 ++-- firebase_admin/_auth_providers.py | 43 ++++++++++++++- firebase_admin/auth.py | 10 ++-- integration/test_auth.py | 18 ++++++- public/index.html | 89 +++++++++++++++++++++++++++++++ tests/test_auth_providers.py | 34 ++++++++++-- 6 files changed, 189 insertions(+), 16 deletions(-) create mode 100644 public/index.html diff --git a/firebase_admin/_auth_client.py b/firebase_admin/_auth_client.py index 2f6713d41..3bcf16ad0 100644 --- a/firebase_admin/_auth_client.py +++ b/firebase_admin/_auth_client.py @@ -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 @@ -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: @@ -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. diff --git a/firebase_admin/_auth_providers.py b/firebase_admin/_auth_providers.py index 5126c862c..90b54891d 100644 --- a/firebase_admin/_auth_providers.py +++ b/firebase_admin/_auth_providers.py @@ -59,6 +59,26 @@ def issuer(self): def client_id(self): return self._data['clientId'] + @property + def client_secret(self): + return self._data.get('clientSecret') + + @property + def response_type(self): + return ResponseTypeProviderConfig(self._data['responseType']) + + +class ResponseTypeProviderConfig(ProviderConfig): + """Represents the "response type" portion of the OIDC auth provider configuration""" + + @property + def id_token(self): + return self._data.get('idToken', False) + + @property + def code(self): + return self._data.get('code', False) + class SAMLProviderConfig(ProviderConfig): """Represents he SAML auth provider configuration. @@ -179,7 +199,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 = { @@ -190,13 +211,23 @@ 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') 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 = {} @@ -211,6 +242,14 @@ 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') if not req: raise ValueError('At least one parameter must be specified for update.') diff --git a/firebase_admin/auth.py b/firebase_admin/auth.py index 5154bb495..cd9d5f2a6 100644 --- a/firebase_admin/auth.py +++ b/firebase_admin/auth.py @@ -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 @@ -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: @@ -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): diff --git a/integration/test_auth.py b/integration/test_auth.py index 16ae52a86..68f87b261 100644 --- a/integration/test_auth.py +++ b/integration/test_auth.py @@ -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 == True + assert oidc_provider.response_type.code == False + assert oidc_provider.client_secret == None def test_get_oidc_provider_config(oidc_provider): @@ -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 == True + assert provider_config.response_type.code == False + assert provider_config.client_secret == None def test_list_oidc_provider_configs(oidc_provider): @@ -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 == False + assert provider_config.response_type.code == True + assert provider_config.client_secret == 'CLIENT_SECRET' finally: auth.delete_oidc_provider_config(provider_config.provider_id) @@ -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(): diff --git a/public/index.html b/public/index.html new file mode 100644 index 000000000..f053deb17 --- /dev/null +++ b/public/index.html @@ -0,0 +1,89 @@ + + + + + + Welcome to Firebase Hosting + + + + + + + + + + + + + + + + + + + +
+

Welcome

+

Firebase Hosting Setup Complete

+

You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!

+ Open Hosting Documentation +
+

Firebase SDK Loading…

+ + + + diff --git a/tests/test_auth_providers.py b/tests/test_auth_providers.py index 0947c77ae..e24b395b7 100644 --- a/tests/test_auth_providers.py +++ b/tests/test_auth_providers.py @@ -79,13 +79,21 @@ class TestOIDCProviderConfig: 'issuer': 'https://oidc.com/issuer', 'display_name': 'oidcProviderName', 'enabled': True, + 'id_token_response_type': True, + 'code_response_type': True, + 'client_secret': 'CLIENT_SECRET', } OIDC_CONFIG_REQUEST = { 'displayName': 'oidcProviderName', 'enabled': True, 'clientId': 'CLIENT_ID', + 'clientSecret': 'CLIENT_SECRET', 'issuer': 'https://oidc.com/issuer', + 'responseType': { + 'code': True, + 'idToken': True, + }, } @pytest.mark.parametrize('provider_id', INVALID_PROVIDER_IDS + ['saml.provider']) @@ -112,6 +120,9 @@ def test_get(self, user_mgt_app): {'issuer': None}, {'issuer': ''}, {'issuer': 'not a url'}, {'display_name': True}, {'enabled': 'true'}, + {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, + {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, + {'code_response_type': True, 'client_secret': None}, ]) def test_create_invalid_args(self, user_mgt_app, invalid_opts): options = dict(self.VALID_CREATE_OPTIONS) @@ -139,9 +150,14 @@ def test_create_minimal(self, user_mgt_app): options = dict(self.VALID_CREATE_OPTIONS) del options['display_name'] del options['enabled'] + del options['client_secret'] + del options['id_token_response_type'] + del options['code_response_type'] want = dict(self.OIDC_CONFIG_REQUEST) del want['displayName'] del want['enabled'] + del want['clientSecret'] + del want['responseType'] provider_config = auth.create_oidc_provider_config(**options, app=user_mgt_app) @@ -159,9 +175,16 @@ def test_create_empty_values(self, user_mgt_app): options = dict(self.VALID_CREATE_OPTIONS) options['display_name'] = '' options['enabled'] = False + options['code_response_type'] = False + options['id_token_response_type'] = False want = dict(self.OIDC_CONFIG_REQUEST) want['displayName'] = '' want['enabled'] = False + want['responseType'] = { + 'code': False, + 'idToken': False, + } + del want['clientSecret'] provider_config = auth.create_oidc_provider_config(**options, app=user_mgt_app) @@ -181,6 +204,9 @@ def test_create_empty_values(self, user_mgt_app): {'issuer': ''}, {'issuer': 'not a url'}, {'display_name': True}, {'enabled': 'true'}, + {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, + {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, + {'code_response_type': True, 'client_secret': None}, ]) def test_update_invalid_args(self, user_mgt_app, invalid_opts): options = {'provider_id': 'oidc.provider'} @@ -198,7 +224,7 @@ def test_update(self, user_mgt_app): assert len(recorder) == 1 req = recorder[0] assert req.method == 'PATCH' - mask = ['clientId', 'displayName', 'enabled', 'issuer'] + mask = ['clientId', 'clientSecret', 'displayName', 'enabled', 'issuer', 'responseType.code', 'responseType.idToken'] assert req.url == '{0}/oauthIdpConfigs/oidc.provider?updateMask={1}'.format( USER_MGT_URLS['PREFIX'], ','.join(mask)) got = json.loads(req.body.decode()) @@ -223,17 +249,17 @@ def test_update_empty_values(self, user_mgt_app): recorder = _instrument_provider_mgt(user_mgt_app, 200, OIDC_PROVIDER_CONFIG_RESPONSE) provider_config = auth.update_oidc_provider_config( - 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, app=user_mgt_app) + 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, id_token_response_type=False, code_response_type=False, app=user_mgt_app) self._assert_provider_config(provider_config) assert len(recorder) == 1 req = recorder[0] assert req.method == 'PATCH' - mask = ['displayName', 'enabled'] + mask = ['displayName', 'enabled', 'responseType.code', 'responseType.idToken'] assert req.url == '{0}/oauthIdpConfigs/oidc.provider?updateMask={1}'.format( USER_MGT_URLS['PREFIX'], ','.join(mask)) got = json.loads(req.body.decode()) - assert got == {'displayName': None, 'enabled': False} + assert got == {'displayName': None, 'enabled': False, 'responseType': {'code': False, 'idToken': False}} @pytest.mark.parametrize('provider_id', INVALID_PROVIDER_IDS + ['saml.provider']) def test_delete_invalid_provider_id(self, user_mgt_app, provider_id): From 956b3cd9d25891bf4f23e25a953d1814955b83c0 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Mon, 3 May 2021 08:39:17 -0700 Subject: [PATCH 03/11] removing unintended file --- public/index.html | 89 ----------------------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 public/index.html diff --git a/public/index.html b/public/index.html deleted file mode 100644 index f053deb17..000000000 --- a/public/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - Welcome to Firebase Hosting - - - - - - - - - - - - - - - - - - - -
-

Welcome

-

Firebase Hosting Setup Complete

-

You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!

- Open Hosting Documentation -
-

Firebase SDK Loading…

- - - - From 2e4de1261d547459a5a1c331a827497f9797936a Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Mon, 7 Jun 2021 09:38:46 -0700 Subject: [PATCH 04/11] Changes requested by hiranya911 --- firebase_admin/_auth_providers.py | 52 +++++++++++++++++++++---------- integration/test_auth.py | 30 +++++++----------- tests/test_auth_providers.py | 11 ++++--- 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/firebase_admin/_auth_providers.py b/firebase_admin/_auth_providers.py index 4ae58d7d6..ab5facba0 100644 --- a/firebase_admin/_auth_providers.py +++ b/firebase_admin/_auth_providers.py @@ -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. @@ -191,14 +203,18 @@ 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) @@ -222,14 +238,18 @@ 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.') diff --git a/integration/test_auth.py b/integration/test_auth.py index 3f47ed16a..51a00a2fe 100644 --- a/integration/test_auth.py +++ b/integration/test_auth.py @@ -692,9 +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 == False - assert oidc_provider.response_type.code == False - assert oidc_provider.client_secret == None + 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): @@ -705,9 +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 oidc_provider.response_type.id_token == False - assert oidc_provider.response_type.code == False - assert oidc_provider.client_secret == None + 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): @@ -729,20 +729,14 @@ 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, - client_secret='CLIENT_SECRET', - id_token_response_type=False, - code_response_type=True) + enabled=False) 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.code == True - assert provider_config.response_type.id_token == True - assert provider_config.client_secret == True - assert oidc_provider.response_type.id_token == False - assert oidc_provider.response_type.code == True - assert oidc_provider.client_secret == 'CLIENT_SECRET' + 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) @@ -834,9 +828,7 @@ def _create_oidc_provider_config(): client_id='OIDC_CLIENT_ID', issuer='https://oidc.com/issuer', display_name='OIDC_DISPLAY_NAME', - enabled=True, - id_token_response_type=True, - code_response_type=False) + enabled=True) def _create_saml_provider_config(): diff --git a/tests/test_auth_providers.py b/tests/test_auth_providers.py index e24b395b7..34a3239bc 100644 --- a/tests/test_auth_providers.py +++ b/tests/test_auth_providers.py @@ -123,6 +123,7 @@ def test_get(self, user_mgt_app): {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, {'code_response_type': True, 'client_secret': None}, + {'code_response_type': False, 'id_token_response_type': False}, ]) def test_create_invalid_args(self, user_mgt_app, invalid_opts): options = dict(self.VALID_CREATE_OPTIONS) @@ -176,13 +177,12 @@ def test_create_empty_values(self, user_mgt_app): options['display_name'] = '' options['enabled'] = False options['code_response_type'] = False - options['id_token_response_type'] = False want = dict(self.OIDC_CONFIG_REQUEST) want['displayName'] = '' want['enabled'] = False want['responseType'] = { 'code': False, - 'idToken': False, + 'idToken': True, } del want['clientSecret'] @@ -207,6 +207,7 @@ def test_create_empty_values(self, user_mgt_app): {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, {'code_response_type': True, 'client_secret': None}, + {'code_response_type': False, 'id_token_response_type': False}, ]) def test_update_invalid_args(self, user_mgt_app, invalid_opts): options = {'provider_id': 'oidc.provider'} @@ -249,17 +250,17 @@ def test_update_empty_values(self, user_mgt_app): recorder = _instrument_provider_mgt(user_mgt_app, 200, OIDC_PROVIDER_CONFIG_RESPONSE) provider_config = auth.update_oidc_provider_config( - 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, id_token_response_type=False, code_response_type=False, app=user_mgt_app) + 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, id_token_response_type=False, app=user_mgt_app) self._assert_provider_config(provider_config) assert len(recorder) == 1 req = recorder[0] assert req.method == 'PATCH' - mask = ['displayName', 'enabled', 'responseType.code', 'responseType.idToken'] + mask = ['displayName', 'enabled', 'responseType.idToken'] assert req.url == '{0}/oauthIdpConfigs/oidc.provider?updateMask={1}'.format( USER_MGT_URLS['PREFIX'], ','.join(mask)) got = json.loads(req.body.decode()) - assert got == {'displayName': None, 'enabled': False, 'responseType': {'code': False, 'idToken': False}} + assert got == {'displayName': None, 'enabled': False, 'responseType': {'idToken': False}} @pytest.mark.parametrize('provider_id', INVALID_PROVIDER_IDS + ['saml.provider']) def test_delete_invalid_provider_id(self, user_mgt_app, provider_id): From d30726d7f89d427921f544b74f47d361a78dd296 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Mon, 7 Jun 2021 09:44:56 -0700 Subject: [PATCH 05/11] Changes requested by hiranya911 --- firebase_admin/_auth_providers.py | 52 +++++++++++++++++++++---------- integration/test_auth.py | 30 +++++++----------- tests/test_auth_providers.py | 11 ++++--- 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/firebase_admin/_auth_providers.py b/firebase_admin/_auth_providers.py index 4ae58d7d6..ab5facba0 100644 --- a/firebase_admin/_auth_providers.py +++ b/firebase_admin/_auth_providers.py @@ -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. @@ -191,14 +203,18 @@ 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) @@ -222,14 +238,18 @@ 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.') diff --git a/integration/test_auth.py b/integration/test_auth.py index 3f47ed16a..51a00a2fe 100644 --- a/integration/test_auth.py +++ b/integration/test_auth.py @@ -692,9 +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 == False - assert oidc_provider.response_type.code == False - assert oidc_provider.client_secret == None + 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): @@ -705,9 +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 oidc_provider.response_type.id_token == False - assert oidc_provider.response_type.code == False - assert oidc_provider.client_secret == None + 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): @@ -729,20 +729,14 @@ 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, - client_secret='CLIENT_SECRET', - id_token_response_type=False, - code_response_type=True) + enabled=False) 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.code == True - assert provider_config.response_type.id_token == True - assert provider_config.client_secret == True - assert oidc_provider.response_type.id_token == False - assert oidc_provider.response_type.code == True - assert oidc_provider.client_secret == 'CLIENT_SECRET' + 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) @@ -834,9 +828,7 @@ def _create_oidc_provider_config(): client_id='OIDC_CLIENT_ID', issuer='https://oidc.com/issuer', display_name='OIDC_DISPLAY_NAME', - enabled=True, - id_token_response_type=True, - code_response_type=False) + enabled=True) def _create_saml_provider_config(): diff --git a/tests/test_auth_providers.py b/tests/test_auth_providers.py index e24b395b7..34a3239bc 100644 --- a/tests/test_auth_providers.py +++ b/tests/test_auth_providers.py @@ -123,6 +123,7 @@ def test_get(self, user_mgt_app): {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, {'code_response_type': True, 'client_secret': None}, + {'code_response_type': False, 'id_token_response_type': False}, ]) def test_create_invalid_args(self, user_mgt_app, invalid_opts): options = dict(self.VALID_CREATE_OPTIONS) @@ -176,13 +177,12 @@ def test_create_empty_values(self, user_mgt_app): options['display_name'] = '' options['enabled'] = False options['code_response_type'] = False - options['id_token_response_type'] = False want = dict(self.OIDC_CONFIG_REQUEST) want['displayName'] = '' want['enabled'] = False want['responseType'] = { 'code': False, - 'idToken': False, + 'idToken': True, } del want['clientSecret'] @@ -207,6 +207,7 @@ def test_create_empty_values(self, user_mgt_app): {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, {'code_response_type': True, 'client_secret': None}, + {'code_response_type': False, 'id_token_response_type': False}, ]) def test_update_invalid_args(self, user_mgt_app, invalid_opts): options = {'provider_id': 'oidc.provider'} @@ -249,17 +250,17 @@ def test_update_empty_values(self, user_mgt_app): recorder = _instrument_provider_mgt(user_mgt_app, 200, OIDC_PROVIDER_CONFIG_RESPONSE) provider_config = auth.update_oidc_provider_config( - 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, id_token_response_type=False, code_response_type=False, app=user_mgt_app) + 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, id_token_response_type=False, app=user_mgt_app) self._assert_provider_config(provider_config) assert len(recorder) == 1 req = recorder[0] assert req.method == 'PATCH' - mask = ['displayName', 'enabled', 'responseType.code', 'responseType.idToken'] + mask = ['displayName', 'enabled', 'responseType.idToken'] assert req.url == '{0}/oauthIdpConfigs/oidc.provider?updateMask={1}'.format( USER_MGT_URLS['PREFIX'], ','.join(mask)) got = json.loads(req.body.decode()) - assert got == {'displayName': None, 'enabled': False, 'responseType': {'code': False, 'idToken': False}} + assert got == {'displayName': None, 'enabled': False, 'responseType': {'idToken': False}} @pytest.mark.parametrize('provider_id', INVALID_PROVIDER_IDS + ['saml.provider']) def test_delete_invalid_provider_id(self, user_mgt_app, provider_id): From 5788a7171ba27c0d74e442ced95b2906580fcc41 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Wed, 6 Oct 2021 12:48:11 -0700 Subject: [PATCH 06/11] Changes requested by hiranya911 --- firebase_admin/_auth_providers.py | 4 +- public/index.html | 89 ------------------------------- 2 files changed, 2 insertions(+), 91 deletions(-) delete mode 100644 public/index.html diff --git a/firebase_admin/_auth_providers.py b/firebase_admin/_auth_providers.py index ab5facba0..3d6bf8bd1 100644 --- a/firebase_admin/_auth_providers.py +++ b/firebase_admin/_auth_providers.py @@ -206,7 +206,7 @@ def create_oidc_provider_config( 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.") + 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: @@ -241,7 +241,7 @@ def update_oidc_provider_config( 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.") + 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: diff --git a/public/index.html b/public/index.html deleted file mode 100644 index f053deb17..000000000 --- a/public/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - Welcome to Firebase Hosting - - - - - - - - - - - - - - - - - - - -
-

Welcome

-

Firebase Hosting Setup Complete

-

You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!

- Open Hosting Documentation -
-

Firebase SDK Loading…

- - - - From 1644b15c3ad2176b7fa29c39ca9ff46c435f1fe0 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Thu, 28 Oct 2021 13:56:30 -0700 Subject: [PATCH 07/11] Changes requested by Hiranya --- firebase_admin/_auth_providers.py | 24 ------------------------ integration/test_auth.py | 9 +++++++-- 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/firebase_admin/_auth_providers.py b/firebase_admin/_auth_providers.py index dc8631f6a..3d6bf8bd1 100644 --- a/firebase_admin/_auth_providers.py +++ b/firebase_admin/_auth_providers.py @@ -216,18 +216,6 @@ def create_oidc_provider_config( if response_type: req['responseType'] = 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 - params = 'oauthIdpConfigId={0}'.format(provider_id) body = self._make_request('post', '/oauthIdpConfigs', json=req, params=params) return OIDCProviderConfig(body) @@ -263,18 +251,6 @@ def update_oidc_provider_config( if response_type: req['responseType'] = 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.') diff --git a/integration/test_auth.py b/integration/test_auth.py index 863944c03..1009816eb 100644 --- a/integration/test_auth.py +++ b/integration/test_auth.py @@ -773,7 +773,10 @@ 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' @@ -872,7 +875,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(): From 15c69bcb6c76bfab21cc0347b519c9e88064a03a Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 30 Nov 2021 15:25:28 -0800 Subject: [PATCH 08/11] Linting errors --- firebase_admin/_auth_client.py | 21 ++++++++++++++++++++- firebase_admin/_auth_providers.py | 12 ++++++++---- firebase_admin/auth.py | 24 ++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/firebase_admin/_auth_client.py b/firebase_admin/_auth_client.py index 03a431c1f..812f716a6 100644 --- a/firebase_admin/_auth_client.py +++ b/firebase_admin/_auth_client.py @@ -529,6 +529,15 @@ def create_oidc_provider_config( This name is also used as the provider label in the Cloud Console. enabled: A boolean indicating whether the provider configuration is enabled or disabled (optional). A user cannot sign in using a disabled provider. + client_secret: A string which sets the client secret for the new provider. + This is required for the code flow. + code_response_type: Sets whether to enable the code response flow for the new provider. + By default, this is not enabled if no response type is specified. + A client secret must be set for this response type. + Having both the code and ID token response flows is currently not supported. + id_token_response_type: Sets whether to enable the ID token response flow for the new + provider. By default, this is enabled if no response type is specified. + Having both the code and ID token response flows is currently not supported. Returns: OIDCProviderConfig: The newly created OIDC provider config instance. @@ -543,7 +552,8 @@ def create_oidc_provider_config( 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, client_secret=None, id_token_response_type=None, code_response_type=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: @@ -554,6 +564,15 @@ def update_oidc_provider_config( Pass ``auth.DELETE_ATTRIBUTE`` to delete the current display name. enabled: A boolean indicating whether the provider configuration is enabled or disabled (optional). + client_secret: A string which sets the client secret for the new provider. + This is required for the code flow. + code_response_type: Sets whether to enable the code response flow for the new provider. + By default, this is not enabled if no response type is specified. + A client secret must be set for this response type. + Having both the code and ID token response flows is currently not supported. + id_token_response_type: Sets whether to enable the ID token response flow for the new + provider. By default, this is enabled if no response type is specified. + Having both the code and ID token response flows is currently not supported. Returns: OIDCProviderConfig: The updated OIDC provider config instance. diff --git a/firebase_admin/_auth_providers.py b/firebase_admin/_auth_providers.py index 3d6bf8bd1..31511f3c5 100644 --- a/firebase_admin/_auth_providers.py +++ b/firebase_admin/_auth_providers.py @@ -208,9 +208,11 @@ def create_oidc_provider_config( 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') + 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') + 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: @@ -243,9 +245,11 @@ def update_oidc_provider_config( 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') + 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') + 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: diff --git a/firebase_admin/auth.py b/firebase_admin/auth.py index ca5e806b5..a61fda9b3 100644 --- a/firebase_admin/auth.py +++ b/firebase_admin/auth.py @@ -656,7 +656,8 @@ 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, client_secret=None, id_token_response_type=None, code_response_type=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 @@ -671,6 +672,15 @@ def create_oidc_provider_config( enabled: A boolean indicating whether the provider configuration is enabled or disabled (optional). A user cannot sign in using a disabled provider. app: An App instance (optional). + client_secret: A string which sets the client secret for the new provider. + This is required for the code flow. + code_response_type: Sets whether to enable the code response flow for the new provider. + By default, this is not enabled if no response type is specified. + A client secret must be set for this response type. + Having both the code and ID token response flows is currently not supported. + id_token_response_type: Sets whether to enable the ID token response flow for the new + provider. By default, this is enabled if no response type is specified. + Having both the code and ID token response flows is currently not supported. Returns: OIDCProviderConfig: The newly created OIDC provider config instance. @@ -687,7 +697,8 @@ def create_oidc_provider_config( def update_oidc_provider_config( - 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): + 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: @@ -699,6 +710,15 @@ def update_oidc_provider_config( enabled: A boolean indicating whether the provider configuration is enabled or disabled (optional). app: An App instance (optional). + client_secret: A string which sets the client secret for the new provider. + This is required for the code flow. + code_response_type: Sets whether to enable the code response flow for the new provider. + By default, this is not enabled if no response type is specified. + A client secret must be set for this response type. + Having both the code and ID token response flows is currently not supported. + id_token_response_type: Sets whether to enable the ID token response flow for the new + provider. By default, this is enabled if no response type is specified. + Having both the code and ID token response flows is currently not supported. Returns: OIDCProviderConfig: The updated OIDC provider config instance. From 93ff944aea5b0f71214e7cfdb6ccbeee6d4d5c7a Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 7 Dec 2021 13:09:49 -0800 Subject: [PATCH 09/11] Linting Errors --- tests/test_auth_providers.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/test_auth_providers.py b/tests/test_auth_providers.py index 34a3239bc..a13b19636 100644 --- a/tests/test_auth_providers.py +++ b/tests/test_auth_providers.py @@ -121,7 +121,8 @@ def test_get(self, user_mgt_app): {'display_name': True}, {'enabled': 'true'}, {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, - {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, + {'code_response_type': True, 'client_secret': ''}, + {'code_response_type': True, 'client_secret': True}, {'code_response_type': True, 'client_secret': None}, {'code_response_type': False, 'id_token_response_type': False}, ]) @@ -205,7 +206,8 @@ def test_create_empty_values(self, user_mgt_app): {'display_name': True}, {'enabled': 'true'}, {'id_token_response_type': 'true'}, {'code_response_type': 'true'}, - {'code_response_type': True, 'client_secret': ''}, {'code_response_type': True, 'client_secret': True}, + {'code_response_type': True, 'client_secret': ''}, + {'code_response_type': True, 'client_secret': True}, {'code_response_type': True, 'client_secret': None}, {'code_response_type': False, 'id_token_response_type': False}, ]) @@ -225,7 +227,8 @@ def test_update(self, user_mgt_app): assert len(recorder) == 1 req = recorder[0] assert req.method == 'PATCH' - mask = ['clientId', 'clientSecret', 'displayName', 'enabled', 'issuer', 'responseType.code', 'responseType.idToken'] + mask = ['clientId', 'clientSecret', 'displayName', 'enabled', 'issuer', + 'responseType.code', 'responseType.idToken'] assert req.url == '{0}/oauthIdpConfigs/oidc.provider?updateMask={1}'.format( USER_MGT_URLS['PREFIX'], ','.join(mask)) got = json.loads(req.body.decode()) @@ -250,7 +253,8 @@ def test_update_empty_values(self, user_mgt_app): recorder = _instrument_provider_mgt(user_mgt_app, 200, OIDC_PROVIDER_CONFIG_RESPONSE) provider_config = auth.update_oidc_provider_config( - 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, id_token_response_type=False, app=user_mgt_app) + 'oidc.provider', display_name=auth.DELETE_ATTRIBUTE, enabled=False, + id_token_response_type=False, app=user_mgt_app) self._assert_provider_config(provider_config) assert len(recorder) == 1 From 5d021c65c1e6a5d6c6583949a605d358152cdb20 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 7 Dec 2021 13:30:30 -0800 Subject: [PATCH 10/11] Linting Errors --- tests/test_auth_providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_auth_providers.py b/tests/test_auth_providers.py index a13b19636..b67a8eb96 100644 --- a/tests/test_auth_providers.py +++ b/tests/test_auth_providers.py @@ -228,7 +228,7 @@ def test_update(self, user_mgt_app): req = recorder[0] assert req.method == 'PATCH' mask = ['clientId', 'clientSecret', 'displayName', 'enabled', 'issuer', - 'responseType.code', 'responseType.idToken'] + 'responseType.code', 'responseType.idToken'] assert req.url == '{0}/oauthIdpConfigs/oidc.provider?updateMask={1}'.format( USER_MGT_URLS['PREFIX'], ','.join(mask)) got = json.loads(req.body.decode()) From df4a0f16be5979f0f2f336f452fef6f824b438c4 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Fri, 10 Dec 2021 13:43:31 -0800 Subject: [PATCH 11/11] Changes requested by kevinthecheung@ --- firebase_admin/_auth_client.py | 20 +++++++++++--------- firebase_admin/auth.py | 16 ++++++++-------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/firebase_admin/_auth_client.py b/firebase_admin/_auth_client.py index 812f716a6..eaf491f32 100644 --- a/firebase_admin/_auth_client.py +++ b/firebase_admin/_auth_client.py @@ -531,12 +531,13 @@ def create_oidc_provider_config( (optional). A user cannot sign in using a disabled provider. client_secret: A string which sets the client secret for the new provider. This is required for the code flow. - code_response_type: Sets whether to enable the code response flow for the new provider. - By default, this is not enabled if no response type is specified. - A client secret must be set for this response type. + code_response_type: A boolean which sets whether to enable the code response flow for + the new provider. By default, this is not enabled if no response type is + specified. A client secret must be set for this response type. Having both the code and ID token response flows is currently not supported. - id_token_response_type: Sets whether to enable the ID token response flow for the new - provider. By default, this is enabled if no response type is specified. + id_token_response_type: A boolean which sets whether to enable the ID token response + flow for the new provider. By default, this is enabled if no response type is + specified. Having both the code and ID token response flows is currently not supported. Returns: @@ -566,12 +567,13 @@ def update_oidc_provider_config( (optional). client_secret: A string which sets the client secret for the new provider. This is required for the code flow. - code_response_type: Sets whether to enable the code response flow for the new provider. - By default, this is not enabled if no response type is specified. + code_response_type: A boolean which sets whether to enable the code response flow for + the new provider. By default, this is not enabled if no response type is specified. A client secret must be set for this response type. Having both the code and ID token response flows is currently not supported. - id_token_response_type: Sets whether to enable the ID token response flow for the new - provider. By default, this is enabled if no response type is specified. + id_token_response_type: A boolean which sets whether to enable the ID token response + flow for the new provider. By default, this is enabled if no response type is + specified. Having both the code and ID token response flows is currently not supported. Returns: diff --git a/firebase_admin/auth.py b/firebase_admin/auth.py index a61fda9b3..6902a322f 100644 --- a/firebase_admin/auth.py +++ b/firebase_admin/auth.py @@ -674,12 +674,12 @@ def create_oidc_provider_config( app: An App instance (optional). client_secret: A string which sets the client secret for the new provider. This is required for the code flow. - code_response_type: Sets whether to enable the code response flow for the new provider. - By default, this is not enabled if no response type is specified. + code_response_type: A boolean which sets whether to enable the code response flow for the + new provider. By default, this is not enabled if no response type is specified. A client secret must be set for this response type. Having both the code and ID token response flows is currently not supported. - id_token_response_type: Sets whether to enable the ID token response flow for the new - provider. By default, this is enabled if no response type is specified. + id_token_response_type: A boolean which sets whether to enable the ID token response flow + for the new provider. By default, this is enabled if no response type is specified. Having both the code and ID token response flows is currently not supported. Returns: @@ -712,12 +712,12 @@ def update_oidc_provider_config( app: An App instance (optional). client_secret: A string which sets the client secret for the new provider. This is required for the code flow. - code_response_type: Sets whether to enable the code response flow for the new provider. - By default, this is not enabled if no response type is specified. + code_response_type: A boolean which sets whether to enable the code response flow for the + new provider. By default, this is not enabled if no response type is specified. A client secret must be set for this response type. Having both the code and ID token response flows is currently not supported. - id_token_response_type: Sets whether to enable the ID token response flow for the new - provider. By default, this is enabled if no response type is specified. + id_token_response_type: A boolean which sets whether to enable the ID token response flow + for the new provider. By default, this is enabled if no response type is specified. Having both the code and ID token response flows is currently not supported. Returns: