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