- {t('A list of schemas that CSVs are allowed to upload to.')}
+ {t(
+ 'A comma-separated list of schemas that CSVs are allowed to upload to.',
+ )}
diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
index d655ed3ec8..119f15fdde 100644
--- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
@@ -222,6 +222,17 @@ function dbReducer(
},
};
}
+ if (action.payload.name === 'schemas_allowed_for_csv_upload') {
+ return {
+ ...trimmedState,
+ extra_json: {
+ ...trimmedState.extra_json,
+ schemas_allowed_for_csv_upload: (action.payload.value || '').split(
+ ',',
+ ),
+ },
+ };
+ }
return {
...trimmedState,
extra_json: {
@@ -409,8 +420,9 @@ const serializeExtra = (extraJson: DatabaseObject['extra_json']) =>
engine_params: JSON.parse(
((extraJson?.engine_params as unknown) as string) || '{}',
),
- schemas_allowed_for_csv_upload:
- (extraJson?.schemas_allowed_for_csv_upload as string) || '[]',
+ schemas_allowed_for_csv_upload: (
+ extraJson?.schemas_allowed_for_csv_upload || []
+ ).filter(schema => schema !== ''),
});
const DatabaseModal: FunctionComponent = ({
diff --git a/superset-frontend/src/views/CRUD/data/database/types.ts b/superset-frontend/src/views/CRUD/data/database/types.ts
index 4cf4b8475a..f6341d34ee 100644
--- a/superset-frontend/src/views/CRUD/data/database/types.ts
+++ b/superset-frontend/src/views/CRUD/data/database/types.ts
@@ -83,7 +83,7 @@ export type DatabaseObject = {
table_cache_timeout?: number; // in Performance
}; // No field, holds schema and table timeout
allows_virtual_table_explore?: boolean; // in SQL Lab
- schemas_allowed_for_csv_upload?: [] | string; // in Security
+ schemas_allowed_for_csv_upload?: string[]; // in Security
cancel_query_on_windows_unload?: boolean; // in Performance
version?: string;
diff --git a/superset/migrations/versions/e323605f370a_fix_schemas_allowed_for_csv_upload.py b/superset/migrations/versions/e323605f370a_fix_schemas_allowed_for_csv_upload.py
new file mode 100644
index 0000000000..eb5d1b4242
--- /dev/null
+++ b/superset/migrations/versions/e323605f370a_fix_schemas_allowed_for_csv_upload.py
@@ -0,0 +1,82 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""fix schemas_allowed_for_csv_upload
+
+Revision ID: e323605f370a
+Revises: 31b2a1039d4a
+Create Date: 2021-08-02 16:39:45.329151
+
+"""
+import json
+import logging
+
+from alembic import op
+from sqlalchemy import Column, Integer, Text
+from sqlalchemy.ext.declarative import declarative_base
+
+from superset import db
+
+# revision identifiers, used by Alembic.
+revision = "e323605f370a"
+down_revision = "31b2a1039d4a"
+
+
+Base = declarative_base()
+
+
+class Database(Base):
+
+ __tablename__ = "dbs"
+ id = Column(Integer, primary_key=True)
+ extra = Column(Text)
+
+
+def upgrade():
+ """
+ Fix databases with ``schemas_allowed_for_csv_upload`` stored as string.
+ """
+ bind = op.get_bind()
+ session = db.Session(bind=bind)
+
+ for database in session.query(Database).all():
+ try:
+ extra = json.loads(database.extra)
+ except json.decoder.JSONDecodeError as ex:
+ logging.warning(str(ex))
+ continue
+
+ schemas_allowed_for_csv_upload = extra.get("schemas_allowed_for_csv_upload")
+ if not isinstance(schemas_allowed_for_csv_upload, str):
+ continue
+
+ if schemas_allowed_for_csv_upload == "[]":
+ extra["schemas_allowed_for_csv_upload"] = []
+ else:
+ extra["schemas_allowed_for_csv_upload"] = [
+ schema.strip()
+ for schema in schemas_allowed_for_csv_upload.split(",")
+ if schema.strip()
+ ]
+
+ database.extra = json.dumps(extra)
+
+ session.commit()
+ session.close()
+
+
+def downgrade():
+ pass