From 392d8a81073bde7e68236d6d4c6e02c398429a7a Mon Sep 17 00:00:00 2001 From: "Hugh A. Miles II" Date: Tue, 20 Apr 2021 19:19:36 -0400 Subject: [PATCH] fix: Handle bad permission errors for bigquery test connections (#14147) * starter make file * yea * move messaging to config * Delete Makefile * remove * checkout * check for db generic errors * checkout bad files * add proper message * add docs for new permissions codes * Update superset/errors.py Co-authored-by: AAfghahi <48933336+AAfghahi@users.noreply.github.com> * Update superset/errors.py Co-authored-by: AAfghahi <48933336+AAfghahi@users.noreply.github.com> * rename var * starter regex * fix * fix * fix linting * update test * yerp * fixed test * added regex * Apply suggestions from code review Co-authored-by: Beto Dealmeida * address comments * update docs * prettier * fux * add space * Update errors.py * Update types.ts Co-authored-by: AAfghahi <48933336+AAfghahi@users.noreply.github.com> Co-authored-by: Beto Dealmeida --- .../pages/docs/Miscellaneous/issue_codes.mdx | 10 +++++++++- .../src/components/ErrorMessage/types.ts | 2 ++ .../src/setup/setupErrorMessages.ts | 4 ++++ superset/db_engine_specs/bigquery.py | 19 +++++++++++++++++++ superset/errors.py | 7 +++++++ tests/db_engine_specs/bigquery_tests.py | 16 ++++++++++++++++ 6 files changed, 57 insertions(+), 1 deletion(-) diff --git a/docs/src/pages/docs/Miscellaneous/issue_codes.mdx b/docs/src/pages/docs/Miscellaneous/issue_codes.mdx index 34e5b1306..6b4a72d10 100644 --- a/docs/src/pages/docs/Miscellaneous/issue_codes.mdx +++ b/docs/src/pages/docs/Miscellaneous/issue_codes.mdx @@ -150,6 +150,7 @@ The password provided when connecting to a database is not valid. The user provided a password that is incorrect. Please check that the password is typed correctly. + ## Issue 1014 ``` @@ -167,7 +168,6 @@ Either the database is spelled incorrectly or does not exist. Either the database was written incorrectly or it does not exist. Check that it was typed correctly. - ## Issue 1016 ``` @@ -175,3 +175,11 @@ The schema was deleted or renamed in the database. ``` The schema was either removed or renamed. Check that the schema is typed correctly and exists. + +## Issue 1017 + +``` +The user doesn't have the proper permissions to connect to the database +``` + +We were unable to connect to your database. Please confirm that your service account has the Viewer and Job User roles on the project. diff --git a/superset-frontend/src/components/ErrorMessage/types.ts b/superset-frontend/src/components/ErrorMessage/types.ts index 9a164e912..19c485b0c 100644 --- a/superset-frontend/src/components/ErrorMessage/types.ts +++ b/superset-frontend/src/components/ErrorMessage/types.ts @@ -36,6 +36,8 @@ export const ErrorTypeEnum = { CONNECTION_HOST_DOWN_ERROR: 'CONNECTION_HOST_DOWN_ERROR', CONNECTION_ACCESS_DENIED_ERROR: 'CONNECTION_ACCESS_DENIED_ERROR', CONNECTION_UNKNOWN_DATABASE_ERROR: 'CONNECTION_UNKNOWN_DATABASE_ERROR', + CONNECTION_DATABASE_PERMISSIONS_ERROR: + 'CONNECTION_DATABASE_PERMISSIONS_ERROR', // Viz errors VIZ_GET_DF_ERROR: 'VIZ_GET_DF_ERROR', diff --git a/superset-frontend/src/setup/setupErrorMessages.ts b/superset-frontend/src/setup/setupErrorMessages.ts index 50d1fb501..ed244614d 100644 --- a/superset-frontend/src/setup/setupErrorMessages.ts +++ b/superset-frontend/src/setup/setupErrorMessages.ts @@ -83,5 +83,9 @@ export default function setupErrorMessages() { ErrorTypeEnum.SCHEMA_DOES_NOT_EXIST_ERROR, DatabaseErrorMessage, ); + errorMessageComponentRegistry.registerValue( + ErrorTypeEnum.CONNECTION_DATABASE_PERMISSIONS_ERROR, + DatabaseErrorMessage, + ); setupErrorMessagesExtra(); } diff --git a/superset/db_engine_specs/bigquery.py b/superset/db_engine_specs/bigquery.py index 621525060..59f61d14c 100644 --- a/superset/db_engine_specs/bigquery.py +++ b/superset/db_engine_specs/bigquery.py @@ -20,16 +20,24 @@ from datetime import datetime from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING import pandas as pd +from flask_babel import gettext as __ from sqlalchemy import literal_column from sqlalchemy.sql.expression import ColumnClause from superset.db_engine_specs.base import BaseEngineSpec +from superset.errors import SupersetErrorType from superset.utils import core as utils if TYPE_CHECKING: from superset.models.core import Database # pragma: no cover +CONNECTION_DATABASE_PERMISSIONS_REGEX = re.compile( + "Access Denied: Project User does not have bigquery.jobs.create " + + "permission in project (?P.+?)" +) + + class BigQueryEngineSpec(BaseEngineSpec): """Engine spec for Google's BigQuery @@ -86,6 +94,17 @@ class BigQueryEngineSpec(BaseEngineSpec): "P1Y": "{func}({col}, YEAR)", } + custom_errors = { + CONNECTION_DATABASE_PERMISSIONS_REGEX: ( + __( + "We were unable to connect to your database. Please " + "confirm that your service account has the Viewer " + "and Job User roles on the project." + ), + SupersetErrorType.CONNECTION_DATABASE_PERMISSIONS_ERROR, + ), + } + @classmethod def convert_dttm(cls, target_type: str, dttm: datetime) -> Optional[str]: tt = target_type.upper() diff --git a/superset/errors.py b/superset/errors.py index 901ad8cfc..be05944ca 100644 --- a/superset/errors.py +++ b/superset/errors.py @@ -47,6 +47,7 @@ class SupersetErrorType(str, Enum): CONNECTION_HOST_DOWN_ERROR = "CONNECTION_HOST_DOWN_ERROR" CONNECTION_ACCESS_DENIED_ERROR = "CONNECTION_ACCESS_DENIED_ERROR" CONNECTION_UNKNOWN_DATABASE_ERROR = "CONNECTION_UNKNOWN_DATABASE_ERROR" + CONNECTION_DATABASE_PERMISSIONS_ERROR = "CONNECTION_DATABASE_PERMISSIONS_ERROR" # Viz errors VIZ_GET_DF_ERROR = "VIZ_GET_DF_ERROR" @@ -213,6 +214,12 @@ ERROR_TYPES_TO_ISSUE_CODES_MAPPING = { ), } ], + SupersetErrorType.CONNECTION_DATABASE_PERMISSIONS_ERROR: [ + { + "code": 1017, + "message": _("Issue 1017 - User doesn't have the proper permissions."), + }, + ], } diff --git a/tests/db_engine_specs/bigquery_tests.py b/tests/db_engine_specs/bigquery_tests.py index 37e95e95e..d01500760 100644 --- a/tests/db_engine_specs/bigquery_tests.py +++ b/tests/db_engine_specs/bigquery_tests.py @@ -22,6 +22,7 @@ from sqlalchemy import column from superset.db_engine_specs.base import BaseEngineSpec from superset.db_engine_specs.bigquery import BigQueryEngineSpec +from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from tests.db_engine_specs.base_tests import TestDbEngineSpec @@ -223,3 +224,18 @@ class TestBigQueryDbEngineSpec(TestDbEngineSpec): credentials="account_info", if_exists="extra_key", ) + + def test_extract_errors(self): + msg = "403 POST https://bigquery.googleapis.com/bigquery/v2/projects/test-keel-310804/jobs?prettyPrint=false: Access Denied: Project User does not have bigquery.jobs.create permission in project profound-keel-310804" + result = BigQueryEngineSpec.extract_errors(Exception(msg)) + assert result == [ + SupersetError( + message="We were unable to connect to your database. Please confirm that your service account has the Viewer and Job User roles on the project.", + error_type=SupersetErrorType.CONNECTION_DATABASE_PERMISSIONS_ERROR, + level=ErrorLevel.ERROR, + extra={ + "engine_name": "Google BigQuery", + "issue_codes": [{"code": 1017, "message": "",}], + }, + ) + ]