def test_no_credenntials_raises_bad_user_configuration_error(): no_credentials_exception = BadUserConfigurationException( "Failed to obtain access token. Run `gcloud auth login` in your command line \ to authorize gcloud to access the Cloud Platform with Google user credentials to authenticate. Run `gcloud auth \ application-default login` acquire new user credentials to use for Application Default Credentials." ) google_auth = GoogleAuth() google_auth.project_widget.value = 'project_id' google_auth.region_widget.value = 'region' google_auth.cluster_widget.value = 'cluster_name' google_auth.credentials = None assert_raises(google_auth.update_with_widget_values(), no_credentials_exception)
def test_initialize_credentials_with_auth_dropdown_user_credentials_to_user_credentials( ): """If Google Authenticator is initialized with user credentials, if the account dropdown is not changed to a different account, credentials should not be reinitialized when the endpoint is added.""" with patch('subprocess.check_output', return_value=AUTH_DESCRIBE_USER), \ patch('google.auth.default', side_effect=DefaultCredentialsError), \ patch('google.auth._cloud_sdk.get_auth_access_token', return_value='token'), \ patch('google.oauth2._client.refresh_grant', return_value=('token', 'refresh', \ expiry, grant_response)), \ patch('googledataprocauthenticator.google.list_credentialed_user_accounts', return_value=mock_credentialed_accounts_valid_accounts): google_auth = GoogleAuth() assert_equals(google_auth.active_credentials, '*****@*****.**') google_auth.initialize_credentials_with_auth_account_selection( google_auth.active_credentials) google.auth.default.assert_called_once_with(scopes=google_auth.scopes)
def test_google_auth(): retry_policy = LinearRetryPolicy(0.01, 5) endpoint = Endpoint("http://url.com", GoogleAuth()) client = ReliableHttpClient(endpoint, {}, retry_policy) assert_is_not_none(client._auth) assert isinstance(client._auth, GoogleAuth) assert hasattr(client._auth, 'url') assert hasattr(client._auth, 'widgets')
def test_default_credentials_not_configured_and_no_active_account_credentials_is_none( ): """Tests GoogleAuth.credentials gets initialized to None when default credentials are not configured and the user has no credentialed accounts""" with patch('google.auth.default', side_effect=DefaultCredentialsError, \ autospec=True), patch('googledataprocauthenticator.google.list_credentialed_user_accounts',\ return_value=mock_credentialed_accounts_no_accounts): assert_equals(GoogleAuth().credentials, None)
def test_default_credentials_not_configured_account_pairs_contains_no_default( ): """Tests default-credentials is not in google credentials dropdown if if default credentials are not configured""" with patch('google.auth.default', side_effect=DefaultCredentialsError, \ autospec=True): assert_false( 'default-credentials' in GoogleAuth().account_widget.items)
def test_get_google(): retry_policy = LinearRetryPolicy(0.01, 5) with patch('requests.Session.get') as patched_get: type(patched_get.return_value).status_code = 200 endpoint = Endpoint("http://url.com", GoogleAuth()) client = ReliableHttpClient(endpoint, {}, retry_policy) result = client.get("r", [200]) assert_equals(200, result.status_code)
def test_initialize_credentials_with_auth_dropdown_default_credentials_to_default_credentials( ): """If Google Authenticator is initialized with default-credentials, if the account dropdown is not changed to a different account, credentials should not be reinitialized when the endpoint is added.""" with patch('subprocess.check_output', return_value=AUTH_LIST), \ patch('google.auth.default', return_value=(not_refreshed_credentials(), 'project')) as d, \ patch('google.auth._cloud_sdk.get_auth_access_token', return_value='token'), \ patch('google.oauth2._client.refresh_grant', return_value=('token', 'refresh', \ expiry, grant_response)), \ patch('googledataprocauthenticator.google.list_credentialed_user_accounts', return_value=mock_credentialed_accounts_valid_accounts): google_auth = GoogleAuth() assert_equals(google_auth.active_credentials, 'default-credentials') google_auth.initialize_credentials_with_auth_account_selection( google_auth.active_credentials) assert_equals(google_auth.active_credentials, 'default-credentials') d.assert_has_calls( [call(scopes=google_auth.scopes), call(scopes=google_auth.scopes)])
def test_default_credentials_not_configured_credentials_and_active_account_is_not_none( ): """Tests GoogleAuth.credentials gets initialized with active credentialed user account when one is available""" with patch('google.auth.default', side_effect=DefaultCredentialsError, \ autospec=True), patch('googledataprocauthenticator.google.list_credentialed_user_accounts', \ return_value=mock_credentialed_accounts_valid_accounts), patch('subprocess.check_output', \ return_value=AUTH_DESCRIBE_USER): assert_is_not_none(GoogleAuth().credentials)
def test_initialize_credentials_with_default_credentials_configured(): with patch('subprocess.check_output', return_value=AUTH_LIST), \ patch('google.auth.default', return_value=(not_refreshed_credentials(), 'project')), \ patch('google.auth._cloud_sdk.get_auth_access_token', return_value='token'), \ patch('google.oauth2._client.refresh_grant', return_value=('token', 'refresh', \ expiry, grant_response)): google_auth = GoogleAuth() assert_equals(google_auth.active_credentials, 'default-credentials') assert_equals(google_auth.credentials.client_secret, 'client_secret') assert_equals(google_auth.credentials.token, None)
def test_initialize_credentials_with_no_default_credentials_configured(): with patch('subprocess.check_output', return_value=AUTH_DESCRIBE_USER), \ patch('google.auth.default', side_effect=DefaultCredentialsError), \ patch('googledataprocauthenticator.google.list_credentialed_user_accounts', return_value=AUTH_LIST), \ patch('google.auth._cloud_sdk.get_auth_access_token', return_value='token'), \ patch('google.oauth2._client.refresh_grant', return_value=('token', 'refresh', \ expiry, grant_response)), \ patch('googledataprocauthenticator.google.list_credentialed_user_accounts', return_value=mock_credentialed_accounts_valid_accounts): google_auth = GoogleAuth() assert_equals(google_auth.active_credentials, '*****@*****.**') assert_equals(google_auth.credentials.client_secret, 'secret') assert_equals(google_auth.credentials.token, None)
def test_call_default_credentials_no_dropdown_change(): with patch('subprocess.check_output', return_value=AUTH_LIST), \ patch('google.auth.default', return_value=(not_refreshed_credentials(), 'project')), \ patch('google.auth._cloud_sdk.get_auth_access_token', return_value='token'), \ patch('google.oauth2._client.refresh_grant', return_value=('token', 'refresh', \ expiry, grant_response)): google_auth = GoogleAuth() google_auth.initialize_credentials_with_auth_account_selection( 'default-credentials') request = requests.Request(url="http://www.example.org") google_auth.__call__(request) assert_true('Authorization' in request.headers) assert_equals(request.headers['Authorization'], 'Bearer {}'.format(google_auth.credentials.token))
def test_call_user_credentials_no_dropdown_change(): with patch('subprocess.check_output', return_value=AUTH_DESCRIBE_USER), \ patch('google.auth.default', return_value=(DefaultCredentialsError, 'project')), \ patch('google.auth._cloud_sdk.get_auth_access_token', return_value='token'), \ patch('google.oauth2._client.refresh_grant', return_value=('token', 'refresh', \ expiry, grant_response)), \ patch('googledataprocauthenticator.google.list_credentialed_user_accounts', return_value=mock_credentialed_accounts_valid_accounts): google_auth = GoogleAuth() google_auth.initialize_credentials_with_auth_account_selection( '*****@*****.**') request = requests.Request(url="http://www.example.org") google_auth.__call__(request) assert_true('Authorization' in request.headers) assert_equals(request.headers['Authorization'], 'Bearer {}'.format(google_auth.credentials.token))
class AddEndpointWidget(AbstractMenuWidget): def __init__(self, spark_controller, ipywidget_factory, ipython_display, endpoints, refresh_method, state, db): super(AddEndpointWidget, self).__init__(spark_controller, ipywidget_factory, ipython_display, True) self.endpoints = endpoints self.refresh_method = refresh_method self.state = state self.delete_pressed = False self.db = db self.auth = GoogleAuth() add_endpoint_button = v.Btn(class_='ma-2', color='primary', children=['Add Endpoint']) add_endpoint_button.on_event('click', self._add_endpoint) cancel_button = v.Btn(class_='ma-2', color='primary', children=['Cancel']) cancel_button.on_event('click', self._on_cancel_click) backicon = v.Icon(children=['mdi-arrow-left']) backicon.on_event('click', self._on_back_click) back_toolbar = v.Toolbar( elevation="0", children=[ v.ToolbarItems(children=[backicon]), v.ToolbarTitle(children=['Create new endpoint']), v.Spacer() ], app=True, # If true, the other widgets float under on scroll ) self.create_endpoint_widget = v.Container( style_=f'width: {WIDGET_WIDTH};', class_='ma-2', children=[ back_toolbar, v.Row(class_='ma-2', children=[ v.Col(children=[self.auth.account_widget]), v.Col(children=[self.auth.project_widget]), v.Col(children=[self.auth.region_widget]) ]), v.Row(class_='ma-2', children=[ v.Col(children=[self.auth.cluster_widget]), v.Col(children=[self.auth.filter_widget]), v.Col(children=[v.Spacer()]), ]), v.Row(class_='ma-2', children=[add_endpoint_button, cancel_button]) ]) endpoint_table_values = self._generate_endpoint_values() new_endpoint = v.Btn(class_='ma-2', color='primary', children=['New Endpoint']) new_endpoint.on_event('click', self._on_new_endpoint_click) no_back_toolbar = v.Toolbar( elevation="0", children=[ v.ToolbarTitle(titleMarginStart='12dp', contentInsetStartWithNavigation="56dp", children=['Endpoints']), v.Spacer() ], app=True, # If true, the other widgets float under on scroll ) toolbar = v.Row(children=[no_back_toolbar, new_endpoint]) delete_icon = v.Icon(children=['mdi-delete']) delete_icon.on_event('click', self._on_delete_icon_pressed) endpoint_table = v.DataTable(style_=f'width: {WIDGET_WIDTH};', no_data_text='No endpoints', hide_default_footer=True, disable_pagination=True, item_key='url', headers=[ { 'text': 'Cluster', 'align': 'start', 'sortable': False, 'value': 'name' }, { 'text': 'Project', 'sortable': False, 'value': 'project' }, { 'text': 'Region', 'sortable': False, 'value': 'region' }, { 'text': 'Account', 'sortable': False, 'value': 'account' }, { 'text': 'Url', 'sortable': False, 'value': 'url' }, { 'text': '', 'sortable': False, 'value': 'actions' }, ], items=endpoint_table_values, dense=False, v_slots=[{ 'name': 'item.actions', 'children': [delete_icon] }, { 'name': 'no-data', 'children': ['No endpoints'] }]) endpoint_table.on_event('click:row', self._remove_row_from_table) self.toolbar_with_table = v.Container( style_=f'width: {WIDGET_WIDTH};', class_='mx-auto', children=[ v.Row(class_='mx-auto', children=[toolbar]), v.Row(class_='mx-auto', children=[endpoint_table]) ]) self.children = [self.create_endpoint_widget, self.toolbar_with_table] for child in self.children: child.parent_widget = self self._update_view() def run(self): pass def _add_endpoint(self, _widget, _event, _data): self.state = 'list' self.auth.update_with_widget_values() endpoint = Endpoint(self.auth.url, self.auth) self.endpoints[self.auth.url] = endpoint # convert Endpoints in self.endpoints into list of dictionaries, each storing an Endpoints # writeable attributes stored_endpoints = [ SerializableEndpoint(endpoint).__dict__ for endpoint in self.endpoints.values() ] # stored updated stored_endpoints self.db['autorestore/' + 'stored_endpoints'] = stored_endpoints self.ipython_display.writeln("Added endpoint {}".format(self.auth.url)) try: self.refresh_method(1) except: self.endpoints.pop(self.auth.url, None) self.refresh_method(1) raise def _update_view(self): if self.state == 'add': self.toolbar_with_table.layout.display = 'none' self.create_endpoint_widget.layout.display = 'flex' elif self.state == 'list': self.create_endpoint_widget.layout.display = 'none' self.toolbar_with_table.layout.display = 'flex' def _remove_row_from_table(self, _table, _event, row): if self.delete_pressed: endpoint_url = row.get('url') try: self.endpoints.pop(endpoint_url) stored_endpoints = [ SerializableEndpoint(endpoint).__dict__ for endpoint in self.endpoints.values() ] # stored updated stored_endpoints self.db['autorestore/' + 'stored_endpoints'] = stored_endpoints self.refresh_method(1) except Exception as caught_exc: self.ipython_display.send_error("Failed delete session due to the following "\ f"error: {str(caught_exc)}") def _on_cancel_click(self, _widget, _event, _data): self.state = 'list' self._update_view() def _on_back_click(self, _widget, _event, _data): self.state = 'list' self._update_view() def _on_new_endpoint_click(self, _widget, _event, _data): self.state = 'add' self._update_view() def _on_delete_icon_pressed(self, _widget, _event, _data): self.delete_pressed = True def _generate_endpoint_values(self): endpoint_table_values = [] for endpoint in get_stored_endpoints(self.db, self.ipython_display): endpoint_table_values.append({ 'name': endpoint.get('cluster'), 'url': endpoint.get('url'), 'project': endpoint.get('project'), 'region': endpoint.get('region'), 'account': endpoint.get('account') }) return endpoint_table_values
def test_default_credentials_configured_account_pairs_contains_default(): """Tests default-credentials is in google credentials dropdown if if default credentials are configured""" with patch('google.auth.default', return_value=(MOCK_CREDENTIALS, 'project'), \ autospec=True): assert_true('default-credentials' in GoogleAuth().account_widget.items)
def test_default_credentials_configured_credentials_is_not_none(): """Tests GoogleAuth.credentials gets initialized when default credentials are configured""" with patch('google.auth.default', return_value=(creds, 'project'), \ autospec=True): assert_equals(GoogleAuth().credentials, creds) assert_is_not_none(GoogleAuth().credentials)
def test_dropdown_items_with_default_credentials_configured(): with patch('subprocess.check_output', return_value=AUTH_LIST), \ patch('google.auth.default', return_value=(MOCK_CREDENTIALS, 'project')), \ patch('google.auth._cloud_sdk.get_auth_access_token', return_value='token'): assert_equals(GoogleAuth().account_widget.items, ['*****@*****.**', 'default-credentials'])
def __init__(self, spark_controller, ipywidget_factory, ipython_display, endpoints, refresh_method, state, db): super(AddEndpointWidget, self).__init__(spark_controller, ipywidget_factory, ipython_display, True) self.endpoints = endpoints self.refresh_method = refresh_method self.state = state self.delete_pressed = False self.db = db self.auth = GoogleAuth() add_endpoint_button = v.Btn(class_='ma-2', color='primary', children=['Add Endpoint']) add_endpoint_button.on_event('click', self._add_endpoint) cancel_button = v.Btn(class_='ma-2', color='primary', children=['Cancel']) cancel_button.on_event('click', self._on_cancel_click) backicon = v.Icon(children=['mdi-arrow-left']) backicon.on_event('click', self._on_back_click) back_toolbar = v.Toolbar( elevation="0", children=[ v.ToolbarItems(children=[backicon]), v.ToolbarTitle(children=['Create new endpoint']), v.Spacer() ], app=True, # If true, the other widgets float under on scroll ) self.create_endpoint_widget = v.Container( style_=f'width: {WIDGET_WIDTH};', class_='ma-2', children=[ back_toolbar, v.Row(class_='ma-2', children=[ v.Col(children=[self.auth.account_widget]), v.Col(children=[self.auth.project_widget]), v.Col(children=[self.auth.region_widget]) ]), v.Row(class_='ma-2', children=[ v.Col(children=[self.auth.cluster_widget]), v.Col(children=[self.auth.filter_widget]), v.Col(children=[v.Spacer()]), ]), v.Row(class_='ma-2', children=[add_endpoint_button, cancel_button]) ]) endpoint_table_values = self._generate_endpoint_values() new_endpoint = v.Btn(class_='ma-2', color='primary', children=['New Endpoint']) new_endpoint.on_event('click', self._on_new_endpoint_click) no_back_toolbar = v.Toolbar( elevation="0", children=[ v.ToolbarTitle(titleMarginStart='12dp', contentInsetStartWithNavigation="56dp", children=['Endpoints']), v.Spacer() ], app=True, # If true, the other widgets float under on scroll ) toolbar = v.Row(children=[no_back_toolbar, new_endpoint]) delete_icon = v.Icon(children=['mdi-delete']) delete_icon.on_event('click', self._on_delete_icon_pressed) endpoint_table = v.DataTable(style_=f'width: {WIDGET_WIDTH};', no_data_text='No endpoints', hide_default_footer=True, disable_pagination=True, item_key='url', headers=[ { 'text': 'Cluster', 'align': 'start', 'sortable': False, 'value': 'name' }, { 'text': 'Project', 'sortable': False, 'value': 'project' }, { 'text': 'Region', 'sortable': False, 'value': 'region' }, { 'text': 'Account', 'sortable': False, 'value': 'account' }, { 'text': 'Url', 'sortable': False, 'value': 'url' }, { 'text': '', 'sortable': False, 'value': 'actions' }, ], items=endpoint_table_values, dense=False, v_slots=[{ 'name': 'item.actions', 'children': [delete_icon] }, { 'name': 'no-data', 'children': ['No endpoints'] }]) endpoint_table.on_event('click:row', self._remove_row_from_table) self.toolbar_with_table = v.Container( style_=f'width: {WIDGET_WIDTH};', class_='mx-auto', children=[ v.Row(class_='mx-auto', children=[toolbar]), v.Row(class_='mx-auto', children=[endpoint_table]) ]) self.children = [self.create_endpoint_widget, self.toolbar_with_table] for child in self.children: child.parent_widget = self self._update_view()