Skip to content

Commit

Permalink
Servicing for release/6.0 (#1911)
Browse files Browse the repository at this point in the history
* Fix spacing and change for minimal api scopes (#1901)

* adding IdentityHostingStartup file back (#1907)

* supporting os version tfm for "-windows" (#1909)

* Fixes for parameter updates and code modifier configs for web apps / … (#1905)

* Fixes for parameter updates and code modifier configs for web apps / web apis that use startup.cs

* Refactor top-level statement code modification

* Fix formatting

* Remove debugger

* Refactor appsettings.json modification logic (#1903)

* refactor appSettings

* Refactoring appsettings modifier

* refactor appSettings and ServerAPI block

* Refactor appsettings and tests

* PR comments

* bumping msidentity and aspnet-codegenerator v

Co-authored-by: Zachary Halzel <zahalzel@microsoft.com>
  • Loading branch information
deepchoudhery and zahalzel committed Jun 2, 2022
1 parent d86ca9a commit 8aaaee6
Show file tree
Hide file tree
Showing 18 changed files with 454 additions and 195 deletions.
2 changes: 1 addition & 1 deletion eng/Versions.MSIdentity.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<UsingToolNetFrameworkReferenceAssemblies>true</UsingToolNetFrameworkReferenceAssemblies>
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.0.4</VersionPrefix>
<VersionPrefix>1.0.5</VersionPrefix>
<PreReleaseVersionLabel>rtm</PreReleaseVersionLabel>
<IsServicingBuild Condition="'$(PreReleaseVersionLabel)' == 'servicing'">true</IsServicingBuild>
<!--
Expand Down
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<!-- Ref packages -->
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>6.0.5</VersionPrefix>
<VersionPrefix>6.0.6</VersionPrefix>
<PreReleaseVersionLabel>rtm</PreReleaseVersionLabel>
<IsServicingBuild Condition="'$(PreReleaseVersionLabel)' == 'servicing'">true</IsServicingBuild>
<!--
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System;
using Newtonsoft.Json.Linq;

namespace Microsoft.DotNet.MSIdentity.AuthenticationParameters
{
public class PropertyNames
Expand Down Expand Up @@ -29,9 +32,110 @@ public static class DefaultProperties
public const string ClientSecret = "Client secret from app-registration. Check user secrets/azure portal.";

public const string Authority = "https://login.microsoftonline.com/22222222-2222-2222-2222-222222222222";
public const string ValidateAuthority = "true";
public const bool ValidateAuthority = true;

public const string MicrosoftGraphBaseUrl = "https://graph.microsoft.com/v1.0";
public const string MicrosoftGraphScopes = "user.read";
public const string DefaultScopes = "user.read";
}

public class AzureAdBlock
{
public bool IsBlazorWasm;
public bool IsWebApi;

public string? ClientId;
public string? Instance = DefaultProperties.Instance;
public string? Domain;
public string? TenantId;
public string? Authority;
public string? CallbackPath = DefaultProperties.CallbackPath;

public string? Scopes;

public string? ClientSecret = DefaultProperties.ClientSecret;
public string[]? ClientCertificates;

public AzureAdBlock(ApplicationParameters applicationParameters)
{
IsBlazorWasm = applicationParameters.IsBlazorWasm;
IsWebApi = applicationParameters.IsWebApi.GetValueOrDefault();

Domain = !string.IsNullOrEmpty(applicationParameters.Domain) ? applicationParameters.Domain : null;
TenantId = !string.IsNullOrEmpty(applicationParameters.TenantId) ? applicationParameters.TenantId : null;
ClientId = !string.IsNullOrEmpty(applicationParameters.ClientId) ? applicationParameters.ClientId : null;
Instance = !string.IsNullOrEmpty(applicationParameters.Instance) ? applicationParameters.Instance : null;
Authority = !string.IsNullOrEmpty(applicationParameters.Authority) ? applicationParameters.Authority : null;
CallbackPath = !string.IsNullOrEmpty(applicationParameters.CallbackPath) ? applicationParameters.CallbackPath : null;
Scopes = !string.IsNullOrEmpty(applicationParameters.CalledApiScopes) ? applicationParameters.CalledApiScopes : null;
}

/// <summary>
/// Updates AzureAdBlock object from existing appSettings.json
/// </summary>
/// <param name="azureAdToken"></param>
public AzureAdBlock UpdateFromJToken(JToken azureAdToken)
{
JObject azureAdObj = JObject.FromObject(azureAdToken);

ClientId ??= azureAdObj.Value<string>(PropertyNames.ClientId); // here, if the applicationparameters value is null, we use the existing app settings value
Instance ??= azureAdObj.Value<string>(PropertyNames.Instance);
Domain ??= azureAdObj.Value<string>(PropertyNames.Domain);
TenantId ??= azureAdObj.Value<string>(PropertyNames.TenantId);
Authority ??= azureAdObj.Value<string>(PropertyNames.Authority);
CallbackPath ??= azureAdObj.Value<string>(PropertyNames.CallbackPath);
Scopes ??= azureAdObj.Value<string>(PropertyNames.Scopes);
ClientSecret ??= azureAdObj.Value<string>(PropertyNames.ClientSecret);
ClientCertificates ??= azureAdObj.Value<string[]>(PropertyNames.ClientCertificates);

return this;
}

public dynamic BlazorSettings => new
{
ClientId = ClientId ?? DefaultProperties.ClientId, // here, if a value is null, we could use the default properties
Authority = Authority ?? (string.IsNullOrEmpty(Instance) || string.IsNullOrEmpty(TenantId) ? DefaultProperties.Authority : $"{Instance}{TenantId}"),
ValidateAuthority = true
};

public dynamic WebAppSettings => new
{
Instance = Instance ?? DefaultProperties.Instance,
Domain = Domain ?? DefaultProperties.Domain,
TenantId = TenantId ?? DefaultProperties.TenantId,
ClientId = ClientId ?? DefaultProperties.ClientId,
CallbackPath = CallbackPath ?? DefaultProperties.CallbackPath
};

public dynamic WebApiSettings => new
{
Instance = Instance ?? DefaultProperties.Instance,
Domain = Domain ?? DefaultProperties.Domain,
TenantId = TenantId ?? DefaultProperties.TenantId,
ClientId = ClientId ?? DefaultProperties.ClientId,
CallbackPath = CallbackPath ?? DefaultProperties.CallbackPath,
Scopes = Scopes ?? DefaultProperties.DefaultScopes,
ClientSecret = ClientSecret ?? DefaultProperties.ClientSecret,
ClientCertificates = ClientCertificates ?? Array.Empty<string>()
};

public JObject ToJObject()
{
if (IsBlazorWasm)
{
return JObject.FromObject(BlazorSettings);
}
if (IsWebApi)
{
return JObject.FromObject(WebApiSettings);
}

return JObject.FromObject(WebAppSettings);
}
}

public class ApiSettingsBlock
{
public string? BaseUrl;
public string? Scopes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"MicrosoftGraph"
],
"MultiLineBlock": [
" AddMicrosoftGraph(builder.Configuration.GetSection(\"MicrosoftGraph\"))",
"AddMicrosoftGraph(builder.Configuration.GetSection(\"MicrosoftGraph\"))",
" .AddInMemoryTokenCaches()"
],
"LeadingTrivia": {
Expand All @@ -98,7 +98,7 @@
"DownstreamApi"
],
"MultiLineBlock": [
" AddDownstreamWebApi(\"DownstreamApi\",builder.Configuration.GetSection(\"DownstreamApi\"))",
"AddDownstreamWebApi(\"DownstreamApi\",builder.Configuration.GetSection(\"DownstreamApi\"))",
" .AddInMemoryTokenCaches()"
],
"LeadingTrivia": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"MultiLineBlock": [
"{",
" builder.Configuration.Bind(\"AzureAd\", options.ProviderOptions.Authentication);",
" options.ProviderOptions.DefaultAccessTokenScopes.Add(builder.Configuration[\"ServerApi\"]);",
" options.ProviderOptions.DefaultAccessTokenScopes.Add(builder.Configuration.GetSection(\"ServerApi\")[\"Scopes\"]);",
"}"
],
"Replace": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
},
{
"MultiLineBlock": [
" AddMicrosoftGraph(builder.Configuration.GetSection(\"MicrosoftGraph\"))",
"AddMicrosoftGraph(builder.Configuration.GetSection(\"MicrosoftGraph\"))",
" .AddInMemoryTokenCaches()"
],
"Parent": "EnableTokenAcquisitionToCallDownstreamApi",
Expand All @@ -58,7 +58,7 @@
},
{
"MultiLineBlock": [
" AddDownstreamWebApi(\"DownstreamApi\", WebApplication.CreateBuilder.Configuration.GetSection(\"DownstreamApi\"))",
"AddDownstreamWebApi(\"DownstreamApi\", WebApplication.CreateBuilder.Configuration.GetSection(\"DownstreamApi\"))",
" .AddInMemoryTokenCaches()"
],
"Parent": "EnableTokenAcquisitionToCallDownstreamApi",
Expand Down Expand Up @@ -88,7 +88,9 @@
},
{
"Block": "var scopeRequiredByApi = app.Configuration[\"AzureAd:Scopes\"]",
"InsertAfter": "app.UseAuthorization",
"InsertBefore": [
"app.MapGet"
],
"LeadingTrivia": {
"Newline": true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
"Parameters": [ "IServiceCollection" ],
"CodeChanges": [
{
"Block": "IServiceCollection.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)"
"Block": "IServiceCollection.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)",
"LeadingTrivia": {
"NumberOfSpaces": 12,
"Newline": true
}
},
{
"Parent": "IServiceCollection.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)",
Expand Down Expand Up @@ -74,7 +78,7 @@
},
{
"MultiLineBlock": [
" AddMicrosoftGraph(builder.Configuration.GetSection(\"MicrosoftGraph\"))",
"AddMicrosoftGraph(builder.Configuration.GetSection(\"MicrosoftGraph\"))",
" .AddInMemoryTokenCaches()"
],"Parent": "EnableTokenAcquisitionToCallDownstreamApi",
"CodeChangeType": "MemberAccess",
Expand All @@ -86,7 +90,7 @@
},
{
"MultiLineBlock": [
" AddDownstreamWebApi(\"DownstreamApi\", WebApplication.CreateBuilder.Configuration.GetSection(\"DownstreamApi\"))",
"AddDownstreamWebApi(\"DownstreamApi\", WebApplication.CreateBuilder.Configuration.GetSection(\"DownstreamApi\"))",
" .AddInMemoryTokenCaches()"
],
"Parent": "EnableTokenAcquisitionToCallDownstreamApi",
Expand Down Expand Up @@ -140,7 +144,11 @@
"CodeChanges": [
{
"InsertAfter": "IApplicationBuilder.UseRouting",
"Block": "IApplicationBuilder.UseAuthentication()"
"Block": "IApplicationBuilder.UseAuthentication()",
"LeadingTrivia": {
"NumberOfSpaces": 12,
"Newline": true
}
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
},
{
"Parent": "IApplicationBuilder.UseEndpoints",
"Parameter": "endpoints",
"CodeChangeType": "Lambda",
"Block": "endpoints.MapControllers()"
"Block": "endpoints.MapControllers()",
"LeadingTrivia": {
"NumberOfSpaces": 16
}
}
]
},
Expand Down Expand Up @@ -106,7 +110,7 @@
},
{
"MultiLineBlock": [
" AddMicrosoftGraph(builder.Configuration.GetSection(\"MicrosoftGraph\"))",
"AddMicrosoftGraph(builder.Configuration.GetSection(\"MicrosoftGraph\"))",
" .AddInMemoryTokenCaches()"
],
"Parent": "EnableTokenAcquisitionToCallDownstreamApi",
Expand All @@ -119,7 +123,7 @@
},
{
"MultiLineBlock": [
" AddDownstreamWebApi(\"DownstreamApi\",builder.Configuration.GetSection(\"DownstreamApi\"))",
"AddDownstreamWebApi(\"DownstreamApi\",builder.Configuration.GetSection(\"DownstreamApi\"))",
" .AddInMemoryTokenCaches()"
],
"Parent": "EnableTokenAcquisitionToCallDownstreamApi",
Expand Down Expand Up @@ -174,11 +178,11 @@
},
"Usings": [
"Microsoft.AspNetCore.Authentication",
"Microsoft.Identity.Web",
"Microsoft.Identity.Web.UI",
"Microsoft.AspNetCore.Authentication.OpenIdConnect",
"Microsoft.AspNetCore.Authorization",
"Microsoft.AspNetCore.Mvc.Authorization"
"Microsoft.AspNetCore.Mvc.Authorization",
"Microsoft.Identity.Web",
"Microsoft.Identity.Web.UI"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,15 @@ internal async Task ModifyCsFile(CodeFile file, CodeAnalysis.Project project, Co
}
if (!options.UsingTopLevelsStatements)
{
var mainMethod = root?.ChildNodes().FirstOrDefault(n => n is MethodDeclarationSyntax
&& ((MethodDeclarationSyntax)n).Identifier.ToString().Equals(Main, StringComparison.OrdinalIgnoreCase));
if (mainMethod != null)
var mainMethod = root?.DescendantNodes().OfType<MethodDeclarationSyntax>()
.FirstOrDefault(n => Main.Equals(n.Identifier.ToString(), StringComparison.OrdinalIgnoreCase));
if (mainMethod != null
&& DocumentBuilder.ApplyChangesToMethod(mainMethod.Body, filteredChanges) is BlockSyntax updatedBody)
{
var updatedMethod = DocumentBuilder.ApplyChangesToMethod(mainMethod, filteredChanges);
var updatedMethod = mainMethod.WithBody(updatedBody);
return root?.ReplaceNode(mainMethod, updatedMethod);
}

}
else if (root.Members.Any(node => node.IsKind(SyntaxKind.GlobalStatement)))
{
Expand All @@ -291,8 +293,8 @@ internal async Task ModifyCsFile(CodeFile file, CodeAnalysis.Project project, Co
var namespaceNode = root?.Members.OfType<BaseNamespaceDeclarationSyntax>()?.FirstOrDefault();

string className = ProjectModifierHelper.GetClassName(file.FileName);
// get classNode. All class changes are done on the ClassDeclarationSyntax and then that node is replaced using documentEditor.

// get classNode. All class changes are done on the ClassDeclarationSyntax and then that node is replaced using documentEditor.
if (namespaceNode?.DescendantNodes().FirstOrDefault(node =>
node is ClassDeclarationSyntax cds &&
cds.Identifier.ValueText.Contains(className)) is ClassDeclarationSyntax classNode)
Expand All @@ -303,10 +305,8 @@ node is ClassDeclarationSyntax cds &&
modifiedClassDeclarationSyntax = documentBuilder.AddProperties(modifiedClassDeclarationSyntax, options);
//add class attributes
modifiedClassDeclarationSyntax = documentBuilder.AddClassAttributes(modifiedClassDeclarationSyntax, options);

modifiedClassDeclarationSyntax = ModifyMethods(modifiedClassDeclarationSyntax, documentBuilder, file.Methods, options);

//add code snippets/changes.
modifiedClassDeclarationSyntax = ModifyMethods(modifiedClassDeclarationSyntax, documentBuilder, file.Methods, options);

//replace class node with all the updates.
#pragma warning disable CS8631 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type.
Expand All @@ -333,6 +333,12 @@ private static ClassDeclarationSyntax ModifyMethods(ClassDeclarationSyntax class
continue;
}

var parameters = ProjectModifierHelper.VerifyParameters(methodChanges.Parameters, methodNode.ParameterList.Parameters.ToList());
foreach ((string oldValue, string newValue) in parameters)
{
methodChanges.CodeChanges = ProjectModifierHelper.UpdateVariables(methodChanges.CodeChanges, oldValue, newValue);
}

var updatedMethodNode = DocumentBuilder.GetModifiedMethod(methodNode, methodChanges, options);
if (updatedMethodNode != null)
{
Expand Down
Loading

0 comments on commit 8aaaee6

Please sign in to comment.