Skip to content

Commit

Permalink
feat: allow validators for oauth fields (#1355)
Browse files Browse the repository at this point in the history
**Issue number:**
https://splunk.atlassian.net/browse/ADDON-61740
## Summary

allows validators to oauth fields
### Changes
allow validators array inside globalConfig.json scheme
> Please provide a summary of what's being changed

### User experience
right now oauth fields can be validated
> Please describe what the user experience looks like before and after
this change

## Checklist

If your change doesn't seem to apply, please leave them unchecked.

* [x] I have performed a self-review of this change
* [x] Changes have been tested
* [x] Changes are documented
* [x] PR title follows [conventional commit
semantics](https://www.conventionalcommits.org/en/v1.0.0/)
  • Loading branch information
soleksy-splunk authored Oct 15, 2024
1 parent 03df8b3 commit ef3b6a9
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 33 deletions.
1 change: 1 addition & 0 deletions docs/advanced/oauth_support.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Auth can be used inside the entity tag. Use `type: "oauth"` in the entity list a
- `encrypted` should be true if the user wants that particular field encrypted, otherwise, there is no need to have this parameter.
- `required` specifies whether the field is required or not. The default value is true.
- `defaultValue` is the initial input value (string, number, or boolean).
- `validators` array that is used to validate the values of fields using various [validators](../entity/validators.md).
- `options`:
+ `placeholder`: (RENOUNCED) The placeholder for the field.
+ `disableonEdit`: When the form is in edit mode, the field becomes unable to be edited. The default value is false.
Expand Down
64 changes: 35 additions & 29 deletions splunk_add_on_ucc_framework/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -595,35 +595,8 @@
"encrypted": {
"$ref": "#/definitions/encrypted"
},
"validators": {
"type": "array",
"description": "It is used to validate the values of fields using various validators.",
"minItems": 1,
"items": {
"anyOf": [
{
"$ref": "#/definitions/NumberValidator"
},
{
"$ref": "#/definitions/StringValidator"
},
{
"$ref": "#/definitions/RegexValidator"
},
{
"$ref": "#/definitions/EmailValidator"
},
{
"$ref": "#/definitions/Ipv4Validator"
},
{
"$ref": "#/definitions/UrlValidator"
},
{
"$ref": "#/definitions/DateValidator"
}
]
}
"validators":{
"$ref": "#/definitions/AnyValidator"
},
"options": {
"type": "object",
Expand Down Expand Up @@ -2114,6 +2087,9 @@
},
"modifyFieldsOnValue": {
"$ref": "#/definitions/modifyFieldsOnValue"
},
"validators":{
"$ref": "#/definitions/AnyValidator"
}
},
"additionalProperties": false
Expand Down Expand Up @@ -2354,6 +2330,36 @@
],
"additionalProperties": false
},
"AnyValidator":{
"type": "array",
"description": "It is used to validate the values of fields using various validators.",
"minItems": 1,
"items": {
"anyOf": [
{
"$ref": "#/definitions/NumberValidator"
},
{
"$ref": "#/definitions/StringValidator"
},
{
"$ref": "#/definitions/RegexValidator"
},
{
"$ref": "#/definitions/EmailValidator"
},
{
"$ref": "#/definitions/Ipv4Validator"
},
{
"$ref": "#/definitions/UrlValidator"
},
{
"$ref": "#/definitions/DateValidator"
}
]
}
},
"ValueLabelPair": {
"type": "object",
"description": "Options with a label and a value.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,15 @@
required=False,
encrypted=False,
default=None,
validator=None
validator=validator.AllOf(
validator.String(
max_len=4096,
min_len=10,
),
validator.Pattern(
regex=r"""^[a-zA-Z]\w*$""",
)
)
),
field.RestField(
'client_id',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,25 @@
{
"oauth_field": "some_text",
"label": "Disabled on edit for oauth",
"help": "Enter text for field disabled on edit",
"help": "Enter text for field disabled on edit, no special characters allowed",
"field": "basic_oauth_text",
"required": false,
"options": {
"disableonEdit": true
}
},
"validators": [
{
"type": "string",
"errorMsg": "Length should be between 10 and 4096",
"minLength": 10,
"maxLength": 4096
},
{
"type": "regex",
"errorMsg": "Do not use special characters",
"pattern": "^[a-zA-Z]\\w*$"
}
]
}
],
"oauth": [
Expand Down Expand Up @@ -1864,7 +1877,7 @@
"meta": {
"name": "Splunk_TA_UCCExample",
"restRoot": "splunk_ta_uccexample",
"version": "5.50.1+8cbb9b3c",
"version": "5.50.1+b4cfdcd44",
"displayName": "Splunk UCC test Add-on",
"schemaVersion": "0.0.8",
"_uccVersion": "5.50.1",
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/pages/account_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ def __init__(self, browser, container):
browser,
Selector(select='[data-test="control-group"][data-name="redirect_url"]'),
)
self.basic_oauth_text = TextBox(
browser,
Selector(
select='[data-test="control-group"][data-name="basic_oauth_text"]'
),
)
self.search_query = TextBox(
browser, Selector(select='[data-test="textbox"][role="textbox"]')
)
Expand Down
81 changes: 81 additions & 0 deletions tests/ui/test_configuration_page_account_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -1189,3 +1189,84 @@ def test_account_url_validation(
account.entity.save(expect_error=True),
"Invalid URL provided. URL should start with 'https' as only secure URLs are supported. Provide URL in this format", # noqa: E501
)

@pytest.mark.execute_enterprise_cloud_true
@pytest.mark.forwarder
@pytest.mark.input
def test_example_validation_of_oauth_fields_too_short(
self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper
):
"""Verifies required field client id"""
account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper)
account.entity.open()
account.entity.name.set_value(_ACCOUNT_CONFIG["name"])
account.entity.environment.select("Value2")
account.entity.account_radio.select("No")
account.entity.multiple_select.select("Option Two")
account.entity.username.set_value("TestClientId")
account.entity.password.set_value("ClientSecretTest")
account.entity.security_token.set_value("SecurityTokenTest")
account.entity.basic_oauth_text.set_value("Invalid")

