User memberships
This commit is contained in:
parent
47d617f066
commit
0c1701314a
|
@ -712,6 +712,33 @@ For more information about how to use social logins, see: `Satellizer <https://g
|
|||
|
||||
PING_AUTH_ENDPOINT = "https://<yourpingserver>/oauth2/authorize"
|
||||
|
||||
.. data:: PING_USER_MEMBERSHIP_URL
|
||||
:noindex:
|
||||
|
||||
An optional additional endpoint to learn membership details post the user validation.
|
||||
|
||||
::
|
||||
|
||||
PING_USER_MEMBERSHIP_URL = "https://<yourmembershipendpoint>"
|
||||
|
||||
.. data:: PING_USER_MEMBERSHIP_TLS_PROVIDER
|
||||
:noindex:
|
||||
|
||||
A custom TLS session provider plugin name
|
||||
|
||||
::
|
||||
|
||||
PING_USER_MEMBERSHIP_TLS_PROVIDER = "slug-name"
|
||||
|
||||
.. data:: PING_USER_MEMBERSHIP_SERVICE
|
||||
:noindex:
|
||||
|
||||
Membership service name used by PING_USER_MEMBERSHIP_TLS_PROVIDER to create a session
|
||||
|
||||
::
|
||||
|
||||
PING_USER_MEMBERSHIP_SERVICE = "yourmembershipservice"
|
||||
|
||||
.. data:: OAUTH2_SECRET
|
||||
:noindex:
|
||||
|
||||
|
|
|
@ -285,6 +285,17 @@ The `ExportPlugin` object requires the implementation of one function::
|
|||
Support of various formats sometimes relies on external tools system calls. Always be mindful of sanitizing any input to these calls.
|
||||
|
||||
|
||||
Custom TLS Provider
|
||||
------
|
||||
|
||||
Managing TLS at the enterprise scale could be hard and often organizations offer custom wrapper implementations. It could
|
||||
be ideal to use those while making calls to internal services. The `TLSPlugin` would help to achieve this. It requires the
|
||||
implementation of one function which creates a TLS session::
|
||||
|
||||
def session(self, server_application):
|
||||
# return active session
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
:license: Apache, see LICENSE for more details.
|
||||
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
|
||||
"""
|
||||
import json
|
||||
|
||||
import jwt
|
||||
import base64
|
||||
import requests
|
||||
|
@ -23,7 +25,7 @@ from lemur.roles import service as role_service
|
|||
from lemur.logs import service as log_service
|
||||
from lemur.auth.service import create_token, fetch_token_header, get_rsa_public_key
|
||||
from lemur.auth import ldap
|
||||
|
||||
from lemur.plugins.base import plugins
|
||||
|
||||
mod = Blueprint("auth", __name__)
|
||||
api = Api(mod)
|
||||
|
@ -138,6 +140,44 @@ def retrieve_user(user_api_url, access_token):
|
|||
return user, profile
|
||||
|
||||
|
||||
def retrieve_user_memberships(user_api_url, user_membership_api_url, access_token):
|
||||
user, profile = retrieve_user(user_api_url, access_token)
|
||||
|
||||
if user_membership_api_url is None:
|
||||
return user, profile
|
||||
"""
|
||||
Potentially, below code can be made more generic i.e., plugin driven. Unaware of the usage of this
|
||||
code across the community, current implementation is config driven. Without user_membership_api_url
|
||||
configured, it is backward compatible.
|
||||
"""
|
||||
|
||||
# put user id in url
|
||||
user_membership_api_url = user_membership_api_url.replace("%user_id%", profile["userId"])
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
data = {"relation": "DIRECT_ONLY", "groupFilter": {"type": "GOOGLE"}, "size": 500}
|
||||
|
||||
tls_provider = plugins.get(current_app.config.get("PING_USER_MEMBERSHIP_TLS_PROVIDER"))
|
||||
|
||||
# retrieve information about the current user
|
||||
session = tls_provider.session(current_app.config.get("PING_USER_MEMBERSHIP_SERVICE"))
|
||||
r = session.post(user_membership_api_url, data=json.dumps(data), headers=headers)
|
||||
|
||||
user_membership = {"email": profile["email"],
|
||||
"thumbnailPhotoUrl": profile["thumbnailPhotoUrl"],
|
||||
"googleGroups": []}
|
||||
|
||||
if r.status_code == 200:
|
||||
response = r.json()
|
||||
membership_details = response["data"]
|
||||
for membership in membership_details:
|
||||
user_membership["googleGroups"].append(membership["membership"]["name"])
|
||||
|
||||
return user, user_membership
|
||||
|
||||
current_app.logger.error(f"Response Code:{r.status_code} {r.text}")
|
||||
|
||||
|
||||
def create_user_roles(profile):
|
||||
"""Creates new roles based on profile information.
|
||||
|
||||
|
@ -375,7 +415,6 @@ class Ping(Resource):
|
|||
|
||||
# you can either discover these dynamically or simply configure them
|
||||
access_token_url = current_app.config.get("PING_ACCESS_TOKEN_URL")
|
||||
user_api_url = current_app.config.get("PING_USER_API_URL")
|
||||
|
||||
secret = current_app.config.get("PING_SECRET")
|
||||
|
||||
|
@ -391,7 +430,12 @@ class Ping(Resource):
|
|||
error_code = validate_id_token(id_token, args["clientId"], jwks_url)
|
||||
if error_code:
|
||||
return error_code
|
||||
user, profile = retrieve_user(user_api_url, access_token)
|
||||
|
||||
user, profile = retrieve_user_memberships(
|
||||
current_app.config.get("PING_USER_API_URL"),
|
||||
current_app.config.get("PING_USER_MEMBERSHIP_URL"),
|
||||
access_token
|
||||
)
|
||||
roles = create_user_roles(profile)
|
||||
update_user(user, profile, roles)
|
||||
|
||||
|
|
|
@ -3,3 +3,4 @@ from .issuer import IssuerPlugin # noqa
|
|||
from .source import SourcePlugin # noqa
|
||||
from .notification import NotificationPlugin, ExpirationNotificationPlugin # noqa
|
||||
from .export import ExportPlugin # noqa
|
||||
from .tls import TLSPlugin # noqa
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"""
|
||||
.. module: lemur.plugins.bases.tls
|
||||
:platform: Unix
|
||||
:copyright: (c) 2021 by Netflix Inc., see AUTHORS for more
|
||||
:license: Apache, see LICENSE for more details.
|
||||
|
||||
.. moduleauthor:: Sayali Charhate <scharhate@netflix.com>
|
||||
"""
|
||||
from lemur.plugins.base import Plugin
|
||||
|
||||
|
||||
class TLSPlugin(Plugin):
|
||||
"""
|
||||
This is the base class from which all supported
|
||||
tls session providers will inherit from.
|
||||
"""
|
||||
type = "tls"
|
||||
|
||||
def session(self, server_application):
|
||||
raise NotImplementedError
|
Loading…
Reference in New Issue