Public/Get-PAAccount.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
function Get-PAAccount {
    [CmdletBinding()]
    [OutputType('PoshACME.PAAccount')]
    param(
        [Parameter(ParameterSetName='Specific',Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateScript({Test-ValidFriendlyName $_ -ThrowOnFail})]
        [Alias('Name')]
        [string]$ID,
        [Parameter(ParameterSetName='List',Mandatory)]
        [switch]$List,
        [Parameter(ParameterSetName='List')]
        [ValidateSet('valid','deactivated','revoked')]
        [string]$Status,
        [Parameter(ParameterSetName='List')]
        [string[]]$Contact,
        [Parameter(ParameterSetName='List')]
        [ValidateScript({Test-ValidKeyLength $_ -ThrowOnFail})]
        [Alias('AccountKeyLength')]
        [string[]]$KeyLength,
        [switch]$Refresh,
        [Parameter(ValueFromRemainingArguments=$true)]
        $ExtraParams
    )

    Begin {
        # make sure we have a server configured
        if (-not ($server = Get-PAServer)) {
            try { throw "No ACME server configured. Run Set-PAServer first." }
            catch { $PSCmdlet.ThrowTerminatingError($_) }
        }

        # make sure the Contact emails have a "mailto:" prefix
        # this may get more complex later if ACME servers support more than email based contacts
        if ($Contact.Count -gt 0) {
            0..($Contact.Count-1) | ForEach-Object {
                if ($Contact[$_] -notlike 'mailto:*') {
                    $Contact[$_] = "mailto:$($Contact[$_])"
                }
            }
        }
    }

    Process {

        # List mode
        if ('List' -eq $PSCmdlet.ParameterSetName) {

            # update from the server first if requested
            if ($Refresh) {
                Write-Debug "Refreshing valid accounts"
                Get-PAAccount -List -Status 'valid' | Update-PAAccount
            }

            # read the contents of each accounts's acct.json
            Write-Debug "Loading PAAccount list from disk"

            $accts = Get-ChildItem (Join-Path $server.Folder '\*\acct.json') | ForEach-Object {

                # parse the json
                $acct = $_ | Get-Content -Raw | ConvertFrom-Json

                # insert the type name
                $acct.PSObject.TypeNames.Insert(0,'PoshACME.PAAccount')

                # add the dynamic id (Name) and Folder property
                $acct | Add-Member 'id' $_.Directory.Name -Force
                $acct | Add-Member 'Folder' $_.Directory.FullName -Force

                # send the result to the pipeline
                Write-Output $acct
            }

            # filter by Status if specified
            if ('Status' -in $PSBoundParameters.Keys) {
                $accts = $accts | Where-Object { $_.status -eq $Status }
            }

            # filter by KeyLength if specified
            if ('KeyLength' -in $PSBoundParameters.Keys) {
                $accts = $accts | Where-Object { $_.KeyLength -eq $KeyLength }
            }

            # filter by Contact if specified
            if ('Contact' -in $PSBoundParameters.Keys) {
                if (-not $Contact) {
                    $accts = $accts | Where-Object { $_.contact.Count -eq 0 }
                } else {
                    $accts = $accts | Where-Object { $_.contact.Count -gt 0 -and $null -eq (Compare-Object $Contact $_.contact) }
                }
            }

            return $accts

        # Specific mode
        } else {

            if ($ID) {

                # build the path to acct.json
                $acctFolder = Join-Path $server.Folder $ID
                $acctFile = Join-Path $acctFolder 'acct.json'

                # check if it exists
                if (Test-Path $acctFile -PathType Leaf) {
                    Write-Debug "Loading PAAccount $ID from disk"
                    $acct = Get-Content $acctFile -Raw | ConvertFrom-Json
                    $acct.PSObject.TypeNames.Insert(0,'PoshACME.PAAccount')

                    # add the dynamic id (Name) and Folder property
                    $acct | Add-Member 'id' (Get-Item $acctFolder).Name -Force
                    $acct | Add-Member 'Folder' $acctFolder -Force

                } else {
                    return $null
                }

            } else {
                # just use the current one
                $acct = $script:Acct
            }

            if ($acct -and $Refresh -and $acct.status -eq 'valid') {

                # update and then recurse to return the updated data
                Update-PAAccount $acct.id
                return (Get-PAAccount $acct.id)

            } else {
                # just return whatever we've got
                return $acct
            }
        }
    }
}