self.assert_util(
account.entity.save,
"Length should be between 10 and 4096",
left_args={"expect_error": True},
)

@pytest.mark.execute_enterprise_cloud_true
@pytest.mark.forwarder
@pytest.mark.input
def test_example_validation_of_oauth_fields_wrong_characters(
self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper
):
"""Verifies required field client id"""
account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper)
account.entity.open()
account.entity.name.set_value(_ACCOUNT_CONFIG["name"])
account.entity.environment.select("Value2")
account.entity.account_radio.select("No")
account.entity.multiple_select.select("Option Two")
account.entity.username.set_value("TestClientId")
account.entity.password.set_value("ClientSecretTest")
account.entity.security_token.set_value("SecurityTokenTest")
account.entity.basic_oauth_text.set_value(
"Invalid due to special characters: !@#$%^&*()"
)

self.assert_util(
account.entity.save,
"Do not use special characters",
left_args={"expect_error": True},
)

@pytest.mark.execute_enterprise_cloud_true
@pytest.mark.forwarder
@pytest.mark.input
def test_example_validation_of_oauth_valid(
self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper
):
"""Verifies required field client id"""
account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper)
account.entity.open()
account.entity.name.set_value(_ACCOUNT_CONFIG["name"])
account.entity.environment.select("Value2")
account.entity.account_radio.select("No")
account.entity.multiple_select.select("Option Two")
account.entity.username.set_value("TestClientId")
account.entity.password.set_value("ClientSecretTest")
account.entity.security_token.set_value("SecurityTokenTest")
account.entity.basic_oauth_text.set_value("Valid_text_for_oauth")

self.assert_util(account.entity.save, True)

account.table.wait_for_rows_to_appear(1)

self.assert_util(
account.table.get_table()[_ACCOUNT_CONFIG["name"]],
{
"name": _ACCOUNT_CONFIG["name"],
"auth type": "basic",
"actions": "Edit | Clone | Delete",
},
)
1 change: 1 addition & 0 deletions ui/src/types/globalConfig/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ export const OAuthFields = z.object({
defaultValue: z.union([z.string(), z.number(), z.boolean()]).optional(),
options: CommonEditableEntityOptions.optional(),
modifyFieldsOnValue: ModifyFieldsOnValue,
validators: AllValidators.optional(),
});

export const OAuthEntity = CommonEditableEntityFields.extend({
Expand Down

0 comments on commit ef3b6a9

Please sign in to comment.