Skip to content

Commit

Permalink
Merge pull request #1399 from Badgerati/Issue-1361
Browse files Browse the repository at this point in the history
Replaces occurrences of New-Object with new()
  • Loading branch information
Badgerati authored Sep 22, 2024
2 parents d51eda6 + 7e97569 commit 473c9be
Show file tree
Hide file tree
Showing 39 changed files with 546 additions and 430 deletions.
13 changes: 13 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The following is a set of guidelines for contributing to Pode on GitHub. These a
- [Where-Object](#where-object)
- [Select-Object](#select-object)
- [Measure-Object](#measure-object)
- [New-Object](#new-object)

## Code of Conduct

Expand Down Expand Up @@ -245,3 +246,15 @@ Instead of using the `Measure-Object` commandlet, please use either the `.Length
(@(1, 2, 3)).Length
(@{ Name = 'Rick' }).Count
```

#### New-Object

Instead of using the `New-Object` commandlet, please use `::new()` as this is far faster than the former.

```powershell
# instead of
$stream = New-Object System.IO.MemoryStream
# do this
$stream = [System.IO.MemoryStream]::new()
```
10 changes: 3 additions & 7 deletions .github/workflows/PSScriptAnalyzer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# separate terms of service, privacy policy, and support
# documentation.
#
# https://github.com/microsoft/action-psscriptanalyzer
# https://github.com/microsoft/psscriptanalyzer-action
# For more information on PSScriptAnalyzer in general, see
# https://github.com/PowerShell/PSScriptAnalyzer

Expand Down Expand Up @@ -48,15 +48,11 @@ jobs:
- name: Run PSScriptAnalyzer
uses: microsoft/psscriptanalyzer-action@6b2948b1944407914a58661c49941824d149734f
with:
# Check https://github.com/microsoft/action-psscriptanalyzer for more info about the options.
# The below set up runs PSScriptAnalyzer to your entire repository and runs some basic security rules.
path: .\
path: .\src
recurse: true
# Include your own basic security rules. Removing this option will run all the rules
includeRule: '"PSAvoidUsingCmdletAliases" ,"PSAvoidUsingPlainTextForPassword","PSAvoidUsingWriteHost","PSAvoidUsingInvokeExpression","PSUseShouldProcessForStateChangingFunctions","PSAvoidUsingUsernameAndPasswordParams","PSUseProcessBlockForPipelineCommand","PSAvoidUsingConvertToSecureStringWithPlainText","PSUseSingularNouns","PSReviewUnusedParameter"'
settings: .\PSScriptAnalyzerSettings.psd1
output: results.sarif

# Upload the SARIF file generated in the previous step
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v3
with:
Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"powershell.codeFormatting.whitespaceBetweenParameters": false,
"powershell.codeFormatting.whitespaceInsideBrace": true,
"powershell.scriptAnalysis.settingsPath": "PSScriptAnalyzerSettings.psd1",
"powershell.scriptAnalysis.enable": true,
"files.trimTrailingWhitespace": true,
"files.associations": {
"*.pode": "html"
Expand Down
26 changes: 20 additions & 6 deletions PSScriptAnalyzerSettings.psd1
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
# PSScriptAnalyzerSettings.psd1
@{
Severity = @('Error', 'Warning', 'Information')
Severity = @('Error', 'Warning', 'Information')
IncludeDefaultRules = $true

Rules = @{
CustomRulePath = @(
'./analyzers/AvoidNewObjectRule.psm1'
)

Rules = @{
PSReviewUnusedParameter = @{
CommandsToTraverse = @(
'Where-Object','Remove-PodeRoute'
'Where-Object',
'Remove-PodeRoute'
)
}
AvoidNewObjectRule = @{
Severity = 'Warning'
}
}
ExcludeRules = @( 'PSAvoidUsingPlainTextForPassword','PSUseShouldProcessForStateChangingFunctions',
'PSAvoidUsingUsernameAndPasswordParams','PSUseProcessBlockForPipelineCommand','PSAvoidUsingConvertToSecureStringWithPlainText','PSReviewUnusedParameter' ,'PSAvoidAssignmentToAutomaticVariable')

ExcludeRules = @(
'PSAvoidUsingPlainTextForPassword',
'PSUseShouldProcessForStateChangingFunctions',
'PSAvoidUsingUsernameAndPasswordParams',
'PSUseProcessBlockForPipelineCommand',
'PSAvoidUsingConvertToSecureStringWithPlainText',
'PSReviewUnusedParameter'
)
}
38 changes: 38 additions & 0 deletions analyzers/AvoidNewObjectRule.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
function Measure-AvoidNewObjectRule {
[CmdletBinding()]
[OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.ScriptBlockAst]
$ScriptBlockAst
)

# Initialize an empty array to collect diagnostic records
$diagnostics = @()

try {
# Traverse the AST to find all instances of New-Object cmdlet
$ScriptBlockAst.FindAll({
param($Ast)
$Ast -is [System.Management.Automation.Language.CommandAst] -and
$Ast.CommandElements[0].Extent.Text -eq 'New-Object'
}, $true) | ForEach-Object {
$diagnostics += [PSCustomObject]@{
Message = "Avoid using 'New-Object' and use '::new()' instead."
Extent = $_.Extent
RuleName = 'AvoidNewObjectRule'
Severity = 'Warning'
ScriptName = $FileName
}
}

# Return the diagnostic records
return $diagnostics
}
catch {
$PSCmdlet.ThrowTerminatingError($PSItem)
}
}

Export-ModuleMember -Function Measure-AvoidNewObjectRule
22 changes: 11 additions & 11 deletions docs/Servers/TCP.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,14 @@ Start-PodeServer {

Verbs will be passed the `$TcpEvent` object, that contains the Request, Response, and other properties:

| Name | Type | Description |
| ---- | ---- | ----------- |
| Request | object | The raw Request object |
| Response | object | The raw Response object |
| Lockable | hashtable | A synchronized hashtable that can be used with `Lock-PodeObject` |
| Endpoint | hashtable | Contains the Address and Protocol of the endpoint being hit - such as "pode.example.com" or "127.0.0.2", or HTTP or HTTPS for the Protocol |
| Parameters | hashtable | Contains the parsed parameter values from the Verb's path |
| Timestamp | datetime | The current date and time of the Request |
| Name | Type | Description |
| ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Request | object | The raw Request object |
| Response | object | The raw Response object |
| Lockable | hashtable | A synchronized hashtable that can be used with `Lock-PodeObject` |
| Endpoint | hashtable | Contains the Address and Protocol of the endpoint being hit - such as "pode.example.com" or "127.0.0.2", or HTTP or HTTPS for the Protocol |
| Parameters | hashtable | Contains the parsed parameter values from the Verb's path |
| Timestamp | datetime | The current date and time of the Request |

## Test Send

Expand All @@ -189,11 +189,11 @@ The following function can be used to test sending messages to a TCP server. Thi
function Send-TCPMessage($Endpoint, $Port, $Message) {
# Setup connection
$Address = [System.Net.IPAddress]::Parse([System.Net.Dns]::GetHostAddresses($EndPoint))
$Socket = New-Object System.Net.Sockets.TCPClient($Address,$Port)
$Socket = [System.Net.Sockets.TcpClient]::new($Address, $Port)
# Setup stream wrtier
# Setup stream writer
$Stream = $Socket.GetStream()
$Writer = New-Object System.IO.StreamWriter($Stream)
$Writer = [System.IO.StreamWriter]::new($Stream)
# Write message to stream
$Writer.WriteLine($Message)
Expand Down
34 changes: 17 additions & 17 deletions docs/Tutorials/Authentication/Inbuilt/UserFile.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ The default users file is `./users.json` at the root of the server. You can supp

The users file is a JSON array of user objects, each user object must contain the following (metadata is optional):

| Name | Type | Description |
| ---- | ---- | ----------- |
| Username | string | The user's username |
| Name | string | The user's fullname |
| Email | string | The user's email address |
| Password | string | Either a SHA256 or an HMAC SHA256 of the user's password |
| Groups | string[] | An array of groups which the the user is a member |
| Metadata | psobject | Custom metadata for the user |
| Name | Type | Description |
| -------- | -------- | -------------------------------------------------------- |
| Username | string | The user's username |
| Name | string | The user's fullname |
| Email | string | The user's email address |
| Password | string | Either a SHA256 or an HMAC SHA256 of the user's password |
| Groups | string[] | An array of groups which the the user is a member |
| Metadata | psobject | Custom metadata for the user |

For example:

Expand Down Expand Up @@ -66,7 +66,7 @@ Regardless of whether the password is a standard SHA256 hash or HMAC hash, the h
```powershell
function ConvertTo-SHA256([string]$String)
{
$SHA256 = New-Object System.Security.Cryptography.SHA256Managed
$SHA256 = [System.Security.Cryptography.SHA256Managed]::new()
$SHA256Hash = $SHA256.ComputeHash([Text.Encoding]::ASCII.GetBytes($String))
$SHA256HashString = [Convert]::ToBase64String($SHA256Hash)
return $SHA256HashString
Expand All @@ -77,7 +77,7 @@ function ConvertTo-SHA256([string]$String)

```powershell
function ConvertTo-HMACSHA256([string]$String, [string]$Secret) {
$HMACSHA256 = New-Object System.Security.Cryptography.HMACSHA256
$HMACSHA256 = [System.Security.Cryptography.HMACSHA256]::new()
$HMACSHA256.Secret = [Text.Encoding]::ASCII.GetBytes($Secret)
$HMACSHA256Hash = $HMACSHA256.ComputeHash([Text.Encoding]::ASCII.GetBytes($String))
$HMACSHA256HashString = [Convert]::ToBase64String($HMACSHA256Hash)
Expand All @@ -89,13 +89,13 @@ function ConvertTo-HMACSHA256([string]$String, [string]$Secret) {

The User object returned, and accessible on Routes, and other functions via the [web event](../../../WebEvent)'s `$WebEvent.Auth.User` property, will contain the following information:

| Name | Type | Description |
| ---- | ---- | ----------- |
| Username | string | The user's username |
| Name | string | The user's fullname |
| Email | string | The user's email address |
| Groups | string[] | An array of groups which the the user is a member |
| Metadata | psobject | Custom metadata for the user |
| Name | Type | Description |
| -------- | -------- | ------------------------------------------------- |
| Username | string | The user's username |
| Name | string | The user's fullname |
| Email | string | The user's email address |
| Groups | string[] | An array of groups which the the user is a member |
| Metadata | psobject | Custom metadata for the user |

Such as:

Expand Down
4 changes: 2 additions & 2 deletions docs/Tutorials/Compression/Requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ $message = ($data | ConvertTo-Json)
$bytes = [System.Text.Encoding]::UTF8.GetBytes($message)
# compress the message using gzip
$ms = New-Object -TypeName System.IO.MemoryStream
$gzip = New-Object System.IO.Compression.GZipStream($ms, [IO.Compression.CompressionMode]::Compress, $true)
$ms = [System.IO.MemoryStream]::new()
$gzip = [System.IO.Compression.GZipStream]::new($ms, [IO.Compression.CompressionMode]::Compress, $true)
$gzip.Write($bytes, 0, $bytes.Length)
$gzip.Close()
$ms.Position = 0
Expand Down
2 changes: 1 addition & 1 deletion docs/Tutorials/Middleware/Types/Sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ For example, the following is a mock up of a Storage for Redis. Note that the fu

```powershell
# create the object
$store = New-Object -TypeName psobject
$store = [psobject]::new()
# add a Get property for retreiving a session's data by SessionId
$store | Add-Member -MemberType NoteProperty -Name Get -Value {
Expand Down
9 changes: 6 additions & 3 deletions examples/Web-Pages.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ try {
# Import the Pode module from the source path if it exists, otherwise from installed modules
if (Test-Path -Path "$($podePath)/src/Pode.psm1" -PathType Leaf) {
Import-Module "$($podePath)/src/Pode.psm1" -Force -ErrorAction Stop
} else {
}
else {
Import-Module -Name 'Pode' -MaximumVersion 2.99 -ErrorAction Stop
}
} catch { throw }
}
catch { throw }

# or just:
# Import-Module Pode
Expand Down Expand Up @@ -117,7 +119,8 @@ Start-PodeServer -Threads 2 -Verbose {
Add-PodeRoute -Method Get -Path '/redirect-port' -ScriptBlock {
if ($WebEvent.Request.Url.Port -ne 8086) {
Move-PodeResponseUrl -Port 8086
} else {
}
else {
Write-PodeJsonResponse -Value @{ 'value' = 'you got redirected!'; }
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Locales/ar/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,5 @@
scheduleProcessDoesNotExistExceptionMessage = 'عملية الجدول الزمني غير موجودة: {0}'
definitionTagChangeNotAllowedExceptionMessage = 'لا يمكن تغيير علامة التعريف لمسار.'
getRequestBodyNotAllowedExceptionMessage = 'لا يمكن أن تحتوي عمليات {0} على محتوى الطلب.'
unsupportedStreamCompressionEncodingExceptionMessage = 'تشفير الضغط غير مدعوم للتشفير {0}'
}
1 change: 1 addition & 0 deletions src/Locales/de/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,5 @@
scheduleProcessDoesNotExistExceptionMessage = "Der Aufgabenplanerprozess '{0}' existiert nicht."
definitionTagChangeNotAllowedExceptionMessage = 'Definitionstag für eine Route kann nicht geändert werden.'
getRequestBodyNotAllowedExceptionMessage = '{0}-Operationen können keinen Anforderungstext haben.'
unsupportedStreamCompressionEncodingExceptionMessage = 'Die Stream-Komprimierungskodierung wird nicht unterstützt: {0}'
}
Loading

0 comments on commit 473c9be

Please sign in to comment.