diff --git a/PiHoleShell/PiHoleShell.psd1 b/PiHoleShell/PiHoleShell.psd1 index 63feccc..12c97c9 100644 Binary files a/PiHoleShell/PiHoleShell.psd1 and b/PiHoleShell/PiHoleShell.psd1 differ diff --git a/PiHoleShell/Private/Misc.ps1 b/PiHoleShell/Private/Misc.ps1 index b0c7772..b75175c 100644 --- a/PiHoleShell/Private/Misc.ps1 +++ b/PiHoleShell/Private/Misc.ps1 @@ -45,4 +45,29 @@ function Convert-LocalTimeToPiHoleUnixTime { $ObjectFinal = $Object Write-Output $ObjectFinal +} + +function Remove-PiHoleCurrentAuthSession { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification = "It removes sessions from PiHole only")] + [CmdletBinding()] + param ( + [System.URI]$PiHoleServer, + [string]$Sid, + [bool]$IgnoreSsl = $false + ) + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/auth" + Method = "Delete" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + try { + Invoke-RestMethod @Params + } + + catch { + Write-Error -Message $_.Exception.Message + } } \ No newline at end of file diff --git a/PiHoleShell/Public/Authentication.ps1 b/PiHoleShell/Public/Authentication.ps1 index b3cc3a2..1a31236 100644 --- a/PiHoleShell/Public/Authentication.ps1 +++ b/PiHoleShell/Public/Authentication.ps1 @@ -115,32 +115,6 @@ Get-PiHoleCurrentAuthSession -PiHoleServer "http://pihole.domain.com:8080" -Pass } } -function Remove-PiHoleCurrentAuthSession { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification = "It removes sessions from PiHole only")] - #INTERNAL FUNCTION - [CmdletBinding()] - param ( - $PiHoleServer, - $Sid, - $IgnoreSsl = $false - ) - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/auth" - Method = "Delete" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - try { - Invoke-RestMethod @Params - } - - catch { - Write-Error -Message $_.Exception.Message - } -} - function Remove-PiHoleAuthSession { <# .SYNOPSIS diff --git a/PiHoleShell/Public/DnsControl.ps1 b/PiHoleShell/Public/DnsControl.ps1 index 146247d..e45c7fb 100644 --- a/PiHoleShell/Public/DnsControl.ps1 +++ b/PiHoleShell/Public/DnsControl.ps1 @@ -68,7 +68,6 @@ Get-PiHoleDnsBlockingStatus -PiHoleServer "http://pihole.domain.com:8080" -Passw } } - function Set-PiHoleDnsBlocking { <# .SYNOPSIS @@ -110,18 +109,18 @@ Set-PiHoleDnsBlocking -PiHoleServer "http://pihole.domain.com:8080" -Password "f try { $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - $Blocking = $Blocking.ToLower() + $Body = @{ + blocking = $Blocking + timer = $TimeInSeconds + } - $Body = "{`"blocking`":$Blocking,`"timer`":$TimeInSeconds}" $Params = @{ - Headers = @{sid = $($Sid) - Accept = "application/json" - } + Headers = @{sid = $($Sid) } Uri = "$($PiHoleServer.OriginalString)/api/dns/blocking" Method = "Post" - ContentType = "application/json" - Body = $Body SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + Body = $Body | ConvertTo-Json -Depth 10 } $Response = Invoke-RestMethod @Params @@ -141,7 +140,6 @@ Set-PiHoleDnsBlocking -PiHoleServer "http://pihole.domain.com:8080" -Password "f } Write-Output $ObjectFinal } - } catch { diff --git a/PiHoleShell/Public/FTLInformation.ps1 b/PiHoleShell/Public/FTLInformation.ps1 new file mode 100644 index 0000000..98beadf --- /dev/null +++ b/PiHoleShell/Public/FTLInformation.ps1 @@ -0,0 +1,135 @@ +function Get-PiHoleInfoMessage { + <# +.SYNOPSIS +Get Pi-hole diagnosis messages +Request Pi-hole diagnosis messages + #> + [CmdletBinding()] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/info/messages" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + foreach ($Item in $Response.messages) { + $Object = $null + $Object = [PSCustomObject]@{ + Id = $Item.id + Timestamp = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.timestamp).LocalTime + Type = $Item.type + Plain = $Item.plain + Html = $Item.html + + } + + Write-Verbose -Message "Name - $($Object.Id)" + Write-Verbose -Message "Timestamp - $($Object.Timestamp)" + Write-Verbose -Message "Type - $($Object.Type)" + Write-Verbose -Message "Plain - $($Object.Plain)" + Write-Verbose -Message "Html - $($Object.Html)" + $ObjectFinal += $Object + } + + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} + +function Get-PiHoleInfoHost { + <# +.SYNOPSIS +Get info about various host parameters +This API hook returns a collection of host infos. + + #> + #Work In Progress + [CmdletBinding()] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/info/host" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + foreach ($Item in $Response.host) { + $Object = $null + $Object = [PSCustomObject]@{ + DomainName = $Item.uname.domainname + Machine = $Item.uname.machine + NodeName = $Item.uname.nodename + Release = $Item.uname.release + SysName = $Item.uname.sysname + Version = $Item.uname.version + + } + $ObjectFinal += $Object + Write-Output $ObjectFinal + } + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/GroupManagement.ps1 b/PiHoleShell/Public/GroupManagement.ps1 index a7d3c7a..a874595 100644 --- a/PiHoleShell/Public/GroupManagement.ps1 +++ b/PiHoleShell/Public/GroupManagement.ps1 @@ -9,7 +9,7 @@ https://TODO [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] param ( [Parameter(Mandatory = $true)] - $PiHoleServer, + [System.URI]$PiHoleServer, [Parameter(Mandatory = $true)] $Password, $GroupName = $null, @@ -21,7 +21,7 @@ https://TODO $Params = @{ Headers = @{sid = $($Sid) } - Uri = "$PiHoleServer/api/groups" + Uri = "$($PiHoleServer.OriginalString)/api/groups" Method = "Get" SkipCertificateCheck = $IgnoreSsl ContentType = "application/json" @@ -137,6 +137,7 @@ https://TODO if ($RawOutput) { Write-Output $Response } + else { $ObjectFinal = @() $Object = [PSCustomObject]@{ diff --git a/PiHoleShell/Public/ListManagement.ps1 b/PiHoleShell/Public/ListManagement.ps1 new file mode 100644 index 0000000..7366e3d --- /dev/null +++ b/PiHoleShell/Public/ListManagement.ps1 @@ -0,0 +1,87 @@ +function Get-PiHoleList { + <# +.SYNOPSIS +https://TODO + + #> + #Work In Progress + [CmdletBinding()] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [System.URI]$List = $null, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Groups = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/lists/$List" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + foreach ($Item in $Response.lists) { + $GroupNames = [System.Collections.ArrayList]@() + foreach ($Group in $Item.groups) { + $GroupNames += ($Groups | Where-Object { $_.Id -eq $Group }).Name + } + + $Object = $null + if ($Item.date_updated -eq 0) { + $DateUpdated = $null + } + else { + $DateUpdated = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime + } + $Object = [PSCustomObject]@{ + Address = $Item.address + Comment = $Item.comment + Groups = $GroupNames + Enabled = $Item.enabled + Id = $Item.id + DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime + DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime + Type = $Item.type + DateUpdated = $DateUpdated + Number = $Item.number + InvalidDomains = $Item.invalid_domains + AbpEntries = $Item.abp_entries + Status = $Item.status + } + + $ObjectFinal += $Object + } + + Write-Output $ObjectFinal + + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/tests/Set-PiHoleDnsBlocking.Tests.ps1 b/tests/Set-PiHoleDnsBlocking.Tests.ps1 index 4f31a2f..a855059 100644 --- a/tests/Set-PiHoleDnsBlocking.Tests.ps1 +++ b/tests/Set-PiHoleDnsBlocking.Tests.ps1 @@ -1,13 +1,27 @@ + # Requires -Module Pester Describe 'Set-PiHoleDnsBlocking' { BeforeAll { + Import-Module .\PiHoleShell\PiHoleShell.psm1 + + Mock -CommandName Request-PiHoleAuth -MockWith { return 'mock-sid' } + Mock -CommandName Invoke-RestMethod -MockWith { + return @{ + blocking = 'false' + timer = 60 + } + } + Mock -CommandName Remove-PiHoleCurrentAuthSession + Mock -CommandName Format-PiHoleSecond -MockWith { + return @{ TimeInSeconds = 60 } + } # Sample input values $server = [uri]'http://pihole.local' $password = 'mock-password' $sid = 'mock-session-id' # Mock external functions - Mock -CommandName Request-PiHoleAuth -MockWith { return $sid } + Mock -CommandName Request-PiHoleAuth -MockWith { 'mock-sid' } Mock -CommandName Remove-PiHoleCurrentAuthSession Mock -CommandName Format-PiHoleSecond -MockWith { return @{ TimeInSeconds = 60 }