diff --git a/README.md b/README.md index 46649900..49d18c7b 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ be on your way to contributing! ## Changelog +* 2.46.2 - Fixed VersionValidator regex failing to validate x0.x.x semantic version strings * 2.46.1 - Add null variable check to example input validator * 2.46.0 - Add new help.md validator to ensure there are key features, links, and examples * 2.45.0 - Separated UseCaseValidator for workflows as plugins and workflows now have different usecase tags diff --git a/icon_validator/rules/plugin_validators/version_validator.py b/icon_validator/rules/plugin_validators/version_validator.py index f97a2f36..62141631 100644 --- a/icon_validator/rules/plugin_validators/version_validator.py +++ b/icon_validator/rules/plugin_validators/version_validator.py @@ -9,7 +9,7 @@ class VersionValidator(KomandPluginValidator): @staticmethod def validate_version(version): - if re.match("[1-9]+.[0-9]+.[0-9]+$", version) is None: + if re.match("^[1-9][0-9]*.[0-9]+.[0-9]+$", version) is None: raise ValidationException("Version does not match required semver format. " "Version should be in form X.Y.Z with X, Y, and Z " "being numbers. No special characters or spaces allowed. " @@ -35,7 +35,7 @@ def validate_plugin_version(spec): def validate_version_bump_needed(spec): plugin_name = spec.spec_dictionary()["name"] response = requests.get( - url=f"https://extensions-api.rapid7.com/v1/public/extensions/{plugin_name}", + url=f"https://extensions-api.rapid7.com/v2/public/extensions/{plugin_name}", timeout=3 ) if response.status_code == 404: diff --git a/setup.py b/setup.py index b945b6ac..43376c44 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name="insightconnect_integrations_validators", - version="2.46.1", + version="2.46.2", description="Validator tooling for InsightConnect integrations", long_description=long_description, long_description_content_type="text/markdown", diff --git a/unit_test/plugin_examples/version_validator/plugin.spec_bad.yaml b/unit_test/plugin_examples/version_validator/plugin.spec_bad.yaml index e8e41a07..b67891a6 100755 --- a/unit_test/plugin_examples/version_validator/plugin.spec_bad.yaml +++ b/unit_test/plugin_examples/version_validator/plugin.spec_bad.yaml @@ -1,3 +1,3 @@ plugin_spec_version: v2 name: active_directory_ldap -version: 5.2.0 \ No newline at end of file +version: 5.3.3 diff --git a/unit_test/plugin_examples/version_validator/plugin.spec_ten.yaml b/unit_test/plugin_examples/version_validator/plugin.spec_ten.yaml new file mode 100755 index 00000000..4b9df713 --- /dev/null +++ b/unit_test/plugin_examples/version_validator/plugin.spec_ten.yaml @@ -0,0 +1,258 @@ +plugin_spec_version: v2 +extension: plugin +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: 10.0.0 +vendor: rapid7 +support: microsoft +status: [] +resources: + source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/active_directory_ldap + license_url: https://github.com/rapid7/insightconnect-plugins/blob/master/LICENSE + vendor_url: https://www.microsoft.com +tags: +- ldap +- active directory +- microsoft +hub_tags: + use_cases: [user_management, credential_management, application_management, threat_detection_and_response] + keywords: [ldap, active directory, microsoft] + features: [] +types: + result: + attributes: + type: object + dn: + type: string +connection: + host: + title: Host + description: Server Host, e.g. ldap://192.5.5.5. Must use either ldap:// or ldaps:// + for SSL prefix + type: string + required: true + port: + title: Port + description: Port, e.g. 389 + type: integer + default: 389 + required: true + use_ssl: + title: Use SSL + type: boolean + description: Use SSL? + required: true + username_password: + title: Username and Password + type: credential_username_password + description: Username and password + required: true +actions: + query: + title: Query + description: Run an LDAP query + input: + search_filter: + title: Search Filter + type: string + description: 'The filter of the search request. It must conform to the LDAP + filter syntax specified in RFC4515. Example: (accountName=joesmith)' + required: true + search_base: + title: Search Base + type: string + description: The base of the search request + required: true + output: + results: + description: Results returned + type: '[]result' + required: false + delete: + title: Delete + description: Deletes the LDAP object specified + input: + distinguished_name: + title: Distinguished Name + type: string + description: The distinguished name of the object to delete. Example CN=user,OU=domain_users,DC=mydomain,DC=com + required: true + output: + success: + description: Operation status + type: boolean + required: false + add_user: + title: Add + description: Adds the specified Active Directory user + input: + domain_name: + title: Domain Name + type: string + description: The domain name this user will belong to, e.g. mydomain.com + required: true + logon_name: + title: Logon Name + type: string + description: The logon name for the account + required: true + first_name: + title: First Name + type: string + description: User's first name + required: true + last_name: + title: Last Name + type: string + description: User's last name + required: true + user_ou: + title: User OU + type: string + description: The OU that the user account will be created in + required: true + default: Users + password: + title: Password + type: password + description: The account's starting password + required: true + account_disabled: + title: Account Disabled + type: string + enum: + - 'true' + - 'false' + description: Set this to true to disable the user account at creation + required: true + default: 'true' + user_principal_name: + title: User Principal Name + description: The users principal name, e.g. user@example.com + type: string + required: true + additional_parameters: + title: Additional Parameters + description: 'Add additional user parameters in JSON format e.g. {''telephoneNumber'': + ''(617)555-1234''}' + type: object + required: false + output: + success: + description: Operation status + type: boolean + required: false + enable_user: + title: Enable + description: Enable an account + input: + distinguished_name: + title: Distinguished Name + type: string + description: The distinguished name of the user to enable e.g. CN=user,OU=domain_users,DC=mydomain,DC=com + required: true + output: + success: + description: Operation status + type: boolean + required: false + disable_user: + title: Disable + description: Disable an account + input: + distinguished_name: + title: Distinguished Name + type: string + description: The distinguished name of the user to disable e.g. CN=user,OU=domain_users,DC=mydomain,DC=com + required: true + output: + success: + description: Operation status + type: boolean + required: false + modify_groups: + title: Modify Groups + description: Add or remove a user from an Active Directory group + input: + distinguished_name: + title: Distinguished Name + type: string + description: The distinguished name of the user whose membership will be modified + e.g. CN=user,OU=domain_users,DC=mydomain,DC=com + required: true + group_dn: + title: Group DN + type: string + description: The Distinguished Name of the group to add or remove + required: true + add_remove: + title: Add or Remove + description: Add or remove the group + type: string + enum: + - add + - remove + required: true + output: + success: + description: Operation status + type: boolean + required: false + move_object: + title: Move Object + description: Move an Active Directory object from one organizational unit to another + input: + distinguished_name: + title: Distinguished Name + type: string + description: The distinguished name of the user whose membership will be modified + e.g. CN=user,OU=domain_users,DC=mydomain,DC=com + required: true + new_ou: + title: New OU + type: string + description: The distinguished name of the OU to move the object to e.g. OU=disabled_users,DC=mydomain,DC=com + required: true + output: + success: + description: Operation status + type: boolean + required: false + reset_password: + title: Reset Password + description: Reset a users password + input: + distinguished_name: + title: Distinguished Name + type: string + description: The distinguished name of the user whose membership will be modified + e.g. CN=user,OU=domain_users,DC=mydomain,DC=com + required: true + new_password: + title: New Password + description: The new password + type: password + required: true + output: + success: + description: Operation status + type: boolean + required: false + force_password_reset: + title: Force Password Reset + description: Force a user to reset their password on next login + input: + distinguished_name: + title: Distinguished Name + type: string + description: The distinguished name of the user who will be forced to reset + their password e.g. CN=user,OU=domain_users,DC=mydomain,DC=com + required: true + output: + success: + title: Success + description: Operation status + type: boolean + required: false diff --git a/unit_test/test_validate_plugin.py b/unit_test/test_validate_plugin.py index 5c8d7baa..19cb2043 100644 --- a/unit_test/test_validate_plugin.py +++ b/unit_test/test_validate_plugin.py @@ -112,10 +112,17 @@ def test_version_validator(self): result = validate(directory_to_test, file_to_test, False, True, [VersionValidator()]) self.assertEqual(result, 0) - def test_version_validator_should_faile_when_version_same_in_api(self): + def test_version_validator_major_version_ten(self): + # example workflow in plugin_examples directory. Run tests with these files + directory_to_test = "plugin_examples/version_validator" + file_to_test = "plugin.spec_ten.yaml" + result = validate(directory_to_test, file_to_test, False, True, [VersionValidator()]) + self.assertEqual(result, 0) + + def test_version_validator_should_fail_when_version_same_in_api(self): # example workflow in plugin_examples directory. Run tests with these files version = requests.get( - url=f"https://extensions-api.rapid7.com/v1/public/extensions/active_directory_ldap", + url=f"https://extensions-api.rapid7.com/v2/public/extensions/active_directory_ldap", timeout=3 ).json()["version"]