fix(sqllab): Close already removed tab (#27391)

This commit is contained in:
JUST.in DO IT 2024-03-06 08:59:56 -08:00 committed by GitHub
parent 66bf70172f
commit 5107cc0fd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 90 additions and 13 deletions

View File

@ -743,15 +743,18 @@ export function removeQueryEditor(queryEditor) {
return sync
.then(() => dispatch({ type: REMOVE_QUERY_EDITOR, queryEditor }))
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while removing tab. Please contact your administrator.',
.catch(({ status }) => {
if (status !== 404) {
return dispatch(
addDangerToast(
t(
'An error occurred while removing tab. Please contact your administrator.',
),
),
),
),
);
);
}
return dispatch({ type: REMOVE_QUERY_EDITOR, queryEditor });
});
};
}

View File

@ -64,7 +64,10 @@ export const supersetClientQuery: BaseQueryFn<
}))
.catch(response =>
getClientErrorObject(response).then(errorObj => ({
error: errorObj,
error: {
error: errorObj?.message || errorObj?.error || response.statusText,
status: response.status,
},
})),
);

View File

@ -112,7 +112,10 @@ class TabStateView(BaseSupersetView):
@has_access_api
@expose("/<int:tab_state_id>", methods=("DELETE",))
def delete(self, tab_state_id: int) -> FlaskResponse:
if _get_owner_id(tab_state_id) != get_user_id():
owner_id = _get_owner_id(tab_state_id)
if owner_id is None:
return Response(status=404)
if owner_id != get_user_id():
return Response(status=403)
db.session.query(TabState).filter(TabState.id == tab_state_id).delete(
@ -127,7 +130,10 @@ class TabStateView(BaseSupersetView):
@has_access_api
@expose("/<int:tab_state_id>", methods=("GET",))
def get(self, tab_state_id: int) -> FlaskResponse:
if _get_owner_id(tab_state_id) != get_user_id():
owner_id = _get_owner_id(tab_state_id)
if owner_id is None:
return Response(status=404)
if owner_id != get_user_id():
return Response(status=403)
tab_state = db.session.query(TabState).filter_by(id=tab_state_id).first()
@ -157,7 +163,10 @@ class TabStateView(BaseSupersetView):
@has_access_api
@expose("<int:tab_state_id>", methods=("PUT",))
def put(self, tab_state_id: int) -> FlaskResponse:
if _get_owner_id(tab_state_id) != get_user_id():
owner_id = _get_owner_id(tab_state_id)
if owner_id is None:
return Response(status=404)
if owner_id != get_user_id():
return Response(status=403)
fields = {k: json.loads(v) for k, v in request.form.to_dict().items()}
@ -172,7 +181,10 @@ class TabStateView(BaseSupersetView):
@has_access_api
@expose("<int:tab_state_id>/migrate_query", methods=("POST",))
def migrate_query(self, tab_state_id: int) -> FlaskResponse:
if _get_owner_id(tab_state_id) != get_user_id():
owner_id = _get_owner_id(tab_state_id)
if owner_id is None:
return Response(status=404)
if owner_id != get_user_id():
return Response(status=403)
client_id = json.loads(request.form["queryId"])

View File

@ -137,6 +137,65 @@ class TestSqlLabApi(SupersetTestCase):
result = resp["result"]
self.assertEqual(len(result["queries"]), 1)
@mock.patch.dict(
"superset.extensions.feature_flag_manager._feature_flags",
{"SQLLAB_BACKEND_PERSISTENCE": True},
clear=True,
)
def test_deleted_tab(self):
username = "admin"
self.login(username)
data = {
"queryEditor": json.dumps(
{
"title": "Untitled Query 2",
"dbId": 1,
"schema": None,
"autorun": False,
"sql": "SELECT ...",
"queryLimit": 1000,
}
)
}
resp = self.get_json_resp("/tabstateview/", data=data)
tab_state_id = resp["id"]
resp = self.client.delete("/tabstateview/" + str(tab_state_id))
assert resp.status_code == 200
resp = self.client.get("/tabstateview/" + str(tab_state_id))
assert resp.status_code == 404
resp = self.client.put(
"/tabstateview/" + str(tab_state_id),
json=data,
)
assert resp.status_code == 404
@mock.patch.dict(
"superset.extensions.feature_flag_manager._feature_flags",
{"SQLLAB_BACKEND_PERSISTENCE": True},
clear=True,
)
def test_delete_tab_already_removed(self):
username = "admin"
self.login(username)
data = {
"queryEditor": json.dumps(
{
"title": "Untitled Query 3",
"dbId": 1,
"schema": None,
"autorun": False,
"sql": "SELECT ...",
"queryLimit": 1000,
}
)
}
resp = self.get_json_resp("/tabstateview/", data=data)
tab_state_id = resp["id"]
resp = self.client.delete("/tabstateview/" + str(tab_state_id))
assert resp.status_code == 200
resp = self.client.delete("/tabstateview/" + str(tab_state_id))
assert resp.status_code == 404
def test_get_access_denied(self):
new_role = Role(name="Dummy Role", permissions=[])
db.session.add(new_role)