Skip to content

Commit 21269c8

Browse files
author
Quoc Truong
committed
Change logic to check for both CredentialAttribute and PSCredential type
1 parent f880cf1 commit 21269c8

8 files changed

+43
-41
lines changed

Rules/AvoidUserNameAndPasswordParams.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,9 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
5656
TypeInfo paramType = (TypeInfo)paramAst.StaticType;
5757
String paramName = paramAst.Name.VariablePath.ToString();
5858

59-
// if this is pscredential type, skip
60-
if (paramType == typeof(PSCredential) || (paramType.IsArray && paramType.GetElementType() == typeof (PSCredential)))
61-
{
62-
continue;
63-
}
64-
65-
// if this has credential attribute, skip
66-
if (paramAst.Attributes.Any(paramAttribute => paramAttribute.TypeName.GetReflectionType() == typeof(CredentialAttribute)))
59+
// if this is pscredential type with credential attribute, skip
60+
if ((paramType == typeof(PSCredential) || (paramType.IsArray && paramType.GetElementType() == typeof (PSCredential)))
61+
&& paramAst.Attributes.Any(paramAttribute => paramAttribute.TypeName.GetReflectionType() == typeof(CredentialAttribute)))
6762
{
6863
continue;
6964
}

Rules/Strings.Designer.cs

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rules/Strings.resx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,13 @@
217217
<value>One Char</value>
218218
</data>
219219
<data name="UsePSCredentialTypeDescription" xml:space="preserve">
220-
<value>Checks that cmdlets that have a Credential parameter accept PSCredential or has a CredentialAttribute. This comes from the PowerShell teams best practices.</value>
220+
<value>Checks that cmdlets that have a Credential parameter accept PSCredential with CredentialAttribute. This comes from the PowerShell teams best practices.</value>
221221
</data>
222222
<data name="UsePSCredentialTypeError" xml:space="preserve">
223-
<value>The Credential parameter in '{0}' must be of the type PSCredential or has a CredentialAttribute.</value>
223+
<value>The Credential parameter in '{0}' must be of the type PSCredential with CredentialAttribute.</value>
224224
</data>
225225
<data name="UsePSCredentialTypeErrorSB" xml:space="preserve">
226-
<value>The Credential parameter in a found script block must be of the type PSCredential or has a CredentialAttribute.</value>
226+
<value>The Credential parameter in a found script block must be of the type PSCredential with CredentialAttribute.</value>
227227
</data>
228228
<data name="UsePSCredentialTypeCommonName" xml:space="preserve">
229229
<value>PSCredential</value>
@@ -511,10 +511,10 @@
511511
<value>Avoid Using Username and Password Parameters</value>
512512
</data>
513513
<data name="AvoidUsernameAndPasswordParamsDescription" xml:space="preserve">
514-
<value>Functions should only take in a credential parameter of type PSCredential or has a CredentialAttribute instead of username and password parameters.</value>
514+
<value>Functions should only take in a credential parameter of type PSCredential with CredentialAttribute instead of username and password parameters.</value>
515515
</data>
516516
<data name="AvoidUsernameAndPasswordParamsError" xml:space="preserve">
517-
<value>Function '{0}' has both username and password parameters. A credential parameter of type PSCredential or has a CredentialAttribute should be used.</value>
517+
<value>Function '{0}' has both username and password parameters. A credential parameter of type PSCredential with a CredentialAttribute should be used.</value>
518518
</data>
519519
<data name="AvoidUsernameAndPasswordParamsName" xml:space="preserve">
520520
<value>AvoidUsingUserNameAndPassWordParams</value>

Rules/UsePSCredentialType.cs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//
1212

