From da993204e704995cc517f133e18d82f9f750f4fe Mon Sep 17 00:00:00 2001 From: igorski-r7 <99184344+igorski-r7@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:24:40 +0100 Subject: [PATCH] Active Directory LDAP - 629 - Fix problem where some ASCII characters were not escaped properly (#2201) --- plugins/active_directory_ldap/.CHECKSUM | 6 +- plugins/active_directory_ldap/Dockerfile | 2 +- .../bin/komand_active_directory_ldap | 2 +- plugins/active_directory_ldap/help.md | 100 +++++++++--------- .../actions/add_user/action.py | 28 ++++- .../actions/delete/action.py | 20 +++- .../actions/disable_user/action.py | 16 ++- .../actions/disable_users/action.py | 10 +- .../actions/enable_user/action.py | 16 ++- .../actions/enable_users/action.py | 9 +- .../actions/force_password_reset/action.py | 24 +++-- .../actions/modify_groups/action.py | 26 ++++- .../actions/modify_object/action.py | 27 +++-- .../actions/move_object/action.py | 26 +++-- .../actions/query/action.py | 28 +++-- .../actions/query_group_membership/action.py | 9 +- .../actions/reset_password/action.py | 26 +++-- .../actions/unlock_user/action.py | 21 ++-- .../komand_active_directory_ldap/util/api.py | 12 ++- .../util/utils.py | 38 ++++--- .../active_directory_ldap/plugin.spec.yaml | 12 +-- plugins/active_directory_ldap/setup.py | 2 +- .../active_directory_ldap/unit_test/common.py | 10 +- ...st_action_add_user.py => test_add_user.py} | 6 +- .../{test_action_delete.py => test_delete.py} | 6 +- ...n_disable_user.py => test_disable_user.py} | 6 +- ...disable_users.py => test_disable_users.py} | 9 +- ...ion_enable_user.py => test_enable_user.py} | 6 +- ...n_enable_users.py => test_enable_users.py} | 8 +- .../test_escape_brackets_formatter.py | 1 - ..._reset.py => test_force_password_reset.py} | 6 +- .../unit_test/test_host_formatter.py | 4 +- ...modify_groups.py => test_modify_groups.py} | 6 +- ...modify_object.py => test_modify_object.py} | 6 +- ...ion_move_object.py => test_move_object.py} | 6 +- .../{test_action_query.py => test_query.py} | 6 +- ...ship.py => test_query_group_membership.py} | 6 +- ...set_password.py => test_reset_password.py} | 6 +- ...ion_unlock_user.py => test_unlock_user.py} | 10 +- 39 files changed, 362 insertions(+), 206 deletions(-) rename plugins/active_directory_ldap/unit_test/{test_action_add_user.py => test_add_user.py} (94%) rename plugins/active_directory_ldap/unit_test/{test_action_delete.py => test_delete.py} (92%) rename plugins/active_directory_ldap/unit_test/{test_action_disable_user.py => test_disable_user.py} (96%) rename plugins/active_directory_ldap/unit_test/{test_action_disable_users.py => test_disable_users.py} (96%) rename plugins/active_directory_ldap/unit_test/{test_action_enable_user.py => test_enable_user.py} (96%) rename plugins/active_directory_ldap/unit_test/{test_action_enable_users.py => test_enable_users.py} (96%) rename plugins/active_directory_ldap/unit_test/{test_action_force_password_reset.py => test_force_password_reset.py} (93%) rename plugins/active_directory_ldap/unit_test/{test_action_modify_groups.py => test_modify_groups.py} (96%) rename plugins/active_directory_ldap/unit_test/{test_action_modify_object.py => test_modify_object.py} (94%) rename plugins/active_directory_ldap/unit_test/{test_action_move_object.py => test_move_object.py} (91%) rename plugins/active_directory_ldap/unit_test/{test_action_query.py => test_query.py} (91%) rename plugins/active_directory_ldap/unit_test/{test_action_query_group_membership.py => test_query_group_membership.py} (96%) rename plugins/active_directory_ldap/unit_test/{test_action_reset_password.py => test_reset_password.py} (95%) rename plugins/active_directory_ldap/unit_test/{test_action_unlock_user.py => test_unlock_user.py} (97%) diff --git a/plugins/active_directory_ldap/.CHECKSUM b/plugins/active_directory_ldap/.CHECKSUM index 9011fe1c85..cf6221775b 100644 --- a/plugins/active_directory_ldap/.CHECKSUM +++ b/plugins/active_directory_ldap/.CHECKSUM @@ -1,7 +1,7 @@ { - "spec": "d5dfdb03974651b69e5a02256df71e03", - "manifest": "5d016144fec71b932d8182d5c1a7f81d", - "setup": "def3e06498eabadbc9aaa7270aff8be6", + "spec": "7ccbd3e54069b451819765d331a5e422", + "manifest": "eec2dabd6adf20679bf09da7cda157b5", + "setup": "c2867f07c815fafae59884272249fe1e", "schemas": [ { "identifier": "add_user/schema.py", diff --git a/plugins/active_directory_ldap/Dockerfile b/plugins/active_directory_ldap/Dockerfile index 9a0c6530db..87b38ede0b 100755 --- a/plugins/active_directory_ldap/Dockerfile +++ b/plugins/active_directory_ldap/Dockerfile @@ -1,4 +1,4 @@ -FROM rapid7/insightconnect-python-3-38-plugin:5 +FROM --platform=linux/amd64 rapid7/insightconnect-python-3-slim-plugin:5 LABEL organization=rapid7 LABEL sdk=python diff --git a/plugins/active_directory_ldap/bin/komand_active_directory_ldap b/plugins/active_directory_ldap/bin/komand_active_directory_ldap index c88bef873e..ad0381739b 100755 --- a/plugins/active_directory_ldap/bin/komand_active_directory_ldap +++ b/plugins/active_directory_ldap/bin/komand_active_directory_ldap @@ -6,7 +6,7 @@ from sys import argv Name = "Active Directory LDAP" Vendor = "rapid7" -Version = "9.0.0" +Version = "9.0.1" Description = "This plugin utilizes Microsoft's Active Directory service to create and manage domains, users, and objects within a network" diff --git a/plugins/active_directory_ldap/help.md b/plugins/active_directory_ldap/help.md index dbfc552746..8f41c6b2e0 100644 --- a/plugins/active_directory_ldap/help.md +++ b/plugins/active_directory_ldap/help.md @@ -57,7 +57,7 @@ Example input: #### Add User -Adds the specified Active Directory user +This action is used to add the specified Active Directory user ##### Input @@ -107,7 +107,7 @@ Example output: #### Delete -Deletes the LDAP object specified +This action is used to delete the LDAP object specified ##### Input @@ -139,7 +139,7 @@ Example output: #### Disable User -Disable an account +This action is used to disable an account ##### Input @@ -171,7 +171,7 @@ Example output: #### Disable Users -Disable multiple accounts +This action is used to disable multiple accounts ##### Input @@ -214,7 +214,7 @@ Example output: #### Enable User -Enable an account +This action is used to enable an account ##### Input @@ -246,7 +246,7 @@ Example output: #### Enable Users -Enable multiple accounts +This action is used to enable multiple accounts ##### Input @@ -289,7 +289,7 @@ Example output: #### Force Password Reset -Force a user to reset their password on next login +This action is used to force a user to reset their password on next login ##### Input @@ -321,7 +321,7 @@ Example output: #### Add or Remove an Object from Group -Add or remove an object from an Active Directory group +This action is used to add or remove an object from an Active Directory group ##### Input @@ -357,7 +357,7 @@ Example output: #### Modify Object -Modify the attributes for an Active Directory object +This action is used to modify the attributes for an Active Directory object ##### Input @@ -393,7 +393,7 @@ Example output: #### Move Object -Move an Active Directory object from one organizational unit to another +This action is used to move an Active Directory object from one organizational unit to another ##### Input @@ -427,7 +427,7 @@ Example output: #### Query -Run an LDAP query +This action is used to run an LDAP query ##### Input @@ -455,7 +455,7 @@ Example input: |Name|Type|Required|Description|Example| | :--- | :--- | :--- | :--- | :--- | |count|integer|False|Number of results|1| -|results|[]result|False|Results returned|[ { "dn": string, "attributes": { "pwdLastSet": date, "objectClass": [ string, string, string, string ], "memberOf": [ string ], "sAMAccountType": int, "uSNChanged": int, "givenName": string, "userPrincipalName": string, "countryCode": int, "lastLogon": date, "sAMAccountName": string, "name": string, "primaryGroupID": int, "dSCorePropagationData": [ date ], "displayName": string, "logonCount": int, "cn": string, "objectSid": string, "codePage": int, "badPwdCount": int, "objectGUID": string, "distinguishedName": string, "whenChanged": date, "badPasswordTime": date, "instanceType": int, "uSNCreated": int, "sn": string, "whenCreated": date, "accountExpires": date, "userAccountControl": int, "lastLogoff": date, "objectCategory": "string" } } ]| +|results|[]result|False|Results returned|[{"dn":"string","attributes":{"pwdLastSet":"date","objectClass":["string","string","string","string"],"memberOf":["string"],"sAMAccountType":"int","uSNChanged":"int","givenName":"string","userPrincipalName":"string","countryCode":"int","lastLogon":"date","sAMAccountName":"string","name":"string","primaryGroupID":"int","dSCorePropagationData":["date"],"displayName":"string","logonCount":"int","cn":"string","objectSid":"string","codePage":"int","badPwdCount":"int","objectGUID":"string","distinguishedName":"string","whenChanged":"date","badPasswordTime":"date","instanceType":"int","uSNCreated":"int","sn":"string","whenCreated":"date","accountExpires":"date","userAccountControl":"int","lastLogoff":"date","objectCategory":"string"}}]| Example output: @@ -464,49 +464,49 @@ Example output: "count": 1, "results": [ { - "dn": "string", "attributes": { - "pwdLastSet": "date", + "accountExpires": "date", + "badPasswordTime": "date", + "badPwdCount": "int", + "cn": "string", + "codePage": "int", + "countryCode": "int", + "dSCorePropagationData": [ + "date" + ], + "displayName": "string", + "distinguishedName": "string", + "givenName": "string", + "instanceType": "int", + "lastLogoff": "date", + "lastLogon": "date", + "logonCount": "int", + "memberOf": [ + "string" + ], + "name": "string", + "objectCategory": "string", "objectClass": [ "string", "string", "string", "string" ], - "memberOf": [ - "string" - ], + "objectGUID": "string", + "objectSid": "string", + "primaryGroupID": "int", + "pwdLastSet": "date", + "sAMAccountName": "string", "sAMAccountType": "int", + "sn": "string", "uSNChanged": "int", - "givenName": "string", - "userPrincipalName": "string", - "countryCode": "int", - "lastLogon": "date", - "sAMAccountName": "string", - "name": "string", - "primaryGroupID": "int", - "dSCorePropagationData": [ - "date" - ], - "displayName": "string", - "logonCount": "int", - "cn": "string", - "objectSid": "string", - "codePage": "int", - "badPwdCount": "int", - "objectGUID": "string", - "distinguishedName": "string", - "whenChanged": "date", - "badPasswordTime": "date", - "instanceType": "int", "uSNCreated": "int", - "sn": "string", - "whenCreated": "date", - "accountExpires": "date", "userAccountControl": "int", - "lastLogoff": "date", - "objectCategory": "string" - } + "userPrincipalName": "string", + "whenChanged": "date", + "whenCreated": "date" + }, + "dn": "string" } ] } @@ -514,7 +514,7 @@ Example output: #### Query Group Membership -Return users and groups that belonging to the specific group +This action is used to return users and groups that belonging to the specific group ##### Input @@ -604,7 +604,7 @@ Example output: #### Reset Password -Reset a users password +This action is used to reset a users password ##### Input @@ -638,7 +638,7 @@ Example output: #### Unlock User -Unlock an account +This action is used to unlock an account ##### Input @@ -667,11 +667,9 @@ Example output: "success": true } ``` - ### Triggers *This plugin does not contain any triggers.* - ### Tasks *This plugin does not contain any tasks.* @@ -762,6 +760,7 @@ the query results, and then using the variable step $item.dn # Version History +* 9.0.1 - Fix problem where some ASCII characters were not escaped properly * 9.0.0 - Action: `Disable User` & `Enable User` - Rename title of actions from `Disable` & `Enable` to `Disable Users` & `Enable Users` on the front-end. * 8.0.0 - Update actions Enable Users and Enable Users to add outputs Completed and Failed and remove output All Operations Succeeded * 7.0.0 - Update actions Enable Users and Enable Users to replace output Success with All Operations Succeeded True/False @@ -809,10 +808,11 @@ the query results, and then using the variable step $item.dn * 1.0.0 - Revise input names, bugfixes for missing attributes and character escaping, fix security issue * 0.1.0 - Initial plugin - # Links [Learn Azure Active Directory](https://learn.microsoft.com/en-us/azure/active-directory/) +[AD LDAP](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/3c5916a9-f1a0-429d-b937-f8fe672d777c) +[Microsoft's Active Directory service](https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx) ## References diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/add_user/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/add_user/action.py index cae4e94b46..d8b565ef61 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/add_user/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/add_user/action.py @@ -1,7 +1,9 @@ import insightconnect_plugin_runtime +from insightconnect_plugin_runtime.exceptions import PluginException # Custom imports below from .schema import AddUserInput, AddUserOutput, Output, Input +from komand_active_directory_ldap.util.utils import ADUtils class AddUser(insightconnect_plugin_runtime.Action): @@ -14,7 +16,7 @@ def __init__(self): ) def run(self, params={}): - use_ssl = self.connection.use_ssl + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION domain_name = params.get(Input.DOMAIN_NAME) first_name = params.get(Input.FIRST_NAME) last_name = params.get(Input.LAST_NAME) @@ -24,8 +26,9 @@ def run(self, params={}): password = params.get(Input.PASSWORD) additional_parameters = params.get(Input.ADDITIONAL_PARAMETERS) user_principal_name = params.get(Input.USER_PRINCIPAL_NAME) + # END INPUT BINDING - DO NOT REMOVE - if account_disabled or not use_ssl: + if account_disabled or not self.connection.use_ssl: user_account_control = 514 else: user_account_control = 512 @@ -56,6 +59,21 @@ def run(self, params={}): log_parameters = parameters log_parameters.pop("userPassword") self.logger.info(log_parameters) - return { - Output.SUCCESS: self.connection.client.add_user(dn, user_account_control, use_ssl, password, parameters) - } + + try: + return { + Output.SUCCESS: self.connection.client.add_user( + dn, user_account_control, self.connection.use_ssl, password, parameters + ) + } + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.add_user( + ADUtils.escape_non_ascii_characters(dn), + user_account_control, + self.connection.use_ssl, + password, + parameters, + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/delete/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/delete/action.py index 9aaef64fe5..8b3a9b64b3 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/delete/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/delete/action.py @@ -1,6 +1,7 @@ import insightconnect_plugin_runtime # Custom imports below +from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.util.utils import ADUtils from .schema import DeleteInput, DeleteOutput, Output, Input @@ -15,8 +16,17 @@ def __init__(self): ) def run(self, params={}): - formatter = ADUtils() - dn = params.get(Input.DISTINGUISHED_NAME) - dn = formatter.format_dn(dn)[0] - dn = formatter.unescape_asterisk(dn) - return {Output.SUCCESS: self.connection.client.delete(dn)} + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) + # END INPUT BINDING - DO NOT REMOVE + + distinguished_name = ADUtils.format_dn(distinguished_name)[0] + distinguished_name = ADUtils.unescape_asterisk(distinguished_name) + + try: + return {Output.SUCCESS: self.connection.client.delete(distinguished_name)} + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.delete(ADUtils.escape_non_ascii_characters(distinguished_name)) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/disable_user/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/disable_user/action.py index 6f4b263c06..9ada30759d 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/disable_user/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/disable_user/action.py @@ -1,7 +1,9 @@ import insightconnect_plugin_runtime +from insightconnect_plugin_runtime.exceptions import PluginException # Custom imports below from .schema import DisableUserInput, DisableUserOutput, Input, Output +from komand_active_directory_ldap.util.utils import ADUtils class DisableUser(insightconnect_plugin_runtime.Action): @@ -14,4 +16,16 @@ def __init__(self): ) def run(self, params={}): - return {Output.SUCCESS: self.connection.client.manage_user(params.get(Input.DISTINGUISHED_NAME), False)} + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) + # END INPUT BINDING - DO NOT REMOVE + + try: + return {Output.SUCCESS: self.connection.client.manage_user(distinguished_name, False)} + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.manage_user( + ADUtils.escape_non_ascii_characters(distinguished_name), False + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/disable_users/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/disable_users/action.py index 8b034df69c..4e1669d218 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/disable_users/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/disable_users/action.py @@ -3,6 +3,7 @@ from .schema import DisableUsersInput, DisableUsersOutput, Input, Output, Component # Custom imports below +from komand_active_directory_ldap.util.utils import ADUtils class DisableUsers(insightconnect_plugin_runtime.Action): @@ -15,14 +16,17 @@ def __init__(self): ) def run(self, params={}): - if not params.get(Input.DISTINGUISHED_NAMES): + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_names = params.get(Input.DISTINGUISHED_NAMES) + # END INPUT BINDING - DO NOT REMOVE + + if not distinguished_names: raise PluginException( cause="Distinguished Names must contain at least one entry", assistance="Please enter one or more Distinguished Names", ) - disabled_users = self.connection.client.manage_users(params.get(Input.DISTINGUISHED_NAMES), False) - + disabled_users = self.connection.client.manage_users(distinguished_names, False) return { Output.COMPLETED: disabled_users.get("successes"), Output.FAILED: disabled_users.get("failures"), diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/enable_user/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/enable_user/action.py index 4eea258618..0a9a8deded 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/enable_user/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/enable_user/action.py @@ -1,7 +1,9 @@ import insightconnect_plugin_runtime +from insightconnect_plugin_runtime.exceptions import PluginException # Custom imports below from .schema import EnableUserInput, EnableUserOutput, Input, Output +from komand_active_directory_ldap.util.utils import ADUtils class EnableUser(insightconnect_plugin_runtime.Action): @@ -14,4 +16,16 @@ def __init__(self): ) def run(self, params={}): - return {Output.SUCCESS: self.connection.client.manage_user(params.get(Input.DISTINGUISHED_NAME), True)} + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) + # END INPUT BINDING - DO NOT REMOVE + + try: + return {Output.SUCCESS: self.connection.client.manage_user(distinguished_name, True)} + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.manage_user( + ADUtils.escape_non_ascii_characters(distinguished_name), True + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/enable_users/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/enable_users/action.py index 08fcd0b21b..a9a3c31a1c 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/enable_users/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/enable_users/action.py @@ -12,14 +12,17 @@ def __init__(self): ) def run(self, params={}): - if not params.get(Input.DISTINGUISHED_NAMES): + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_names = params.get(Input.DISTINGUISHED_NAMES) + # END INPUT BINDING - DO NOT REMOVE + + if not distinguished_names: raise PluginException( cause="Distinguished Names must contain at least one entry", assistance="Please enter one or more Distinguished Names", ) - enabled_users = self.connection.client.manage_users(params.get(Input.DISTINGUISHED_NAMES), True) - + enabled_users = self.connection.client.manage_users(distinguished_names, True) return { Output.COMPLETED: enabled_users.get("successes"), Output.FAILED: enabled_users.get("failures"), diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/force_password_reset/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/force_password_reset/action.py index 6259c44142..25199ca7c2 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/force_password_reset/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/force_password_reset/action.py @@ -1,4 +1,5 @@ import insightconnect_plugin_runtime +from insightconnect_plugin_runtime.exceptions import PluginException # Custom imports below from komand_active_directory_ldap.util.utils import ADUtils @@ -15,10 +16,21 @@ def __init__(self): ) def run(self, params={}): - formatter = ADUtils() - dn = params.get(Input.DISTINGUISHED_NAME) - dn = formatter.format_dn(dn)[0] - dn = formatter.unescape_asterisk(dn) - self.logger.info(f"Escaped DN {dn}") + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) + # END INPUT BINDING - DO NOT REMOVE + + distinguished_name = ADUtils.format_dn(distinguished_name)[0] + distinguished_name = ADUtils.unescape_asterisk(distinguished_name) + self.logger.info(f"Escaped DN {distinguished_name}") password_expire = {"pwdLastSet": ("MODIFY_REPLACE", [0])} - return {Output.SUCCESS: self.connection.client.force_password_reset(dn, password_expire)} + + try: + return {Output.SUCCESS: self.connection.client.force_password_reset(distinguished_name, password_expire)} + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.force_password_reset( + ADUtils.escape_non_ascii_characters(distinguished_name), password_expire + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/modify_groups/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/modify_groups/action.py index 27c5eb053b..81ca0422ef 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/modify_groups/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/modify_groups/action.py @@ -1,4 +1,5 @@ import insightconnect_plugin_runtime +from insightconnect_plugin_runtime.exceptions import PluginException # Custom imports below from komand_active_directory_ldap.util.utils import ADUtils @@ -15,17 +16,32 @@ def __init__(self): ) def run(self, params={}): - dn = params.get(Input.DISTINGUISHED_NAME) + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) group_dn = params.get(Input.GROUP_DN) add_remove = params.get(Input.ADD_REMOVE) + # END INPUT BINDING - DO NOT REMOVE # Normalize dn - dn, search_base = ADUtils.format_dn(dn) - dn = ADUtils.unescape_asterisk(dn) - self.logger.info(f"Escaped DN {dn}") + distinguished_name, search_base = ADUtils.format_dn(distinguished_name) + distinguished_name = ADUtils.unescape_asterisk(distinguished_name) + self.logger.info(f"Escaped DN {distinguished_name}") + # Normalize group dn group_dn = ADUtils.format_dn(group_dn)[0] group_dn = ADUtils.unescape_asterisk(group_dn) self.logger.info(f"Escaped group DN {group_dn}") - return {Output.SUCCESS: self.connection.client.modify_groups(dn, search_base, add_remove, group_dn)} + try: + return { + Output.SUCCESS: self.connection.client.modify_groups( + distinguished_name, search_base, add_remove, group_dn + ) + } + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.modify_groups( + ADUtils.escape_non_ascii_characters(distinguished_name), search_base, add_remove, group_dn + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/modify_object/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/modify_object/action.py index 4b6487f45c..c9ceeb4335 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/modify_object/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/modify_object/action.py @@ -1,4 +1,5 @@ import insightconnect_plugin_runtime +from insightconnect_plugin_runtime.exceptions import PluginException # Custom imports below from komand_active_directory_ldap.util.utils import ADUtils @@ -15,14 +16,26 @@ def __init__(self): ) def run(self, params={}): - formatter = ADUtils() - dn = params.get(Input.DISTINGUISHED_NAME) + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) attribute = params.get(Input.ATTRIBUTE_TO_MODIFY) attribute_value = params.get(Input.ATTRIBUTE_VALUE) - dn, _ = formatter.format_dn(dn) - self.logger.info(f"Escaped DN {dn}") + # END INPUT BINDING - DO NOT REMOVE - dn = formatter.escape_brackets_for_query(dn) - self.logger.info(dn) + distinguished_name, _ = ADUtils.format_dn(distinguished_name) + self.logger.info(f"Escaped DN {distinguished_name}") - return {Output.SUCCESS: self.connection.client.modify_object(dn, attribute, attribute_value)} + distinguished_name = ADUtils.escape_brackets_for_query(distinguished_name) + self.logger.info(distinguished_name) + + try: + return { + Output.SUCCESS: self.connection.client.modify_object(distinguished_name, attribute, attribute_value) + } + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.modify_object( + ADUtils.escape_non_ascii_characters(distinguished_name), attribute, attribute_value + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/move_object/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/move_object/action.py index a110cffda7..051b053e87 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/move_object/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/move_object/action.py @@ -2,6 +2,7 @@ import re import insightconnect_plugin_runtime +from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.util.utils import ADUtils from .schema import MoveObjectInput, MoveObjectOutput, Output, Input @@ -17,18 +18,29 @@ def __init__(self): ) def run(self, params={}): - formatter = ADUtils() - dn = params.get(Input.DISTINGUISHED_NAME) + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) new_ou = params.get(Input.NEW_OU) + # END INPUT BINDING - DO NOT REMOVE + relative_dn = "" - dn = formatter.format_dn(dn)[0] - dn = formatter.unescape_asterisk(dn) - self.logger.info(f"Escaped DN {dn}") + distinguished_name = ADUtils.format_dn(distinguished_name)[0] + distinguished_name = ADUtils.unescape_asterisk(distinguished_name) + self.logger.info(f"Escaped DN {distinguished_name}") - pattern = re.search(r"CN=[^,]*,", dn) + pattern = re.search(r"CN=[^,]*,", distinguished_name) self.logger.debug(pattern) if pattern: relative_dn = pattern.group() relative_dn = relative_dn[:-1] self.logger.debug(relative_dn) - return {Output.SUCCESS: self.connection.client.move_object(dn, relative_dn, new_ou)} + + try: + return {Output.SUCCESS: self.connection.client.move_object(distinguished_name, relative_dn, new_ou)} + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.move_object( + ADUtils.escape_non_ascii_characters(distinguished_name), relative_dn, new_ou + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/query/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/query/action.py index 0437c769ac..7669d4b8a1 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/query/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/query/action.py @@ -2,6 +2,7 @@ import ldap3 # Custom imports below +from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.util.utils import ADUtils from .schema import QueryInput, QueryOutput, Input, Output @@ -13,22 +14,27 @@ def __init__(self): ) def run(self, params={}): - formatter = ADUtils() - query = params.get(Input.SEARCH_FILTER) - - query = query.replace("\\>=", ">=") - query = query.replace("\\<=", "<=") + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + query = params.get(Input.SEARCH_FILTER, "").replace("\\>=", ">=").replace("\\<=", "<=") + search_base = params.get(Input.SEARCH_BASE) + attributes = params.get(Input.ATTRIBUTES, []) + # END INPUT BINDING - DO NOT REMOVE # replace ( and ) when they are part of a name rather than a search parameter - escaped_query = formatter.escape_brackets_for_query(query) - self.logger.info("Escaped query: %s", escaped_query) + escaped_query = ADUtils.escape_brackets_for_query(query) + self.logger.info(f"Escaped query: {escaped_query}") - attributes = params.get(Input.ATTRIBUTES, []) if not attributes: attributes = [ldap3.ALL_ATTRIBUTES, ldap3.ALL_OPERATIONAL_ATTRIBUTES] - entries = self.connection.client.query(params.get(Input.SEARCH_BASE), escaped_query, attributes) + try: + entries = self.connection.client.query(search_base, escaped_query, attributes) + except PluginException: + self.logger.info("Escaping non-ascii characters...") + entries = self.connection.client.query( + search_base, ADUtils.escape_non_ascii_characters(escaped_query), attributes + ) + if entries: return {Output.RESULTS: entries, Output.COUNT: len(entries)} - else: - return {Output.RESULTS: [], Output.COUNT: 0} + return {Output.RESULTS: [], Output.COUNT: 0} diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/query_group_membership/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/query_group_membership/action.py index 8d7b4790de..1dc1818666 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/query_group_membership/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/query_group_membership/action.py @@ -1,6 +1,7 @@ import insightconnect_plugin_runtime # Custom imports below +from insightconnect_plugin_runtime.exceptions import PluginException from .schema import QueryGroupMembershipInput, QueryGroupMembershipOutput, Input, Output, Component @@ -14,10 +15,12 @@ def __init__(self): ) def run(self, params={}): + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION base = params.get(Input.SEARCH_BASE) + group_name = params.get(Input.GROUP_NAME) include_groups = params.get(Input.INCLUDE_GROUPS) expand_nested_groups = params.get(Input.EXPAND_NESTED_GROUPS) - entries = self.connection.client.query_group_membership( - base, params.get(Input.GROUP_NAME), include_groups, expand_nested_groups - ) + # END INPUT BINDING - DO NOT REMOVE + + entries = self.connection.client.query_group_membership(base, group_name, include_groups, expand_nested_groups) return {Output.RESULTS: entries, Output.COUNT: len(entries)} diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/reset_password/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/reset_password/action.py index fa0a028ebe..8ae04c8bb5 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/reset_password/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/reset_password/action.py @@ -16,16 +16,26 @@ def __init__(self): ) def run(self, params={}): - formatter = ADUtils() - dn = params.get(Input.DISTINGUISHED_NAME) + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) new_password = params.get(Input.NEW_PASSWORD) - use_ssl = self.connection.use_ssl - dn = formatter.format_dn(dn)[0] - dn = formatter.unescape_asterisk(dn) - self.logger.info(f"Escaped DN {dn}") + # END INPUT BINDING - DO NOT REMOVE - if use_ssl is False: + distinguished_name = ADUtils.format_dn(distinguished_name)[0] + distinguished_name = ADUtils.unescape_asterisk(distinguished_name) + self.logger.info(f"Escaped DN {distinguished_name}") + + if self.connection.use_ssl is False: raise PluginException( cause="SSL must be enabled", assistance="SSL must be enabled for the reset password action" ) - return {Output.SUCCESS: self.connection.client.reset_password(dn, new_password)} + + try: + return {Output.SUCCESS: self.connection.client.reset_password(distinguished_name, new_password)} + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.reset_password( + ADUtils.escape_non_ascii_characters(distinguished_name), new_password + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/unlock_user/action.py b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/unlock_user/action.py index 0ee5d866eb..cba8abb2a4 100755 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/actions/unlock_user/action.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/actions/unlock_user/action.py @@ -1,7 +1,8 @@ import insightconnect_plugin_runtime # Custom imports below -from komand_active_directory_ldap.util.utils import UserAccountFlags +from insightconnect_plugin_runtime.exceptions import PluginException +from komand_active_directory_ldap.util.utils import UserAccountFlags, ADUtils from .schema import UnlockUserInput, UnlockUserOutput, Input, Output, Component @@ -12,8 +13,16 @@ def __init__(self): ) def run(self, params={}): - return { - Output.SUCCESS: self.connection.client.unblock_user( - params.get(Input.DISTINGUISHED_NAME), UserAccountFlags.LOCKOUT - ) - } + # START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION + distinguished_name = params.get(Input.DISTINGUISHED_NAME) + # END INPUT BINDING - DO NOT REMOVE + + try: + return {Output.SUCCESS: self.connection.client.unblock_user(distinguished_name, UserAccountFlags.LOCKOUT)} + except PluginException: + self.logger.info("Escaping non-ascii characters...") + return { + Output.SUCCESS: self.connection.client.unblock_user( + ADUtils.escape_non_ascii_characters(distinguished_name), UserAccountFlags.LOCKOUT + ) + } diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/util/api.py b/plugins/active_directory_ldap/komand_active_directory_ldap/util/api.py index f865d55fe2..d57147a9e1 100644 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/util/api.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/util/api.py @@ -176,15 +176,21 @@ def manage_users(self, conn, dns: List[str], status: bool) -> dict: :return: Dictionary containing two lists, one for successfully modified Distinguishes Names and another for unsuccessfully modified Distinguishes Names and the cause of the failure """ + successes = [] failures = [] for dn in dns: try: ADUtils.change_account_status(conn, dn, status, self.logger) successes.append(dn) - except Exception as exception: - failures.append({"dn": dn, "error": str(exception)}) - self.logger.error(f"Error: Failed to modify user {dn}") + except Exception: + try: + escaped_dn = ADUtils.escape_non_ascii_characters(dn) + ADUtils.change_account_status(conn, escaped_dn, status, self.logger) + successes.append(dn) + except Exception as error: + failures.append({"dn": dn, "error": str(error)}) + self.logger.error(f"Error: Failed to modify user {dn}") return {"successes": successes, "failures": failures} @with_connection diff --git a/plugins/active_directory_ldap/komand_active_directory_ldap/util/utils.py b/plugins/active_directory_ldap/komand_active_directory_ldap/util/utils.py index 778ab9a557..b8b7b67296 100644 --- a/plugins/active_directory_ldap/komand_active_directory_ldap/util/utils.py +++ b/plugins/active_directory_ldap/komand_active_directory_ldap/util/utils.py @@ -7,10 +7,25 @@ class ADUtils: + @staticmethod + def escape_non_ascii_characters(input_string: str) -> str: + non_ascii_list = { + "á": "\\E1", + "é": "\\E9", + "í": "\\ED", + "ó": "\\F3", + "ú": "\\FA", + "ñ": "\\F1", + } + + for non_ascii, escaped_character in non_ascii_list.items(): + input_string = input_string.replace(non_ascii, escaped_character) + return input_string + @staticmethod def dn_normalize(dn: str) -> str: """ - This method normalizes dn keys so that inputs are not case sensitive + This method normalizes dn keys so that inputs are not case-sensitive :param dn: A dn :return: A normalized dn """ @@ -33,16 +48,16 @@ def dn_escape_and_split(dn: str) -> list: # Ensure that special characters and non ascii characters are escaped character_list = [",", "#", "+", "<", ">", ";", '"'] - non_ascii_list = { - "á": "\\E1", - "é": "\\E9", - "í": "\\ED", - "ó": "\\F3", - "ú": "\\FA", - "ñ": "\\F1", - } - # These are legal characters that some times need to be escaped and sometimes do not + # non_ascii_list = { + # "á": "\\E1", + # "é": "\\E9", + # "í": "\\ED", + # "ó": "\\F3", + # "ú": "\\FA", + # "ñ": "\\F1", + # } + # These are legal characters that sometimes need to be escaped and sometimes do not # We make the use escape them correctly in their inputs if they want to use them manual_escape = ["*", "="] @@ -51,9 +66,6 @@ def dn_escape_and_split(dn: str) -> list: for escaped_char in character_list: if f"\\{escaped_char}" not in value: dn_list[idx] = dn_list[idx].replace(escaped_char, f"\\{escaped_char}") - # Escape non ascii characters - for non_ascii_char, escaped_char in non_ascii_list.items(): - dn_list[idx] = dn_list[idx].replace(non_ascii_char, escaped_char) # escape \\ as needed for idx, value in enumerate(dn_list): location = value.find("\\") diff --git a/plugins/active_directory_ldap/plugin.spec.yaml b/plugins/active_directory_ldap/plugin.spec.yaml index 6c06915a68..867d472e1c 100644 --- a/plugins/active_directory_ldap/plugin.spec.yaml +++ b/plugins/active_directory_ldap/plugin.spec.yaml @@ -4,7 +4,7 @@ products: [insightconnect] name: active_directory_ldap title: Active Directory LDAP description: "This plugin utilizes Microsoft's Active Directory service to create and manage domains, users, and objects within a network" -version: 9.0.0 +version: 9.0.1 supported_versions: ["Azure Active Directory 2.0.89.0"] vendor: rapid7 support: rapid7 @@ -14,15 +14,15 @@ resources: license_url: https://github.com/rapid7/insightconnect-plugins/blob/master/LICENSE vendor_url: https://www.microsoft.com tags: -- ldap -- active directory -- microsoft + - ldap + - active directory + - microsoft hub_tags: use_cases: [user_management, credential_management, application_management, threat_detection_and_response] keywords: [ldap, microsoft] features: [] sdk: - type: full + type: slim version: 5 user: nobody types: @@ -274,7 +274,7 @@ actions: description: Results returned type: '[]result' required: false - example: '[ { "dn": string, "attributes": { "pwdLastSet": date, "objectClass": [ string, string, string, string ], "memberOf": [ string ], "sAMAccountType": int, "uSNChanged": int, "givenName": string, "userPrincipalName": string, "countryCode": int, "lastLogon": date, "sAMAccountName": string, "name": string, "primaryGroupID": int, "dSCorePropagationData": [ date ], "displayName": string, "logonCount": int, "cn": string, "objectSid": string, "codePage": int, "badPwdCount": int, "objectGUID": string, "distinguishedName": string, "whenChanged": date, "badPasswordTime": date, "instanceType": int, "uSNCreated": int, "sn": string, "whenCreated": date, "accountExpires": date, "userAccountControl": int, "lastLogoff": date, "objectCategory": "string" } } ]' + example: '[{"dn":"string","attributes":{"pwdLastSet":"date","objectClass":["string","string","string","string"],"memberOf":["string"],"sAMAccountType":"int","uSNChanged":"int","givenName":"string","userPrincipalName":"string","countryCode":"int","lastLogon":"date","sAMAccountName":"string","name":"string","primaryGroupID":"int","dSCorePropagationData":["date"],"displayName":"string","logonCount":"int","cn":"string","objectSid":"string","codePage":"int","badPwdCount":"int","objectGUID":"string","distinguishedName":"string","whenChanged":"date","badPasswordTime":"date","instanceType":"int","uSNCreated":"int","sn":"string","whenCreated":"date","accountExpires":"date","userAccountControl":"int","lastLogoff":"date","objectCategory":"string"}}]' count: title: Count description: Number of results diff --git a/plugins/active_directory_ldap/setup.py b/plugins/active_directory_ldap/setup.py index f1c7b7bc76..f5609c3073 100755 --- a/plugins/active_directory_ldap/setup.py +++ b/plugins/active_directory_ldap/setup.py @@ -3,7 +3,7 @@ setup(name="active_directory_ldap-rapid7-plugin", - version="9.0.0", + version="9.0.1", description="This plugin utilizes Microsoft's Active Directory service to create and manage domains, users, and objects within a network", author="rapid7", author_email="", diff --git a/plugins/active_directory_ldap/unit_test/common.py b/plugins/active_directory_ldap/unit_test/common.py index 57c884055a..a2e7ab9849 100644 --- a/plugins/active_directory_ldap/unit_test/common.py +++ b/plugins/active_directory_ldap/unit_test/common.py @@ -3,15 +3,11 @@ import logging import ldap3 -from ldap3.core.connection import SyncStrategy -from ldap3.core.exceptions import LDAPInvalidDnError -from ldap3.core.exceptions import LDAPObjectClassError -from ldap3.core.exceptions import LDAPOperationsErrorResult -from ldap3.core.results import RESULT_OPERATIONS_ERROR -from ldap3.core.results import RESULT_SUCCESS - from komand_active_directory_ldap import connection from komand_active_directory_ldap.connection.schema import Input +from ldap3.core.connection import SyncStrategy +from ldap3.core.exceptions import LDAPInvalidDnError, LDAPObjectClassError, LDAPOperationsErrorResult +from ldap3.core.results import RESULT_OPERATIONS_ERROR, RESULT_SUCCESS class MockConnection: diff --git a/plugins/active_directory_ldap/unit_test/test_action_add_user.py b/plugins/active_directory_ldap/unit_test/test_add_user.py similarity index 94% rename from plugins/active_directory_ldap/unit_test/test_action_add_user.py rename to plugins/active_directory_ldap/unit_test/test_add_user.py index 5aaa45c584..b7e42aa55d 100644 --- a/plugins/active_directory_ldap/unit_test/test_action_add_user.py +++ b/plugins/active_directory_ldap/unit_test/test_add_user.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.add_user import AddUser from komand_active_directory_ldap.actions.add_user.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionAddUser(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_delete.py b/plugins/active_directory_ldap/unit_test/test_delete.py similarity index 92% rename from plugins/active_directory_ldap/unit_test/test_action_delete.py rename to plugins/active_directory_ldap/unit_test/test_delete.py index 9280b69899..8e2fc85e32 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_delete.py +++ b/plugins/active_directory_ldap/unit_test/test_delete.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.delete import Delete from komand_active_directory_ldap.actions.delete.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionDelete(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_disable_user.py b/plugins/active_directory_ldap/unit_test/test_disable_user.py similarity index 96% rename from plugins/active_directory_ldap/unit_test/test_action_disable_user.py rename to plugins/active_directory_ldap/unit_test/test_disable_user.py index e43130f483..33d0bf506a 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_disable_user.py +++ b/plugins/active_directory_ldap/unit_test/test_disable_user.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.disable_user import DisableUser from komand_active_directory_ldap.actions.disable_user.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionDisableUser(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_disable_users.py b/plugins/active_directory_ldap/unit_test/test_disable_users.py similarity index 96% rename from plugins/active_directory_ldap/unit_test/test_action_disable_users.py rename to plugins/active_directory_ldap/unit_test/test_disable_users.py index 154c73818f..a3a0b3248b 100644 --- a/plugins/active_directory_ldap/unit_test/test_action_disable_users.py +++ b/plugins/active_directory_ldap/unit_test/test_disable_users.py @@ -1,12 +1,11 @@ -from parameterized import parameterized - from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.disable_users import DisableUsers from komand_active_directory_ldap.actions.disable_users.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector +from parameterized import parameterized + +from common import MockConnection, MockServer, default_connector class TestActionDisableUsers(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_enable_user.py b/plugins/active_directory_ldap/unit_test/test_enable_user.py similarity index 96% rename from plugins/active_directory_ldap/unit_test/test_action_enable_user.py rename to plugins/active_directory_ldap/unit_test/test_enable_user.py index c669cddec2..086abb71a5 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_enable_user.py +++ b/plugins/active_directory_ldap/unit_test/test_enable_user.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.enable_user import EnableUser from komand_active_directory_ldap.actions.enable_user.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionEnableUser(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_enable_users.py b/plugins/active_directory_ldap/unit_test/test_enable_users.py similarity index 96% rename from plugins/active_directory_ldap/unit_test/test_action_enable_users.py rename to plugins/active_directory_ldap/unit_test/test_enable_users.py index f60978d716..209dca8b34 100644 --- a/plugins/active_directory_ldap/unit_test/test_action_enable_users.py +++ b/plugins/active_directory_ldap/unit_test/test_enable_users.py @@ -1,11 +1,11 @@ -from parameterized import parameterized from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.enable_users import EnableUsers from komand_active_directory_ldap.actions.enable_users.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector +from parameterized import parameterized + +from common import MockConnection, MockServer, default_connector class TestActionEnableUsers(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_escape_brackets_formatter.py b/plugins/active_directory_ldap/unit_test/test_escape_brackets_formatter.py index 9f66f6e09a..436713c9d3 100644 --- a/plugins/active_directory_ldap/unit_test/test_escape_brackets_formatter.py +++ b/plugins/active_directory_ldap/unit_test/test_escape_brackets_formatter.py @@ -1,6 +1,5 @@ from unittest import TestCase - from komand_active_directory_ldap.util.utils import ADUtils from parameterized import parameterized diff --git a/plugins/active_directory_ldap/unit_test/test_action_force_password_reset.py b/plugins/active_directory_ldap/unit_test/test_force_password_reset.py similarity index 93% rename from plugins/active_directory_ldap/unit_test/test_action_force_password_reset.py rename to plugins/active_directory_ldap/unit_test/test_force_password_reset.py index de54027aac..7da3629549 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_force_password_reset.py +++ b/plugins/active_directory_ldap/unit_test/test_force_password_reset.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.force_password_reset import ForcePasswordReset from komand_active_directory_ldap.actions.force_password_reset.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionForcePasswordReset(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_host_formatter.py b/plugins/active_directory_ldap/unit_test/test_host_formatter.py index f0379a81a3..9ae5580d9a 100644 --- a/plugins/active_directory_ldap/unit_test/test_host_formatter.py +++ b/plugins/active_directory_ldap/unit_test/test_host_formatter.py @@ -4,8 +4,8 @@ from komand_active_directory_ldap import connection from komand_active_directory_ldap.connection.schema import Input from komand_active_directory_ldap.util.api import ActiveDirectoryLdapAPI -from common import MockConnection -from common import MockServer + +from common import MockConnection, MockServer class TestHostFormatter(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_modify_groups.py b/plugins/active_directory_ldap/unit_test/test_modify_groups.py similarity index 96% rename from plugins/active_directory_ldap/unit_test/test_action_modify_groups.py rename to plugins/active_directory_ldap/unit_test/test_modify_groups.py index f572422211..9444854bdc 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_modify_groups.py +++ b/plugins/active_directory_ldap/unit_test/test_modify_groups.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.modify_groups import ModifyGroups from komand_active_directory_ldap.actions.modify_groups.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionModifyGroups(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_modify_object.py b/plugins/active_directory_ldap/unit_test/test_modify_object.py similarity index 94% rename from plugins/active_directory_ldap/unit_test/test_action_modify_object.py rename to plugins/active_directory_ldap/unit_test/test_modify_object.py index 02b653c13b..821397d2ec 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_modify_object.py +++ b/plugins/active_directory_ldap/unit_test/test_modify_object.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.modify_object import ModifyObject from komand_active_directory_ldap.actions.modify_object.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionModifyObject(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_move_object.py b/plugins/active_directory_ldap/unit_test/test_move_object.py similarity index 91% rename from plugins/active_directory_ldap/unit_test/test_action_move_object.py rename to plugins/active_directory_ldap/unit_test/test_move_object.py index 5102716306..4887426d97 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_move_object.py +++ b/plugins/active_directory_ldap/unit_test/test_move_object.py @@ -1,9 +1,9 @@ from unittest import TestCase, mock + from komand_active_directory_ldap.actions.move_object import MoveObject from komand_active_directory_ldap.actions.move_object.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionMoveObject(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_query.py b/plugins/active_directory_ldap/unit_test/test_query.py similarity index 91% rename from plugins/active_directory_ldap/unit_test/test_action_query.py rename to plugins/active_directory_ldap/unit_test/test_query.py index fe6fafffe9..8d525197c3 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_query.py +++ b/plugins/active_directory_ldap/unit_test/test_query.py @@ -1,9 +1,9 @@ from unittest import TestCase, mock + from komand_active_directory_ldap.actions.query import Query from komand_active_directory_ldap.actions.query.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionQuery(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_query_group_membership.py b/plugins/active_directory_ldap/unit_test/test_query_group_membership.py similarity index 96% rename from plugins/active_directory_ldap/unit_test/test_action_query_group_membership.py rename to plugins/active_directory_ldap/unit_test/test_query_group_membership.py index bd1cb8f62a..0c469f3cc2 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_query_group_membership.py +++ b/plugins/active_directory_ldap/unit_test/test_query_group_membership.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.query_group_membership import QueryGroupMembership from komand_active_directory_ldap.actions.query_group_membership.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionQueryGroupMembership(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_reset_password.py b/plugins/active_directory_ldap/unit_test/test_reset_password.py similarity index 95% rename from plugins/active_directory_ldap/unit_test/test_action_reset_password.py rename to plugins/active_directory_ldap/unit_test/test_reset_password.py index 7e5bc5a71f..1212303e56 100755 --- a/plugins/active_directory_ldap/unit_test/test_action_reset_password.py +++ b/plugins/active_directory_ldap/unit_test/test_reset_password.py @@ -1,10 +1,10 @@ from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException from komand_active_directory_ldap.actions.reset_password import ResetPassword from komand_active_directory_ldap.actions.reset_password.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector + +from common import MockConnection, MockServer, default_connector class TestActionResetPassword(TestCase): diff --git a/plugins/active_directory_ldap/unit_test/test_action_unlock_user.py b/plugins/active_directory_ldap/unit_test/test_unlock_user.py similarity index 97% rename from plugins/active_directory_ldap/unit_test/test_action_unlock_user.py rename to plugins/active_directory_ldap/unit_test/test_unlock_user.py index 071dcb18c9..5ab93bb9c9 100644 --- a/plugins/active_directory_ldap/unit_test/test_action_unlock_user.py +++ b/plugins/active_directory_ldap/unit_test/test_unlock_user.py @@ -1,12 +1,12 @@ +import logging from unittest import TestCase, mock + from insightconnect_plugin_runtime.exceptions import PluginException -from komand_active_directory_ldap.actions.unlock_user import UnlockUser from komand_active_directory_ldap.actions.enable_user.schema import Input, Output -from common import MockConnection -from common import MockServer -from common import default_connector +from komand_active_directory_ldap.actions.unlock_user import UnlockUser from komand_active_directory_ldap.connection import Connection -import logging + +from common import MockConnection, MockServer, default_connector class TestActionUnlockUser(TestCase):