-
Notifications
You must be signed in to change notification settings - Fork 14.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add schema level access control on csv upload #5787
Changes from all commits
1876168
3f19778
dd33783
ff12706
ad8b16e
ae7bce2
9a85831
e421c17
6f6d158
2805853
7952913
e87cf4d
00e19cd
1c72ee4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -638,19 +638,19 @@ class Database(Model, AuditMixinNullable, ImportMixin): | |
expose_in_sqllab = Column(Boolean, default=False) | ||
allow_run_sync = Column(Boolean, default=True) | ||
allow_run_async = Column(Boolean, default=False) | ||
allow_csv_upload = Column(Boolean, default=True) | ||
allow_csv_upload = Column(Boolean, default=False) | ||
allow_ctas = Column(Boolean, default=False) | ||
allow_dml = Column(Boolean, default=False) | ||
force_ctas_schema = Column(String(250)) | ||
allow_multi_schema_metadata_fetch = Column(Boolean, default=True) | ||
extra = Column(Text, default=textwrap.dedent("""\ | ||
{ | ||
"metadata_params": {}, | ||
"engine_params": {} | ||
"engine_params": {}, | ||
"schemas_allowed_for_csv_upload": [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: leave a trailing comma on the last line, it makes it easier to sort lines and for better There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
""")) | ||
perm = Column(String(1000)) | ||
|
||
impersonate_user = Column(Boolean, default=False) | ||
export_fields = ('database_name', 'sqlalchemy_uri', 'cache_timeout', | ||
'expose_in_sqllab', 'allow_run_sync', 'allow_run_async', | ||
|
@@ -908,6 +908,7 @@ def get_extra(self): | |
extra = json.loads(self.extra) | ||
except Exception as e: | ||
logging.error(e) | ||
raise e | ||
return extra | ||
|
||
def get_table(self, table_name, schema=None): | ||
|
@@ -931,6 +932,9 @@ def get_pk_constraint(self, table_name, schema=None): | |
def get_foreign_keys(self, table_name, schema=None): | ||
return self.inspector.get_foreign_keys(table_name, schema) | ||
|
||
def get_schema_access_for_csv_upload(self): | ||
return self.get_extra().get('schemas_allowed_for_csv_upload', []) | ||
|
||
@property | ||
def sqlalchemy_uri_decrypted(self): | ||
conn = sqla.engine.url.make_url(self.sqlalchemy_uri) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{% extends 'appbuilder/general/model/edit.html' %} | ||
|
||
{% block tail_js %} | ||
{{ super() }} | ||
<script> | ||
var db = $("#con"); | ||
var schema = $("#schema"); | ||
|
||
// this element is a text input | ||
// copy it here so it can be reused later | ||
var any_schema_is_allowed = schema.clone(); | ||
|
||
update_schemas_allowed_for_csv_upload(db.val()); | ||
db.change(function(){ | ||
update_schemas_allowed_for_csv_upload(db.val()); | ||
}); | ||
|
||
function update_schemas_allowed_for_csv_upload(db_id) { | ||
$.ajax({ | ||
method: "GET", | ||
url: "/superset/schema_access_for_csv_upload", | ||
data: {db_id: db_id}, | ||
dataType: 'json', | ||
contentType: "application/json; charset=utf-8" | ||
}).done(function(data) { | ||
change_schema_field_in_formview(data) | ||
}).fail(function(error) { | ||
var errorMsg = error.responseJSON.error; | ||
alert("ERROR: " + errorMsg); | ||
}); | ||
} | ||
|
||
function change_schema_field_in_formview(schemas_allowed){ | ||
if (schemas_allowed && schemas_allowed.length > 0) { | ||
var dropdown_schema_lists = '<select id="schema" name="schema" required>'; | ||
schemas_allowed.forEach(function(schema_allowed) { | ||
dropdown_schema_lists += ('<option value="' + schema_allowed + '">' + schema_allowed + '</option>'); | ||
}); | ||
dropdown_schema_lists += '</select>'; | ||
$("#schema").replaceWith(dropdown_schema_lists); | ||
} else { | ||
$("#schema").replaceWith(any_schema_is_allowed) | ||
} | ||
} | ||
</script> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,5 @@ | |
{% block tail_js %} | ||
{{ super() }} | ||
{{ macros.testconn() }} | ||
{{ macros.expand_extra_textarea() }} | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,5 @@ | |
{% block tail_js %} | ||
{{ super() }} | ||
{{ macros.testconn() }} | ||
{{ macros.expand_extra_textarea() }} | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -844,6 +844,7 @@ def get_or_create_main_db(): | |
dbobj.set_sqlalchemy_uri(conf.get('SQLALCHEMY_DATABASE_URI')) | ||
dbobj.expose_in_sqllab = True | ||
dbobj.allow_run_sync = True | ||
dbobj.allow_csv_upload = True | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @youngyjd why is this explicitly set? Note in general one would not want to have users upload to the @mistercrunch personally I don't think we should be setting any of these fields if the
i.e., all these settings should be initialized as |
||
db.session.add(dbobj) | ||
db.session.commit() | ||
return dbobj | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!