Create or Update Roles in Apache Superset Programmatically
Asked Answered
M

3

5

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.

Marinmarina answered 19/5, 2021 at 17:28 Comment(0)
A
4

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.

  • Add a new role (without permissions):
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.

  • Add permission to role:
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])
Amazon answered 4/8, 2023 at 23:21 Comment(3)
Without doing the steps mentioned in this ans I was getting an API not found error, after doing this I got 403 FORBIDDEN error. It worked only after doing the steps mentioned in puchal's ans.Clite
How did you get the id = 6?Inelegant
@Inelegant GET on /api/v1/security/roles. There you will see all your roles and ids.Amazon
D
3

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

enter image description here

Duky answered 3/8, 2023 at 9:30 Comment(0)
P
2

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

--

  • SupersetSecurityManager is the object that have available functions to manage user programatically
  • Sorry for my bad english, this is my first collaboration, hope this helps
Prehension answered 27/6, 2021 at 5:57 Comment(1)
Thanks, but more details like in puchal's answer would have been helpful.Clite

© 2022 - 2024 — McMap. All rights reserved.