1313
using System;
14+
using System.Reflection;
1415
using System.Linq;
1516
using System.Collections.Generic;
1617
using System.Management.Automation;
@@ -51,9 +52,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
5152
{
5253
foreach (ParameterAst parameter in funcDefAst.Parameters)
5354
{
54-
if (parameter.Name.VariablePath.UserPath.Equals("Credential", StringComparison.OrdinalIgnoreCase)
55-
&& parameter.StaticType != typeof(PSCredential)
56-
&& !parameter.Attributes.Any(paramAttribute => paramAttribute.TypeName.GetReflectionType() == typeof(CredentialAttribute)))
55+
if (WrongCredentialUsage(parameter))
5756
{
5857
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.UsePSCredentialTypeError, funcName), funcDefAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
5958
}
@@ -64,9 +63,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
6463
{
6564
foreach (ParameterAst parameter in funcDefAst.Body.ParamBlock.Parameters)
6665
{
67-
if (parameter.Name.VariablePath.UserPath.Equals("Credential", StringComparison.OrdinalIgnoreCase)
68-
&& parameter.StaticType != typeof(PSCredential)
69-
&& !parameter.Attributes.Any(paramAttribute => paramAttribute.TypeName.GetReflectionType() == typeof(CredentialAttribute)))
66+
if (WrongCredentialUsage(parameter))
7067
{
7168
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.UsePSCredentialTypeError, funcName), funcDefAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
7269
}
@@ -80,9 +77,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
8077
{
8178
foreach (ParameterAst parameter in scriptBlockAst.ParamBlock.Parameters)
8279
{
83-
if (parameter.Name.VariablePath.UserPath.Equals("Credential", StringComparison.OrdinalIgnoreCase)
84-
&& parameter.StaticType != typeof(PSCredential)
85-
&& !parameter.Attributes.Any(paramAttribute => paramAttribute.TypeName.GetReflectionType() == typeof(CredentialAttribute)))
80+
if (WrongCredentialUsage(parameter))
8681
{
8782
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.UsePSCredentialTypeErrorSB), scriptBlockAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
8883
}
@@ -91,6 +86,24 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
9186
}
9287
}
9388

89+
private bool WrongCredentialUsage(ParameterAst parameter)
90+
{
91+
if (parameter.Name.VariablePath.UserPath.Equals("Credential", StringComparison.OrdinalIgnoreCase))
92+
{
93+
TypeInfo paramType = (TypeInfo)parameter.StaticType;
94+
95+
if ((paramType == typeof(PSCredential) || (paramType.IsArray && paramType.GetElementType() == typeof(PSCredential)))
96+
&& parameter.Attributes.Any(paramAttribute => paramAttribute.TypeName.GetReflectionType() == typeof(CredentialAttribute)))
97+
{
98+
return false;
99+
}
100+
101+
return true;
102+
}
103+
104+
return false;
105+
}
106+
94107
/// <summary>
95108
/// GetName: Retrieves the name of this rule.
96109
/// </summary>

Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Import-Module PSScriptAnalyzer
22

3-
$violationMessage = "Function 'Verb-Noun' has both username and password parameters. A credential parameter of type PSCredential or has a CredentialAttribute should be used."
3+
$violationMessage = "Function 'Verb-Noun' has both username and password parameters. A credential parameter of type PSCredential with a CredentialAttribute should be used."
44
$violationName = "PSAvoidUsingUserNameAndPasswordParams"
55
$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
66
$violations = Invoke-ScriptAnalyzer $directory\AvoidUserNameAndPasswordParams.ps1 | Where-Object {$_.RuleName -eq $violationName}

Tests/Rules/AvoidUserNameAndPasswordParamsNoViolations.ps1

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@ function MyFunction2 ($param1, $passwords)
88

99
}
1010

11-
function MyFunction3 ([PSCredential]$username, $passwords)
12-
{
13-
}
14-
15-
function MyFunction4
11+
function MyFunction3
1612
{
1713
[CmdletBinding()]
1814
[Alias()]
@@ -24,10 +20,11 @@ function MyFunction4
2420
ValueFromPipelineByPropertyName=$true,
2521
Position=0)]
2622
[System.Management.Automation.CredentialAttribute()]
23+
[pscredential]
2724
$UserName,
2825

2926
# Param2 help description
30-
[int]
27+
[pscredential]
3128
[System.Management.Automation.CredentialAttribute()]
3229
$Password
3330
)

Tests/Rules/PSCredentialType.tests.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Import-Module PSScriptAnalyzer
2-
$violationMessage = "The Credential parameter in 'Credential' must be of the type PSCredential or has a CredentialAttribute."
2+
$violationMessage = "The Credential parameter in 'Credential' must be of the type PSCredential with CredentialAttribute."
33
$violationName = "PSUsePSCredentialType"
44
$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
55
$violations = Invoke-ScriptAnalyzer $directory\PSCredentialType.ps1 | Where-Object {$_.RuleName -eq $violationName}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
function Credential([pscredential]$credential) {
2-
3-
}
4-
5-
function Credential2
1+
function Credential
62
{
73
[CmdletBinding()]
84
[Alias()]
@@ -14,6 +10,7 @@ function Credential2
1410
ValueFromPipelineByPropertyName=$true,
1511
Position=0)]
1612
[System.Management.Automation.CredentialAttribute()]
13+
[pscredential]
1714
$Credential
1815
)
19-
}
16+
}

0 commit comments

Comments
 (0)