From 7fe5868c5becd6a8bd45cd637eed5afb141019de Mon Sep 17 00:00:00 2001 From: IDN Date: Tue, 4 Feb 2025 21:36:35 +0530 Subject: [PATCH 1/7] Test --- ... - AttributeGenerator - EmailGenerator.xml | 196 +++++++++++++++ ...AttributeGenerator - UsernameGenerator.xml | 237 ++++++++++++------ ...tributeGenerator - sAMAccountNameGenerator | 185 ++++++++++++++ .../java/sailpoint/EmailGeneratorTest.java | 191 ++++++++++++++ 4 files changed, 734 insertions(+), 75 deletions(-) create mode 100644 src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml create mode 100644 src/main/resources/rules/Rule - AttributeGenerator - sAMAccountNameGenerator create mode 100644 src/test/java/sailpoint/EmailGeneratorTest.java diff --git a/src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml b/src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml new file mode 100644 index 0000000..d94bd7a --- /dev/null +++ b/src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml @@ -0,0 +1,196 @@ + + + + Generate a unique email address for Active Directory. + + diff --git a/src/main/resources/rules/Rule - AttributeGenerator - UsernameGenerator.xml b/src/main/resources/rules/Rule - AttributeGenerator - UsernameGenerator.xml index 5b10ce0..049a938 100644 --- a/src/main/resources/rules/Rule - AttributeGenerator - UsernameGenerator.xml +++ b/src/main/resources/rules/Rule - AttributeGenerator - UsernameGenerator.xml @@ -1,95 +1,182 @@ - - Generate a unique username for Active Directory. + + Generate a unique email address for Active Directory. companyDomains = new HashMap<>(); + companyDomains.put(98, "jmfamily.com"); + companyDomains.put(10, "jmfamily.com"); + companyDomains.put(100, "jmfamily.com"); + companyDomains.put(101, "jmfamily.com"); + companyDomains.put(160, "jmfamilyholdings.com"); + companyDomains.put(200, "setoyota.com"); + companyDomains.put(250, "setoyota.com"); + companyDomains.put(290, "setoyota.com"); + companyDomains.put(300, "jmagroup.com"); + companyDomains.put(301, "jmagroup.com"); + companyDomains.put(303, "jmagroup.com"); + companyDomains.put(305, "jmagroup.com"); + companyDomains.put(307, "jmagroup.com"); + companyDomains.put(400, "setf.com"); + companyDomains.put(40011, "wofco.com"); + companyDomains.put(40013, "ctrone.com"); + companyDomains.put(40014, "yatc.org"); + companyDomains.put(40015, "centurywarranty.com"); + companyDomains.put(40016, "fiasolutions.com"); + companyDomains.put(40017, "dsfs.ca"); + companyDomains.put(40018, "mmsa.com"); + companyDomains.put(40019, "jmcustomcreations.com"); + companyDomains.put(40020, "dsfs.com"); + companyDomains.put(421, "onedatascan.com"); + companyDomains.put(422, "onedatascan.com"); + companyDomains.put(424, "onedatascan.ca"); + companyDomains.put(464, "onedatascan.com"); + companyDomains.put(470, "onedatascan.com"); + companyDomains.put(495, "onedatascan.ca"); + companyDomains.put(700, "jmlexus.com"); + companyDomains.put(997, "bellsouth.net"); - if((firstName == null) || (lastName == null)) { - log.debug( "AD Create User Name | Exit from generateUsername method. No last name and first name for user" ); - return null; - } + // Return the domain for the given CompanyID, or a message if not found + String domain = companyDomains.getOrDefault(companyID, "CompanyID not found!"); + log.info("EMAIL GENERATOR RULE AD || 5: Exiting getDomainByCompanyID method with domain: " + domain); + return domain; +} - String username = null; - String fullName = firstName + "." + lastName; +log.info("EMAIL GENERATOR RULE AD || 6: COMPANY ID IS: " + getDomainByCompanyID(identity.getAttribute("companyId"))); - if(fullName.length() > MAX_USERNAME_LENGTH) { - int firstNameLength = firstName.length(); +/** + * Method to check if the generated email is unique. + * It validates if the generated email already exists in LDAP for the given identity and application. + * + * @param email The generated email to check for uniqueness. + * @param identityId The identity ID of the user. + * @param applicationName The name of the application. + * @param attributeName The LDAP attribute name to check. + * @return true if the email is unique, false otherwise. + * @throws GeneralException If there is an error during the check. + */ +public boolean isUnique(String email, String identityId, String applicationName, String attributeName) throws GeneralException { + log.info("EMAIL GENERATOR RULE AD || 7: Entering isUnique method with email: " + email); - if(firstNameLength > (MAX_USERNAME_LENGTH - 2)) { - for(int lastNameLength = 0; lastNameLength < lastName.length(); lastNameLength++) { - username = firstName.substring(0, (MAX_USERNAME_LENGTH - 2)) + "." + lastName.charAt(lastNameLength); - username = username.toLowerCase(); - if (isUnique(username)) { - log.debug( "AD Create User Name | Unique username generated: " + username); - log.debug( "AD Create User Name | Exit from the GenerateUsername Method" ); - return username; - } - } - } else { - for(int lastNameLength = 0; lastNameLength < lastName.length(); lastNameLength++) { - username = firstName + "." + lastName.charAt(lastNameLength); - username = username.toLowerCase(); - if (isUnique(username)) { - log.debug( "AD Create User Name | Unique username generated: " + username); - log.debug( "AD Create User Name | Exit from the GenerateUsername Method" ); - return username; + try { + boolean isUnique = idn.isUniqueLDAPValue(identityId, applicationName, attributeName, email); + log.info("EMAIL GENERATOR RULE AD || 8: Exiting isUnique method with result: " + isUnique); + return isUnique; + } catch (Exception e) { + log.error("EMAIL GENERATOR RULE AD || 9: Error in isUnique method: " + e.getMessage()); + throw new GeneralException("Error in isUnique method", e); + } +} + +/** + * Method to generate a valid and unique email address for the user based on their first name, + * last name, and company ID. + * It first tries to generate a basic email and check its uniqueness. If the email is not unique, + * it appends a number to create a unique version. + * + * @param firstName The first name of the user. + * @param lastName The last name of the user. + * @param companyId The company ID of the user to generate domain. + * @return The generated unique email address. + * @throws GeneralException If the email cannot be generated after 100 attempts. + */ +public String generateEmail() throws GeneralException { + + String firstName = identity.getFirstname(); + String lastName = identity.getLastname(); + String companyId = identity.getAttribute("companyId"); + + log.info("EMAIL GENERATOR RULE AD || 10: Entering generateEmail method with firstName: " + firstName + ", lastName: " + lastName + ", companyId: " + companyId); + + try { + String domain = getDomainByCompanyID(Integer.parseInt(companyId)); + String generatedEmail = firstName + "." + lastName + "@" + domain; + String applicationName = application.getName(); + String identityId = identity.getId(); + String attributeName = "mail"; + String[] sourceIdsArray = {"de15dbc4e37b4e4abdd0a56e54d1376c"}; + List sourceIds = Arrays.asList(sourceIdsArray); + String[] valuesArray = {generatedEmail}; + List values = Arrays.asList(valuesArray); + String operation = "Create"; + String workdayAttributeName = "promotedEmailId"; + + log.info("EMAIL GENERATOR RULE AD || 11: Generated email is: " + generatedEmail); + + if (Util.isNotNullOrEmpty(firstName) && Util.isNotNullOrEmpty(lastName) && Util.isNotNullOrEmpty(domain)) { + if (Util.isNotNullOrEmpty(applicationName) && Util.isNotNullOrEmpty(identityId) && Util.isNotNullOrEmpty(attributeName)) { + if (generatedEmail != null && !generatedEmail.isEmpty()) { + if (isUnique(generatedEmail, identityId, applicationName, attributeName)) { + String workdayAttributeValue = ""; + workdayAttributeValue = idn.attrSearchGetIdentityName(sourceIds, workdayAttributeName, operation, values); + log.info("EMAIL GENERATOR RULE AD || 12: Exiting generateEmail method with result: " + generatedEmail.toLowerCase()); + return generatedEmail.toLowerCase(); + } else { + log.warn("EMAIL GENERATOR RULE AD || 13: Generated email is not unique, proceeding to fallback logic."); } } } - } else { - username = fullName; - username = username.toLowerCase(); - if (isUnique(username)) { - log.debug( "AD Create User Name | Unique username generated: " + username); - log.debug( "AD Create User Name | Exit from the GenerateUsername Method" ); - return username; - } else { - for(int lastNameLength = 0; lastNameLength < lastName.length(); lastNameLength++) { - username = firstName + "." + lastName.charAt(lastNameLength); - username = username.toLowerCase(); - if (isUnique(username)) { - log.debug( "AD Create User Name | Unique username generated: " + username); - log.debug( "AD Create User Name | Exit from the GenerateUsername Method" ); - return username; - } + + // Fallback logic to add iteration number to email + int iteration = 1; + while (iteration < 100) { + String emailWithIteration = firstName + "." + lastName + iteration + "@" + domain; + String[] emailIdtArray = {emailWithIteration}; + List emailIdvalue = Arrays.asList(emailIdtArray); + if (isUnique(emailWithIteration, identityId, applicationName, attributeName)) { + String workdayAttributeValue = ""; + workdayAttributeValue = idn.attrSearchGetIdentityName(sourceIds, workdayAttributeName, operation, emailIdvalue); + log.info("EMAIL GENERATOR RULE AD || 14: Exiting generateEmail method with result (generated with iteration): " + emailWithIteration.toLowerCase()); + return emailWithIteration.toLowerCase(); } + iteration++; } } - - - - return null; - } - - public boolean isUnique(String username) throws GeneralException { - return !idn.accountExistsByDisplayName(application.getName(), username); + throw new GeneralException("EMAIL GENERATOR RULE AD || 15: Cannot generate email after 100 attempts"); + } catch (Exception e) { + log.error("EMAIL GENERATOR RULE AD || 16: Error in generateEmail method: " + e.getMessage()); + throw new GeneralException("Error in generateEmail method", e); } +} - return generateUsername(identity.getFirstname(), identity.getLastname()); - - ]]> - \ No newline at end of file +log.info("EMAIL GENERATOR RULE AD || 17: Exiting EmailGenerator rule - Generated email: " + generateEmail()); +return generateEmail(); +]]> + diff --git a/src/main/resources/rules/Rule - AttributeGenerator - sAMAccountNameGenerator b/src/main/resources/rules/Rule - AttributeGenerator - sAMAccountNameGenerator new file mode 100644 index 0000000..b2e4a96 --- /dev/null +++ b/src/main/resources/rules/Rule - AttributeGenerator - sAMAccountNameGenerator @@ -0,0 +1,185 @@ + + + + Generate a unique email address for Active Directory. + + diff --git a/src/test/java/sailpoint/EmailGeneratorTest.java b/src/test/java/sailpoint/EmailGeneratorTest.java new file mode 100644 index 0000000..1f6d43e --- /dev/null +++ b/src/test/java/sailpoint/EmailGeneratorTest.java @@ -0,0 +1,191 @@ +package sailpoint; + +import bsh.EvalError; +import bsh.Interpreter; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.junit.jupiter.api.Test; +import sailpoint.object.Application; +import sailpoint.object.Identity; +import sailpoint.rdk.utils.RuleXmlUtils; +import sailpoint.server.IdnRuleUtil; +import sailpoint.tools.GeneralException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class EmailGeneratorTest { + Logger log = LogManager.getLogger(EmailGeneratorTest.class); + + private static final String RULE_FILENAME = "src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml"; + + @Test + public void testUsernameGeneratorWhereFirstAndLastNameValid () throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + IdnRuleUtil idn = mock(); + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); + when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); + when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); + + Application application = mock(Application.class); + when(application.getName()).thenReturn("Active Directory [source]"); + + Identity identity = mock(Identity.class); + when(identity.getFirstname()).thenReturn("tyler"); + when(identity.getLastname()).thenReturn("Smith"); + when(identity.getAttribute("companyId")).thenReturn("100"); + when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + String result = ""; + + i.set("log", log); + i.set("idn", idn); + i.set("application", application); + i.set("identity", identity); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + result = (String) i.eval(source); + + assertNotNull(result); + assertEquals(result, "tyler.smith@jmfamily.com"); + + log.info("Beanshell script returned: " + result); + + } + @Test + public void testUsernameGeneratorWithDifferentCompanyID() throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + IdnRuleUtil idn = mock(IdnRuleUtil.class); + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); + when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); + when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); + + Application application = mock(Application.class); + when(application.getName()).thenReturn("Active Directory [source]"); + + Identity identity = mock(Identity.class); + when(identity.getFirstname()).thenReturn("Alice"); + when(identity.getLastname()).thenReturn("Johnson"); + when(identity.getAttribute("companyId")).thenReturn("300"); // Different Company ID + when(identity.getId()).thenReturn("a1b2c3d4"); + String result = ""; + + i.set("log", log); + i.set("idn", idn); + i.set("application", application); + i.set("identity", identity); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + result = (String) i.eval(source); + + // The domain should be "jmagroup.com" based on company ID "300" + assertNotNull(result); + assertEquals(result, "alice.johnson@jmagroup.com"); + + log.info("Beanshell script returned: " + result); + } + @Test + public void testUsernameGeneratorWithNullFirstName() throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + IdnRuleUtil idn = mock(IdnRuleUtil.class); + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); + when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); + when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); + + Application application = mock(Application.class); + when(application.getName()).thenReturn("Active Directory [source]"); + + Identity identity = mock(Identity.class); + when(identity.getFirstname()).thenReturn(""); // Null or empty first name + when(identity.getLastname()).thenReturn("Smith"); + when(identity.getAttribute("companyId")).thenReturn("100"); + when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + String result = ""; + + i.set("log", log); + i.set("idn", idn); + i.set("application", application); + i.set("identity", identity); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + result = (String) i.eval(source); + + // Since the first name is empty, it may throw an error or return null based on your logic + assertNotNull(result); // Could be a fail if your system requires valid first name + log.info("Beanshell script returned: " + result); + } + @Test + public void testUsernameGeneratorWithNullLastName() throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + IdnRuleUtil idn = mock(IdnRuleUtil.class); + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); + when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); + when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); + + Application application = mock(Application.class); + when(application.getName()).thenReturn("Active Directory [source]"); + + Identity identity = mock(Identity.class); + when(identity.getFirstname()).thenReturn("John"); + when(identity.getLastname()).thenReturn(""); // Null or empty last name + when(identity.getAttribute("companyId")).thenReturn("100"); + when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + String result = ""; + + i.set("log", log); + i.set("idn", idn); + i.set("application", application); + i.set("identity", identity); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + result = (String) i.eval(source); + + // Since the last name is empty, it may throw an error or return null based on your logic + assertNotNull(result); // Could be a fail if your system requires valid last name + log.info("Beanshell script returned: " + result); + } + @Test + public void testUsernameGeneratorWithInvalidCompanyID() throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + IdnRuleUtil idn = mock(IdnRuleUtil.class); + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); + when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); + when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); + + Application application = mock(Application.class); + when(application.getName()).thenReturn("Active Directory [source]"); + + Identity identity = mock(Identity.class); + when(identity.getFirstname()).thenReturn("Samantha"); + when(identity.getLastname()).thenReturn("Taylor"); + when(identity.getAttribute("companyId")).thenReturn("999"); // Invalid company ID + when(identity.getId()).thenReturn("f7h4g8b6v2j9z8"); + String result = ""; + + i.set("log", log); + i.set("idn", idn); + i.set("application", application); + i.set("identity", identity); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + result = (String) i.eval(source); + + // The company ID "999" doesn't exist in the mapping, so it should return "CompanyID not found!" + assertNotNull(result); + assertEquals(result, "samantha.taylor@CompanyID not found!"); + + log.info("Beanshell script returned: " + result); + } + + + + + +} From be7a53ae6d0f674447ae174371be140646e7ba19 Mon Sep 17 00:00:00 2001 From: IDN Date: Tue, 4 Feb 2025 22:21:42 +0530 Subject: [PATCH 2/7] test --- ... - AttributeGenerator - EmailGenerator.xml | 176 +++++++-------- ...ioningRule - AddAccessRequesterDetails.xml | 46 ++++ .../Rule - BuildMap - JoinAttributes.xml | 42 +++- .../rules/Rule - BuildMap - Morrissey.xml | 0 .../java/sailpoint/EmailGeneratorTest.java | 209 +++++++++++++++--- .../java/sailpoint/JoinAttributesTest.java | 32 ++- 6 files changed, 369 insertions(+), 136 deletions(-) create mode 100644 src/main/resources/rules/Rule - BeforeProvisioningRule - AddAccessRequesterDetails.xml create mode 100644 src/main/resources/rules/Rule - BuildMap - Morrissey.xml diff --git a/src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml b/src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml index d94bd7a..7adee0e 100644 --- a/src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml +++ b/src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml @@ -1,9 +1,6 @@ - - Generate a unique email address for Active Directory. diff --git a/src/main/resources/rules/Rule - BeforeProvisioningRule - AddAccessRequesterDetails.xml b/src/main/resources/rules/Rule - BeforeProvisioningRule - AddAccessRequesterDetails.xml new file mode 100644 index 0000000..b5d2a2c --- /dev/null +++ b/src/main/resources/rules/Rule - BeforeProvisioningRule - AddAccessRequesterDetails.xml @@ -0,0 +1,46 @@ + + + + Before Provisioning Rule which changes disables and enables to a modify. + 0) + { + requester = requesterList.get(0); + if(requester != null) + { + String requesterNetID = (String)requester.getAttribute(\"netid\"); + accountRequest.add(new AttributeRequest(\"extensionAttribute1\", ProvisioningPlan.Operation.Set, requesterNetID)); + log.debug(\"UIH AD Before Provisioning Rule : Added Requester Information\"); + } + } + } + } + } + log.debug(\"UIH AD Before Provisioning Rule : Exiting Rule\"); +} + + ]]> + \ No newline at end of file diff --git a/src/main/resources/rules/Rule - BuildMap - JoinAttributes.xml b/src/main/resources/rules/Rule - BuildMap - JoinAttributes.xml index f004b46..c3467ef 100644 --- a/src/main/resources/rules/Rule - BuildMap - JoinAttributes.xml +++ b/src/main/resources/rules/Rule - BuildMap - JoinAttributes.xml @@ -17,20 +17,40 @@ \ No newline at end of file diff --git a/src/main/resources/rules/Rule - BuildMap - Morrissey.xml b/src/main/resources/rules/Rule - BuildMap - Morrissey.xml new file mode 100644 index 0000000..e69de29 diff --git a/src/test/java/sailpoint/EmailGeneratorTest.java b/src/test/java/sailpoint/EmailGeneratorTest.java index 1f6d43e..83ef0a9 100644 --- a/src/test/java/sailpoint/EmailGeneratorTest.java +++ b/src/test/java/sailpoint/EmailGeneratorTest.java @@ -20,16 +20,56 @@ public class EmailGeneratorTest { Logger log = LogManager.getLogger(EmailGeneratorTest.class); + String result1 = ""; private static final String RULE_FILENAME = "src/main/resources/rules/Rule - AttributeGenerator - EmailGenerator.xml"; + // Test case for "N" (Contractor) @Test - public void testUsernameGeneratorWhereFirstAndLastNameValid () throws GeneralException, EvalError { + public void testUsernameGeneratorWhereFirstAndLastNameValidContractor() throws GeneralException, EvalError { Interpreter i = new Interpreter(); - IdnRuleUtil idn = mock(); + IdnRuleUtil idn = mock(IdnRuleUtil.class); when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); - when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); + when(idn.isUniqueLDAPValue(any(), any(), any(), any())) + .thenReturn(false) // First attempt: email is not unique + .thenReturn(true); // Second attempt: email becomes unique after the first iteration + + Application application = mock(Application.class); + when(application.getName()).thenReturn("Active Directory [source]"); + + Identity identity = mock(Identity.class); + when(identity.getFirstname()).thenReturn("tyler"); + when(identity.getLastname()).thenReturn("Smith"); + when(identity.getAttribute("companyId")).thenReturn("100"); + when(identity.getAttribute("isAssociate")).thenReturn("N"); // Contractor + when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + + i.set("log", log); + i.set("idn", idn); + i.set("application", application); + i.set("identity", identity); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + result1 = (String) i.eval(source); + + assertNotNull(result1); + assertEquals(result1, "tyler.smith1_contractor@jmfamily.com"); + + log.info("Beanshell script returned: " + result1); + } + + // Test case for "Y" (Non-Contractor) + @Test + public void testUsernameGeneratorWhereFirstAndLastNameValidEmployee() throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + IdnRuleUtil idn = mock(IdnRuleUtil.class); + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); + when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); + when(idn.isUniqueLDAPValue(any(), any(), any(), any())) + .thenReturn(false) // First attempt: email is not unique + .thenReturn(true); // Second attempt: email becomes unique after the first iteration Application application = mock(Application.class); when(application.getName()).thenReturn("Active Directory [source]"); @@ -38,7 +78,45 @@ public void testUsernameGeneratorWhereFirstAndLastNameValid () throws GeneralExc when(identity.getFirstname()).thenReturn("tyler"); when(identity.getLastname()).thenReturn("Smith"); when(identity.getAttribute("companyId")).thenReturn("100"); + when(identity.getAttribute("isAssociate")).thenReturn("Y"); // Non-Contractor when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + + i.set("log", log); + i.set("idn", idn); + i.set("application", application); + i.set("identity", identity); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + result1 = (String) i.eval(source); + + assertNotNull(result1); + assertEquals(result1, "tyler.smith1@jmfamily.com"); + + log.info("Beanshell script returned: " + result1); + } + + // Test case for "N" (Contractor) with a different Company ID + @Test + public void testUsernameGeneratorWithDifferentCompanyIDContractor() throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + IdnRuleUtil idn = mock(IdnRuleUtil.class); + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); + when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); + when(idn.isUniqueLDAPValue(any(), any(), any(), any())) + .thenReturn(false) // First attempt: email is not unique + .thenReturn(true); // Second attempt: email becomes unique after the first iteration + + Application application = mock(Application.class); + when(application.getName()).thenReturn("Active Directory [source]"); + + Identity identity = mock(Identity.class); + when(identity.getFirstname()).thenReturn("alice"); + when(identity.getLastname()).thenReturn("johnson"); + when(identity.getAttribute("companyId")).thenReturn("300"); // Different Company ID + when(identity.getAttribute("isAssociate")).thenReturn("N"); // Contractor + when(identity.getId()).thenReturn("a1b2c3d4"); + String result = ""; i.set("log", log); @@ -49,14 +127,16 @@ public void testUsernameGeneratorWhereFirstAndLastNameValid () throws GeneralExc String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); result = (String) i.eval(source); + // The domain should be "jmagroup.com" based on company ID "300" assertNotNull(result); - assertEquals(result, "tyler.smith@jmfamily.com"); + assertEquals(result, "alice.johnson1_contractor@jmagroup.com"); log.info("Beanshell script returned: " + result); - } + + // Test case for "Y" (Non-Contractor) with a different Company ID @Test - public void testUsernameGeneratorWithDifferentCompanyID() throws GeneralException, EvalError { + public void testUsernameGeneratorWithDifferentCompanyIDEmployee() throws GeneralException, EvalError { Interpreter i = new Interpreter(); IdnRuleUtil idn = mock(IdnRuleUtil.class); @@ -68,10 +148,12 @@ public void testUsernameGeneratorWithDifferentCompanyID() throws GeneralExceptio when(application.getName()).thenReturn("Active Directory [source]"); Identity identity = mock(Identity.class); - when(identity.getFirstname()).thenReturn("Alice"); - when(identity.getLastname()).thenReturn("Johnson"); + when(identity.getFirstname()).thenReturn("alice"); + when(identity.getLastname()).thenReturn("johnson"); when(identity.getAttribute("companyId")).thenReturn("300"); // Different Company ID + when(identity.getAttribute("isAssociate")).thenReturn("Y"); // Non-Contractor when(identity.getId()).thenReturn("a1b2c3d4"); + String result = ""; i.set("log", log); @@ -88,23 +170,32 @@ public void testUsernameGeneratorWithDifferentCompanyID() throws GeneralExceptio log.info("Beanshell script returned: " + result); } + + // Test case for "N" (Contractor) with a non-unique email initially @Test - public void testUsernameGeneratorWithNullFirstName() throws GeneralException, EvalError { + public void testUsernameGeneratorWithNonUniqueEmailInitiallyContractor() throws GeneralException, EvalError { Interpreter i = new Interpreter(); IdnRuleUtil idn = mock(IdnRuleUtil.class); + + // Simulate that the email is initially not unique + when(idn.isUniqueLDAPValue(any(), any(), any(), any())) + .thenReturn(false) // First attempt: email is not unique + .thenReturn(true); // Second attempt: email becomes unique after the first iteration + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); - when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); Application application = mock(Application.class); when(application.getName()).thenReturn("Active Directory [source]"); Identity identity = mock(Identity.class); - when(identity.getFirstname()).thenReturn(""); // Null or empty first name - when(identity.getLastname()).thenReturn("Smith"); + when(identity.getFirstname()).thenReturn("john"); + when(identity.getLastname()).thenReturn("doe"); when(identity.getAttribute("companyId")).thenReturn("100"); when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + when(identity.getAttribute("isAssociate")).thenReturn("N"); + String result = ""; i.set("log", log); @@ -115,27 +206,37 @@ public void testUsernameGeneratorWithNullFirstName() throws GeneralException, Ev String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); result = (String) i.eval(source); - // Since the first name is empty, it may throw an error or return null based on your logic - assertNotNull(result); // Could be a fail if your system requires valid first name + // Since the first email attempt should not be unique, we expect the iteration to happen + assertNotNull(result); + assertEquals(result, "john.doe1_contractor@jmfamily.com"); // After iteration 1, the email should be unique + log.info("Beanshell script returned: " + result); } + + // Test case for "Y" (Non-Contractor) with a non-unique email initially @Test - public void testUsernameGeneratorWithNullLastName() throws GeneralException, EvalError { + public void testUsernameGeneratorWithNonUniqueEmailInitiallyEmployee() throws GeneralException, EvalError { Interpreter i = new Interpreter(); IdnRuleUtil idn = mock(IdnRuleUtil.class); + + // Simulate that the email is initially not unique + when(idn.isUniqueLDAPValue(any(), any(), any(), any())) + .thenReturn(false) // First attempt: email is not unique + .thenReturn(true); // Second attempt: email becomes unique after the first iteration + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); - when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); Application application = mock(Application.class); when(application.getName()).thenReturn("Active Directory [source]"); Identity identity = mock(Identity.class); - when(identity.getFirstname()).thenReturn("John"); - when(identity.getLastname()).thenReturn(""); // Null or empty last name + when(identity.getFirstname()).thenReturn("john"); + when(identity.getLastname()).thenReturn("doe"); when(identity.getAttribute("companyId")).thenReturn("100"); when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + String result = ""; i.set("log", log); @@ -146,27 +247,37 @@ public void testUsernameGeneratorWithNullLastName() throws GeneralException, Eva String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); result = (String) i.eval(source); - // Since the last name is empty, it may throw an error or return null based on your logic - assertNotNull(result); // Could be a fail if your system requires valid last name + // Since the first email attempt should not be unique, we expect the iteration to happen + assertNotNull(result); + assertEquals(result, "john.doe1@jmfamily.com"); // After iteration 1, the email should be unique + log.info("Beanshell script returned: " + result); } @Test - public void testUsernameGeneratorWithInvalidCompanyID() throws GeneralException, EvalError { + public void testUsernameGeneratorWithMultipleNonUniqueEmailAttemptsContractor() throws GeneralException, EvalError { Interpreter i = new Interpreter(); IdnRuleUtil idn = mock(IdnRuleUtil.class); + + // Simulate that the email is not unique for several attempts + when(idn.isUniqueLDAPValue(any(), any(), any(), any())) + .thenReturn(false) // Email is not unique on first attempt + .thenReturn(false) // Email still not unique on second attempt + .thenReturn(true); // Becomes unique after the third attempt + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); - when(idn.isUniqueLDAPValue(any(), any(), any(), any())).thenReturn(true); Application application = mock(Application.class); when(application.getName()).thenReturn("Active Directory [source]"); Identity identity = mock(Identity.class); - when(identity.getFirstname()).thenReturn("Samantha"); - when(identity.getLastname()).thenReturn("Taylor"); - when(identity.getAttribute("companyId")).thenReturn("999"); // Invalid company ID - when(identity.getId()).thenReturn("f7h4g8b6v2j9z8"); + when(identity.getFirstname()).thenReturn("john"); + when(identity.getLastname()).thenReturn("doe"); + when(identity.getAttribute("companyId")).thenReturn("100"); + when(identity.getAttribute("isAssociate")).thenReturn("N"); // Contractor + when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + String result = ""; i.set("log", log); @@ -177,15 +288,55 @@ public void testUsernameGeneratorWithInvalidCompanyID() throws GeneralException, String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); result = (String) i.eval(source); - // The company ID "999" doesn't exist in the mapping, so it should return "CompanyID not found!" + // After several attempts, email should finally be unique assertNotNull(result); - assertEquals(result, "samantha.taylor@CompanyID not found!"); + assertEquals(result, "john.doe2_contractor@jmfamily.com"); // After 2 failed attempts, we expect the third attempt to work log.info("Beanshell script returned: " + result); } + @Test + public void testUsernameGeneratorWithMultipleNonUniqueEmailAttemptsEmployee() throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + IdnRuleUtil idn = mock(IdnRuleUtil.class); + + // Simulate that the email is not unique for several attempts + when(idn.isUniqueLDAPValue(any(), any(), any(), any())) + .thenReturn(false) // Email is not unique on first attempt + .thenReturn(false) // Email still not unique on second attempt + .thenReturn(true); // Becomes unique after the third attempt + + when(idn.accountExistsByDisplayName(any(), any())).thenReturn(false); + when(idn.attrSearchGetIdentityName(any(), any(), any(), any())).thenReturn(null); + + Application application = mock(Application.class); + when(application.getName()).thenReturn("Active Directory [source]"); + + Identity identity = mock(Identity.class); + when(identity.getFirstname()).thenReturn("john"); + when(identity.getLastname()).thenReturn("doe"); + when(identity.getAttribute("companyId")).thenReturn("100"); + when(identity.getAttribute("isAssociate")).thenReturn("Y"); // Non-Contractor + when(identity.getId()).thenReturn("g12h3b1g2y3v12"); + + String result = ""; + + i.set("log", log); + i.set("idn", idn); + i.set("application", application); + i.set("identity", identity); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + result = (String) i.eval(source); + + // After several attempts, email should finally be unique + assertNotNull(result); + assertEquals(result, "john.doe2@jmfamily.com"); // After 2 failed attempts, we expect the third attempt to work + + log.info("Beanshell script returned: " + result); + } - } diff --git a/src/test/java/sailpoint/JoinAttributesTest.java b/src/test/java/sailpoint/JoinAttributesTest.java index b8b5286..8d50614 100644 --- a/src/test/java/sailpoint/JoinAttributesTest.java +++ b/src/test/java/sailpoint/JoinAttributesTest.java @@ -18,17 +18,39 @@ import sailpoint.rdk.utils.RuleXmlUtils; import sailpoint.tools.GeneralException; + public class JoinAttributesTest { - Logger log = LogManager.getLogger(ManagerCorrelationTest.class); + Logger log = LogManager.getLogger(JoinAttributesTest.class); private static final String RULE_FILENAME = "src/main/resources/rules/Rule - BuildMap - JoinAttributes.xml"; @Test - public void testThatNewColumnIsAdded () throws GeneralException, EvalError { + public void testEnableUSer () throws GeneralException, EvalError { + Interpreter i = new Interpreter(); + + List columns = Arrays.asList("User_Status"); + List rows = Arrays.asList("A"); + + + i.set("log", log); + i.set("cols", columns); + i.set("record", rows); + + String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); + + //@SuppressWarnings("unchecked") + Map result = (Map) i.eval(source); + + log.info("FINAL RESULT"+ result); + + + } + @Test + public void testDisableUser () throws GeneralException, EvalError { Interpreter i = new Interpreter(); - List columns = Arrays.asList("access", "permission", "email"); - List rows = Arrays.asList("admin","write","john.doe@sailpoint.com"); + List columns = Arrays.asList("User_Status"); + List rows = Arrays.asList("I"); i.set("log", log); @@ -37,7 +59,7 @@ public void testThatNewColumnIsAdded () throws GeneralException, EvalError { String source = RuleXmlUtils.readRuleSourceFromFilePath(RULE_FILENAME); - @SuppressWarnings("unchecked") + //@SuppressWarnings("unchecked") Map result = (Map) i.eval(source); log.info(result); From 16835b5183013185d1e866baaa87f0263f0a5f64 Mon Sep 17 00:00:00 2001 From: IDN Date: Tue, 4 Feb 2025 22:30:40 +0530 Subject: [PATCH 3/7] test --- .vscode/settings.json | 3 + .../rules/Rule - BuildMap - Morrissey.xml | 56 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7b016a8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.compile.nullAnalysis.mode": "automatic" +} \ No newline at end of file diff --git a/src/main/resources/rules/Rule - BuildMap - Morrissey.xml b/src/main/resources/rules/Rule - BuildMap - Morrissey.xml index e69de29..c3467ef 100644 --- a/src/main/resources/rules/Rule - BuildMap - Morrissey.xml +++ b/src/main/resources/rules/Rule - BuildMap - Morrissey.xml @@ -0,0 +1,56 @@ + + + + This basic rule performs the combines 2 values into a single attribute. + + + + + The columns of the delimited file. + + + + + A single record of the delimited file. + + + + + + \ No newline at end of file From 31e7accd649c45795ce619328df771c7e90e9573 Mon Sep 17 00:00:00 2001 From: IDN Date: Tue, 4 Feb 2025 22:31:25 +0530 Subject: [PATCH 4/7] Test --- ...ule - BeforeProvisioningRule - AddAccessRequesterDetails.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/rules/Rule - BeforeProvisioningRule - AddAccessRequesterDetails.xml b/src/main/resources/rules/Rule - BeforeProvisioningRule - AddAccessRequesterDetails.xml index b5d2a2c..3876730 100644 --- a/src/main/resources/rules/Rule - BeforeProvisioningRule - AddAccessRequesterDetails.xml +++ b/src/main/resources/rules/Rule - BeforeProvisioningRule - AddAccessRequesterDetails.xml @@ -33,7 +33,7 @@ if(plan != null) { String requesterNetID = (String)requester.getAttribute(\"netid\"); accountRequest.add(new AttributeRequest(\"extensionAttribute1\", ProvisioningPlan.Operation.Set, requesterNetID)); - log.debug(\"UIH AD Before Provisioning Rule : Added Requester Information\"); + log.debug(\"UIH AD Before Provisioning Rule : Added Requester Information \"); } } } From 0d629e5541bb1e34a942dbf6fa5570c59252fc4b Mon Sep 17 00:00:00 2001 From: IDN Date: Tue, 4 Feb 2025 22:48:15 +0530 Subject: [PATCH 5/7] TEst --- ...- AttribueGenerator - GenerateUniqueDN.xml | 127 +++++++++++++++++ ...sioning - SAP_Before_provisioning_Rule.xml | 48 +++++++ ..._Remove_Entitlements_After_Termination.xml | 132 ++++++++++++++++++ ... - BeforeProvisioningRule - OUMovement.xml | 94 +++++++++++++ 4 files changed, 401 insertions(+) create mode 100644 src/main/resources/rules/Rule - AttribueGenerator - GenerateUniqueDN.xml create mode 100644 src/main/resources/rules/Rule - BeforeProvisioning - SAP_Before_provisioning_Rule.xml create mode 100644 src/main/resources/rules/Rule - BeforeProvisioning - SAP_Remove_Entitlements_After_Termination.xml create mode 100644 src/main/resources/rules/Rule - BeforeProvisioningRule - OUMovement.xml diff --git a/src/main/resources/rules/Rule - AttribueGenerator - GenerateUniqueDN.xml b/src/main/resources/rules/Rule - AttribueGenerator - GenerateUniqueDN.xml new file mode 100644 index 0000000..0eb4d0c --- /dev/null +++ b/src/main/resources/rules/Rule - AttribueGenerator - GenerateUniqueDN.xml @@ -0,0 +1,127 @@ + + + + Generate a unique email address for Active Directory. + + diff --git a/src/main/resources/rules/Rule - BeforeProvisioning - SAP_Before_provisioning_Rule.xml b/src/main/resources/rules/Rule - BeforeProvisioning - SAP_Before_provisioning_Rule.xml new file mode 100644 index 0000000..58d2e12 --- /dev/null +++ b/src/main/resources/rules/Rule - BeforeProvisioning - SAP_Before_provisioning_Rule.xml @@ -0,0 +1,48 @@ + + + + SAP GRC BeforeProvisioning Rule To Remove Entitltments once user Disabled + + + + \ No newline at end of file diff --git a/src/main/resources/rules/Rule - BeforeProvisioning - SAP_Remove_Entitlements_After_Termination.xml b/src/main/resources/rules/Rule - BeforeProvisioning - SAP_Remove_Entitlements_After_Termination.xml new file mode 100644 index 0000000..ae3bff6 --- /dev/null +++ b/src/main/resources/rules/Rule - BeforeProvisioning - SAP_Remove_Entitlements_After_Termination.xml @@ -0,0 +1,132 @@ + + + + SAP GRC BeforeProvisioning Rule To Remove Entitltments once user Disabled + + 0) { + for (AccountRequest accRequest: accountRequests) { + if (accRequest != null) { + if (accRequest.getNativeIdentity() == null) { + log.info("SAP_Remove_Entitlements_After_Termination_Test || Log 5 - accRequest from list : "+accRequest); + log.info("SAP_Remove_Entitlements_After_Termination_Test || Log 6 - Native identity inside IF) : "+accRequest.getNativeIdentity()); + plan.remove(accRequest); + } else { + + AccountRequest.Operation op = accRequest.getOperation(); + log.info("SAP_Remove_Entitlements_After_Termination_Test || Log - 7 Operation before entering to if condition : "+op); + if (op != null) { + if (op.equals(AccountRequest.Operation.Disable)) { + log.info("SAP_Remove_Entitlements_After_Termination_Test || Log 8 - Entering getAccountAttributeList Function"); + List entList = getAccountAttributeList(accRequest.getApplication(), accRequest.getNativeIdentity(), entName); + log.info("SAP_Remove_Entitlements_After_Termination_Test || Log 14 - Operation after entering to if condition : "+op); + log.info("SAP_Remove_Entitlements_After_Termination_Test || Log 15 - Entitlement List is before remove : "+entList); + for (String ent: entList) { + AttributeRequest attrRequest = new AttributeRequest(entName, ProvisioningPlan.Operation.Remove, ent); + List entListAfterRemoveOp = getAccountAttributeList(accRequest.getApplication(), accRequest.getNativeIdentity(), entName); + log.info("SAP_Remove_Entitlements_After_Termination_Test || Log 16 - Entitlement List is after remove : "+entListAfterRemoveOp); + } + } + } + } + } + accreqs.add(accRequest); + } + } + } + plan.setAccountRequests(accreqs); + +} +]]> + + \ No newline at end of file diff --git a/src/main/resources/rules/Rule - BeforeProvisioningRule - OUMovement.xml b/src/main/resources/rules/Rule - BeforeProvisioningRule - OUMovement.xml new file mode 100644 index 0000000..7be1e08 --- /dev/null +++ b/src/main/resources/rules/Rule - BeforeProvisioningRule - OUMovement.xml @@ -0,0 +1,94 @@ + + + + Before Provisioning Rule which changes disables and enables to a modify + + + + \ No newline at end of file From 94f9aa00c26a7d7263d6f2b34fda27de74e2f67c Mon Sep 17 00:00:00 2001 From: IDN Date: Tue, 4 Feb 2025 22:50:21 +0530 Subject: [PATCH 6/7] Test --- .../rules/Rule - BuildMap - Morrissey.xml | 39 ++++++------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/src/main/resources/rules/Rule - BuildMap - Morrissey.xml b/src/main/resources/rules/Rule - BuildMap - Morrissey.xml index c3467ef..16fd0b4 100644 --- a/src/main/resources/rules/Rule - BuildMap - Morrissey.xml +++ b/src/main/resources/rules/Rule - BuildMap - Morrissey.xml @@ -1,7 +1,7 @@ - - This basic rule performs the combines 2 values into a single attribute. + + This rule sets the IIQDisabled flag based on the User_Status field and adds a default "account" attribute with the value "access." @@ -17,40 +17,23 @@ \ No newline at end of file From b480ac66d5d395f17d9d8f4c523b809812c04866 Mon Sep 17 00:00:00 2001 From: IDN Date: Tue, 4 Feb 2025 23:03:37 +0530 Subject: [PATCH 7/7] Test --- src/main/java/UsernameGenerator.java | 3 ++- src/test/java/sailpoint/JoinAttributesTest.java | 3 +++ src/test/java/sailpoint/ProvisioningTest.java | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/UsernameGenerator.java b/src/main/java/UsernameGenerator.java index 7198936..6a0fccf 100644 --- a/src/main/java/UsernameGenerator.java +++ b/src/main/java/UsernameGenerator.java @@ -17,6 +17,7 @@ public class UsernameGenerator { int MAX_USERNAME_LENGTH = 12; + @SuppressWarnings("null") public String generateUsername(String firstName, String lastName) throws GeneralException { firstName = StringUtils.trimToNull(firstName); lastName = StringUtils.trimToNull(lastName); @@ -46,7 +47,7 @@ public String generateUsername(String firstName, String lastName) throws General String username = null; String fullName = firstName + "." + lastName; - if(fullName.length() > MAX_USERNAME_LENGTH) { + if(fullName.length() > MAX_USERNAME_LENGTH && fullName!=null) { int firstNameLength = firstName.length(); if(firstNameLength > (MAX_USERNAME_LENGTH - 2)) { diff --git a/src/test/java/sailpoint/JoinAttributesTest.java b/src/test/java/sailpoint/JoinAttributesTest.java index 8d50614..347f49b 100644 --- a/src/test/java/sailpoint/JoinAttributesTest.java +++ b/src/test/java/sailpoint/JoinAttributesTest.java @@ -19,11 +19,13 @@ import sailpoint.tools.GeneralException; +@SuppressWarnings("unused") public class JoinAttributesTest { Logger log = LogManager.getLogger(JoinAttributesTest.class); private static final String RULE_FILENAME = "src/main/resources/rules/Rule - BuildMap - JoinAttributes.xml"; + @SuppressWarnings("unchecked") @Test public void testEnableUSer () throws GeneralException, EvalError { Interpreter i = new Interpreter(); @@ -45,6 +47,7 @@ public void testEnableUSer () throws GeneralException, EvalError { } + @SuppressWarnings("unchecked") @Test public void testDisableUser () throws GeneralException, EvalError { Interpreter i = new Interpreter(); diff --git a/src/test/java/sailpoint/ProvisioningTest.java b/src/test/java/sailpoint/ProvisioningTest.java index 95e261e..cbafb8b 100644 --- a/src/test/java/sailpoint/ProvisioningTest.java +++ b/src/test/java/sailpoint/ProvisioningTest.java @@ -19,6 +19,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +@SuppressWarnings("unused") public class ProvisioningTest { Logger log = LogManager.getLogger(ProvisioningTest.class);