apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
60.53k stars 13.07k forks source link

List users not accesible if we use custom login #29505

Open kannant-sf opened 3 days ago

kannant-sf commented 3 days ago

Bug description

We have deployed our apache superset on AWS fargate, we have our internal dashboards from there we want our users to login hence we have implemented custom login setup on superset side, i was able to do it, now everything works fine, but if i navigate to list/users its redirecting me to login screen and logs in back but getting access denied in right bottom popup, If i revert my custom login code it works properly am using the same user credentials, not sure why it behaves differently, attaching my custom login code

 class RemoteUserMiddleware(object):
  def __init__(self, app):
    self.app = app
  def __call__(self, environ, start_response):
    user = environ.pop('HTTP_USER', None)
     environ['REMOTE_USER'] = user
  return self.app(environ, start_response)

 ADDITIONAL_MIDDLEWARE = [RemoteUserMiddleware]

class CustomRemoteUserView(AuthRemoteUserView):
 login_template = ""

@expose("/login/")
def login(self):
    logger.info("Using custom security manager")
    username = ""
    url = ""

    if g.user is not None and g.user.is_authenticated:
        return redirect(self.appbuilder.get_url_for_index)

    def getUserName(user_roles):
       return "dummy"

    try:
        token = "Bearer " + token
        response = requests.get(url, headers={"Tenant_identifier":tenantIdentifier, "Authorization": token})

        if response.status_code == 200:
            user_data = response.json()
            user_roles = user_data['data']['userRoles']

            security_manager = self.appbuilder.sm
            username=getUserName(user_roles)

            logger.info(username)

            user = security_manager.find_user(username=username)

            logger.info("details")
            logger.info(user)
            if user is not None:
                logger.info("Inside if condition")
                login_user(user)
                return redirect(self.appbuilder.get_url_for_index)
        else:
            print('Error:', response.status_code)
            logger.warning("User not found")
            return redirect('/login/')
    except requests.exceptions.RequestException as e:
        logger.error('Error:')
        return redirect('/login/')

    class CustomSecurityManager(SupersetSecurityManager):
         authremoteuserview = CustomRemoteUserView

     CUSTOM_SECURITY_MANAGER = CustomSecurityManager
     AUTH_TYPE = AUTH_REMOTE_USER

`

How to reproduce the bug

  1. Implement custom login on superset/docker/pythonpath_dev/superset_config.py
  2. Login using with any admin role credentials
  3. Navigate to users/list

Screenshots/recordings

image

Superset version

3.1.3

Python version

3.9

Node version

16

Browser

Chrome

Additional context

No response

Checklist

dosubot[bot] commented 3 days ago

To resolve the "Access Denied" issue when navigating to list/users after implementing a custom login setup in Apache Superset, you need to ensure that the user has the necessary permissions to access the "List Users" view. The "List Users" view is restricted to admin users.

Here is the relevant part of the code that defines the permissions:

ADMIN_ONLY_VIEW_MENUS = {
    "Access Requests",
    "Action Log",
    "Log",
    "List Users",
    "List Roles",
    "ResetPasswordView",
    "RoleModelView",
    "Row Level Security",
    "Row Level Security Filters",
    "RowLevelSecurityFiltersModelView",
    "Security",
    "SQL Lab",
    "User Registrations",
    "User's Statistics",
} | USER_MODEL_VIEWS

To resolve the issue, you need to ensure that the user has the appropriate admin role that includes access to the "List Users" view. You can do this by assigning the admin role to the user or by modifying the permissions to include the necessary access for the user's role.

Here is an example of how you might assign the admin role to a user:

from superset import app, db
from superset.security.manager import security_manager

# Get the user and role models
User = security_manager.user_model
Role = security_manager.role_model

# Fetch the user and admin role
user = db.session.query(User).filter_by(username='your_username').one()
admin_role = db.session.query(Role).filter_by(name='Admin').one()

# Assign the admin role to the user
user.roles.append(admin_role)
db.session.commit()

Replace 'your_username' with the actual username of the user you want to grant access to. This will give the user the necessary permissions to access the "List Users" view [1].

To continue talking to Dosu, mention @dosu.

Habeeb556 commented 2 days ago

@kannant-sf check this link may help.

++ this for keycloak.

kannant-sf commented 13 hours ago

@dosu am not getting any roles array am just getting firstname and lastname alone from the userdb query

kannant-sf commented 13 hours ago

@Habeeb556 thanks for the link, but my case is different, i already have admin role only for the user, still its not working, am using superset 3 is that causing a problem here?

Habeeb556 commented 12 hours ago

@kannant-sf Hmm, it's not causing a problem, but Superset 3.x is not yet supported. It is preferable to upgrade to 4.x.

Also, make sure to update the list of roles and permissions with the following commands:

export FLASK_APP=superset
superset db upgrade
superset init