mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-07 06:15:36 +00:00
Safely handle missing fields during import for LocalBaserowUserSource and LocalBaserowPasswordAppAuthProvider
This commit is contained in:
parent
5f8c81271a
commit
7e32a8d2ed
5 changed files with 181 additions and 3 deletions
changelog/entries/unreleased/bug
enterprise/backend
src/baserow_enterprise/integrations/local_baserow
tests/baserow_enterprise_tests/integrations/local_baserow
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"type": "bug",
|
||||
"message": "[Builder] Fixed bug that caused a workspace import to fail when certain fields were missing.",
|
||||
"issue_number": 3375,
|
||||
"bullet_points": [],
|
||||
"created_at": "2025-01-28"
|
||||
}
|
|
@ -187,7 +187,7 @@ class LocalBaserowPasswordAppAuthProviderType(AppAuthProviderType):
|
|||
and value
|
||||
and "database_fields" in id_mapping
|
||||
):
|
||||
return id_mapping["database_fields"][value]
|
||||
return id_mapping["database_fields"].get(value)
|
||||
|
||||
return super().deserialize_property(
|
||||
prop_name,
|
||||
|
|
|
@ -416,14 +416,14 @@ class LocalBaserowUserSourceType(UserSourceType):
|
|||
"""
|
||||
|
||||
if value and "database_tables" in id_mapping and prop_name == "table_id":
|
||||
return id_mapping["database_tables"][value]
|
||||
return id_mapping["database_tables"].get(value)
|
||||
|
||||
if (
|
||||
value
|
||||
and "database_fields" in id_mapping
|
||||
and prop_name in ("email_field_id", "name_field_id", "role_field_id")
|
||||
):
|
||||
return id_mapping["database_fields"][value]
|
||||
return id_mapping["database_fields"].get(value)
|
||||
|
||||
return super().deserialize_property(
|
||||
prop_name,
|
||||
|
|
|
@ -395,3 +395,75 @@ def test_import_local_baserow_password_app_auth_provider(data_fixture):
|
|||
imported_instance.auth_providers.first().specific.password_field_id
|
||||
== password_field.id
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_import_local_baserow_password_app_auth_provider_without_database(data_fixture):
|
||||
"""
|
||||
Test the import of the LocalBaserowPasswordAppAuthProvider when the
|
||||
password field is missing in the id_mapping.
|
||||
|
||||
The password field might be missing during an import, because the user
|
||||
might have either deleted the password field in the database, or deleted
|
||||
the table entirely.
|
||||
"""
|
||||
|
||||
user = data_fixture.create_user()
|
||||
workspace = data_fixture.create_workspace(user=user)
|
||||
application = data_fixture.create_builder_application(workspace=workspace)
|
||||
database = data_fixture.create_database_application(workspace=workspace)
|
||||
|
||||
integration = data_fixture.create_local_baserow_integration(
|
||||
application=application, user=user
|
||||
)
|
||||
|
||||
table_from_same_workspace1, fields, rows = data_fixture.build_table(
|
||||
user=user,
|
||||
database=database,
|
||||
columns=[
|
||||
("Email", "text"),
|
||||
("Name", "text"),
|
||||
("Password", "password"),
|
||||
],
|
||||
rows=[
|
||||
["test@baserow.io", "Test", "password"],
|
||||
],
|
||||
)
|
||||
|
||||
email_field, name_field, password_field = fields
|
||||
|
||||
TO_IMPORT = {
|
||||
"email_field_id": 42,
|
||||
"id": 28,
|
||||
"integration_id": 42,
|
||||
"name": "Test name",
|
||||
"name_field_id": 43,
|
||||
"order": "1.00000000000000000000",
|
||||
"table_id": 42,
|
||||
"type": "local_baserow",
|
||||
"auth_providers": [
|
||||
{
|
||||
"id": 42,
|
||||
"type": "local_baserow_password",
|
||||
"domain": None,
|
||||
"enabled": True,
|
||||
"password_field_id": 44,
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
id_mapping = defaultdict(MirrorDict)
|
||||
id_mapping["integrations"] = {42: integration.id}
|
||||
id_mapping["database_tables"] = {42: table_from_same_workspace1.id}
|
||||
|
||||
# the password field is intentionally excluded from database_fields
|
||||
id_mapping["database_fields"] = {
|
||||
42: email_field.id,
|
||||
43: name_field.id,
|
||||
}
|
||||
|
||||
imported_instance = UserSourceHandler().import_user_source(
|
||||
application, TO_IMPORT, id_mapping
|
||||
)
|
||||
|
||||
assert imported_instance.auth_providers.first().specific.password_field_id is None
|
||||
|
|
|
@ -868,6 +868,105 @@ def test_import_local_baserow_user_source(data_fixture):
|
|||
assert imported_instance.name_field_id == name_field.id
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize(
|
||||
"id_mapping_key,missing_field_name",
|
||||
[
|
||||
("database_tables", "table_id"),
|
||||
("database_fields", "email_field_id"),
|
||||
("database_fields", "name_field_id"),
|
||||
("database_fields", "role_field_id"),
|
||||
],
|
||||
)
|
||||
def test_import_local_baserow_user_source_with_missing_fields(
|
||||
data_fixture, id_mapping_key, missing_field_name
|
||||
):
|
||||
"""
|
||||
Test the import of the LocalBaserowUserSource when one or more fields
|
||||
are missing in the exported workspace's database.
|
||||
|
||||
A field, such as the Role field might have been deleted before the user
|
||||
has exported the workspace. As such, when importing the workspace, the
|
||||
missing field needs to be safely handled.
|
||||
"""
|
||||
|
||||
user = data_fixture.create_user()
|
||||
workspace = data_fixture.create_workspace(user=user)
|
||||
application = data_fixture.create_builder_application(workspace=workspace)
|
||||
database = data_fixture.create_database_application(workspace=workspace)
|
||||
|
||||
integration = data_fixture.create_local_baserow_integration(
|
||||
application=application, user=user
|
||||
)
|
||||
|
||||
table_from_same_workspace1, fields, rows = data_fixture.build_table(
|
||||
user=user,
|
||||
database=database,
|
||||
columns=[
|
||||
("Email", "text"),
|
||||
("Name", "text"),
|
||||
("Role", "text"),
|
||||
],
|
||||
rows=[
|
||||
["test@baserow.io", "Test", "Foo Role"],
|
||||
],
|
||||
)
|
||||
|
||||
email_field, name_field, role_field = fields
|
||||
|
||||
TO_IMPORT = {
|
||||
"id": 28,
|
||||
"name": "Test name",
|
||||
"order": "1.00000000000000000000",
|
||||
"type": "local_baserow",
|
||||
"integration_id": 42,
|
||||
"table_id": 42,
|
||||
"name_field_id": 43,
|
||||
"email_field_id": 42,
|
||||
"role_field_id": 44,
|
||||
"auth_providers": [
|
||||
{
|
||||
"id": 42,
|
||||
"type": "local_baserow_password",
|
||||
"domain": None,
|
||||
"enabled": True,
|
||||
"password_field_id": None,
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
id_mapping = defaultdict(MirrorDict)
|
||||
|
||||
id_mapping_data = {
|
||||
"table_id": (42, table_from_same_workspace1.id),
|
||||
"email_field_id": (42, email_field.id),
|
||||
"name_field_id": (43, name_field.id),
|
||||
"role_field_id": (44, role_field.id),
|
||||
}
|
||||
id_mapping["integrations"] = {42: integration.id}
|
||||
id_mapping["database_tables"] = {42: table_from_same_workspace1.id}
|
||||
id_mapping["database_fields"] = {
|
||||
42: email_field.id,
|
||||
43: name_field.id,
|
||||
44: role_field.id,
|
||||
}
|
||||
|
||||
# Remove a specific field to simulate a "missing field"
|
||||
id_mapping[id_mapping_key].pop(id_mapping_data[missing_field_name][0])
|
||||
|
||||
imported_instance = UserSourceHandler().import_user_source(
|
||||
application, TO_IMPORT, id_mapping
|
||||
)
|
||||
|
||||
for property in id_mapping_data:
|
||||
value = getattr(imported_instance, property)
|
||||
if property == missing_field_name:
|
||||
# Ensure that None is returned instead of raising a KeyError
|
||||
assert value is None
|
||||
else:
|
||||
assert value is id_mapping_data[property][1]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_local_baserow_user_source_w_auth_providers(api_client, data_fixture):
|
||||
user, token = data_fixture.create_user_and_token()
|
||||
|
|
Loading…
Add table
Reference in a new issue