Skip to content

Commit

Permalink
Add Async method to ContentDefinitionManager to prevent possible thre…
Browse files Browse the repository at this point in the history
…ad starvation (#14668)
  • Loading branch information
MikeAlhayek authored Nov 23, 2023
1 parent 3146636 commit 582653c
Show file tree
Hide file tree
Showing 175 changed files with 1,823 additions and 1,318 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public async Task<IActionResult> Index()
if (model.CanManageDashboard || await _authorizationService.AuthorizeAsync(User, Permissions.AccessAdminDashboard))
{
var wrappers = new List<DashboardWrapper>();
var widgetContentTypes = GetDashboardWidgets();
var widgetContentTypes = await GetDashboardWidgetsAsync();

var widgets = await _adminDashboardService.GetWidgetsAsync(x => x.Published);
foreach (var widget in widgets)
Expand Down Expand Up @@ -99,7 +99,7 @@ public async Task<IActionResult> Manage()
});

var dashboardCreatable = new List<SelectListItem>();
var widgetContentTypes = GetDashboardWidgets();
var widgetContentTypes = await GetDashboardWidgetsAsync();

var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);

Expand Down Expand Up @@ -202,8 +202,8 @@ public async Task<IActionResult> Update([FromForm] DashboardPartViewModel[] part
return RedirectToAction(nameof(Manage));
}

private Dictionary<string, ContentTypeDefinition> GetDashboardWidgets()
=> _contentDefinitionManager.ListTypeDefinitions()
private async Task<Dictionary<string, ContentTypeDefinition>> GetDashboardWidgetsAsync()
=> (await _contentDefinitionManager.ListTypeDefinitionsAsync())
.Where(t => t.StereotypeEquals("DashboardWidget"))
.ToDictionary(ctd => ctd.Name, ctd => ctd);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task<int> CreateAsync()
"Position")
);

_contentDefinitionManager.AlterPartDefinition("DashboardPart", builder => builder
await _contentDefinitionManager.AlterPartDefinitionAsync("DashboardPart", builder => builder
.Attachable()
.WithDescription("Provides a way to add widgets to a dashboard.")
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -61,7 +60,7 @@ public async override Task UpdatedAsync(UpdateContentContext context, AliasPart
return;
}

var pattern = GetPattern(part);
var pattern = await GetPatternAsync(part);

if (!string.IsNullOrEmpty(pattern))
{
Expand Down Expand Up @@ -122,9 +121,9 @@ public override async Task CloningAsync(CloneContentContext context, AliasPart p
/// <summary>
/// Get the pattern from the AliasPartSettings property for its type.
/// </summary>
private string GetPattern(AliasPart part)
private async Task<string> GetPatternAsync(AliasPart part)
{
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType);
var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.PartDefinition.Name, nameof(AliasPart)));
var pattern = contentTypePartDefinition.GetSettings<AliasPartSettings>().Pattern;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public AliasPartIndexProvider(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
}

public override Task UpdatedAsync(UpdateContentContext context)
public override async Task UpdatedAsync(UpdateContentContext context)
{
var part = context.ContentItem.As<AliasPart>();

Expand All @@ -43,19 +43,19 @@ public override Task UpdatedAsync(UpdateContentContext context)
_contentDefinitionManager ??= _serviceProvider.GetRequiredService<IContentDefinitionManager>();

// Search for this part.
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType);
if (!contentTypeDefinition.Parts.Any(ctpd => ctpd.Name == nameof(AliasPart)))
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType);
if (!contentTypeDefinition.Parts.Any(ctd => ctd.Name == nameof(AliasPart)))
{
context.ContentItem.Remove<AliasPart>();
_partRemoved.Add(context.ContentItem.ContentItemId);
}
}

return Task.CompletedTask;
}

public string CollectionName { get; set; }

public Type ForType() => typeof(ContentItem);

public void Describe(IDescriptor context) => Describe((DescribeContext<ContentItem>)context);

public void Describe(DescribeContext<ContentItem> context)
Expand Down
5 changes: 3 additions & 2 deletions src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using OrchardCore.Alias.Indexes;
using OrchardCore.Alias.Models;
using OrchardCore.ContentManagement.Metadata;
Expand All @@ -16,9 +17,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager)
_contentDefinitionManager = contentDefinitionManager;
}

public int Create()
public async Task<int> CreateAsync()
{
_contentDefinitionManager.AlterPartDefinition(nameof(AliasPart), builder => builder
await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(AliasPart), builder => builder
.Attachable()
.WithDescription("Provides a way to define custom aliases for content items."));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,21 @@ public ArchiveLaterPartIndexProvider(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
}

public override Task UpdatedAsync(UpdateContentContext context)
public override async Task UpdatedAsync(UpdateContentContext context)
{
var part = context.ContentItem.As<ArchiveLaterPart>();

if (part != null)
{
_contentDefinitionManager ??= _serviceProvider.GetRequiredService<IContentDefinitionManager>();

var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType);
if (!contentTypeDefinition.Parts.Any(pd => pd.Name == nameof(ArchiveLaterPart)))
{
context.ContentItem.Remove<ArchiveLaterPart>();
_partRemoved.Add(context.ContentItem.ContentItemId);
}
}

return Task.CompletedTask;
}

