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

[PowerShell] Add useOneOfDiscriminatorLookup option #6516

Merged
merged 2 commits into from
Jun 2, 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
1 change: 1 addition & 0 deletions docs/generators/powershell.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ sidebar_label: powershell
|packageName|Client package name (e.g. PSTwitter).| |PSOpenAPITools|
|packageVersion|Package version (e.g. 0.1.2).| |0.1.2|
|powershellGalleryUrl|URL to the module in PowerShell Gallery (e.g. https://www.powershellgallery.com/packages/PSTwitter/).| |null|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and onlye one match in oneOf's schemas) will be skipped.| |null|

## IMPORT MAPPING

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,4 +375,6 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,
" 2) Boolean values of the 'additionalProperties' keyword are ignored. It's as if additional properties are NOT allowed." +
"Note: the root cause are issues #1369 and #1371, which must be resolved in the swagger-parser project.";

public static final String USE_ONEOF_DISCRIMINATOR_LOOKUP = "useOneOfDiscriminatorLookup";
public static final String USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC = "Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and onlye one match in oneOf's schemas) will be skipped.";
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class PowerShellClientCodegen extends DefaultCodegen implements CodegenCo
protected HashSet powershellVerbs;
protected Map<String, String> commonVerbs; // verbs not in the official ps verb list but can be mapped to one of the verbs
protected HashSet methodNames; // store a list of method names to detect duplicates
protected boolean useOneOfDiscriminatorLookup = false; // use oneOf discriminator's mapping for model lookup

/**
* Constructs an instance of `PowerShellClientCodegen`.
Expand Down Expand Up @@ -498,7 +499,7 @@ public PowerShellClientCodegen() {
cliOptions.add(new CliOption(CodegenConstants.OPTIONAL_PROJECT_GUID, "GUID for PowerShell module (e.g. a27b908d-2a20-467f-bc32-af6f3a654ac5). A random GUID will be generated by default."));
cliOptions.add(new CliOption(CodegenConstants.API_NAME_PREFIX, "Prefix that will be appended to all PS objects. Default: empty string. e.g. Pet => PSPet."));
cliOptions.add(new CliOption("commonVerbs", "PS common verb mappings. e.g. Delete=Remove:Patch=Update to map Delete with Remove and Patch with Update accordingly."));

cliOptions.add(new CliOption(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC));
}

public CodegenType getTag() {
Expand Down Expand Up @@ -535,6 +536,14 @@ public void setPowershellGalleryUrl(String powershellGalleryUrl) {
this.powershellGalleryUrl = powershellGalleryUrl;
}

public void setUseOneOfDiscriminatorLookup(boolean useOneOfDiscriminatorLookup) {
this.useOneOfDiscriminatorLookup = useOneOfDiscriminatorLookup;
}

public boolean getUseOneOfDiscriminatorLookup() {
return this.useOneOfDiscriminatorLookup;
}

@Override
public void processOpts() {
super.processOpts();
Expand All @@ -550,6 +559,12 @@ public void processOpts() {
additionalProperties.put("powershellGalleryUrl", powershellGalleryUrl);
}

if (additionalProperties.containsKey(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP)) {
setUseOneOfDiscriminatorLookup(convertPropertyToBooleanAndWriteBack(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP));
} else {
additionalProperties.put(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, useOneOfDiscriminatorLookup);
}

if (StringUtils.isNotBlank(powershellGalleryUrl)) {
// get the last segment of the URL
// e.g. https://www.powershellgallery.com/packages/PSTwitter => PSTwitter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,37 @@ function ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{classname}}} {
}

{{/isNullable}}
{{#useOneOfDiscriminatorLookup}}
{{#discriminator}}
{{#mappedModels}}
{{#-first}}
$JsonData = ConvertFrom-Json -InputObject $Json
{{/-first}}
# check if the discriminator value is '{{{mappingName}}}'
if ($JsonData.PSobject.Properties["{{{propertyBaseName}}}"].value == "{{{mappingName}}}") {
# try to match {{{modelName}}} defined in the oneOf schemas
try {
$matchInstance = ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{modelName}}} $Json

foreach($property in $matchInstance.PsObject.Properties) {
if ($null -ne $property.Value) {
$matchType = "{{{modelName}}}"
return [PSCustomObject]@{
"ActualType" = ${matchType}
"ActualInstance" = ${matchInstance}
"oneOfSchemas" = @({{#oneOf}}"{{{.}}}"{{^-last}}, {{/-last}}{{/oneOf}})
}
}
}
} catch {
# fail to match the schema defined in oneOf with the discriminator lookup, proceed to the next one
Write-Debug "Failed to match '{{{modelName}}}' defined in oneOf ({{{apiNamePrefix}}}{{{classname}}}) using the discriminator lookup ({{{mappingName}}}). Proceeding with the typical oneOf type matching."
}
}

{{/mappedModels}}
{{/discriminator}}
{{/useOneOfDiscriminatorLookup}}
{{#oneOf}}
# try to match {{{.}}} defined in the oneOf schemas
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,3 +388,140 @@ function Get-PSUrlFromHostSetting {

}
}

<#
.SYNOPSIS
Sets the configuration for http signing.
.DESCRIPTION

Sets the configuration for the HTTP signature security scheme.
The HTTP signature security scheme is used to sign HTTP requests with a key
which is in possession of the API client.
An 'Authorization' header is calculated by creating a hash of select headers,
and optionally the body of the HTTP request, then signing the hash value using
a key. The 'Authorization' header is added to outbound HTTP requests.

Ref: https://openapi-generator.tech

.PARAMETER KeyId
KeyId for HTTP signing

.PARAMETER KeyFilePath
KeyFilePath for HTTP signing

.PARAMETER KeyPassPhrase
KeyPassPhrase, if the HTTP signing key is protected

.PARAMETER HttpSigningHeader
HttpSigningHeader list of HTTP headers used to calculate the signature. The two special signature headers '(request-target)' and '(created)'
SHOULD be included.
The '(created)' header expresses when the signature was created.
The '(request-target)' header is a concatenation of the lowercased :method, an
ASCII space, and the :path pseudo-headers.
If no headers are specified then '(created)' sets as default.

.PARAMETER HashAlgorithm
HashAlgrithm to calculate the hash, Supported values are "sha256" and "sha512"

.PARAMETER SigningAlgorithm
SigningAlgorithm specifies the signature algorithm, supported values are "RSASSA-PKCS1-v1_5" and "RSASSA-PSS"
RSA key : Supported values "RSASSA-PKCS1-v1_5" and "RSASSA-PSS", for ECDSA key this parameter is not applicable

.PARAMETER SignatureValidityPeriod
SignatureValidityPeriod specifies the signature maximum validity time in seconds. It accepts integer value

.OUTPUTS

System.Collections.Hashtable
#>
function Set-PSConfigurationHttpSigning {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$KeyId,
[Parameter(Mandatory = $true)]
[string]$KeyFilePath,
[Parameter(Mandatory = $false)]
[securestring]$KeyPassPhrase,
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string[]] $HttpSigningHeader = @("(created)"),
[Parameter(Mandatory = $false)]
[ValidateSet("sha256", "sha512")]
[string] $HashAlgorithm = "sha256",
[Parameter(Mandatory = $false)]
[ValidateSet("RSASSA-PKCS1-v1_5", "RSASSA-PSS")]
[string]$SigningAlgorithm ,
[Parameter(Mandatory = $false)]
[int]$SignatureValidityPeriod
)

Process {
$httpSignatureConfiguration = @{ }

if (Test-Path -Path $KeyFilePath) {
$httpSignatureConfiguration["KeyId"] = $KeyId
$httpSignatureConfiguration["KeyFilePath"] = $KeyFilePath
}
else {
throw "Private key file path does not exist"
}

$keyType = Get-PSKeyTypeFromFile -KeyFilePath $KeyFilePath
if ([String]::IsNullOrEmpty($SigningAlgorithm)) {
if ($keyType -eq "RSA") {
$SigningAlgorithm = "RSASSA-PKCS1-v1_5"
}
}

if ($keyType -eq "RSA" -and
($SigningAlgorithm -ne "RSASSA-PKCS1-v1_5" -and $SigningAlgorithm -ne "RSASSA-PSS" )) {
throw "Provided Key and SigningAlgorithm : $SigningAlgorithm is not compatible."
}

if ($HttpSigningHeader -contains "(expires)" -and $SignatureValidityPeriod -le 0) {
throw "SignatureValidityPeriod must be greater than 0 seconds."
}

if ($HttpSigningHeader -contains "(expires)") {
$httpSignatureConfiguration["SignatureValidityPeriod"] = $SignatureValidityPeriod
}
if ($null -ne $HttpSigningHeader -and $HttpSigningHeader.Length -gt 0) {
$httpSignatureConfiguration["HttpSigningHeader"] = $HttpSigningHeader
}

if ($null -ne $HashAlgorithm ) {
$httpSignatureConfiguration["HashAlgorithm"] = $HashAlgorithm
}

if ($null -ne $SigningAlgorithm) {
$httpSignatureConfiguration["SigningAlgorithm"] = $SigningAlgorithm
}

if ($null -ne $KeyPassPhrase) {
$httpSignatureConfiguration["KeyPassPhrase"] = $KeyPassPhrase
}

$Script:Configuration["HttpSigning"] = New-Object -TypeName PSCustomObject -Property $httpSignatureConfiguration
}
}

<#
.SYNOPSIS

Get the configuration object 'PSConfigurationHttpSigning'.

.DESCRIPTION

Get the configuration object 'PSConfigurationHttpSigning'.

.OUTPUTS

[PSCustomObject]
#>
function Get-PSConfigurationHttpSigning{

$httpSignatureConfiguration = $Script:Configuration["HttpSigning"]
return $httpSignatureConfiguration
}
Loading