Skip to content

Commit

Permalink
Fixes contains handling of JValue string #2531 (#2533)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Nov 14, 2023
1 parent 2b5339a commit abf0a9a
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ What's changed since v1.31.0:
- Fixed additional non-sensitive parameter name patterns by `Azure.Deployment.SecureParameter` by @BernieWhite.
[#2528](https://github.com/Azure/PSRule.Rules.Azure/issues/2528)
- Added support for configuration of the rule by setting `AZURE_DEPLOYMENT_NONSENSITIVE_PARAMETER_NAMES`.
- Fixed incorrect handling of expressions with contains with JValue string by @BernieWhite.
[#2531](https://github.com/Azure/PSRule.Rules.Azure/issues/2531)

## v1.31.0

Expand Down
4 changes: 2 additions & 2 deletions src/PSRule.Rules.Azure/Data/Template/Functions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2177,8 +2177,8 @@ private static bool HasChild(object value, object child)
{
if (ExpressionHelpers.TryArray(value, out var array))
return Contains(array, child);
else if (value is string svalue)
return svalue.Contains(child.ToString());
else if (ExpressionHelpers.TryString(value, out var s))
return s.Contains(child.ToString());
else if (value is JObject jObject)
return jObject.ContainsKeyInsensitive(child.ToString());

Expand Down
4 changes: 4 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/FunctionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public void Contains()
// String
Assert.True((bool)Functions.Contains(context, new object[] { "OneTwoThree", "e" }));
Assert.False((bool)Functions.Contains(context, new object[] { "OneTwoThree", "z" }));
Assert.True((bool)Functions.Contains(context, new object[] { "abcd", new JValue("bc") }));
Assert.False((bool)Functions.Not(context, new object[] { Functions.Contains(context, new object[] { "abcd", new JValue("bc") }) }));
Assert.True((bool)Functions.Contains(context, new object[] { new JValue("abcd"), new JValue("bc") }));
Assert.False((bool)Functions.Not(context, new object[] { Functions.Contains(context, new object[] { new JValue("abcd"), new JValue("bc") }) }));

// Object
Assert.True((bool)Functions.Contains(context, new object[] { JObject.Parse("{ \"one\": \"a\", \"two\": \"b\", \"three\": \"c\" }"), "two" }));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@
<None Update="Tests.Bicep.3.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Tests.Bicep.30.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Tests.Bicep.4.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
15 changes: 15 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/TemplateVisitorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,21 @@ public void MockWellKnownProperties()
Assert.Equal("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/providers/Microsoft.Web/locations/eastus/managedApis/servicebus", actual["properties"]["api"]["id"].Value<string>());
}

[Fact]
public void ContainsWithJValue()
{
var resources = ProcessTemplate(GetSourcePath("Tests.Bicep.30.json"), null, out _);
Assert.Equal(3, resources.Length);

var actual = resources[2];
Assert.Equal("Microsoft.ManagedIdentity/userAssignedIdentities", actual["type"].Value<string>());
Assert.False(actual["properties"]["doesNotContain"].Value<bool>());
Assert.True(actual["properties"]["doesContain"].Value<bool>());
Assert.Equal(1, actual["properties"]["indexOfSubstring"].Value<int>());
Assert.Equal("abcd", actual["properties"]["stringToCheck"].Value<string>());
Assert.Equal("bc", actual["properties"]["stringToFind"].Value<string>());
}

#region Helper methods

private static string GetSourcePath(string fileName)
Expand Down
36 changes: 36 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Tests.Bicep.30.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// Community provided sample from: https://github.com/Azure/PSRule.Rules.Azure/issues/2531

var stringToCheck = 'abcd'
var stringToFind = 'bc'
var doesNotContain = !(contains(stringToCheck, stringToFind))
var doesContain = contains(stringToCheck, stringToFind)
var indexOfSubstring = indexOf(stringToCheck, stringToFind)

#disable-next-line BCP081 no-deployments-resources
resource taskDeployment 'Microsoft.Resources/deployments@2020-10-01' = {
name: 'name'
properties: {
mode: 'Incremental'
template: {
'$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
contentVersion: '1.0.0.0'
resources: [
{
apiVersion: '2019-12-01'
type: 'Microsoft.ManagedIdentity/userAssignedIdentities'
name: 'test'
properties: {
doesNotContain: doesNotContain
doesContain: doesContain
indexOfSubstring: indexOfSubstring
stringToCheck: stringToCheck
stringToFind: stringToFind
}
}
]
}
}
}
46 changes: 46 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Tests.Bicep.30.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.23.1.45101",
"templateHash": "15051303941734638046"
}
},
"variables": {
"stringToCheck": "abcd",
"stringToFind": "bc",
"doesNotContain": "[not(contains(variables('stringToCheck'), variables('stringToFind')))]",
"doesContain": "[contains(variables('stringToCheck'), variables('stringToFind'))]",
"indexOfSubstring": "[indexOf(variables('stringToCheck'), variables('stringToFind'))]"
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-10-01",
"name": "name",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2019-12-01",
"type": "Microsoft.ManagedIdentity/userAssignedIdentities",
"name": "test",
"properties": {
"doesNotContain": "[variables('doesNotContain')]",
"doesContain": "[variables('doesContain')]",
"indexOfSubstring": "[variables('indexOfSubstring')]",
"stringToCheck": "[variables('stringToCheck')]",
"stringToFind": "[variables('stringToFind')]"
}
}
]
}
}
}
]
}

0 comments on commit abf0a9a

Please sign in to comment.