From ef788788bdab15460d122868ffda2d0f43714850 Mon Sep 17 00:00:00 2001 From: Christian Lechner Date: Fri, 17 Mar 2023 08:53:12 +0100 Subject: [PATCH] initial enhancement for user mapping --- config/templates/libs/BTPSA-USECASE.json | 36 ++++++ libs/btpsa-usecase.json | 36 ++++++ libs/python/helperRolesAndUsers.py | 140 +++++++++++++++++++++++ 3 files changed, 212 insertions(+) diff --git a/config/templates/libs/BTPSA-USECASE.json b/config/templates/libs/BTPSA-USECASE.json index 0f61c5af..316792d4 100644 --- a/config/templates/libs/BTPSA-USECASE.json +++ b/config/templates/libs/BTPSA-USECASE.json @@ -95,6 +95,24 @@ "description": "user groups to be assigned from the parameter file", "title": "user groups from parameter file" }, + "attribute": { + "type": "string", + "description": "the name of the attribute. To be found in the identity provider.", + "title": "attribute name (custom IdP)", + "default": null + }, + "attributeValue": { + "type": "string", + "description": "the value of the attribute. To be found in the identity provider.", + "title": "attribute value (custom IdP)", + "default": null + }, + "group":{ + "type": "string", + "description": "the name of the user group. To be found in the identity provider.", + "title": "group name (custom IdP)", + "default": null + }, "idp":{ "type": "string", "description": "the identity provider that hosts the user. ", @@ -302,6 +320,24 @@ "description": "list of user groups to assign the role collection", "title": "list of user groups to assign the role collection" }, + "attribute": { + "type": "string", + "description": "the name of the attribute. To be found in the identity provider.", + "title": "attribute name (custom IdP)", + "default": null + }, + "attributeValue": { + "type": "string", + "description": "the value of the attribute. To be found in the identity provider.", + "title": "attribute value (custom IdP)", + "default": null + }, + "group":{ + "type": "string", + "description": "the name of the user group. To be found in the identity provider.", + "title": "group name (custom IdP)", + "default": null + }, "idp":{ "type": "string", "description": "the identity provider that hosts the user. ", diff --git a/libs/btpsa-usecase.json b/libs/btpsa-usecase.json index 1c6059c5..8f1d133a 100644 --- a/libs/btpsa-usecase.json +++ b/libs/btpsa-usecase.json @@ -81,6 +81,24 @@ "description": "user groups to be assigned from the parameter file", "title": "user groups from parameter file" }, + "attribute": { + "type": "string", + "description": "the name of the attribute. To be found in the identity provider.", + "title": "attribute name (custom IdP)", + "default": null + }, + "attributeValue": { + "type": "string", + "description": "the value of the attribute. To be found in the identity provider.", + "title": "attribute value (custom IdP)", + "default": null + }, + "group":{ + "type": "string", + "description": "the name of the user group. To be found in the identity provider.", + "title": "group name (custom IdP)", + "default": null + }, "idp":{ "type": "string", "description": "the identity provider that hosts the user. ", @@ -288,6 +306,24 @@ "description": "list of user groups to assign the role collection", "title": "list of user groups to assign the role collection" }, + "attribute": { + "type": "string", + "description": "the name of the attribute. To be found in the identity provider.", + "title": "attribute name (custom IdP)", + "default": null + }, + "attributeValue": { + "type": "string", + "description": "the value of the attribute. To be found in the identity provider.", + "title": "attribute value (custom IdP)", + "default": null + }, + "group":{ + "type": "string", + "description": "the name of the user group. To be found in the identity provider.", + "title": "group name (custom IdP)", + "default": null + }, "idp":{ "type": "string", "description": "the identity provider that hosts the user. ", diff --git a/libs/python/helperRolesAndUsers.py b/libs/python/helperRolesAndUsers.py index 71e98a91..d46be3a0 100644 --- a/libs/python/helperRolesAndUsers.py +++ b/libs/python/helperRolesAndUsers.py @@ -6,6 +6,8 @@ from libs.python.helperCommandExecution import login_cf from libs.python.helperJson import getJsonFromFile import logging +import sys +import os log = logging.getLogger(__name__) @@ -119,6 +121,32 @@ def assignUsergroupsToRoleCollection(btpUsecase, rolecollection): ) if idp is not None: command += " --of-idp '" + idp + "'" + + # Additional mapping for custom IdP only relevant if custom IdP is used + ( + groupForIdp, + attributeForIdp, + attributeValueForIdp, + ) = getCustomIdpMapping(rolecollection) + + if isMappingForIdpValid( + groupForIdp, attributeForIdp, attributeValueForIdp + ): + + if groupForIdp is not None: + command += " --to-group '" + groupForIdp + "'" + + if attributeForIdp is not None: + command += " --to-attribute '" + attributeForIdp + "'" + command += ( + " --attribute-value '" + attributeValueForIdp + "'" + ) + else: + log.error( + "Custom IdP configuration is not valid. Please check." + ) + sys.exit(os.EX_DATAERR) + thisResult = runCommandAndGetJsonResult( btpUsecase, command, "INFO", message ) @@ -189,6 +217,32 @@ def assignUsersToGlobalAndSubaccount(btpUsecase): ) if idp is not None: command += " --of-idp '" + idp + "'" + + # Additional mapping for custom IdP only relevant if custom IdP is used + ( + groupForIdp, + attributeForIdp, + attributeValueForIdp, + ) = getCustomIdpMapping(rolecollection) + + if isMappingForIdpValid( + groupForIdp, attributeForIdp, attributeValueForIdp + ): + + if groupForIdp is not None: + command += " --to-group '" + groupForIdp + "'" + + if attributeForIdp is not None: + command += " --to-attribute '" + attributeForIdp + "'" + command += ( + " --attribute-value '" + attributeValueForIdp + "'" + ) + else: + log.error( + "Custom IdP configuration is not valid. Please check." + ) + sys.exit(os.EX_DATAERR) + runCommandAndGetJsonResult(btpUsecase, command, "INFO", message) log.header("Set administrators for sub account") @@ -215,6 +269,32 @@ def assignUsersToGlobalAndSubaccount(btpUsecase): ) if idp is not None: command += " --of-idp '" + idp + "'" + + # Additional mapping for custom IdP only relevant if custom IdP is used + ( + groupForIdp, + attributeForIdp, + attributeValueForIdp, + ) = getCustomIdpMapping(rolecollection) + + if isMappingForIdpValid( + groupForIdp, attributeForIdp, attributeValueForIdp + ): + + if groupForIdp is not None: + command += " --to-group '" + groupForIdp + "'" + + if attributeForIdp is not None: + command += " --to-attribute '" + attributeForIdp + "'" + command += ( + " --attribute-value '" + attributeValueForIdp + "'" + ) + else: + log.error( + "Custom IdP configuration is not valid. Please check." + ) + sys.exit(os.EX_DATAERR) + runCommandAndGetJsonResult(btpUsecase, command, "INFO", message) @@ -331,6 +411,32 @@ def assignUsersToCustomRoleCollections(btpUsecase): ) if idp is not None: command += " --of-idp '" + idp + "'" + + # Additional mapping for custom IdP only relevant if custom IdP is used + ( + groupForIdp, + attributeForIdp, + attributeValueForIdp, + ) = getCustomIdpMapping(rolecollection) + + if isMappingForIdpValid( + groupForIdp, attributeForIdp, attributeValueForIdp + ): + + if groupForIdp is not None: + command += " --to-group '" + groupForIdp + "'" + + if attributeForIdp is not None: + command += " --to-attribute '" + attributeForIdp + "'" + command += ( + " --attribute-value '" + attributeValueForIdp + "'" + ) + else: + log.error( + "Custom IdP configuration is not valid. Please check." + ) + sys.exit(os.EX_DATAERR) + runCommandAndGetJsonResult(btpUsecase, command, "INFO", message) @@ -380,6 +486,7 @@ def assignUsersToEnvironments(btpUsecase): ) if idp is not None: command += " --origin '" + idp + "'" + p = runShellCommandFlex( btpUsecase, command, "INFO", message, False, False ) @@ -438,3 +545,36 @@ def determineIdpForRoleCollection(btpUsecase, rolecollection): idp = rolecollection.get("idp") return idp + + +def getCustomIdpMapping(rolecollection): + groupForIdp = None + attributeForIdp = None + attributeValueForIdp = None + + if rolecollection.get("group"): + groupForIdp = rolecollection.get("group") + + if rolecollection.get("attribute"): + attributeForIdp = rolecollection.get("attribute") + + if rolecollection.get("attributeValue"): + attributeValueForIdp = rolecollection.get("attributeValue") + + return groupForIdp, attributeForIdp, attributeValueForIdp + + +def isMappingForIdpValid(groupForIdp, attributeForIdp, attributeValueForIdp): + if groupForIdp is not None and attributeForIdp is not None: + log.error( + "A group and an attribute is configured for the IdP mapping. Only one is allowed." + ) + return False + if (attributeForIdp is None and attributeValueForIdp is not None) or ( + attributeForIdp is not None and attributeValueForIdp is None + ): + log.error( + "Attribute and attributeValue are both required for the IdP mapping. One is missing." + ) + return False + return True