mirror of
https://github.com/apache/superset.git
synced 2026-04-20 00:24:38 +00:00
chore(database): Creating helper make_url_safe to wrap potential errors (#19526)
* Creating helper make_url_safe to wrap potential errors * Fixing imports * Fixing imports again * Adding comment * Linting * Fixing test * Fixing test again... * Fixing import
This commit is contained in:
@@ -23,7 +23,6 @@ from flask import current_app as app
|
||||
from flask_appbuilder.security.sqla.models import User
|
||||
from flask_babel import gettext as _
|
||||
from func_timeout import func_timeout, FunctionTimedOut
|
||||
from sqlalchemy.engine.url import make_url
|
||||
from sqlalchemy.exc import DBAPIError, NoSuchModuleError
|
||||
|
||||
from superset.commands.base import BaseCommand
|
||||
@@ -34,6 +33,7 @@ from superset.databases.commands.exceptions import (
|
||||
DatabaseTestConnectionUnexpectedError,
|
||||
)
|
||||
from superset.databases.dao import DatabaseDAO
|
||||
from superset.databases.utils import make_url_safe
|
||||
from superset.errors import ErrorLevel, SupersetErrorType
|
||||
from superset.exceptions import SupersetSecurityException, SupersetTimeoutException
|
||||
from superset.extensions import event_logger
|
||||
@@ -55,7 +55,7 @@ class TestConnectionDatabaseCommand(BaseCommand):
|
||||
uri = self._model.sqlalchemy_uri_decrypted
|
||||
|
||||
# context for error messages
|
||||
url = make_url(uri)
|
||||
url = make_url_safe(uri)
|
||||
context = {
|
||||
"hostname": url.host,
|
||||
"password": url.password,
|
||||
|
||||
@@ -20,7 +20,6 @@ from typing import Any, Dict, Optional
|
||||
|
||||
from flask_appbuilder.security.sqla.models import User
|
||||
from flask_babel import gettext as __
|
||||
from sqlalchemy.engine.url import make_url
|
||||
|
||||
from superset.commands.base import BaseCommand
|
||||
from superset.databases.commands.exceptions import (
|
||||
@@ -30,6 +29,7 @@ from superset.databases.commands.exceptions import (
|
||||
InvalidParametersError,
|
||||
)
|
||||
from superset.databases.dao import DatabaseDAO
|
||||
from superset.databases.utils import make_url_safe
|
||||
from superset.db_engine_specs import get_engine_specs
|
||||
from superset.db_engine_specs.base import BasicParametersMixin
|
||||
from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
|
||||
@@ -121,7 +121,7 @@ class ValidateDatabaseParametersCommand(BaseCommand):
|
||||
with closing(engine.raw_connection()) as conn:
|
||||
alive = engine.dialect.do_ping(conn)
|
||||
except Exception as ex:
|
||||
url = make_url(sqlalchemy_uri)
|
||||
url = make_url_safe(sqlalchemy_uri)
|
||||
context = {
|
||||
"hostname": url.host,
|
||||
"password": url.password,
|
||||
|
||||
@@ -24,10 +24,10 @@ from marshmallow import EXCLUDE, fields, pre_load, Schema, validates_schema
|
||||
from marshmallow.validate import Length, ValidationError
|
||||
from marshmallow_enum import EnumField
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy.engine.url import make_url
|
||||
from sqlalchemy.exc import ArgumentError
|
||||
|
||||
from superset import db
|
||||
from superset.databases.commands.exceptions import DatabaseInvalidError
|
||||
from superset.databases.utils import make_url_safe
|
||||
from superset.db_engine_specs import BaseEngineSpec, get_engine_specs
|
||||
from superset.exceptions import CertificateException, SupersetSecurityException
|
||||
from superset.models.core import ConfigurationMethod, Database, PASSWORD_MASK
|
||||
@@ -144,8 +144,8 @@ def sqlalchemy_uri_validator(value: str) -> str:
|
||||
Validate if it's a valid SQLAlchemy URI and refuse SQLLite by default
|
||||
"""
|
||||
try:
|
||||
uri = make_url(value.strip())
|
||||
except (ArgumentError, AttributeError, ValueError) as ex:
|
||||
uri = make_url_safe(value.strip())
|
||||
except DatabaseInvalidError as ex:
|
||||
raise ValidationError(
|
||||
[
|
||||
_(
|
||||
@@ -649,7 +649,7 @@ class ImportV1DatabaseSchema(Schema):
|
||||
return
|
||||
|
||||
uri = data["sqlalchemy_uri"]
|
||||
password = make_url(uri).password
|
||||
password = make_url_safe(uri).password
|
||||
if password == PASSWORD_MASK and data.get("password") is None:
|
||||
raise ValidationError("Must provide a password for the database")
|
||||
|
||||
|
||||
@@ -16,14 +16,15 @@
|
||||
# under the License.
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from superset import app
|
||||
from superset.models.core import Database
|
||||
from sqlalchemy.engine.url import make_url, URL
|
||||
|
||||
custom_password_store = app.config["SQLALCHEMY_CUSTOM_PASSWORD_STORE"]
|
||||
from superset.databases.commands.exceptions import DatabaseInvalidError
|
||||
|
||||
|
||||
def get_foreign_keys_metadata(
|
||||
database: Database, table_name: str, schema_name: Optional[str]
|
||||
database: Any,
|
||||
table_name: str,
|
||||
schema_name: Optional[str],
|
||||
) -> List[Dict[str, Any]]:
|
||||
foreign_keys = database.get_foreign_keys(table_name, schema_name)
|
||||
for fk in foreign_keys:
|
||||
@@ -33,7 +34,7 @@ def get_foreign_keys_metadata(
|
||||
|
||||
|
||||
def get_indexes_metadata(
|
||||
database: Database, table_name: str, schema_name: Optional[str]
|
||||
database: Any, table_name: str, schema_name: Optional[str]
|
||||
) -> List[Dict[str, Any]]:
|
||||
indexes = database.get_indexes(table_name, schema_name)
|
||||
for idx in indexes:
|
||||
@@ -51,7 +52,7 @@ def get_col_type(col: Dict[Any, Any]) -> str:
|
||||
|
||||
|
||||
def get_table_metadata(
|
||||
database: Database, table_name: str, schema_name: Optional[str]
|
||||
database: Any, table_name: str, schema_name: Optional[str]
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Get table metadata information, including type, pk, fks.
|
||||
@@ -101,3 +102,17 @@ def get_table_metadata(
|
||||
"indexes": keys,
|
||||
"comment": table_comment,
|
||||
}
|
||||
|
||||
|
||||
def make_url_safe(raw_url: str) -> URL:
|
||||
"""
|
||||
Wrapper for SQLAlchemy's make_url(), which tends to raise too detailed of
|
||||
errors, which inevitably find their way into server logs. ArgumentErrors
|
||||
tend to contain usernames and passwords, which makes them non-log-friendly
|
||||
:param raw_url:
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
return make_url(raw_url.strip())
|
||||
except Exception:
|
||||
raise DatabaseInvalidError() # pylint: disable=raise-missing-from
|
||||
|
||||
Reference in New Issue
Block a user