Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved P12 handling #255

Merged
merged 6 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions PSGSuite/Public/Authentication/New-GoogleService.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,50 @@ function New-GoogleService {
$script:_PSGSuiteSessions[$sessionKey] | Select-Object -ExpandProperty Service
}
else {
if ($script:PSGSuite.P12KeyPath -or $script:PSGSuite.P12Key) {
if ($script:PSGSuite.JSONServiceAccountKey -or $script:PSGSuite.JSONServiceAccountKeyPath) {
Write-Verbose "Building ServiceAccountCredential from JSONServiceAccountKey as user '$User'"
try {
if (-not $script:PSGSuite.JSONServiceAccountKey) {
$script:PSGSuite.JSONServiceAccountKey = ([System.IO.File]::ReadAllBytes($script:PSGSuite.JSONServiceAccountKeyPath))
Set-PSGSuiteConfig -ConfigName $script:PSGSuite.ConfigName -JSONServiceAccountKey $script:PSGSuite.JSONServiceAccountKey -Verbose:$false
}
$stream = New-Object System.IO.MemoryStream $([System.Text.Encoding]::ASCII.GetBytes($script:PSGSuite.JSONServiceAccountKey)), $null
$credential = ([Google.Apis.Auth.OAuth2.GoogleCredential]::FromStream($stream)).CreateWithUser($User).CreateScoped($Scope).UnderlyingCredential
}
catch {
$PSCmdlet.ThrowTerminatingError($_)
}
finally {
if ($stream) {
$stream.Close()
}
}
}
elseif ($script:PSGSuite.P12KeyPath -or $script:PSGSuite.P12Key -or $script:PSGSuite.P12KeyObject) {
try {
Write-Verbose "Building ServiceAccountCredential from P12Key as user '$User'"
if (-not $script:PSGSuite.P12Key) {
$script:PSGSuite.P12Key = ([System.IO.File]::ReadAllBytes($script:PSGSuite.P12KeyPath))
Set-PSGSuiteConfig -ConfigName $script:PSGSuite.ConfigName -P12Key $script:PSGSuite.P12Key -Verbose:$false
if ($script:PSGSuite.P12KeyPath -or $script:PSGSuite.P12Key) {
if (-not $script:PSGSuite.P12Key) {
$script:PSGSuite.P12Key = ([System.IO.File]::ReadAllBytes($script:PSGSuite.P12KeyPath))
Set-PSGSuiteConfig -ConfigName $script:PSGSuite.ConfigName -P12Key $script:PSGSuite.P12Key -Verbose:$false
}
if ($script:PSGSuite.P12KeyPassword) {
$P12KeyPassword = $script:PSGSuite.P12KeyPassword
}
else {
$P12KeyPassword = "notasecret"
}
$certificate = New-Object 'System.Security.Cryptography.X509Certificates.X509Certificate2' -ArgumentList ([System.Byte[]]$script:PSGSuite.P12Key),$P12KeyPassword,([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
}
else {
$certificate = $script:PSGSuite.P12KeyObject
}
$certificate = New-Object 'System.Security.Cryptography.X509Certificates.X509Certificate2' -ArgumentList ([System.Byte[]]$script:PSGSuite.P12Key),"notasecret",([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$credential = New-Object 'Google.Apis.Auth.OAuth2.ServiceAccountCredential' (New-Object 'Google.Apis.Auth.OAuth2.ServiceAccountCredential+Initializer' $script:PSGSuite.AppEmail -Property @{
User = $User
Scopes = [string[]]$Scope
}
).FromCertificate($certificate)

}
catch {
$PSCmdlet.ThrowTerminatingError($_)
Expand Down Expand Up @@ -116,7 +147,7 @@ function New-GoogleService {
}
}
else {
$PSCmdlet.ThrowTerminatingError((ThrowTerm "The current config '$($script:PSGSuite.ConfigName)' does not contain a P12KeyPath or a ClientSecretsPath! PSGSuite is unable to build a credential object for the service without a path to a credential file! Please update the configuration to include a path at least one of the two credential types."))
$PSCmdlet.ThrowTerminatingError((ThrowTerm "The current config '$($script:PSGSuite.ConfigName)' does not contain a JSONServiceAccountKeyPath, P12KeyPath, or ClientSecretsPath! PSGSuite is unable to build a credential object for the service without a path to a credential file! Please update the configuration to include a path at least one of the three credential types."))
}
$svc = New-Object "$ServiceType" (New-Object 'Google.Apis.Services.BaseClientService+Initializer' -Property @{
HttpClientInitializer = $credential
Expand Down
23 changes: 21 additions & 2 deletions PSGSuite/Public/Configuration/Get-PSGSuiteConfig.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ function Get-PSGSuiteConfig {
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(
$String))
}
elseif ($String -is [ScriptBlock]) {
$String.InvokeReturnAsIs()
}
else {
$String
}
Expand All @@ -65,14 +68,30 @@ function Get-PSGSuiteConfig {
@{l = 'ConfigName';e = {$choice}},
@{l = 'P12KeyPath';e = {Decrypt $_.P12KeyPath}},
'P12Key',
@{l = 'P12KeyPassword';e = {Decrypt $_.P12KeyPassword}},
@{l = 'P12KeyObject';e = {Decrypt $_.P12KeyObject}},
@{l = 'ClientSecretsPath';e = {Decrypt $_.ClientSecretsPath}},
@{l = 'ClientSecrets';e = {Decrypt $_.ClientSecrets}},
@{l = 'AppEmail';e = {Decrypt $_.AppEmail}},
@{l = 'AppEmail';e = {
if ($_.AppEmail) {
Decrypt $_.ServiceAccountClientID
}
elseif ($_.ClientSecrets) {
(Decrypt $_.ClientSecrets | ConvertFrom-Json).client_email
}
}},
@{l = 'AdminEmail';e = {Decrypt $_.AdminEmail}},
@{l = 'CustomerID';e = {Decrypt $_.CustomerID}},
@{l = 'Domain';e = {Decrypt $_.Domain}},
@{l = 'Preference';e = {Decrypt $_.Preference}},
@{l = 'ServiceAccountClientID';e = {Decrypt $_.ServiceAccountClientID}},
@{l = 'ServiceAccountClientID';e = {
if ($_.ServiceAccountClientID) {
Decrypt $_.ServiceAccountClientID
}
elseif ($_.ClientSecrets) {
(Decrypt $_.ClientSecrets | ConvertFrom-Json).client_id
}
}},
@{l = 'Chat';e = {
$dict = @{
Webhooks = @{}
Expand Down
18 changes: 15 additions & 3 deletions PSGSuite/Public/Configuration/Set-PSGSuiteConfig.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ function Set-PSGSuiteConfig {
.PARAMETER P12Key
The P12Key in byte array format. If the actual P12Key is present on the config, the P12KeyPath is not needed. The config will auto-update with this value after running any command, if P12KeyPath is filled and this value is not already present.

.PARAMETER P12KeyPassword
The password for the P12 Key file. If not specified the default of 'notasecret' will be used and this config value will not be set. This is only needed in the case where the P12 file has been manually rexported with a custom password

.PARAMETER ClientSecretsPath
The path to the Client Secrets JSON file downloaded from the Google Developer's Console. Using the ClientSecrets JSON will prompt the user to complete OAuth2 authentication in their browser on the first run and store the retrieved Refresh and Access tokens in the user's home directory. The config will auto-update with this value after running any command, if ClientSecretsPath is filled and this value is not already present. If P12KeyPath is also specified, ClientSecretsPath will be ignored.
The path to the Client Secrets JSON file downloaded from the Google Developer's Console. Using the ClientSecrets JSON will prompt the user to complete OAuth2 authentication in their browser on the first run and store the retrieved Refresh and Access tokens in the user's home directory. The config will auto-update with this value after running any command, if ClientSecretsPath is filled and this value is not already present. If JSONServiceAccountKeyPath or P12KeyPath is also specified, ClientSecretsPath will be ignored.

.PARAMETER ClientSecrets
The string contents of the Client Secrets JSON file downloaded from the Google Developer's Console. Using the ClientSecrets JSON will prompt the user to complete OAuth2 authentication in their browser on the first run and store the retrieved Refresh and Access tokens in the user's home directory. If P12KeyPath is also specified, ClientSecrets will be ignored.
The string contents of the Client Secrets JSON file downloaded from the Google Developer's Console. Using the ClientSecrets JSON will prompt the user to complete OAuth2 authentication in their browser on the first run and store the retrieved Refresh and Access tokens in the user's home directory. If JSONServiceAccountKeyPath or P12KeyPath is also specified, ClientSecrets will be ignored.

.PARAMETER AppEmail
The application email from the Google Developer's Console. This typically looks like the following:
Expand Down Expand Up @@ -95,6 +98,9 @@ function Set-PSGSuiteConfig {
[Byte[]]
$P12Key,
[parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true)]
[SecureString]
$P12KeyPassword,
[parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true)]
[string]
$ClientSecretsPath,
[parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true)]
Expand Down Expand Up @@ -145,6 +151,9 @@ function Set-PSGSuiteConfig {
elseif ($string -is [System.String] -and $String -notlike '') {
ConvertTo-SecureString -String $string -AsPlainText -Force
}
elseif ($string -is [System.Management.Automation.ScriptBlock]) {
$string
}
}
}
Process {
Expand All @@ -164,7 +173,7 @@ function Set-PSGSuiteConfig {
}
}
Write-Verbose "Setting config name '$ConfigName'"
$configParams = @('P12Key','P12KeyPath','ClientSecretsPath','ClientSecrets','AppEmail','AdminEmail','CustomerID','Domain','Preference','ServiceAccountClientID','Webhook','Space')
$configParams = @('P12Key','P12KeyPath','P12KeyPassword','ClientSecretsPath','ClientSecrets','AppEmail','AdminEmail','CustomerID','Domain','Preference','ServiceAccountClientID','Webhook','Space')
if ($SetAsDefaultConfig -or !$configHash["DefaultConfig"]) {
$configHash["DefaultConfig"] = $ConfigName
}
Expand All @@ -190,6 +199,9 @@ function Set-PSGSuiteConfig {
$configHash["$ConfigName"]['P12Key'] = ([System.IO.File]::ReadAllBytes($PSBoundParameters[$key]))
}
}
P12KeyPassword {
$configHash["$ConfigName"][$key] = $PSBoundParameters[$key]
}
ClientSecretsPath {
if (-not [System.String]::IsNullOrWhiteSpace($PSBoundParameters[$key].Trim())) {
$configHash["$ConfigName"][$key] = (Encrypt $PSBoundParameters[$key])
Expand Down