anuvdas commented on issue #44868:
URL: https://github.com/apache/superset/issues/44868#issuecomment-6075230813

   @dosu
   In the superset_config.py file below is the entry for CUSTOM_SECURITY_MANAGER
   ```
   
   if os.getenv('ENABLE_W3ID_AUTH', 'False').lower() == 'true':
       from w3id_oidc_security_manager import W3IDSecurityManager
       CUSTOM_SECURITY_MANAGER = W3IDSecurityManager
   ```
   And in the w3id_oidc_security_manager.py file below is the entry
   
   ```
   from flask_appbuilder.baseviews import expose
   from flask_appbuilder.security.views import AuthOAuthView
   from flask_login import login_user, logout_user
   from superset.security import SupersetSecurityManager
   import os
   import logging
   
   logger = logging.getLogger(__name__)
   
   class W3IDSecurityManager(SupersetSecurityManager):
       '''
       Custom security manager to support w3id OpenID Connect with auto-created 
groups
       '''
   
       def auth_user_oauth(self, userinfo):
           """
           Assign users to their w3id groups after OAuth login.
          
           :param userinfo: dict with user information from oauth_user_info()
           :return: User object with groups assigned
           """
           # Call parent method to create/update the user
           user = super().auth_user_oauth(userinfo)
   
           if os.environ.get('AUTH_GROUPS_SYNC_AT_LOGIN', '').lower() != 'true':
               return user
           
           if user:
               # Get the groups that should be assigned (from oauth_user_info 
return)
               group_names = userinfo.get('groups', [])
               
               if group_names:
                   logger.info(f"Assigning user {user.username} to 
{len(group_names)} groups: {group_names}")
                   
                   # Get group prefix to identify w3id-managed groups
                   group_prefix = os.environ.get('SUPERSET_GROUP_PREFIX', 
'superset-')
                   
                   # Safety check: ensure user.groups exists and is not None
                   if user.groups is None:
                       logger.warning(f"User {user.username} has None groups, 
initializing to empty list")
                       user.groups = []
                   
                   # Remove user from old w3id-managed groups (those starting 
with prefix)
                   # This ensures group membership stays in sync with w3id
                   for group in list(user.groups):
                       if group and group.name and 
group.name.startswith(group_prefix):
                           user.groups.remove(group)
                           logger.debug(f"Removed user from old W3ID group: 
{group.name}")
                   
                   # Add user to new w3id groups
                   for group_name in group_names:
                       if not group_name:
                           logger.warning("Skipping empty group name")
                           continue
                           
                       group = self.find_group(group_name)
                       if group:
                           if group not in user.groups:
                               user.groups.append(group)
                               logger.info(f"Added user to group: {group_name}")
                       else:
                           logger.warning(f"Group not found (should have been 
created): {group_name}")
                   
                   # Commit changes to database
                   self.appbuilder.session.commit()
                   logger.info(f"Successfully assigned user {user.username} to 
groups")
           
           return user
   
       def oauth_user_info(self, provider, response=None):
           if provider == 'w3id-oidc':
               # As OpenID connect 1.0 provider, w3id provides id_token in 
response
               user_info = 
self.appbuilder.sm.oauth_remotes[provider].parse_id_token(response, None)
   
               # DEBUG: Print all claims to see what W3ID returns
               logger.debug("W3ID Token Claims: %s", user_info)
   
               if os.environ.get('AUTH_GROUPS_SYNC_AT_LOGIN', '').lower() != 
'true':
                   return {
                       # use email as username
                       'username': user_info['email'],
                       'email': user_info['email'],
                   }
   
               # Extract blueGroups from W3ID token
               # W3ID returns IBM groups in the 'blueGroups' claim
               blue_groups = user_info.get('blueGroups', [])
               logger.info(f"User {user_info.get('email')} has {len(blue_groups 
or [])} total Blue Groups")
               
               # Get group prefix from environment (default: 'superset-')
               group_prefix = os.environ.get('SUPERSET_GROUP_PREFIX', 
'superset-')
               
               # Filter to only Superset-related groups (those with the prefix)
               superset_groups = [g for g in blue_groups if g and 
g.startswith(group_prefix)]
               logger.info(f"Filtered to {len(superset_groups)} Superset 
groups: {superset_groups}")
               
               # Auto-create Superset groups if they don't exist
               for group_name in superset_groups:
                   existing_group = self.appbuilder.sm.find_group(group_name)
                   if not existing_group:
                       logger.info(f"Auto-creating Superset group: 
{group_name}")
                       self.appbuilder.sm.add_group(
                           name=group_name,
                           label=group_name,
                           description=f"Auto-created from Blue Group: 
{group_name}"
                       )
                   else:
                       logger.debug(f"Group already exists: {group_name}")
   
               return {
                   # use email as username
                   'username': user_info['email'],
                   'email': user_info['email'],
                   'first_name': user_info.get('firstName', ''),
                   'last_name': user_info.get('lastName', ''),
                   # Assign user to Superset groups (roles assigned to groups 
in UI)
                   'groups': superset_groups
               }
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to