Open giacomochiarella opened 1 year ago
I am having the same problem. Tried with curl and python requests and nothing returned. dataset endpoint works fine.
Also checked and doing PUT to /api/v1/dashboard/{id} works fine so only GET doesn't get anything.
Using 3.0,1 image.
I have just discovered that if you make a request and pass Cookie header with syntactically valid session cookie (you can get it from making the same request in a browser) I get expected response from /database and /chart endpoints.
Stange that they behave differently from /dataset
url = "http://localhost/api/v1/dashboard/"
payload = {}
headers = {
'Accept': 'application/json',
'Cookie': 'session=valid_cookie here',
'Authorization': 'Bearer valid_token'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
I have found that if I take the session=.cookie
from my swagger and use that (hardcoded) in my api request it works (the dot before the cookie is intentional as it is not apart of the other cookie).
If I use the session=cookie
returned from /api/v1/security/csrf_token/
it does not work, I am not sure what that means and I have no idea how to solve it right now, but being able to display the dashboards as a list is essential to any application that has embedded dashboards.
If I figure out how I can be apart of the solution or if I find a solution I will share it here ✌️ Also if anyone has some ideas of how I can get this endpoint to work /api/v1/dashboard/
I welcome all of them 😅.
code example:
import axios from 'axios';
import { SUPERSET_BASE } from '../../constants';
import { getCsrfToken, login } from './auth.helper';
export async function getDashboards() {
const { accessToken } = await login();
// const { sessionCookie, csrfToken } = await getCsrfToken(accessToken);
const headers = {
Accept: 'application/json',
Authorization: `Bearer ${accessToken}`,
// Cookie: `session=${sessionCookie}`, // This does not work 😑
Cookie:
'session=.session_cookie_copied_from_hosted_swagger_dev_tools' // this works...
};
const response = await axios.get(`${SUPERSET_BASE}/api/v1/dashboard/`, {
headers
});
return response;
}
The solution for this issue can be found here, I think this should be marked as resolved. https://apache-superset.slack.com/archives/C01EP56QGTS/p1705521514606739?thread_ts=1704717577.433489&cid=C01EP56QGTS
Okay so as discussed below this is a fix for displaying the dashboard list only, if you try to view an embedded dashboard with the changes it will not work.
When getting the guest token there is a request to the /api/v1/me/roles/
endpoint which returns the Public
role, even if you assign a different Role to the user requesting to view the embedded dashboard, the token is requested as a guest(Public Role), not as the assigned role, maybe after manually getting the roles of the signed in user (GET /api/v1/me/roles/
), we should then be able to send them in the payload along with the rls
?
For example; if the roles matrix is provided in the payload of the request, the token is granted with the provided roles, if not, it is granted with the default Public role. This is a naive idea of a solution, I dont know the complexities of the python code. maybe it is related to this? config.py line 345 fe-embedded
const payload = {
user: {
username: 'js1',
firstName: 'John',
lastName: 'Smith'
},
resources: [
{
type: 'dashboard',
id
}
],
roles: {
gamma: [
['can_read', 'Chart'],
['can_read', 'Dashboard'],
['can_list', 'DynamicPlugin'],
['can_explore_json', 'Superset'],
...
]
},
rls: []
};
@bronz3beard I think the link you sent is not a solution to the problem.
It seems that having can read on Dashboard
or can read on Chart
in the public role breaks the dashboard/chart api.
We need a workaround in case we need these permissions on the public role.
@ss-ravi Ahh okay I see, I thought the permission change to public was intentional, but it is just a temp fix not a solution. thanks for the extra context 🙌
if I change this GUEST_ROLE_NAME = "Public"
in the config.py on line 1561
toGUEST_ROLE_NAME = "Guest"
and then create and give the Guest role the same permissions as
Public role` everything is working as expected.
@bronz3beard I think the link you sent is not a solution to the problem. It seems that having
can read on Dashboard
orcan read on Chart
in the public role breaks the dashboard/chart api. We need a workaround in case we need these permissions on the public role.
Thanks to save my life. Just removed the Public role's perm and everything works.... Don't get it.
@cw1427 do you mean you just deleted the Public
role?
@cw1427 do you mean you just deleted the
Public
role?
You need to update the config to use GUEST
(a role you create with exactly the same permissions as PUBLIC Role) rather than PUBLIC
.
After you make that change to the config you could delete it if you want, up to you.
@bronz3beard thanks for the answer. It was not clear. What is the difference between PUBLIC_ROLE_LIKE
and GUEST_ROLE_NAME
? Right now I have setup PUBLIC_ROLE_LIKE
to a custom role, can I assign the same role to GUEST_ROLE_NAME
?
@bronz3beard thanks for the answer. It was not clear. What is the difference between
PUBLIC_ROLE_LIKE
andGUEST_ROLE_NAME
? Right now I have setupPUBLIC_ROLE_LIKE
to a custom role, can I assign the same role toGUEST_ROLE_NAME
?
My response was as clear as your question.
I dont know what your setup is, but from your question I would experiment with this solution, you suggested as a question.
PUBLIC_ROLE_LIKE to a custom role, can I assign the same role to GUEST_ROLE_NAME?
for me all I had to do was this to get ti to work, obviously this is a work around.
@bronz3beard unfortunately it does not work. I've setup PUBLIC_ROLE_LIKE = None
and GUEST_ROLE_NAME = 'custom_role'
but I still have the same issue. The only way it worked is by deleting Public
role but it gets recreated if I restart Superset. Moreover, if I delete Public
role I get Internal server error 500
if I just open Superset homepage and I'm not logged in (the error is name does not exist on None object or something, it tries to call .name
on role object which is None, because Public does not exist).
I've also tried PUBLIC_ROLE_LIKE = None
and GUEST_ROLE_NAME = 'custom_role'
with custom_role equal to Public and nothing changed. The api still return no dashboards/charts even though the credentials have Admin role.
I've done these changes in superset_config.py
any news here? It is crucial to be able use the api
Check Public
role permissions. If Dashboard
can_read
is set for Public
role, then this happens. I'm not sure if it's intended behavior or bug.
Check
Public
role permissions. IfDashboard
can_read
is set forPublic
role, then this happens. I'm not sure if it's intended behavior or bug.
@gruz could you be more specific on what you are suggesting to do? can_read on Dashboard
is automatically assigned when you start Superset. What are the steps you are suggesting with your statement?
@giacomochiarella In my case someone before me added permissions to the Public
role. From scratch Public
role doesn't have any permissions.
Among those permissions what can_read on Dashboard
in Public
role. After removing it from Public
role I can get the list of Dashboards
as expected (count to zero).
P.S. A guy who added the permissions to the Public role have told, at least some of them are needed for Dashboard embedding to work.
Same problem here, we want to make a simple embedded dashboard from superset with a page listing all dashboard available, when click on one of the item it will redirect to the detail of that dashboard, so to make dashboard embedded work, we have to add
FEATURE_FLAGS = {
"EMBEDDED_SUPERSET": True,
"GUEST_TOKEN": True
}
~~PUBLIC_ROLE_LIKE = "Gamma" # <-- This one will add a bunch of permissions to Public role which is necessary to embedding dashboard to the site~~
But if Public Role have these permission then these API will no longer working as expected
GET: /api/v1/dashboard/ # <-- return count = 0
GET: /api/v1/dashboard/1/embedded # <-- return not found
If we delete public role then these 2 API will working as expected but then we will get internal server error in the embedded dashboard on our site.
If we use Cookie created when login from the browser then we can make these 2 APIs work as well but ofc we can't use that because that cookie will be delete as soon as we close the browser.
We used apache/superset:4.0.2 docker image, if anyone know a version where these APIs work as expected, please let me know
P/S: Nvm, I think I understand the problem now, the problem is, when we login as Guest through API, we can only see published dashboard not all dashboards. This is not a bug at all, hope this answer help others as well.
I think I found a workaround to use the API when the PUBLIC_ROLE_LIKE var is defined.
I’ve attached an example bash script with curl calls. The key is the method save_cookie_from_login. After get access and csrf tokens, the idea is to simulate to access to login html page and save the new cookie. test_list_dashboards.zip
save_cookie_from_login () {
# URL to send the request to
local URL="${superset_url}/login/"
local payload="csrf_token=${csrf_token}&username=admin&password=admin"
# Do a POST request to login saving the new cookie
local response2; response2=$(curl -b /tmp/cookies.txt -c /tmp/cookies.txt -s -X POST "$URL" -d "$payload")
}
I think this is could be a solution for these issues: https://github.com/apache/superset/issues/25876 https://github.com/apache/superset/issues/25740
@jacob-roldan could you be more specific how to use your workaround in Python? I'm still having issues in calling /api/v1/database or database/{pk}, /api/v1/dataset or dataset/{pk}, /api/v1/chart or chart/{pk}, /api/v1/dashboard or dashboard/{pk}. They return 0 or 404
A simple example using python to get all dashboards when user admin uses /api/v1/dashboard
Dashboard api /api/v1/dashboard and /api/v1/chart returning empty responses when get request is made using user with Superset predefined Admin role in Python
Expected results
I expect to get all dashboards when user with Admin role uses /api/v1/dashboard I expect to get all charts when user with Admin role uses /api/v1/chart
Actual results
I get
{"count":0,"description_columns":{},"ids":[],"label_columns":{"certification_details":"Certification Details","certified_by":"Certified By","changed_by.first_name":"Changed By First Name","changed_by.id":"Changed By Id","changed_by.last_name":"Changed By Last Name","changed_by_name":"Changed By Name","changed_on_delta_humanized":"Changed On Delta Humanized","changed_on_utc":"Changed On Utc","created_by.first_name":"Created By First Name","created_by.id":"Created By Id","created_by.last_name":"Created By Last Name","created_on_delta_humanized":"Created On Delta Humanized","css":"Css","dashboard_title":"Dashboard Title","id":"Id","is_managed_externally":"Is Managed Externally","json_metadata":"Json Metadata","owners.first_name":"Owners First Name","owners.id":"Owners Id","owners.last_name":"Owners Last Name","position_json":"Position Json","published":"Published","roles.id":"Roles Id","roles.name":"Roles Name","slug":"Slug","status":"Status","tags.id":"Tags Id","tags.name":"Tags Name","tags.type":"Tags Type","thumbnail_url":"Thumbnail Url","url":"Url"},"list_columns":["id","published","status","slug","url","css","position_json","json_metadata","thumbnail_url","certified_by","certification_details","changed_by.first_name","changed_by.last_name","changed_by.id","changed_by_name","changed_on_utc","changed_on_delta_humanized","created_on_delta_humanized","created_by.first_name","created_by.id","created_by.last_name","dashboard_title","owners.id","owners.first_name","owners.last_name","roles.id","roles.name","is_managed_externally","tags.id","tags.name","tags.type"],"list_title":"List Dashboard","order_columns":["changed_by.first_name","changed_on_delta_humanized","created_by.first_name","dashboard_title","published","changed_on"],"result":[]}
on /api/v1/dashboardI get
{"count":0,"description_columns":{},"ids":[],"label_columns":{"cache_timeout":"Cache Timeout","certification_details":"Certification Details","certified_by":"Certified By","changed_by.first_name":"Changed By First Name","changed_by.last_name":"Changed By Last Name","changed_by_name":"Changed By Name","changed_on_delta_humanized":"Changed On Delta Humanized","changed_on_dttm":"Changed On Dttm","changed_on_utc":"Changed On Utc","created_by.first_name":"Created By First Name","created_by.id":"Created By Id","created_by.last_name":"Created By Last Name","created_by_name":"Created By Name","created_on_delta_humanized":"Created On Delta Humanized","dashboards.dashboard_title":"Dashboards Dashboard Title","dashboards.id":"Dashboards Id","datasource_id":"Datasource Id","datasource_name_text":"Datasource Name Text","datasource_type":"Datasource Type","datasource_url":"Datasource Url","description":"Description","description_markeddown":"Description Markeddown","edit_url":"Edit Url","form_data":"Form Data","id":"Id","is_managed_externally":"Is Managed Externally","last_saved_at":"Last Saved At","last_saved_by.first_name":"Last Saved By First Name","last_saved_by.id":"Last Saved By Id","last_saved_by.last_name":"Last Saved By Last Name","owners.first_name":"Owners First Name","owners.id":"Owners Id","owners.last_name":"Owners Last Name","params":"Params","slice_name":"Slice Name","slice_url":"Slice Url","table.default_endpoint":"Table Default Endpoint","table.table_name":"Table Table Name","tags.id":"Tags Id","tags.name":"Tags Name","tags.type":"Tags Type","thumbnail_url":"Thumbnail Url","url":"Url","viz_type":"Viz Type"},"list_columns":["is_managed_externally","certified_by","certification_details","cache_timeout","changed_by.first_name","changed_by.last_name","changed_by_name","changed_on_delta_humanized","changed_on_dttm","changed_on_utc","created_by.first_name","created_by.id","created_by.last_name","created_by_name","created_on_delta_humanized","datasource_id","datasource_name_text","datasource_type","datasource_url","description","description_markeddown","edit_url","form_data","id","last_saved_at","last_saved_by.id","last_saved_by.first_name","last_saved_by.last_name","owners.first_name","owners.id","owners.last_name","dashboards.id","dashboards.dashboard_title","params","slice_name","slice_url","table.default_endpoint","table.table_name","thumbnail_url","url","viz_type","tags.id","tags.name","tags.type"],"list_title":"List Slice","order_columns":["changed_by.first_name","changed_on_delta_humanized","datasource_id","datasource_name","last_saved_at","last_saved_by.id","last_saved_by.first_name","last_saved_by.last_name","slice_name","viz_type"],"result":[]}
on /api/v1/chartI get 404 if I call /api/v1/dashboard/{id} on an existing dashboard (the id is read by accessing the dashboard and read the id in the url).
Calling /api/v1/log or /api/v1/dashboard return a 308 which is successfully redirected for /api/v1/log, instead it gives above response for /api/v1/dashboard
Environment
Running docker-compose.yml Python 3.9.18 Flask 2.2.5 Werkzeug 2.3.3 Superset images: 3.1.0
DASHBOARD_RBAC: True
Checklist
I can use /api/v1/log without any issue in Python and in RESTClient I can use /api/v1/dashboard in RESTCLient, when I call /api/v1/dashboard in Python I get 308 which is redirected but then I get the above response (no dashboards included)