public string CollectionName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using OrchardCore.ArchiveLater.Indexes;
using OrchardCore.ArchiveLater.Models;
using OrchardCore.ContentManagement.Metadata;
Expand All @@ -17,9 +18,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager)
_contentDefinitionManager = contentDefinitionManager;
}

public int Create()
public async Task<int> CreateAsync()
{
_contentDefinitionManager.AlterPartDefinition(nameof(ArchiveLaterPart), builder => builder
await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(ArchiveLaterPart), builder => builder
.Attachable()
.WithDescription("Adds the ability to schedule content items to be archived at a given future date and time."));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ public async override Task CloningAsync(CloneContentContext context, AutoroutePa

public override Task GetContentItemAspectAsync(ContentItemAspectContext context, AutoroutePart part)
{
return context.ForAsync<RouteHandlerAspect>(aspect =>
return context.ForAsync<RouteHandlerAspect>(async aspect =>
{
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType);
var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.PartDefinition.Name, "AutoroutePart"));
var settings = contentTypePartDefinition.GetSettings<AutoroutePartSettings>();
if (settings.ManageContainedItemRoutes)
Expand All @@ -163,8 +163,6 @@ public override Task GetContentItemAspectAsync(ContentItemAspectContext context,
aspect.Absolute = part.Absolute;
aspect.Disabled = part.Disabled;
}

return Task.CompletedTask;
});
}

Expand Down Expand Up @@ -380,7 +378,7 @@ private async Task GenerateContainerPathFromPatternAsync(AutoroutePart part)
return;
}

var pattern = GetPattern(part);
var pattern = await GetPatternAsync(part);

if (!string.IsNullOrEmpty(pattern))
{
Expand Down Expand Up @@ -422,9 +420,9 @@ private async Task GenerateContainerPathFromPatternAsync(AutoroutePart part)
/// <summary>
/// Get the pattern from the AutoroutePartSettings property for its type.
/// </summary>
private string GetPattern(AutoroutePart part)
private async Task<string> GetPatternAsync(AutoroutePart part)
{
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType);
var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.PartDefinition.Name, nameof(AutoroutePart)));
var pattern = contentTypePartDefinition.GetSettings<AutoroutePartSettings>().Pattern;

Expand Down
9 changes: 5 additions & 4 deletions src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using OrchardCore.Autoroute.Core.Indexes;
using OrchardCore.Autoroute.Models;
using OrchardCore.ContentManagement.Metadata;
Expand All @@ -16,9 +17,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager)
_contentDefinitionManager = contentDefinitionManager;
}

