diff --git a/docs/administration.rst b/docs/administration.rst index 3f282369..3623f311 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -712,6 +712,33 @@ For more information about how to use social logins, see: `Satellizer """ +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,47 @@ 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. + """ + tls_provider = plugins.get(current_app.config.get("PING_USER_MEMBERSHIP_TLS_PROVIDER")) + + # put user id in url + user_membership_api_url = user_membership_api_url.replace("%user_id%", profile["userId"]) + + session = tls_provider.session(current_app.config.get("PING_USER_MEMBERSHIP_SERVICE")) + headers = {"Content-Type": "application/json"} + data = {"relation": "DIRECT_ONLY", "groupFilter": {"type": "GOOGLE"}, "size": 500} + user_membership = {"email": profile["email"], + "thumbnailPhotoUrl": profile["thumbnailPhotoUrl"], + "googleGroups": []} + while True: + # retrieve information about the current user memberships + r = session.post(user_membership_api_url, data=json.dumps(data), headers=headers) + + if r.status_code == 200: + response = r.json() + membership_details = response["data"] + for membership in membership_details: + user_membership["googleGroups"].append(membership["membership"]["name"]) + + if "nextPageToken" in response and response["nextPageToken"]: + data["nextPageToken"] = response["nextPageToken"] + else: + break + else: + current_app.logger.error(f"Response Code:{r.status_code} {r.text}") + break + return user, user_membership + + def create_user_roles(profile): """Creates new roles based on profile information. @@ -156,7 +199,7 @@ def create_user_roles(profile): description="This is a google group based role created by Lemur", third_party=True, ) - if not role.third_party: + if (group != 'admin') and (not role.third_party): role = role_service.set_third_party(role.id, third_party_status=True) roles.append(role) else: @@ -375,7 +418,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 +433,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) diff --git a/lemur/plugins/bases/__init__.py b/lemur/plugins/bases/__init__.py index 9ce6289b..71ee2eb3 100644 --- a/lemur/plugins/bases/__init__.py +++ b/lemur/plugins/bases/__init__.py @@ -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 diff --git a/lemur/plugins/bases/tls.py b/lemur/plugins/bases/tls.py new file mode 100644 index 00000000..509ecd62 --- /dev/null +++ b/lemur/plugins/bases/tls.py @@ -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 +""" +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