Reputation: 906
Is there any way by which we can create new roles programmatically in Superset? I have checked the docs but can't find any hooks to create the roles programmatically.
Upvotes: 6
Views: 6609
Reputation: 1200
An alternative to the previous answers would be to enable the FAB REST API in Superset. Apache Superset uses Flask App Builder (FAB), whose API is hidden by default.
Setting FAB's configuration variable FAB_ADD_SECURITY_API = True
in superset_config.py
adds a CRUD REST API for users, roles, permissions, view_menus reachable under /api/v1/security
. More on how to configure Apache Superset.
curl --request POST \
--url http://localhost:8088/api/v1/security/roles/ \
--header 'Authorization: Bearer token' \
--header 'Content-Type: application/json' \
--header 'X-CSRFToken: token' \
--data '{"name": "my_new_role"}'
This creates the role "my_new_role" with id=6
.
curl --request POST \
--url http://localhost:8088/api/v1/security/roles/6/permissions \
--header 'Authorization: Bearer token' \
--header 'Content-Type: application/json' \
--header 'X-CSRFToken: token' \
--data '{"permission_view_menu_ids": [1,2]}'
This adds the permissions with id=1
and id=2
to the role with id=6
.
Here is an example to do the same with Python:
import requests
base_url = 'http://localhost:8088/api/v1'
def get_bearer_token():
payload = {
"password": "admin",
"provider": "db",
"username": "admin"
}
headers = {"Content-Type": "application/json"}
response = requests.request("POST", f"{base_url}/security/login", json=payload, headers=headers)
return response.json()["access_token"]
def get_csrf_token():
headers = {"Authorization": f"Bearer {get_bearer_token()}"}
response = requests.request("GET", f"{base_url}/security/csrf_token/", data="", headers=headers)
return response.json()["result"]
def add_role(name):
headers = {
'X-CSRFToken': get_csrf_token(),
'Authorization': f"Bearer {get_bearer_token()}"
}
response = requests.request("POST", f"{base_url}/security/roles", json={"name": name}, headers=headers)
return response.json()
def add_permissions_to_role(role_id, permissions):
headers = {
'X-CSRFToken': get_csrf_token(),
'Authorization': f"Bearer {get_bearer_token()}"
}
response = requests.request("POST", f"{base_url}/security/roles/{role_id}/permissions", json={"permission_view_menu_ids": permissions}, headers=headers)
return response.json()
add_role("my_new_role")
add_permissions_to_role(6, [1,2])
Upvotes: 5
Reputation: 2389
Superset is using Flask App Builder which has which also has CRUD REST api for security models.
What you need to do is to enable API during initialisation of app, to achieve that you need to modify superset_config.py
Let's assume that you use docker-compose file provided by Superset https://github.com/apache/superset/tree/master/docker
in pythonpath_dev
directory create custom_initializer.py
file
custom_initializer.py
code:
from superset.app import SupersetAppInitializer
from superset.extensions import appbuilder
from superset.security import SupersetSecurityManager
class MySupsersetAppInitializer(SupersetAppInitializer):
def init_views(self) -> None:
# Adds api for roles
appbuilder.add_api(SupersetSecurityManager.role_api)
# Uncomment if you want as well to add api for permissions, users, ect.
# appbuilder.add_api(SupersetSecurityManager.permission_api)
# appbuilder.add_api(SupersetSecurityManager.user_api)
# appbuilder.add_api(SupersetSecurityManager.view_menu_api)
# appbuilder.add_api(SupersetSecurityManager.permission_view_menu_api)
super().init_views()
Now modify superset_config.py
. Add those lines:
from custom_initializer import MySupsersetAppInitializer
APP_INITIALIZER = MySupsersetAppInitializer
Now you should be able to have access to API implemented by Flask App Builder
Upvotes: 3
Reputation: 39
I use Superset as a python library, and got the same problem a few months ago...
first you have to create a Custom Security Manager... to do this i read this tutorial https://programmer.group/tutorial-how-to-integrate-superset-in-your-own-application.html
Essentially you make the call from your superset_config.py file like this
from core_utils.security import CustomSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSecurityManager
In the init method of the CustomSecurityManager() you can make the call to add_role() function... this do the trick
--
Upvotes: 2