You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2019/08/19 16:15:25 UTC

[GitHub] [incubator-superset] ericandrewmeadows commented on issue #8062: CUSTOM_SECURITY_MANAGER not working in 0.34.0rc1

ericandrewmeadows commented on issue #8062: CUSTOM_SECURITY_MANAGER not working in 0.34.0rc1
URL: https://github.com/apache/incubator-superset/issues/8062#issuecomment-522647904
 
 
   Custom SM:
   ```
   # https://stackoverflow.com/questions/54010314/ ...
   #   using-keycloakopenid-connect-with-apache-superset#54024394
   from flask import redirect, request
   from flask_appbuilder.security.manager import AUTH_OID
   from superset.security import SupersetSecurityManager
   from flask_oidc import OpenIDConnect
   from flask_appbuilder.security.views import AuthOIDView
   from flask_login import login_user
   from urllib.parse import quote
   from flask_appbuilder.views import ModelView, SimpleFormView, expose
   import logging
   import os
   
   # Testing Okta
   from okta import UsersClient
   from okta.framework.ApiClient import ApiClient
   
   # DELETE
   import json
   
   DEFAULT_USER_ROLE = 'Gamma'
   USER_ROLE_TRANSLATION_DICT = {
       'Charts Admin': 'Admin',
       'Charts Alpha Users': 'Alpha',
       'software': 'Software',
   }
   
   
   class AuthOIDCView(AuthOIDView):
       def get_given_and_family_name_from_name(self, info):
           name = info.get('name')
           first_space_location = name.find(' ')
   
           given_name = info.get('given_name', name[:first_space_location])
           family_name = info.get('family_name', name[first_space_location+1:])
           return (given_name, family_name)
   
       def get_user_info(self, okta_client, uid):
           response = ApiClient.get_path(okta_client, '/{0}'.format(uid))
           user_info = json.loads(response.text)
           return user_info
   
       def get_account_creation_info(self, user_info):
           profile = user_info['profile']
           username = profile.get('login')
           first_name = profile.get('firstName')
           last_name = profile.get('lastName')
           email = profile.get('email')
           return (username, first_name, last_name, email)
   
       def create_user(self, sm, user_info):
           (username, first_name, last_name, email) =\
               self.get_account_creation_info(user_info)
           role = sm.find_role(DEFAULT_USER_ROLE)
           user = sm.add_user(username, first_name, last_name, email, role)
           return user
   
       def get_group_info(self, okta_client, uid):
           response = ApiClient.get_path(okta_client, '/{0}/groups'.format(uid))
           group_info = json.loads(response.text)
           return group_info
   
       def get_group_membership(self, group_info):
           group_membership = [group["profile"]["name"] for group in group_info]
           return group_membership
   
       def get_or_create_roles(self, sm, group_membership):
           roles = [
               sm.add_role(USER_ROLE_TRANSLATION_DICT.get(group, group))
               for group in group_membership
           ]
           return roles
   
       def update_user_roles(self, sm, user, group_info):
           group_membership = self.get_group_membership(group_info)
           roles = self.get_or_create_roles(sm, group_membership)
           existing_roles = user.roles
           for role in roles:
               if role in existing_roles:
                   continue
               user.roles.append(role)
               logging.info(f'Role added to {user.username}: {role.name}')
           return user
   
       @expose('/login/', methods=['GET', 'POST'])
       def login(self, flag=True):
           sm = self.appbuilder.sm
           oidc = sm.oid
   
           @self.appbuilder.sm.oid.require_login
           def handle_login():
               uid = oidc.user_getfield("sub")
               user = sm.auth_user_oid(uid)
   
               okta_client = UsersClient(
                   os.environ['ORG_URL'],
                   os.environ['OKTA_AUTH_TOKEN']
               )
   
               user_info = self.get_user_info(okta_client, uid)
               user_active = user_info['status'] == "ACTIVE"
   
               if not user_active:
                   return
               if user is None:
                   user = self.create_user(sm, user_info)
               logging.info(f"User:  {user}")
   
               group_info = self.get_group_info(okta_client, uid)
               user = self.update_user_roles(sm, user, group_info)
               sm.update_user(user)
   
               login_user(user, remember=False)
               return redirect(self.appbuilder.get_url_for_index)
   
           return handle_login()
   
       @expose('/logout/', methods=['GET', 'POST'])
       def logout(self):
   
           oidc = self.appbuilder.sm.oid
   
           oidc.logout()
           super(AuthOIDCView, self).logout()        
           redirect_url = request.url_root.strip('/') + self.appbuilder.get_url_for_login
   
           return redirect(oidc.client_secrets.get('issuer') + '/protocol/openid-connect/logout?redirect_uri=' + quote(redirect_url))
   
   class OIDCSecurityManager(SupersetSecurityManager):
       def __init__(self, appbuilder):
           super(OIDCSecurityManager, self).__init__(appbuilder)
           if self.auth_type == AUTH_OID:
               self.oid = OpenIDConnect(self.appbuilder.get_app)
           self.authoidview = AuthOIDCView
   
   ```

----------------------------------------------------------------
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.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org