Skip to content

Commit

Permalink
fix: accept old database payload (#21923)
Browse files Browse the repository at this point in the history
  • Loading branch information
betodealmeida committed Oct 25, 2022
1 parent fa67315 commit 1388f21
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
32 changes: 28 additions & 4 deletions superset/databases/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# pylint: disable=no-self-use, unused-argument

import inspect
import json
from typing import Any, Dict
Expand Down Expand Up @@ -240,7 +243,6 @@ class DatabaseParametersSchemaMixin: # pylint: disable=too-few-public-methods
missing=ConfigurationMethod.SQLALCHEMY_FORM,
)

# pylint: disable=no-self-use, unused-argument
@pre_load
def build_sqlalchemy_uri(
self, data: Dict[str, Any], **kwargs: Any
Expand Down Expand Up @@ -303,10 +305,28 @@ def build_sqlalchemy_uri(
return data


def rename_encrypted_extra(
self: Schema,
data: Dict[str, Any],
**kwargs: Any,
) -> Dict[str, Any]:
"""
Rename ``encrypted_extra`` to ``masked_encrypted_extra``.
PR #21248 changed the database schema for security reasons. This pre-loader keeps
Superset backwards compatible with older clients.
"""
if "encrypted_extra" in data:
data["masked_encrypted_extra"] = data.pop("encrypted_extra")
return data


class DatabaseValidateParametersSchema(Schema):
class Meta: # pylint: disable=too-few-public-methods
unknown = EXCLUDE

rename_encrypted_extra = pre_load(rename_encrypted_extra)

id = fields.Integer(allow_none=True, description="Database ID (for updates)")
engine = fields.String(required=True, description="SQLAlchemy engine to use")
driver = fields.String(allow_none=True, description="SQLAlchemy driver to use")
Expand Down Expand Up @@ -349,6 +369,8 @@ class DatabasePostSchema(Schema, DatabaseParametersSchemaMixin):
class Meta: # pylint: disable=too-few-public-methods
unknown = EXCLUDE

rename_encrypted_extra = pre_load(rename_encrypted_extra)

database_name = fields.String(
description=database_name_description,
required=True,
Expand Down Expand Up @@ -393,6 +415,8 @@ class DatabasePutSchema(Schema, DatabaseParametersSchemaMixin):
class Meta: # pylint: disable=too-few-public-methods
unknown = EXCLUDE

rename_encrypted_extra = pre_load(rename_encrypted_extra)

database_name = fields.String(
description=database_name_description,
allow_none=True,
Expand Down Expand Up @@ -433,6 +457,9 @@ class Meta: # pylint: disable=too-few-public-methods


class DatabaseTestConnectionSchema(Schema, DatabaseParametersSchemaMixin):

rename_encrypted_extra = pre_load(rename_encrypted_extra)

database_name = fields.String(
description=database_name_description,
allow_none=True,
Expand Down Expand Up @@ -578,7 +605,6 @@ class DatabaseFunctionNamesResponse(Schema):


class ImportV1DatabaseExtraSchema(Schema):
# pylint: disable=no-self-use, unused-argument
@pre_load
def fix_schemas_allowed_for_csv_upload( # pylint: disable=invalid-name
self, data: Dict[str, Any], **kwargs: Any
Expand Down Expand Up @@ -616,7 +642,6 @@ def fix_schemas_allowed_for_csv_upload( # pylint: disable=invalid-name


class ImportV1DatabaseSchema(Schema):
# pylint: disable=no-self-use, unused-argument
@pre_load
def fix_allow_csv_upload(
self, data: Dict[str, Any], **kwargs: Any
Expand Down Expand Up @@ -647,7 +672,6 @@ def fix_allow_csv_upload(
is_managed_externally = fields.Boolean(allow_none=True, default=False)
external_url = fields.String(allow_none=True)

# pylint: disable=no-self-use, unused-argument
@validates_schema
def validate_password(self, data: Dict[str, Any], **kwargs: Any) -> None:
"""If sqlalchemy_uri has a masked password, password is required"""
Expand Down
35 changes: 35 additions & 0 deletions tests/unit_tests/databases/schema_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,38 @@ def test_database_parameters_schema_mixin_invalid_type(
dummy_schema.load(payload)
except ValidationError as err:
assert err.messages == {"port": ["Not a valid integer."]}


def test_rename_encrypted_extra() -> None:
"""
Test that ``encrypted_extra`` gets renamed to ``masked_encrypted_extra``.
"""
from superset.databases.schemas import ConfigurationMethod, DatabasePostSchema

schema = DatabasePostSchema()

# current schema
payload = schema.load(
{
"database_name": "My database",
"masked_encrypted_extra": "{}",
}
)
assert payload == {
"database_name": "My database",
"configuration_method": ConfigurationMethod.SQLALCHEMY_FORM,
"masked_encrypted_extra": "{}",
}

# previous schema
payload = schema.load(
{
"database_name": "My database",
"encrypted_extra": "{}",
}
)
assert payload == {
"database_name": "My database",
"configuration_method": ConfigurationMethod.SQLALCHEMY_FORM,
"masked_encrypted_extra": "{}",
}

0 comments on commit 1388f21

Please sign in to comment.