Skip to content

Commit

Permalink
Moving to file-scoped namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Piedone committed Mar 16, 2022
1 parent b34d30d commit 5b13a38
Show file tree
Hide file tree
Showing 63 changed files with 2,437 additions and 2,500 deletions.
11 changes: 5 additions & 6 deletions ContentTypes.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
namespace Lombiq.TrainingDemo
namespace Lombiq.TrainingDemo;

// Instead of copy-pasting we store frequently used content type names here.
public static class ContentTypes
{
// Instead of copy-pasting we store frequently used content type names here.
public static class ContentTypes
{
public const string PersonPage = nameof(PersonPage);
}
public const string PersonPage = nameof(PersonPage);
}
129 changes: 64 additions & 65 deletions Controllers/AdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,84 +16,83 @@
using System.Threading.Tasks;
using YesSql;

namespace Lombiq.TrainingDemo.Controllers
namespace Lombiq.TrainingDemo.Controllers;

// If you have multiple admin controllers then name them whatever you want but put an [Admin] attribute on them.
public class AdminController : Controller
{
// If you have multiple admin controllers then name them whatever you want but put an [Admin] attribute on them.
public class AdminController : Controller
{
private readonly IContentItemDisplayManager _contentItemDisplayManager;
private readonly ISession _session;
private readonly IAuthorizationService _authorizationService;
private readonly IUpdateModelAccessor _updateModelAccessor;
private readonly IContentItemDisplayManager _contentItemDisplayManager;
private readonly ISession _session;
private readonly IAuthorizationService _authorizationService;
private readonly IUpdateModelAccessor _updateModelAccessor;

public AdminController(
IContentItemDisplayManager contentItemDisplayManager,
ISession session,
IAuthorizationService authorizationService,
IUpdateModelAccessor updateModelAccessor)
{
_contentItemDisplayManager = contentItemDisplayManager;
_session = session;
_authorizationService = authorizationService;
_updateModelAccessor = updateModelAccessor;
}
public AdminController(
IContentItemDisplayManager contentItemDisplayManager,
ISession session,
IAuthorizationService authorizationService,
IUpdateModelAccessor updateModelAccessor)
{
_contentItemDisplayManager = contentItemDisplayManager;
_session = session;
_authorizationService = authorizationService;
_updateModelAccessor = updateModelAccessor;
}

// Let's see how it will be displayed, just type the default URL (/Lombiq.TrainingDemo/Admin/Index) into the
// browser with an administrator account (or at least a user who has a role that has AccessAdmin permission).
// If you are anonymous then a login page will automatically appear. The permission check (i.e. has AccessAdmin
// permission) will be automatic as well.
public ActionResult Index() => View();
// Let's see how it will be displayed, just type the default URL (/Lombiq.TrainingDemo/Admin/Index) into the
// browser with an administrator account (or at least a user who has a role that has AccessAdmin permission).
// If you are anonymous then a login page will automatically appear. The permission check (i.e. has AccessAdmin
// permission) will be automatic as well.
public ActionResult Index() => View();

// You don't have to access the below two actions by typing in their URLs because we have admin menu items for
// them!
// NEXT STATION: Navigation/PersonsAdminMenu.cs
// You don't have to access the below two actions by typing in their URLs because we have admin menu items for
// them!
// NEXT STATION: Navigation/PersonsAdminMenu.cs

public async Task<ActionResult> PersonListNewest()
public async Task<ActionResult> PersonListNewest()
{
// If the user needs to have a specific permission to access a page on the admin panel (besides the
// AccessAdmin permission) you need to check it here.
if (!await _authorizationService.AuthorizeAsync(User, PersonPermissions.AccessPersonListDashboard))
{
// If the user needs to have a specific permission to access a page on the admin panel (besides the
// AccessAdmin permission) you need to check it here.
if (!await _authorizationService.AuthorizeAsync(User, PersonPermissions.AccessPersonListDashboard))
{
return Unauthorized();
}

// Nothing special here just display the last 10 Person Page content items.
var persons = await _session
.Query<ContentItem, ContentItemIndex>()
.Where(index => index.ContentType == ContentTypes.PersonPage)
.OrderByDescending(index => index.CreatedUtc)
.Take(10)
.ListAsync();

// In the Views/Admin/PersonList.cshtml file you can see how shape lists (IEnumerable<dynamic>) are
// displayed.
return View("PersonList", await GetShapesAsync(persons));
return Unauthorized();
}

public async Task<ActionResult> PersonListOldest()
{
if (!await _authorizationService.AuthorizeAsync(User, PersonPermissions.AccessPersonListDashboard))
{
return Unauthorized();
}
// Nothing special here just display the last 10 Person Page content items.
var persons = await _session
.Query<ContentItem, ContentItemIndex>()
.Where(index => index.ContentType == ContentTypes.PersonPage)
.OrderByDescending(index => index.CreatedUtc)
.Take(10)
.ListAsync();

// Display the first 10 Person Page content items.
var persons = await _session
.Query<ContentItem, ContentItemIndex>()
.Where(index => index.ContentType == ContentTypes.PersonPage)
.OrderBy(index => index.CreatedUtc)
.Take(10)
.ListAsync();
// In the Views/Admin/PersonList.cshtml file you can see how shape lists (IEnumerable<dynamic>) are
// displayed.
return View("PersonList", await GetShapesAsync(persons));
}

return View("PersonList", await GetShapesAsync(persons));
public async Task<ActionResult> PersonListOldest()
{
if (!await _authorizationService.AuthorizeAsync(User, PersonPermissions.AccessPersonListDashboard))
{
return Unauthorized();
}

private async Task<IEnumerable<IShape>> GetShapesAsync(IEnumerable<ContentItem> persons) =>
// Notice the "SummaryAdmin" display type which is a built in display type specifically for listing items on
// the dashboard.
await persons.AwaitEachAsync(async person =>
await _contentItemDisplayManager.BuildDisplayAsync(person, _updateModelAccessor.ModelUpdater, "SummaryAdmin"));
// Display the first 10 Person Page content items.
var persons = await _session
.Query<ContentItem, ContentItemIndex>()
.Where(index => index.ContentType == ContentTypes.PersonPage)
.OrderBy(index => index.CreatedUtc)
.Take(10)
.ListAsync();

return View("PersonList", await GetShapesAsync(persons));
}

private async Task<IEnumerable<IShape>> GetShapesAsync(IEnumerable<ContentItem> persons) =>
// Notice the "SummaryAdmin" display type which is a built in display type specifically for listing items on
// the dashboard.
await persons.AwaitEachAsync(async person =>
await _contentItemDisplayManager.BuildDisplayAsync(person, _updateModelAccessor.ModelUpdater, "SummaryAdmin"));
}

// END OF TRAINING SECTION: Admin menus
Expand Down
87 changes: 43 additions & 44 deletions Controllers/ApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,58 @@
using OrchardCore.ContentManagement;
using System.Threading.Tasks;

namespace Lombiq.TrainingDemo.Controllers
namespace Lombiq.TrainingDemo.Controllers;

// This controller will retrieve a Person Page content item for us as a simple example that nevertheless showcases
// the most important things you need to know. If you want to see a more complex example of such a controller do
// check out the ApiController in the OrchardCore.Content module in the official source.

// Using attribute routing to have a proper route for all actions in this controller.
[Route("api/Lombiq.TrainingDemo")]
// The ApiController attribute is not strictly mandatory but pretty useful, see:
// https://docs.microsoft.com/en-us/aspnet/core/web-api/#apicontroller-attribute
[ApiController]
// We'll handle authorization within the actions (i.e. API endpoints) so nothing else needed here. Note that API
// endpoints should most of the time use the "Api" authentication scheme: This is not the same that standard users
// are authenticated with (via cookies).
[Authorize(AuthenticationSchemes = "Api"), IgnoreAntiforgeryToken, AllowAnonymous]
public class ApiController : Controller
{
// This controller will retrieve a Person Page content item for us as a simple example that nevertheless showcases
// the most important things you need to know. If you want to see a more complex example of such a controller do
// check out the ApiController in the OrchardCore.Content module in the official source.
private readonly IAuthorizationService _authorizationService;
private readonly IContentManager _contentManager;

// Using attribute routing to have a proper route for all actions in this controller.
[Route("api/Lombiq.TrainingDemo")]
// The ApiController attribute is not strictly mandatory but pretty useful, see:
// https://docs.microsoft.com/en-us/aspnet/core/web-api/#apicontroller-attribute
[ApiController]
// We'll handle authorization within the actions (i.e. API endpoints) so nothing else needed here. Note that API
// endpoints should most of the time use the "Api" authentication scheme: This is not the same that standard users
// are authenticated with (via cookies).
[Authorize(AuthenticationSchemes = "Api"), IgnoreAntiforgeryToken, AllowAnonymous]
public class ApiController : Controller
public ApiController(IAuthorizationService authorizationService, IContentManager contentManager)
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentManager _contentManager;
_authorizationService = authorizationService;
_contentManager = contentManager;
}

public ApiController(IAuthorizationService authorizationService, IContentManager contentManager)
// You can look up the ID of a Person Page that you've created previously (when you open one from the admin
// content item list the URL will contain it as /Admin/Contents/ContentItems/<content item ID>) and use it to
// access this action under /api/Lombiq.TrainingDemo?contentItemId=<content item ID>. Note though that you'll
// only be able to authorize with a client ID and secret of an OpenID app set up from the Orchard admin. For
// more info see: https://docs.orchardcore.net/en/latest/docs/reference/modules/OpenId/.
// If you just want to quickly test this API then remove the Authorize attribute above.
public async Task<IActionResult> Get(string contentItemId)
{
// Authorization is important in API endpoints as well of course. We're re-using the previously created
// permission here. To authenticate with the API you can use any ASP.NET Core authentication scheme but
// Orchard offers various OpenID-based options. If you just want to quickly check out the API then grant the
// permission for the Anonymous role on the admin.
if (!await _authorizationService.AuthorizeAsync(User, PersonPermissions.ManagePersons))
{
_authorizationService = authorizationService;
_contentManager = contentManager;
return this.ChallengeOrForbid("Api");
}

// You can look up the ID of a Person Page that you've created previously (when you open one from the admin
// content item list the URL will contain it as /Admin/Contents/ContentItems/<content item ID>) and use it to
// access this action under /api/Lombiq.TrainingDemo?contentItemId=<content item ID>. Note though that you'll
// only be able to authorize with a client ID and secret of an OpenID app set up from the Orchard admin. For
// more info see: https://docs.orchardcore.net/en/latest/docs/reference/modules/OpenId/.
// If you just want to quickly test this API then remove the Authorize attribute above.
public async Task<IActionResult> Get(string contentItemId)
{
// Authorization is important in API endpoints as well of course. We're re-using the previously created
// permission here. To authenticate with the API you can use any ASP.NET Core authentication scheme but
// Orchard offers various OpenID-based options. If you just want to quickly check out the API then grant the
// permission for the Anonymous role on the admin.
if (!await _authorizationService.AuthorizeAsync(User, PersonPermissions.ManagePersons))
{
return this.ChallengeOrForbid("Api");
}

// Just the usual stuff again.
var contentItem = await _contentManager.GetAsync(contentItemId);
// Just the usual stuff again.
var contentItem = await _contentManager.GetAsync(contentItemId);

// Only allow the retrieval of Person Page items.
if (contentItem?.ContentType != ContentTypes.PersonPage) contentItem = null;
// Only allow the retrieval of Person Page items.
if (contentItem?.ContentType != ContentTypes.PersonPage) contentItem = null;

// The action will return the JSON representation of the content item automatically. You can then consume
// that from a web SPA or a mobile app, for example.
return contentItem == null ? NotFound() : Ok(contentItem);
}
// The action will return the JSON representation of the content item automatically. You can then consume
// that from a web SPA or a mobile app, for example.
return contentItem == null ? NotFound() : Ok(contentItem);
}
}

Expand Down
Loading

0 comments on commit 5b13a38

Please sign in to comment.