Browse Source

Update the provider generator to support generating string constants

pull/2316/head
Kévin Chalet 9 months ago
parent
commit
99e4ca1404
  1. 69
      gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs
  2. 4
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs
  3. 99
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml
  4. 42
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xsd

69
gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs

@ -805,7 +805,7 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
return template.Render(new
{
Providers = document.Root.Elements("Provider")
.Select(provider => new
.Select(static provider => new
{
Name = (string) provider.Attribute("Name"),
DisplayName = (string?) provider.Attribute("DisplayName") ?? (string) provider.Attribute("Name"),
@ -813,13 +813,13 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
Obsolete = (bool?) provider.Attribute("Obsolete") ?? false,
Environments = provider.Elements("Environment").Select(environment => new
Environments = provider.Elements("Environment").Select(static environment => new
{
Name = (string?) environment.Attribute("Name") ?? "Production"
})
.ToList(),
Settings = provider.Elements("Setting").Select(setting => new
Settings = provider.Elements("Setting").Select(static setting => new
{
PropertyName = (string) setting.Attribute("PropertyName"),
ParameterName = (string) setting.Attribute("ParameterName"),
@ -886,6 +886,15 @@ public static partial class OpenIddictClientWebIntegrationConstants
public const string {{ property.name }} = ""{{ property.dictionary_key }}"";
{{~ end ~}}
}
{{~ for group in provider.constants ~}}
public static class {{ group.key }}
{
{{~ for constant in group ~}}
public const string {{ constant.name }} = ""{{ constant.value }}"";
{{~ end ~}}
}
{{~ end ~}}
}
{{~ end ~}}
@ -907,23 +916,33 @@ public static partial class OpenIddictClientWebIntegrationConstants
return template.Render(new
{
Providers = document.Root.Elements("Provider")
.Select(provider => new
.Select(static provider => new
{
Name = (string) provider.Attribute("Name"),
Id = (string) provider.Attribute("Id"),
Environments = provider.Elements("Environment").Select(environment => new
Environments = provider.Elements("Environment").Select(static environment => new
{
Name = (string?) environment.Attribute("Name") ?? "Production"
})
.ToList(),
Properties = provider.Elements("Property").Select(property => new
Properties = provider.Elements("Property").Select(static property => new
{
Name = (string) property.Attribute("Name"),
DictionaryKey = (string) property.Attribute("DictionaryKey")
})
.ToList(),
Constants = provider.Elements("Constant")
.Select(static constant => new
{
Class = (string) constant.Attribute("Class"),
Name = (string) constant.Attribute("Name"),
Value = (string) constant.Attribute("Value")
})
.GroupBy(static constant => constant.Class)
.ToList(),
})
.ToList()
});
@ -1289,12 +1308,12 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
return template.Render(new
{
Providers = document.Root.Elements("Provider")
.Select(provider => new
.Select(static provider => new
{
Name = (string) provider.Attribute("Name"),
DisplayName = (string?) provider.Attribute("DisplayName") ?? (string) provider.Attribute("Name"),
Environments = provider.Elements("Environment").Select(environment => new
Environments = provider.Elements("Environment").Select(static environment => new
{
Name = (string?) environment.Attribute("Name") ?? "Production",
@ -1314,14 +1333,14 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
CodeChallengeMethodsSupported = configuration.Elements("CodeChallengeMethod").ToList() switch
{
{ Count: > 0 } methods => methods.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } methods => methods.Select(static type => (string?) type.Attribute("Value")).ToList(),
_ => []
},
GrantTypesSupported = configuration.Elements("GrantType").ToList() switch
{
{ Count: > 0 } types => types.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } types => types.Select(static type => (string?) type.Attribute("Value")).ToList(),
// If no explicit grant type was set, assume the provider only supports the code flow.
_ => [GrantTypes.AuthorizationCode]
@ -1329,7 +1348,7 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
ResponseModesSupported = configuration.Elements("ResponseMode").ToList() switch
{
{ Count: > 0 } modes => modes.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } modes => modes.Select(static type => (string?) type.Attribute("Value")).ToList(),
// If no explicit response mode was set, assume the provider only supports the query response mode.
_ => [ResponseModes.Query]
@ -1337,7 +1356,7 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
ResponseTypesSupported = configuration.Elements("ResponseType").ToList() switch
{
{ Count: > 0 } types => types.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } types => types.Select(static type => (string?) type.Attribute("Value")).ToList(),
// If no explicit response type was set, assume the provider only supports the code flow.
_ => [ResponseTypes.Code]
@ -1345,14 +1364,14 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
ScopesSupported = configuration.Elements("Scope").ToList() switch
{
{ Count: > 0 } types => types.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } types => types.Select(static type => (string?) type.Attribute("Value")).ToList(),
_ => []
},
DeviceAuthorizationEndpointAuthMethodsSupported = configuration.Elements("DeviceAuthorizationEndpointAuthMethod").ToList() switch
{
{ Count: > 0 } methods => methods.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } methods => methods.Select(static type => (string?) type.Attribute("Value")).ToList(),
// If no explicit client authentication method was set, assume the provider only supports
// flowing the client credentials as part of the device authorization request payload.
@ -1361,7 +1380,7 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
IntrospectionEndpointAuthMethodsSupported = configuration.Elements("IntrospectionEndpointAuthMethod").ToList() switch
{
{ Count: > 0 } methods => methods.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } methods => methods.Select(static type => (string?) type.Attribute("Value")).ToList(),
// If no explicit client authentication method was set, assume the provider only
// supports flowing the client credentials as part of the introspection request payload.
@ -1370,7 +1389,7 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
RevocationEndpointAuthMethodsSupported = configuration.Elements("RevocationEndpointAuthMethod").ToList() switch
{
{ Count: > 0 } methods => methods.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } methods => methods.Select(static type => (string?) type.Attribute("Value")).ToList(),
// If no explicit client authentication method was set, assume the provider only
// supports flowing the client credentials as part of the revocation request payload.
@ -1379,7 +1398,7 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
TokenEndpointAuthMethodsSupported = configuration.Elements("TokenEndpointAuthMethod").ToList() switch
{
{ Count: > 0 } methods => methods.Select(type => (string?) type.Attribute("Value")).ToList(),
{ Count: > 0 } methods => methods.Select(static type => (string?) type.Attribute("Value")).ToList(),
// If no explicit client authentication method was set, assume the provider only
// supports flowing the client credentials as part of the token request payload.
@ -1390,7 +1409,7 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
_ => null
},
Scopes = environment.Elements("Scope").Select(setting => new
Scopes = environment.Elements("Scope").Select(static setting => new
{
Name = (string) setting.Attribute("Name"),
Default = (bool?) setting.Attribute("Default") ?? false,
@ -1399,7 +1418,7 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
})
.ToList(),
Settings = provider.Elements("Setting").Select(setting => new
Settings = provider.Elements("Setting").Select(static setting => new
{
PropertyName = (string) setting.Attribute("PropertyName"),
@ -1412,7 +1431,7 @@ public sealed partial class OpenIddictClientWebIntegrationConfiguration
DefaultValue = (string?) setting.Attribute("DefaultValue"),
Items = setting.Elements("Item").Select(item => new
Items = setting.Elements("Item").Select(static item => new
{
Value = (string) item.Attribute("Value"),
Default = (bool?) item.Attribute("Default") ?? false,
@ -1456,7 +1475,7 @@ public static partial class OpenIddictClientWebIntegrationHelpers
return template.Render(new
{
Providers = document.Root.Elements("Provider")
.Select(provider => new
.Select(static provider => new
{
Name = (string) provider.Attribute("Name"),
DisplayName = (string?) provider.Attribute("DisplayName") ?? (string) provider.Attribute("Name")
@ -1508,12 +1527,12 @@ public sealed partial class OpenIddictClientWebIntegrationSettings
return template.Render(new
{
Providers = document.Root.Elements("Provider")
.Select(provider => new
.Select(static provider => new
{
Name = (string) provider.Attribute("Name"),
DisplayName = (string?) provider.Attribute("DisplayName") ?? (string) provider.Attribute("Name"),
Settings = provider.Elements("Setting").Select(setting => new
Settings = provider.Elements("Setting").Select(static setting => new
{
PropertyName = (string) setting.Attribute("PropertyName"),
@ -1555,8 +1574,4 @@ public sealed partial class OpenIddictClientWebIntegrationSettings
});
}
}
public void Initialize(GeneratorInitializationContext context)
{
}
}

4
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs

@ -1693,8 +1693,8 @@ public static partial class OpenIddictClientWebIntegrationHandlers
ProviderTypes.StripeConnect when context.Properties.TryGetValue(
StripeConnect.Properties.AccountType, out string? type) => type switch
{
"Express" => new Uri("https://connect.stripe.com/express/oauth/authorize", UriKind.Absolute),
"Standard" => new Uri("https://connect.stripe.com/oauth/authorize", UriKind.Absolute),
"express" => new Uri("https://connect.stripe.com/express/oauth/authorize", UriKind.Absolute),
"standard" => new Uri("https://connect.stripe.com/oauth/authorize", UriKind.Absolute),
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2190))
},

99
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

@ -99,6 +99,9 @@
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2184)) }}" />
<Constant Class="Regions" Value="China" Name="China" />
<Constant Class="Regions" Value="Global" Name="Global" />
<Setting PropertyName="Region" ParameterName="region" Type="String" Required="false" DefaultValue="Global"
Description="The Alibaba Cloud (Aliyun) service region ('Global' for the global Alibaba Cloud by default, or can be set to 'China' for Aliyun)" />
@ -312,6 +315,11 @@
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2185)) }}" />
<Constant Class="Regions" Value="Asia-Pacific" Name="AsiaPacific" />
<Constant Class="Regions" Value="China" Name="China" />
<Constant Class="Regions" Value="European Union" Name="EuropeanUnion" />
<Constant Class="Regions" Value="United States" Name="UnitedStates" />
<Setting PropertyName="Region" ParameterName="region" Type="String" Required="false" DefaultValue="United States"
Description="The preferred Battle.net region (by default, 'United States')" />
</Provider>
@ -474,6 +482,44 @@
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2186)) }}" />
<!--
Note: to make the region constants easier to read, only the name of
the state or the city is included in the name when it is unambiguous.
-->
<Constant Class="Regions" Value="US East (Ohio)" Name="Ohio" />
<Constant Class="Regions" Value="US East (N. Virginia)" Name="NorthVirginia" />
<Constant Class="Regions" Value="US West (N. California)" Name="NorthCalifornia" />
<Constant Class="Regions" Value="US West (Oregon)" Name="Oregon" />
<Constant Class="Regions" Value="Africa (Cape Town)" Name="CapeTown" />
<Constant Class="Regions" Value="Asia Pacific (Hong Kong)" Name="HongKong" />
<Constant Class="Regions" Value="Asia Pacific (Hyderabad)" Name="Hyderabad" />
<Constant Class="Regions" Value="Asia Pacific (Jakarta)" Name="Jakarta" />
<Constant Class="Regions" Value="Asia Pacific (Malaysia)" Name="Malaysia" />
<Constant Class="Regions" Value="Asia Pacific (Melbourne)" Name="Melbourne" />
<Constant Class="Regions" Value="Asia Pacific (Mumbai)" Name="Mumbai" />
<Constant Class="Regions" Value="Asia Pacific (Osaka)" Name="Osaka" />
<Constant Class="Regions" Value="Asia Pacific (Seoul)" Name="Seoul" />
<Constant Class="Regions" Value="Asia Pacific (Singapore)" Name="Singapore" />
<Constant Class="Regions" Value="Asia Pacific (Sydney)" Name="Sydney" />
<Constant Class="Regions" Value="Asia Pacific (Tokyo)" Name="Tokyo" />
<Constant Class="Regions" Value="Canada (Central)" Name="CentralCanada" />
<Constant Class="Regions" Value="Canada West (Calgary)" Name="Calgary" />
<Constant Class="Regions" Value="Europe (Frankfurt)" Name="Frankfurt" />
<Constant Class="Regions" Value="Europe (Ireland)" Name="Ireland" />
<Constant Class="Regions" Value="Europe (London)" Name="London" />
<Constant Class="Regions" Value="Europe (Milan)" Name="Milan" />
<Constant Class="Regions" Value="Europe (Paris)" Name="Paris" />
<Constant Class="Regions" Value="Europe (Spain)" Name="Spain" />
<Constant Class="Regions" Value="Europe (Stockholm)" Name="Stockholm" />
<Constant Class="Regions" Value="Europe (Zurich)" Name="Zurich" />
<Constant Class="Regions" Value="Israel (Tel Aviv)" Name="TelAviv" />
<Constant Class="Regions" Value="Middle East (Bahrain)" Name="Bahrain" />
<Constant Class="Regions" Value="Middle East (UAE)" Name="UnitedArabEmirates" />
<Constant Class="Regions" Value="South America (São Paulo)" Name="SaoPaulo" />
<Constant Class="Regions" Value="AWS GovCloud (US-East)" Name="GovCloudUnitedStatesEast" />
<Constant Class="Regions" Value="AWS GovCloud (US-West)" Name="GovCloudUnitedStatesWest" />
<Setting PropertyName="Region" ParameterName="region" Type="String" Required="true"
Description="The AWS region" />
@ -837,7 +883,7 @@
'Middle East (UAE)' or 'me-central-1' => 'https://login.mec1.pure.cloud/',
'South America (São Paulo)' or 'sa-east-1' => 'https://login.sae1.pure.cloud/',
'US East (Virginia)' or 'us-east-1' => 'https://login.mypurecloud.com/',
'US East 2 (Ohio)' or 'us-east-2' => 'https://login.use2.us-gov-pure.cloud/',
'US East (Ohio)' or 'us-east-2' => 'https://login.use2.us-gov-pure.cloud/',
'US West (Oregon)' or 'us-west-2' => 'https://login.usw2.pure.cloud/',
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2189)) }}">
@ -855,7 +901,7 @@
'Middle East (UAE)' or 'me-central-1' => 'https://login.mec1.pure.cloud/oauth/authorize',
'South America (São Paulo)' or 'sa-east-1' => 'https://login.sae1.pure.cloud/oauth/authorize',
'US East (Virginia)' or 'us-east-1' => 'https://login.mypurecloud.com/oauth/authorize',
'US East 2 (Ohio)' or 'us-east-2' => 'https://login.use2.us-gov-pure.cloud/oauth/authorize',
'US East (Ohio)' or 'us-east-2' => 'https://login.use2.us-gov-pure.cloud/oauth/authorize',
'US West (Oregon)' or 'us-west-2' => 'https://login.usw2.pure.cloud/oauth/authorize',
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2189)) }}"
@ -873,7 +919,7 @@
'Middle East (UAE)' or 'me-central-1' => 'https://login.mec1.pure.cloud/oauth/token',
'South America (São Paulo)' or 'sa-east-1' => 'https://login.sae1.pure.cloud/oauth/token',
'US East (Virginia)' or 'us-east-1' => 'https://login.mypurecloud.com/oauth/token',
'US East 2 (Ohio)' or 'us-east-2' => 'https://login.use2.us-gov-pure.cloud/oauth/token',
'US East (Ohio)' or 'us-east-2' => 'https://login.use2.us-gov-pure.cloud/oauth/token',
'US West (Oregon)' or 'us-west-2' => 'https://login.usw2.pure.cloud/oauth/token',
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2189)) }}"
@ -891,7 +937,7 @@
'Middle East (UAE)' or 'me-central-1' => 'https://api.mec1.pure.cloud/api/v2/users/me',
'South America (São Paulo)' or 'sa-east-1' => 'https://api.sae1.pure.cloud/api/v2/users/me',
'US East (Virginia)' or 'us-east-1' => 'https://api.mypurecloud.com/api/v2/users/me',
'US East 2 (Ohio)' or 'us-east-2' => 'https://api.use2.us-gov-pure.cloud/api/v2/users/me',
'US East (Ohio)' or 'us-east-2' => 'https://api.use2.us-gov-pure.cloud/api/v2/users/me',
'US West (Oregon)' or 'us-west-2' => 'https://api.usw2.pure.cloud/api/v2/users/me',
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2189)) }}">
@ -902,6 +948,27 @@
</Configuration>
</Environment>
<!--
Note: to make the region constants easier to read, only the name of
the state or the city is included in the name when it is unambiguous.
-->
<Constant Class="Regions" Value="Asia Pacific (Mumbai)" Name="Mumbai" />
<Constant Class="Regions" Value="Asia Pacific (Osaka)" Name="Osaka" />
<Constant Class="Regions" Value="Asia Pacific (Seoul)" Name="Seoul" />
<Constant Class="Regions" Value="Asia Pacific (Sydney)" Name="Sydney" />
<Constant Class="Regions" Value="Asia Pacific (Tokyo)" Name="Tokyo" />
<Constant Class="Regions" Value="Canada (Central)" Name="CentralCanada" />
<Constant Class="Regions" Value="Europe (Frankfurt)" Name="Frankfurt" />
<Constant Class="Regions" Value="Europe (Ireland)" Name="Ireland" />
<Constant Class="Regions" Value="Europe (London)" Name="London" />
<Constant Class="Regions" Value="Europe (Zurich)" Name="Zurich" />
<Constant Class="Regions" Value="Middle East (UAE)" Name="UnitedArabEmirates" />
<Constant Class="Regions" Value="South America (São Paulo)" Name="SaoPaulo" />
<Constant Class="Regions" Value="US East (Ohio)" Name="Ohio" />
<Constant Class="Regions" Value="US East (Virginia)" Name="Virginia" />
<Constant Class="Regions" Value="US West (Oregon)" Name="Oregon" />
<Setting PropertyName="Region" ParameterName="region" Type="String" Required="true"
Description="Specifies the region name (e.g., 'US East (Virginia)'). To determine the correct region for your instance, visit https://developer.genesys.cloud/platform/api/" />
</Provider>
@ -1229,6 +1296,9 @@
</Configuration>
</Environment>
<Constant Class="Regions" Value="China" Name="China" />
<Constant Class="Regions" Value="Global" Name="Global" />
<Setting PropertyName="Region" ParameterName="region" Type="String" Required="false" DefaultValue="Global"
Description="The Lark (Feishu) service region ('Global' for the global Lark by default, or can be set to 'China' for Feishu)" />
</Provider>
@ -1835,6 +1905,9 @@
<Scope Name="read_products" Default="true" Required="false" />
</Environment>
<Constant Class="AccessModes" Value="offline" Name="Offline" />
<Constant Class="AccessModes" Value="online" Name="Online" />
<Property Name="ShopName" DictionaryKey=".shopify_shop_name" />
<Setting PropertyName="AccessMode" ParameterName="mode" Type="String" Required="false"
@ -1967,8 +2040,8 @@
-->
<Configuration AuthorizationEndpoint="{settings.AccountType switch {
'Express' => 'https://connect.stripe.com/express/oauth/authorize',
'Standard' => 'https://connect.stripe.com/oauth/authorize',
'express' => 'https://connect.stripe.com/express/oauth/authorize',
'standard' => 'https://connect.stripe.com/oauth/authorize',
_ => throw new InvalidOperationException(SR.GetResourceString(SR.ID2190)) }}"
TokenEndpoint="https://connect.stripe.com/oauth/token" />
@ -1983,10 +2056,13 @@
<Scope Name="read_write" Default="true" Required="false" />
</Environment>
<Constant Class="AccountTypes" Value="express" Name="Express" />
<Constant Class="AccountTypes" Value="standard" Name="Standard" />
<Property Name="AccountType" DictionaryKey=".stripe_account_type" />
<Setting PropertyName="AccountType" ParameterName="type" Type="String" Required="true" DefaultValue="standard"
Description="The type of the Stripe account (by default, 'Standard', but can also be set to 'Express'). Note: the account type can also be set dynamically via the authentication properties" />
Description="The type of the Stripe account (by default, 'standard', but can also be set to 'express'). Note: the account type can also be set dynamically via the authentication properties" />
</Provider>
<!--
@ -2608,6 +2684,15 @@
<Scope Name="AaaServer.profile.READ" Default="true" Required="true" />
</Environment>
<Constant Class="Regions" Value="Australia" Name="Australia" />
<Constant Class="Regions" Value="Canada" Name="Canada" />
<Constant Class="Regions" Value="European Union" Name="EuropeanUnion" />
<Constant Class="Regions" Value="India" Name="India" />
<Constant Class="Regions" Value="Japan" Name="Japan" />
<Constant Class="Regions" Value="Saudi Arabia" Name="SaudiArabia" />
<Constant Class="Regions" Value="United Kingdom" Name="UnitedKingdom" />
<Constant Class="Regions" Value="United States" Name="UnitedStates" />
<Property Name="Location" DictionaryKey=".location" />
<Setting PropertyName="AccessType" ParameterName="type" Type="String" Required="false"

42
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xsd

@ -344,6 +344,48 @@
</xs:complexType>
</xs:element>
<xs:element name="Constant" minOccurs="0" maxOccurs="50">
<xs:annotation>
<xs:documentation>A string constant specific to the provider integration.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="Class" use="required">
<xs:annotation>
<xs:documentation>The name of the parent class that will expose the constant.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="^[A-Z][a-zA-Z0-9]*$" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Name" use="required">
<xs:annotation>
<xs:documentation>The name of the constant.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="^[A-Z][a-zA-Z0-9]*$" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Value" use="required">
<xs:annotation>
<xs:documentation>The value associated with the constant.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Property" minOccurs="0" maxOccurs="10">
<xs:annotation>
<xs:documentation>A custom, user-set authentication property supported by the provider integration.</xs:documentation>

Loading…
Cancel
Save