[incubator-superset] branch master updated: Fix CTAS explore flow (#10147)
This is an automated email from the ASF dual-hosted git repository. bkyryliuk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-superset.git The following commit(s) were added to refs/heads/master by this push: new 763b385 Fix CTAS explore flow (#10147) 763b385 is described below commit 763b38591c551834b416f929464eef25ced4848d Author: Bogdan AuthorDate: Tue Jun 23 22:36:05 2020 -0700 Fix CTAS explore flow (#10147) Co-authored-by: bogdan kyryliuk --- superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx b/superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx index 9311e30..390bfbc 100644 --- a/superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx +++ b/superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx @@ -24,7 +24,7 @@ import Dialog from 'react-bootstrap-dialog'; import { t } from '@superset-ui/translation'; import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls'; -import { exportChart } from '../../explore/exploreUtils'; +import { exploreChart } from '../../explore/exploreUtils'; import * as actions from '../actions/sqlLab'; import Button from '../../components/Button'; @@ -77,7 +77,7 @@ class ExploreCtasResultsButton extends React.PureComponent { ); // open new window for data visualization -exportChart({ formData }); +exploreChart(formData); }) .catch(() => { this.props.actions.addDangerToast(
[incubator-superset] branch master updated: chore(security): Updating assert logic (#10034)
This is an automated email from the ASF dual-hosted git repository. johnbodley pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-superset.git The following commit(s) were added to refs/heads/master by this push: new aefef9c chore(security): Updating assert logic (#10034) aefef9c is described below commit aefef9ca55aeef24950547211c730b84736cfd2c Author: John Bodley <4567245+john-bod...@users.noreply.github.com> AuthorDate: Tue Jun 23 20:49:39 2020 -0700 chore(security): Updating assert logic (#10034) * chore(security): Updating assert logic * Deprecating rejected_tables Co-authored-by: John Bodley --- UPDATING.md| 2 + superset/charts/api.py | 4 +- superset/common/query_context.py | 9 ++ superset/connectors/base/models.py | 10 +++ superset/models/sql_lab.py | 9 ++ superset/security/manager.py | 180 + superset/views/api.py | 7 +- superset/views/core.py | 49 +- superset/views/utils.py| 16 ++-- superset/viz.py| 9 ++ superset/viz_sip38.py | 9 ++ tests/security_tests.py| 117 ++-- 12 files changed, 278 insertions(+), 143 deletions(-) diff --git a/UPDATING.md b/UPDATING.md index 739c3b3..f5a3644 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -23,6 +23,8 @@ assists people when migrating to a new version. ## Next +* [10034](https://github.com/apache/incubator-superset/pull/10034): Deprecates the public security manager `assert_datasource_permission`, `assert_query_context_permission`, `assert_viz_permission`, and `rejected_tables` methods with the `raise_for_access` method which also handles assertion logic for SQL tables. + * [10031](https://github.com/apache/incubator-superset/pull/10030): Renames the following public security manager methods: `can_access_datasource` to `can_access_table`, `all_datasource_access` to `can_access_all_datasources`, `all_database_access` to `can_access_all_databases`, `database_access` to `can_access_database`, `schema_access` to `can_access_schema`, and `datasource_access` to `can_access_datasource`. Regrettably it is not viable to provide aliases for the deprecated methods as this would result in a name clash. Finally the `can_access_table` (previously `can_access_database`) method signature has changed, i.e., the optional `schema` argument no longer exists. diff --git a/superset/charts/api.py b/superset/charts/api.py index d309ef1..c6ff00b 100644 --- a/superset/charts/api.py +++ b/superset/charts/api.py @@ -53,7 +53,7 @@ from superset.charts.schemas import ( ) from superset.constants import RouteMethod from superset.exceptions import SupersetSecurityException -from superset.extensions import event_logger, security_manager +from superset.extensions import event_logger from superset.models.slice import Slice from superset.tasks.thumbnails import cache_chart_thumbnail from superset.utils.core import ChartDataResultFormat, json_int_dttm_ser @@ -454,7 +454,7 @@ class ChartRestApi(BaseSupersetModelRestApi): except KeyError: return self.response_400(message="Request is incorrect") try: -security_manager.assert_query_context_permission(query_context) +query_context.raise_for_access() except SupersetSecurityException: return self.response_401() payload = query_context.get_payload() diff --git a/superset/common/query_context.py b/superset/common/query_context.py index 7cb82a4..fb70f0a 100644 --- a/superset/common/query_context.py +++ b/superset/common/query_context.py @@ -286,3 +286,12 @@ class QueryContext: "stacktrace": stacktrace, "rowcount": len(df.index), } + +def raise_for_access(self) -> None: +""" +Raise an exception if the user cannot access the resource. + +:raises SupersetSecurityException: If the user cannot access the resource +""" + +security_manager.raise_for_access(query_context=self) diff --git a/superset/connectors/base/models.py b/superset/connectors/base/models.py index f2dad88..1f6f032 100644 --- a/superset/connectors/base/models.py +++ b/superset/connectors/base/models.py @@ -23,6 +23,7 @@ from sqlalchemy import and_, Boolean, Column, Integer, String, Text from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.orm import foreign, Query, relationship, RelationshipProperty +from superset import security_manager from superset.constants import NULL_STRING from superset.models.helpers import AuditMixinNullable, ImportMixin, QueryResult from superset.models.slice import Slice @@ -496,6 +497,15 @@ class BaseDatasource( return NotImplemented return self.uid == other.uid +def raise_for_access(self) -> None: +""" +Ra
[incubator-superset] branch master updated: style: listviews closer to SIP-34 (#10094)
This is an automated email from the ASF dual-hosted git repository. tai pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-superset.git The following commit(s) were added to refs/heads/master by this push: new be936c2 style: listviews closer to SIP-34 (#10094) be936c2 is described below commit be936c2eb89fa09ed6147fb9f2dc4c63ed1390bd Author: ʈᵃᵢ AuthorDate: Tue Jun 23 14:17:28 2020 -0700 style: listviews closer to SIP-34 (#10094) --- .../components/ListView/ListView_spec.jsx | 3 +- .../javascripts/views/chartList/ChartList_spec.jsx | 4 + .../views/dashboardList/DashboardList_spec.jsx | 4 + .../javascripts/welcome/DashboardTable_spec.jsx| 8 +- superset-frontend/src/components/AvatarIcon.tsx| 29 ++- .../src/components/ListView/ListView.tsx | 211 ++--- .../src/components/ListView/ListViewStyles.less| 169 ++--- .../src/components/ListView/Pagination.tsx | 11 +- .../src/components/ListView/TableCollection.tsx| 82 ++-- superset-frontend/src/components/Menu/SubMenu.tsx | 16 +- superset-frontend/src/components/Pagination.tsx| 132 + .../src/types/react-table-config.d.ts | 10 +- superset-frontend/src/utils/common.js | 4 + .../src/views/chartList/ChartList.tsx | 103 +- .../src/views/dashboardList/DashboardList.tsx | 125 ++-- .../src/views/datasetList/DatasetList.tsx | 179 + superset-frontend/stylesheets/less/variables.less | 4 - 17 files changed, 682 insertions(+), 412 deletions(-) diff --git a/superset-frontend/spec/javascripts/components/ListView/ListView_spec.jsx b/superset-frontend/spec/javascripts/components/ListView/ListView_spec.jsx index e5e04d5..52e15ff 100644 --- a/superset-frontend/spec/javascripts/components/ListView/ListView_spec.jsx +++ b/superset-frontend/spec/javascripts/components/ListView/ListView_spec.jsx @@ -19,13 +19,14 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; import { act } from 'react-dom/test-utils'; -import { MenuItem, Pagination } from 'react-bootstrap'; +import { MenuItem } from 'react-bootstrap'; import Select from 'src/components/Select'; import { QueryParamProvider } from 'use-query-params'; import ListView from 'src/components/ListView/ListView'; import ListViewFilters from 'src/components/ListView/Filters'; import ListViewPagination from 'src/components/ListView/Pagination'; +import Pagination from 'src/components/Pagination'; import { areArraysShallowEqual } from 'src/reduxUtils'; import { ThemeProvider } from 'emotion-theming'; import { supersetTheme } from '@superset-ui/style'; diff --git a/superset-frontend/spec/javascripts/views/chartList/ChartList_spec.jsx b/superset-frontend/spec/javascripts/views/chartList/ChartList_spec.jsx index d5785bf..1ec7275 100644 --- a/superset-frontend/spec/javascripts/views/chartList/ChartList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/chartList/ChartList_spec.jsx @@ -21,6 +21,8 @@ import { mount } from 'enzyme'; import thunk from 'redux-thunk'; import configureStore from 'redux-mock-store'; import fetchMock from 'fetch-mock'; +import { ThemeProvider } from 'emotion-theming'; +import { supersetTheme } from '@superset-ui/style'; import ChartList from 'src/views/chartList/ChartList'; import ListView from 'src/components/ListView/ListView'; @@ -77,6 +79,8 @@ describe('ChartList', () => { const mockedProps = {}; const wrapper = mount(, { context: { store }, +wrappingComponent: ThemeProvider, +wrappingComponentProps: { theme: supersetTheme }, }); it('renders', () => { diff --git a/superset-frontend/spec/javascripts/views/dashboardList/DashboardList_spec.jsx b/superset-frontend/spec/javascripts/views/dashboardList/DashboardList_spec.jsx index 086d9d1..456035e 100644 --- a/superset-frontend/spec/javascripts/views/dashboardList/DashboardList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/dashboardList/DashboardList_spec.jsx @@ -21,6 +21,8 @@ import { mount } from 'enzyme'; import thunk from 'redux-thunk'; import configureStore from 'redux-mock-store'; import fetchMock from 'fetch-mock'; +import { ThemeProvider } from 'emotion-theming'; +import { supersetTheme } from '@superset-ui/style'; import DashboardList from 'src/views/dashboardList/DashboardList'; import ListView from 'src/components/ListView/ListView'; @@ -67,6 +69,8 @@ describe('DashboardList', () => { const mockedProps = {}; const wrapper = mount(, { context: { store }, +wrappingComponent: ThemeProvider, +wrappingComponentProps: { theme: supersetTheme }, }); it('renders', () => { diff --git a/superset-frontend/spec/javascripts/welcome/DashboardTable_spec.jsx b/superset-frontend/spec/javascripts/welcome/DashboardTable_spec.jsx index a31761a..2fe659b 100644 --- a/superset-frontend/spec/javasc
[incubator-superset] branch master updated: feat: dataset add modal (#10104)
This is an automated email from the ASF dual-hosted git repository. tai pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-superset.git The following commit(s) were added to refs/heads/master by this push: new 4d1d409 feat: dataset add modal (#10104) 4d1d409 is described below commit 4d1d40989c333e85441fb750774bb9cc0d6c831d Author: Lily Kuang AuthorDate: Tue Jun 23 10:15:35 2020 -0700 feat: dataset add modal (#10104) --- superset-frontend/images/icons/warning.svg | 22 superset-frontend/src/components/Icon.tsx | 29 ++--- superset-frontend/src/components/Menu/SubMenu.tsx | 34 -- superset-frontend/src/components/TableSelector.jsx | 44 +-- superset-frontend/src/views/datasetList/Button.tsx | 67 +++ .../src/views/datasetList/DatasetModal.tsx | 129 + superset-frontend/src/views/datasetList/Modal.tsx | 93 +++ 7 files changed, 382 insertions(+), 36 deletions(-) diff --git a/superset-frontend/images/icons/warning.svg b/superset-frontend/images/icons/warning.svg new file mode 100644 index 000..9375f58 --- /dev/null +++ b/superset-frontend/images/icons/warning.svg @@ -0,0 +1,22 @@ + +http://www.w3.org/2000/svg";> + + -{label} +{this.props.label} + -{childs && - childs.map(child => ( +{this.props.childs && + this.props.childs.map(child => ( { ))} - {canCreate && ( + {this.props.canCreate && ( - - {createButton.name} + + {this.props.createButton.name} )} diff --git a/superset-frontend/src/components/TableSelector.jsx b/superset-frontend/src/components/TableSelector.jsx index 6b1ae22..a477c85 100644 --- a/superset-frontend/src/components/TableSelector.jsx +++ b/superset-frontend/src/components/TableSelector.jsx @@ -17,6 +17,7 @@ * under the License. */ import React from 'react'; +import styled from '@superset-ui/style'; import PropTypes from 'prop-types'; import { Select, AsyncSelect } from 'src/components/Select'; import { ControlLabel, Label } from 'react-bootstrap'; @@ -27,6 +28,13 @@ import SupersetAsyncSelect from './AsyncSelect'; import RefreshLabel from './RefreshLabel'; import './TableSelector.less'; +const FieldTitle = styled.p` + color: ${({ theme }) => theme.colors.secondary.light2}; + font-size: ${({ theme }) => theme.typography.sizes.s}; + margin: 20px 0 10px 0; + text-transform: uppercase; +`; + const propTypes = { dbId: PropTypes.number.isRequired, schema: PropTypes.string, @@ -40,6 +48,7 @@ const propTypes = { tableName: PropTypes.string, database: PropTypes.object, sqlLabMode: PropTypes.bool, + formMode: PropTypes.bool, onChange: PropTypes.func, clearable: PropTypes.bool, handleError: PropTypes.func.isRequired, @@ -55,6 +64,7 @@ const defaultProps = { onChange: () => {}, tableNameSticky: true, sqlLabMode: true, + formMode: false, clearable: true, }; @@ -79,8 +89,10 @@ export default class TableSelector extends React.PureComponent { } componentDidMount() { -this.fetchSchemas(this.state.dbId); -this.fetchTables(); +if (this.state.dbId) { + this.fetchSchemas(this.state.dbId); + this.fetchTables(); +} } onChange() { @@ -198,7 +210,10 @@ export default class TableSelector extends React.PureComponent { this.props.onSchemaChange(null); this.props.onDbChange(db); this.fetchSchemas(dbId, force); -this.setState({ dbId, schema: null, tableOptions: [] }, this.onChange); +this.setState( + { dbId, schema: null, tableName: null, tableOptions: [] }, + this.onChange, +); } changeSchema(schemaOpt, force = false) { @@ -289,6 +304,12 @@ export default class TableSelector extends React.PureComponent { } renderSchema() { +const refresh = !this.props.formMode && ( + this.onDatabaseChange({ id: this.props.dbId }, true)} +tooltipContent={t('Force refresh schema list')} + /> +); return this.renderSelectRow( , - this.onDatabaseChange({ id: this.props.dbId }, true)} -tooltipContent={t('Force refresh schema list')} - />, + refresh, ); } @@ -346,15 +364,16 @@ export default class TableSelector extends React.PureComponent { value={this.state.tableName} loadOptions={this.getTableNamesBySubStr} optionRenderer={this.renderTableOption} +isDisabled={this.props.formMode} /> ); -return this.renderSelectRow( - select, +const refresh = !this.props.formMode && ( this.changeSchema({ value: this.props.schema }, true)} tooltipContent={t('Force refresh table list')} - />, +