Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 34f94ed

Browse files
f-alizadaFarhad Alizada
andauthored
Add possibility to parametrize API OAuth2 scope settings (#723)
* Add parametrization possibility for api oauth2 scope * Fix tests concurrency issue with mock. Add oauth2 scope parameter to master template * Introduce ApiParameters variable for extractor, deprecate serviceUrlParameters * Update documentation according to new api parameter Co-authored-by: Farhad Alizada <falizada@microsoft.com>
1 parent 431081e commit 34f94ed

File tree

17 files changed

+312
-90
lines changed

17 files changed

+312
-90
lines changed

src/ArmTemplates/Commands/Configurations/ExtractorConsoleAppConfiguration.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Licensed under the MIT License.
44
// --------------------------------------------------------------------------
55

6+
using System.Collections.Generic;
67
using CommandLine;
78
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Constants;
89
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.Models;
@@ -60,9 +61,6 @@ public class ExtractorConsoleAppConfiguration
6061
[Option(longName: "baseFileName", HelpText = "Specify base name of the template file")]
6162
public string BaseFileName { get; set; }
6263

63-
// this is used only from json-file and --extractorConfig option, so no option possibility here
64-
public ServiceUrlProperty[] ServiceUrlParameters { get; set; }
65-
6664
[Option(longName: "paramServiceUrl", HelpText = "Parameterize serviceUrl")]
6765
public string ParamServiceUrl { get; set; }
6866

@@ -98,5 +96,13 @@ public class ExtractorConsoleAppConfiguration
9896

9997
[Option(longName: "overrideProductGuids", HelpText = "Override product GUID identification to system generated")]
10098
public string OverrideProductGuids { get; set; }
99+
100+
[Option(longName: "paramApiOauth2Scope", HelpText = "Parametrize API OAuth2 scope values")]
101+
public string ParamApiOauth2Scope { get; set; }
102+
103+
/// <summary>
104+
/// Api parameter properties for overriding Api OAuth2 scope or/and Service urloverride. Available via extractor-config file only.
105+
/// </summary>
106+
public Dictionary<string, ApiParameterProperty> ApiParameters { get; set; }
101107
}
102108
}

src/ArmTemplates/Common/Constants/GlobalConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public static class ParameterNames
3939
public const string LinkedTemplatesBaseUrl = "linkedTemplatesBaseUrl";
4040
public const string NamedValueKeyVaultSecrets = "namedValueKeyVaultSecrets";
4141
public const string BackendSettings = "backendSettings";
42+
public const string ApiOauth2ScopeSettings = "apiOauth2ScopeSettings";
4243
}
4344

4445
public static class ParameterPrefix
@@ -48,5 +49,6 @@ public static class ParameterPrefix
4849
public const string Property = "Property";
4950
public const string LogResourceId = "LogResourceId";
5051
public const string Backend = "Backend";
52+
public const string ApiOauth2Scope = "ApiOauth2Scope";
5153
}
5254
}

src/ArmTemplates/Common/Templates/Abstractions/TemplateParameterProperties.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ public TemplateParameterProperties(string metadataDescription, string type)
2626
Description = metadataDescription,
2727
};
2828
this.Type = type;
29-
}
29+
}
3030
}
3131
}