public int Create()
public async Task<int> CreateAsync()
{
_contentDefinitionManager.AlterPartDefinition("AutoroutePart", builder => builder
await _contentDefinitionManager.AlterPartDefinitionAsync("AutoroutePart", builder => builder
.Attachable()
.WithDescription("Provides a custom url for your content item."));

Expand All @@ -37,9 +38,9 @@ public int Create()

// Migrate PartSettings. This only needs to run on old content definition schemas.
// This code can be removed in a later version.
public int UpdateFrom1()
public async Task<int> UpdateFrom1Async()
{
_contentDefinitionManager.MigratePartSettings<AutoroutePart, AutoroutePartSettings>();
await _contentDefinitionManager.MigratePartSettingsAsync<AutoroutePart, AutoroutePartSettings>();

return 2;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,24 @@ IContentManager contentManager

public async Task<string> GetRouteAsync(SitemapBuilderContext context, ContentItem contentItem)
{
var ctd = ListRoutableTypeDefinitions()?
.FirstOrDefault(rctd => rctd.Name == contentItem.ContentType);
var ctd = (await ListRoutableTypeDefinitionsAsync())?.FirstOrDefault(ctd => ctd.Name == contentItem.ContentType);

if (ctd != null)
{
var contentItemMetadata = await _contentManager.PopulateAspectAsync<ContentItemMetadata>(contentItem);
var routes = contentItemMetadata.DisplayRouteValues;

// UrlHelper.Action includes BasePath automatically if present.
// If content item is assigned as home route, Urlhelper resolves as site root.
// If content item is assigned as home route, UrlHelper resolves as site root.
return context.HostPrefix + context.UrlHelper.Action(routes["Action"].ToString(), routes);
}

return null;
}

public IEnumerable<ContentTypeDefinition> ListRoutableTypeDefinitions()
public async Task<IEnumerable<ContentTypeDefinition>> ListRoutableTypeDefinitionsAsync()
{
return _contentDefinitionManager.ListTypeDefinitions()
return (await _contentDefinitionManager.ListTypeDefinitionsAsync())
.Where(ctd => ctd.Parts.Any(p => p.Name == nameof(AutoroutePart)));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public async Task<IActionResult> SearchContentItems(string part, string field, s
return BadRequest("Part and field are required parameters");
}

var partFieldDefinition = _contentDefinitionManager.GetPartDefinition(part)?.Fields
var partFieldDefinition = (await _contentDefinitionManager.GetPartDefinitionAsync(part))?.Fields
.FirstOrDefault(f => f.Name == field);

var fieldSettings = partFieldDefinition?.GetSettings<ContentPickerFieldSettings>();
Expand All @@ -57,7 +57,7 @@ public async Task<IActionResult> SearchContentItems(string part, string field, s

if (fieldSettings.DisplayedStereotypes != null && fieldSettings.DisplayedStereotypes.Length > 0)
{
contentTypes = _contentDefinitionManager.ListTypeDefinitions()
contentTypes = (await _contentDefinitionManager.ListTypeDefinitionsAsync())
.Where(contentType =>
{
var hasStereotype = contentType.TryGetStereotype(out var stereotype);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public async Task<IActionResult> SearchLocalizationSets(string part, string fiel
return BadRequest("Part and field are required parameters");
}

var partFieldDefinition = _contentDefinitionManager.GetPartDefinition(part)?.Fields
var partFieldDefinition = (await _contentDefinitionManager.GetPartDefinitionAsync(part))?.Fields
.FirstOrDefault(f => f.Name == field);

var fieldSettings = partFieldDefinition?.GetSettings<LocalizationSetContentPickerFieldSettings>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
Expand Down Expand Up @@ -53,7 +52,7 @@ public async Task<IActionResult> SearchUsers(string part, string field, string c
return Forbid();
}

var partFieldDefinition = _contentDefinitionManager.GetPartDefinition(part)?.Fields
var partFieldDefinition = (await _contentDefinitionManager.GetPartDefinitionAsync(part))?.Fields
.FirstOrDefault(f => f.Name == field);

var fieldSettings = partFieldDefinition?.GetSettings<UserPickerFieldSettings>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ private static async Task<object> RenderHtml(IResolveFieldContext<HtmlField> ctx
var paths = jsonPath.Split('.');
var partName = paths[0];
var fieldName = paths[1];
var contentTypeDefinition = contentDefinitionManager.GetTypeDefinition(ctx.Source.ContentItem.ContentType);
var contentTypeDefinition = await contentDefinitionManager.GetTypeDefinitionAsync(ctx.Source.ContentItem.ContentType);
var contentPartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.Name, partName));
var contentPartFieldDefintion = contentPartDefinition.PartDefinition.Fields.FirstOrDefault(x => string.Equals(x.Name, fieldName));
var settings = contentPartFieldDefintion.GetSettings<HtmlFieldSettings>();
var contentPartFieldDefinition = contentPartDefinition.PartDefinition.Fields.FirstOrDefault(x => string.Equals(x.Name, fieldName));
var settings = contentPartFieldDefinition.GetSettings<HtmlFieldSettings>();

var html = ctx.Source.Html;

Expand All @@ -59,7 +59,7 @@ private static async Task<object> RenderHtml(IResolveFieldContext<HtmlField> ctx
Html = ctx.Source.Html,
Field = ctx.Source,
Part = ctx.Source.ContentItem.Get<ContentPart>(partName),
PartFieldDefinition = contentPartFieldDefintion
PartFieldDefinition = contentPartFieldDefinition
};
var liquidTemplateManager = serviceProvider.GetRequiredService<ILiquidTemplateManager>();
var htmlEncoder = serviceProvider.GetService<HtmlEncoder>();
Expand All @@ -72,7 +72,7 @@ private static async Task<object> RenderHtml(IResolveFieldContext<HtmlField> ctx
new Context
{
["ContentItem"] = ctx.Source.ContentItem,
["PartFieldDefinition"] = contentPartFieldDefintion
["PartFieldDefinition"] = contentPartFieldDefinition
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public BooleanFieldIndexProvider(IServiceProvider serviceProvider)
public override void Describe(DescribeContext<ContentItem> context)
{
context.For<BooleanFieldIndex>()
.Map(contentItem =>
.Map(async contentItem =>
{
// Remove index records of soft deleted items.
if (!contentItem.Published && !contentItem.Latest)
Expand All @@ -47,7 +47,7 @@ public override void Describe(DescribeContext<ContentItem> context)
_contentDefinitionManager ??= _serviceProvider.GetRequiredService<IContentDefinitionManager>();

// Search for BooleanField
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType);

// This can occur when content items become orphaned, particularly layer widgets when a layer is removed, before its widgets have been unpublished.
if (contentTypeDefinition == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ContentPickerFieldIndexProvider(IServiceProvider serviceProvider)
public override void Describe(DescribeContext<ContentItem> context)
{
context.For<ContentPickerFieldIndex>()
.Map(contentItem =>
.Map(async contentItem =>
{
// Remove index records of soft deleted items.
if (!contentItem.Published && !contentItem.Latest)
Expand All @@ -47,7 +47,7 @@ public override void Describe(DescribeContext<ContentItem> context)
_contentDefinitionManager ??= _serviceProvider.GetRequiredService<IContentDefinitionManager>();

// Search for ContentPickerField
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType);

// This can occur when content items become orphaned, particularly layer widgets when a layer is removed, before its widgets have been unpublished.
if (contentTypeDefinition == null)
Expand Down
Loading

0 comments on commit 582653c

Please sign in to comment.