src/ArmTemplates/Common/Templates/Builders/TemplateBuilder.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ public TemplateBuilder GenerateTemplateWithPresetProperties(ExtractorParameters
6060
=> this.GenerateTemplateWithApimServiceNameProperty()
6161
.AddPolicyProperties(extractorParameters)
6262
.AddParameterizedServiceUrlProperty(extractorParameters)
63-
.AddParameterizedApiLoggerIdProperty(extractorParameters);
63+
.AddParameterizedApiLoggerIdProperty(extractorParameters)
64+
.AddParameterizedApiScopeProperty(extractorParameters);
6465

6566
public TemplateBuilder GenerateEmptyTemplate()
6667
{
@@ -82,7 +83,7 @@ public TemplateBuilder AddPolicyProperties(ExtractorParameters extractorParamete
8283
{
8384
if (extractorParameters.PolicyXMLBaseUrl != null)
8485
{
85-
TemplateParameterProperties policyTemplateBaseUrlParameterProperties = new TemplateParameterProperties()
86+
var policyTemplateBaseUrlParameterProperties = new TemplateParameterProperties()
8687
{
8788
Type = "string"
8889
};
@@ -91,7 +92,7 @@ public TemplateBuilder AddPolicyProperties(ExtractorParameters extractorParamete
9192

9293
if (extractorParameters.PolicyXMLSasToken != null)
9394
{
94-
TemplateParameterProperties policyTemplateSasTokenParameterProperties = new TemplateParameterProperties()
95+
var policyTemplateSasTokenParameterProperties = new TemplateParameterProperties()
9596
{
9697
Type = "string"
9798
};
@@ -104,9 +105,9 @@ public TemplateBuilder AddPolicyProperties(ExtractorParameters extractorParamete
104105

105106
public TemplateBuilder AddParameterizedServiceUrlProperty(ExtractorParameters extractorParameters)
106107
{
107-
if (extractorParameters.ParameterizeServiceUrl || extractorParameters.ServiceUrlParameters != null && extractorParameters.ServiceUrlParameters.Length > 0)
108+
if (extractorParameters.ParameterizeServiceUrl)
108109
{
109-
TemplateParameterProperties serviceUrlParamProperty = new TemplateParameterProperties()
110+
var serviceUrlParamProperty = new TemplateParameterProperties()
110111
{
111112
Type = "object"
112113
};
@@ -116,11 +117,25 @@ public TemplateBuilder AddParameterizedServiceUrlProperty(ExtractorParameters ex
116117
return this;
117118
}
118119

120+
public TemplateBuilder AddParameterizedApiScopeProperty(ExtractorParameters extractorParameters)
121+
{
122+
if (extractorParameters.ParametrizeApiOauth2Scope)
123+
{
124+
var apiScopeParameterProperty = new TemplateParameterProperties()
125+
{
126+
Type = "object"
127+
};
128+
this.template.Parameters.Add(ParameterNames.ApiOauth2ScopeSettings, apiScopeParameterProperty);
129+
}
130+
131+
return this;
132+
}
133+
119134
public TemplateBuilder AddParameterizedApiLoggerIdProperty(ExtractorParameters extractorParameters)
120135
{
121136
if (extractorParameters.ParameterizeApiLoggerId)
122137
{
123-
TemplateParameterProperties apiLoggerProperty = new TemplateParameterProperties()
138+
var apiLoggerProperty = new TemplateParameterProperties()
124139
{
125140
Type = "object"
126141
};

src/ArmTemplates/Extractor/EntityExtractors/APIExtractor.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ void SetArmTemplateValuesToApiTemplateResource(ApiTemplateResource apiResource,
145145
apiResource.Properties.ServiceUrl = $"[parameters('{ParameterNames.ServiceUrl}').{ParameterNamingHelper.GenerateValidParameterName(originalServiceApiName, ParameterPrefix.Api)}]";
146146
}
147147

148+
if (extractorParameters.ParametrizeApiOauth2Scope)
149+
{
150+
if (apiResource.Properties.AuthenticationSettings?.OAuth2?.Scope is not null)
151+
{
152+
apiResource.Properties.AuthenticationSettings.OAuth2.Scope = $"[parameters('{ParameterNames.ApiOauth2ScopeSettings}').{ParameterNamingHelper.GenerateValidParameterName(originalServiceApiName, ParameterPrefix.ApiOauth2Scope)}]";
153+
}
154+
}
155+
148156
if (apiResource.Properties.ApiVersionSetId != null)
149157
{
150158
apiResource.DependsOn = Array.Empty<string>();

src/ArmTemplates/Extractor/EntityExtractors/BackendExtractor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ void SaveBackendApiParametersToCache()
110110
}
111111

112112
var backendApiParameters = new BackendApiParameters();
113-
var backendValidName = ParameterNamingHelper.GenerateValidParameterName(originalBackendName, ParameterPrefix.Diagnostic).ToLower();
113+
var backendValidName = ParameterNamingHelper.GenerateValidParameterName(originalBackendName, ParameterPrefix.Backend).ToLower();
114114

115115
if (!string.IsNullOrEmpty(backendResource.Properties.ResourceId))
116116
{

src/ArmTemplates/Extractor/EntityExtractors/MasterTemplateExtractor.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,17 @@ static MasterTemplateResource CreateLinkedMasterTemplateResourceForApiTemplate(s
262262
{
263263
masterResourceTemplate.Properties.Parameters.Add(ParameterNames.ServiceUrl, new TemplateParameterProperties() { Value = $"[parameters('{ParameterNames.ServiceUrl}')]" });
264264
}
265+
265266
if (extractorParameters.ParameterizeApiLoggerId)
266267
{
267268
masterResourceTemplate.Properties.Parameters.Add(ParameterNames.ApiLoggerId, new TemplateParameterProperties() { Value = $"[parameters('{ParameterNames.ApiLoggerId}')]" });
268269
}
270+
271+
if (extractorParameters.ParametrizeApiOauth2Scope)
272+
{
273+
masterResourceTemplate.Properties.Parameters.Add(ParameterNames.ApiOauth2ScopeSettings, new TemplateParameterProperties() { Value = $"[parameters('{ParameterNames.ApiOauth2ScopeSettings}')]" });
274+
}
275+
269276
return masterResourceTemplate;
270277
}
271278

@@ -423,6 +430,13 @@ Dictionary<string, TemplateParameterProperties> CreateMasterTemplateParameters(E
423430
new TemplateParameterProperties(metadataDescription: "The settings for the Backends", type: "object"));
424431
}
425432

433+
if (extractorParameters.ParametrizeApiOauth2Scope)
434+
{
435+
parameters.Add(
436+
ParameterNames.ApiOauth2ScopeSettings,
437+
new TemplateParameterProperties(metadataDescription: "The settings for the APIs Oauth2 Scope values", type: "object"));
438+
}
439+
426440
return parameters;
427441
}
428442

src/ArmTemplates/Extractor/EntityExtractors/ParametersExtractor.cs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public async Task<Template> CreateMasterTemplateParameterValues(
5454
AddPolicyParameters();
5555
AddNamedValuesParameters();
5656
await AddServiceUrlParameterAsync();
57+
await AddApiOauth2ScopeParameterAsync();
5758

5859
void AddLinkedUrlParameters()
5960
{
@@ -102,15 +103,18 @@ async Task AddServiceUrlParameterAsync()
102103
{
103104
var validApiName = ParameterNamingHelper.GenerateValidParameterName(apiName, ParameterPrefix.Api);
104105

105-
string serviceUrl;
106-
if (extractorParameters.ServiceUrlParameters is null)
106+
string serviceUrl = null;
107+
if (extractorParameters.ApiParameters is null)
107108
{
108109
var apiDetails = await this.apisClient.GetSingleAsync(apiName, extractorParameters);
109110
serviceUrl = apiDetails.Properties.ServiceUrl;
110111
}
111112
else
112113
{
113-
serviceUrl = extractorParameters.ServiceUrlParameters.FirstOrDefault(x => x.ApiName.Equals(apiName))?.ServiceUrl;
114+
if (extractorParameters.ApiParameters.ContainsKey(apiName))
115+
{
116+
serviceUrl = extractorParameters.ApiParameters[apiName].ServiceUrl;
117+
}
114118
}
115119

116120
serviceUrls.Add(validApiName, serviceUrl);
@@ -119,6 +123,42 @@ async Task AddServiceUrlParameterAsync()
119123
parameters.Add(ParameterNames.ServiceUrl, new TemplateObjectParameterProperties() { Value = serviceUrls });
120124
}
121125

126+
async Task AddApiOauth2ScopeParameterAsync()
127+
{
128+
if (!extractorParameters.ParametrizeApiOauth2Scope)
129+
{
130+
return;
131+
}
132+
133+
var apiOauth2Scopes = new Dictionary<string, string>();
134+
foreach (var apiName in apisToExtract)
135+
{
136+
var apiDetails = await this.apisClient.GetSingleAsync(apiName, extractorParameters);
137+
138+
if (apiDetails.Properties.AuthenticationSettings?.OAuth2 is not null)
139+
{
140+
string apiOAuthScope = null;
141+
var validApiName = ParameterNamingHelper.GenerateValidParameterName(apiName, ParameterPrefix.Api);
142+
143+
if (extractorParameters.ApiParameters.IsNullOrEmpty())
144+
{
145+
apiOAuthScope = apiDetails.Properties.AuthenticationSettings.OAuth2?.Scope;
146+
}
147+
else
148+
{
149+
if (extractorParameters.ApiParameters.ContainsKey(apiName))
150+
{
151+
apiOAuthScope = extractorParameters.ApiParameters[apiName].Oauth2Scope;
152+
}
153+
}
154+
155+
apiOauth2Scopes.Add(validApiName, apiOAuthScope);
156+
}
157+
}
158+
159+
parameters.Add(ParameterNames.ApiOauth2ScopeSettings, new TemplateObjectParameterProperties() { Value = apiOauth2Scopes });
160+
}
161+
122162
void AddNamedValuesParameters()
123163
{
124164
if (!extractorParameters.ParameterizeNamedValue &&
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// --------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License.
4+
// --------------------------------------------------------------------------
5+
6+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Extractor.Models
7+
{
8+
public class ApiParameterProperty
9+
{
10+
public string Oauth2Scope { get; }
11+
12+
public string ServiceUrl { get; }
13+
14+
public ApiParameterProperty(string oauth2Scope, string serviceUrl)
15+
{
16+
this.Oauth2Scope = oauth2Scope;
17+
this.ServiceUrl = serviceUrl;
18+
}
19+
}
20+
}

src/ArmTemplates/Extractor/Models/ExtractorParameters.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
using System;
77
using System.Collections.Generic;
8+
using System.Linq;
89
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Commands.Configurations;
910
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Extensions;
1011
using Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.FileHandlers;
@@ -61,8 +62,6 @@ public record ExtractorParameters
6162

6263
public string ApiVersionSetName { get; private set; }
6364

64-
public ServiceUrlProperty[] ServiceUrlParameters { get; private set; }
65-
6665
public bool ParameterizeServiceUrl { get; private set; }
6766

6867
public bool ParameterizeNamedValue { get; private set; }
@@ -85,6 +84,10 @@ public record ExtractorParameters
8584

8685
public bool OverrideProductGuids { get; set; }
8786

87+
public bool ParametrizeApiOauth2Scope { get; set; }
88+
89+
public Dictionary<string, ApiParameterProperty> ApiParameters { get; private set; }
90+
8891
public ExtractorParameters(ExtractorConsoleAppConfiguration extractorConfig)
8992
{
9093
this.SourceApimName = extractorConfig.SourceApimName;
@@ -99,8 +102,6 @@ public ExtractorParameters(ExtractorConsoleAppConfiguration extractorConfig)
99102
this.PolicyXMLSasToken = extractorConfig.PolicyXMLSasToken;
100103
this.ApiVersionSetName = extractorConfig.ApiVersionSetName;
101104
this.IncludeAllRevisions = extractorConfig.IncludeAllRevisions != null && extractorConfig.IncludeAllRevisions.Equals("true", StringComparison.OrdinalIgnoreCase);
102-
this.ServiceUrlParameters = extractorConfig.ServiceUrlParameters;
103-
this.ParameterizeServiceUrl = extractorConfig.ParamServiceUrl != null && extractorConfig.ParamServiceUrl.Equals("true", StringComparison.OrdinalIgnoreCase) || extractorConfig.ServiceUrlParameters != null;
104105
this.ParameterizeNamedValue = extractorConfig.ParamNamedValue != null && extractorConfig.ParamNamedValue.Equals("true", StringComparison.OrdinalIgnoreCase);
105106
this.ParameterizeApiLoggerId = extractorConfig.ParamApiLoggerId != null && extractorConfig.ParamApiLoggerId.Equals("true", StringComparison.OrdinalIgnoreCase);
106107
this.ParameterizeLogResourceId = extractorConfig.ParamLogResourceId != null && extractorConfig.ParamLogResourceId.Equals("true", StringComparison.OrdinalIgnoreCase);
@@ -115,6 +116,9 @@ public ExtractorParameters(ExtractorConsoleAppConfiguration extractorConfig)
115116
this.ExtractGateways = extractorConfig.ExtractGateways != null && extractorConfig.ExtractGateways.Equals("true", StringComparison.OrdinalIgnoreCase);
116117
this.OverrideGroupGuids = extractorConfig.OverrideGroupGuids != null && extractorConfig.OverrideGroupGuids.Equals("true", StringComparison.OrdinalIgnoreCase);
117118
this.OverrideProductGuids = extractorConfig.OverrideProductGuids != null && extractorConfig.OverrideProductGuids.Equals("true", StringComparison.OrdinalIgnoreCase);
119+
this.ApiParameters = extractorConfig.ApiParameters;
120+
this.ParameterizeServiceUrl = extractorConfig.ParamServiceUrl != null && extractorConfig.ParamServiceUrl.Equals("true", StringComparison.OrdinalIgnoreCase) || (extractorConfig.ApiParameters != null && extractorConfig.ApiParameters.Any(x => x.Value.ServiceUrl is not null));
121+
this.ParametrizeApiOauth2Scope = (extractorConfig.ParamApiOauth2Scope != null && extractorConfig.ParamApiOauth2Scope.Equals("true", StringComparison.OrdinalIgnoreCase)) || (extractorConfig.ApiParameters != null && extractorConfig.ApiParameters.Any(x => x.Value.Oauth2Scope is not null));
118122
}
119123

120124
public ExtractorParameters OverrideConfiguration(ExtractorConsoleAppConfiguration overridingConfig)
@@ -137,7 +141,7 @@ public ExtractorParameters OverrideConfiguration(ExtractorConsoleAppConfiguratio
137141
// there can be no service url parameters in overriding configuration
138142
// this.ServiceUrlParameters = overridingConfig.ServiceUrlParameters ?? this.ServiceUrlParameters;
139143

140-
this.ParameterizeServiceUrl = !string.IsNullOrEmpty(overridingConfig.ParamServiceUrl) ? overridingConfig.ParamServiceUrl.Equals("true", StringComparison.OrdinalIgnoreCase) || overridingConfig.ServiceUrlParameters != null : this.ParameterizeServiceUrl;
144+
this.ParameterizeServiceUrl = !string.IsNullOrEmpty(overridingConfig.ParamServiceUrl) ? overridingConfig.ParamServiceUrl.Equals("true", StringComparison.OrdinalIgnoreCase) : this.ParameterizeServiceUrl;
141145
this.ParameterizeNamedValue = !string.IsNullOrEmpty(overridingConfig.ParamNamedValue) ? overridingConfig.ParamNamedValue.Equals("true", StringComparison.OrdinalIgnoreCase) : this.ParameterizeNamedValue;
142146
this.ParameterizeApiLoggerId = !string.IsNullOrEmpty(overridingConfig.ParamApiLoggerId) ? overridingConfig.ParamApiLoggerId.Equals("true", StringComparison.OrdinalIgnoreCase) : this.ParameterizeApiLoggerId;
143147
this.ParameterizeLogResourceId = !string.IsNullOrEmpty(overridingConfig.ParamLogResourceId) ? overridingConfig.ParamLogResourceId.Equals("true", StringComparison.OrdinalIgnoreCase) : this.ParameterizeLogResourceId;
@@ -147,6 +151,7 @@ public ExtractorParameters OverrideConfiguration(ExtractorConsoleAppConfiguratio
147151
this.SplitApis = !string.IsNullOrEmpty(overridingConfig.SplitAPIs) ? overridingConfig.SplitAPIs.Equals("true", StringComparison.OrdinalIgnoreCase) : this.SplitApis;
148152
this.IncludeAllRevisions = !string.IsNullOrEmpty(overridingConfig.IncludeAllRevisions) ? overridingConfig.IncludeAllRevisions.Equals("true", StringComparison.OrdinalIgnoreCase) : this.IncludeAllRevisions;
149153
this.ExtractGateways = !string.IsNullOrEmpty(overridingConfig.ExtractGateways) ? overridingConfig.ExtractGateways.Equals("true", StringComparison.OrdinalIgnoreCase) : this.ExtractGateways;
154+
this.ParametrizeApiOauth2Scope = !string.IsNullOrEmpty(overridingConfig.ParamApiOauth2Scope) ? overridingConfig.ParamApiOauth2Scope.Equals("true", StringComparison.OrdinalIgnoreCase) : this.ParametrizeApiOauth2Scope;
150155

151156
if (!string.IsNullOrEmpty(overridingConfig.BaseFileName))
152157
{

0 commit comments

Comments
 (0)