(refactor): blog item models refactoring

This commit is contained in:
Maksym Sadovnychyy 2023-03-19 23:15:28 +01:00
parent 4c961920af
commit b4d484bf51
110 changed files with 2377 additions and 1782 deletions

View File

@ -11,7 +11,7 @@ namespace DataProviders.Collections
{ {
public interface IBlogCatalogDataProvider { public interface IBlogCatalogDataProvider {
(Guid?, IDomainResult) Insert(BlogDocument blogItem); (Guid?, IDomainResult) Insert(BlogDocument blogItem);
(BlogDocument?, IDomainResult) Get(Guid siteId, Guid blogId); (BlogDocument?, IDomainResult) Get(Guid siteId, Guid userId, Guid blogId);
(BlogDocument?, IDomainResult) GetBySlug(Guid siteId, string slug); (BlogDocument?, IDomainResult) GetBySlug(Guid siteId, string slug);
(List<BlogDocument>?, IDomainResult) GetBySlugs(Guid siteId, List<string> slugs); (List<BlogDocument>?, IDomainResult) GetBySlugs(Guid siteId, List<string> slugs);
(List<BlogDocument>?, IDomainResult) GetMany(Guid siteId, List<Guid> blogIds); (List<BlogDocument>?, IDomainResult) GetMany(Guid siteId, List<Guid> blogIds);
@ -34,8 +34,8 @@ namespace DataProviders.Collections
ISessionService sessionService) : base(logger, client, idGenerator, sessionService, _databaseName, _collectionName) { ISessionService sessionService) : base(logger, client, idGenerator, sessionService, _databaseName, _collectionName) {
} }
public (BlogDocument?, IDomainResult) Get(Guid siteId, Guid blogId) { public (BlogDocument?, IDomainResult) Get(Guid siteId, Guid userId, Guid blogId) {
var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.Id == blogId, x => x); var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.Author == userId && x.Id == blogId, x => x);
if (!result.IsSuccess || list == null) if (!result.IsSuccess || list == null)
return (null, result); return (null, result);

View File

@ -13,6 +13,8 @@ public class User : DomainObjectDocumentBase<User> {
public string Username { get; set; } public string Username { get; set; }
public MediaAttachment? Avatar { get; set; }
public Authentication Authentication { get; set; } public Authentication Authentication { get; set; }
public string? Name { get; set; } public string? Name { get; set; }

View File

@ -7,7 +7,7 @@ public class MediaAttachmentL10n : DomainObjectBase<MediaAttachmentL10n> {
public Locales Locale { get; set; } public Locales Locale { get; set; }
public string Alt { get; set; } public string Alt { get; set; }
public string? Target { get; set; } public string? Target { get; set; }
public string? Titile { get; set; } public string? Title { get; set; }
public string? Description { get; set; } public string? Description { get; set; }
public override int GetHashCode() { public override int GetHashCode() {
@ -18,8 +18,8 @@ public class MediaAttachmentL10n : DomainObjectBase<MediaAttachmentL10n> {
if(Target != null) if(Target != null)
hash = hash * 23 + Target.GetHashCode(); hash = hash * 23 + Target.GetHashCode();
if (Titile != null) if (Title != null)
hash = hash * 23 + Target.GetHashCode(); hash = hash * 23 + Title.GetHashCode();
if (Description != null) if (Description != null)
hash = hash * 23 + Description.GetHashCode(); hash = hash * 23 + Description.GetHashCode();

View File

@ -0,0 +1,61 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace WeatherForecast.Controllers.Abstractions {
/// <summary>
///
/// </summary>
public class AuthorizationControllerBase : ControllerBase {
private readonly IAuthorizationService _authorizationService;
/// <summary>
///
/// </summary>
/// <param name="authorizationService"></param>
public AuthorizationControllerBase(
IAuthorizationService authorizationService
) {
_authorizationService = authorizationService;
}
/// <summary>
///
/// </summary>
/// <typeparam name="TRequirement"></typeparam>
/// <param name="requirement"></param>
/// <param name="businessLogic"></param>
/// <returns></returns>
protected async Task<IActionResult> AuthorizeAsync<TRequirement>(TRequirement requirement, Func<IActionResult> businessLogic)
where TRequirement : IAuthorizationRequirement {
var authorizationResult = await _authorizationService.AuthorizeAsync(User, null, requirement);
if (authorizationResult.Succeeded) {
return businessLogic();
}
return Unauthorized();
}
/// <summary>
///
/// </summary>
/// <typeparam name="TRequirement"></typeparam>
/// <typeparam name="TResource"></typeparam>
/// <param name="requirement"></param>
/// <param name="resource"></param>
/// <param name="businessLogic"></param>
/// <returns></returns>
public async Task<IActionResult> AuthorizeAsync<TRequirement, TResource>(TRequirement requirement, TResource resource, Func<IActionResult> businessLogic)
where TRequirement : IAuthorizationRequirement {
var authorizationResult = await _authorizationService.AuthorizeAsync(User, resource, requirement);
if (authorizationResult.Succeeded) {
return businessLogic();
}
return Unauthorized();
}
}
}

View File

@ -6,8 +6,9 @@ using Microsoft.AspNetCore.Mvc;
using WeatherForecast.Models.Account.Requests; using WeatherForecast.Models.Account.Requests;
using WeatherForecast.Policies; using WeatherForecast.Policies;
using WeatherForecast.Services; using WeatherForecast.Services;
using DomainObjects.Documents.Users;
using DomainResults.Common; using DomainResults.Common;
using WeatherForecast.Controllers.Abstractions;
using Core.Enumerations;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -16,11 +17,10 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
public class AccountController : ControllerBase { public class AccountController : AuthorizationControllerBase {
private const string _password = "Password"; private const string _password = "Password";
private readonly IAuthorizationService _authorizationService;
private readonly IAccountService _accountService; private readonly IAccountService _accountService;
private readonly IUserDataProvider _userDataProvider; private readonly IUserDataProvider _userDataProvider;
/// <summary> /// <summary>
@ -30,8 +30,7 @@ public class AccountController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IAccountService accountService, IAccountService accountService,
IUserDataProvider userDataProvider IUserDataProvider userDataProvider
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_accountService = accountService; _accountService = accountService;
_userDataProvider = userDataProvider; _userDataProvider = userDataProvider;
} }
@ -112,14 +111,12 @@ public class AccountController : ControllerBase {
if (!getUserResult.IsSuccess || user == null) if (!getUserResult.IsSuccess || user == null)
return BadRequest(); return BadRequest();
if ((await _authorizationService.AuthorizeAsync(User, new List<User> { user }, new PasswordChangeRequirement { return await AuthorizeAsync(new PasswordChangeRequirement(CrudActions.Update,
OldPassword = requestData.OldPassword requestData.OldPassword
})).Succeeded) { ), user, () => {
var result = _accountService.PasswordChange(user, requestData); var result = _accountService.PasswordChange(user, requestData);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
#endregion #endregion
} }

View File

@ -8,12 +8,11 @@ using WeatherForecast.Models.Blog.Requests;
using WeatherForecast.Policies; using WeatherForecast.Policies;
using Core.Enumerations; using Core.Enumerations;
using DataProviders.Collections; using DataProviders.Collections;
using Extensions;
using DomainResults.Common;
using DomainObjects.Documents.Posts;
using WeatherForecast.Models.BlogItem.Requests;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using WeatherForecast.Controllers.Abstractions;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
/// <summary> /// <summary>
@ -21,9 +20,8 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
public class BlogItemController : ControllerBase { public class BlogItemController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider; private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
private readonly IBlogItemService _blogItemService; private readonly IBlogItemService _blogItemService;
@ -37,146 +35,129 @@ public class BlogItemController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IBlogCatalogDataProvider blogCatalogDataProvider, IBlogCatalogDataProvider blogCatalogDataProvider,
IBlogItemService blogItemService IBlogItemService blogItemService
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_blogCatalogDataProvider = blogCatalogDataProvider; _blogCatalogDataProvider = blogCatalogDataProvider;
_blogItemService = blogItemService; _blogItemService = blogItemService;
} }
#region Authless methods
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
[HttpGet("{siteId}")]
public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] GetBlogItemSlugRequestModel requestData) {
var result = _blogItemService.GetSlug(siteId, requestData);
return result.ToActionResult();
}
#endregion
/// <summary> /// <summary>
/// Can only Admin, Editor, Author, Contributor (cannot set publish date) /// Can only Admin, Editor, Author, Contributor (cannot set publish date)
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="requestData"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("{siteId}")] [HttpPost("{siteId}/{userId}")]
public async Task<IActionResult> Post([FromRoute] Guid siteId, [FromBody] PostBlogItemRequestModel requestData) { public async Task<IActionResult> Post([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromBody] PostBlogItemRequestModel requestData) {
var userId = User?.Identity?.Name?.ToNullableGuid(); var blogItem = requestData.ToDomainObject(siteId, userId);
if (userId == null)
return IDomainResult.Failed().ToActionResult();
var blogItem = requestData.ToDomainObject(userId.Value, siteId); return await AuthorizeAsync(new BlogAuthorizationRequirement(CrudActions.Create, new List<BlogRole> {
new BlogRole(Roles.Admin),
if ((await _authorizationService.AuthorizeAsync(User, new List<BlogDocument> { blogItem }, new BlogAuthorizationRequirement { new BlogRole(Roles.Editor),
Action = CrudActions.Create, new BlogRole(Roles.Author) { OwnOnly = true },
Roles = new List<BlogRole> { new BlogRole(Roles.Contributor) { OwnOnly = true },
new BlogRole { Role = Roles.Admin }, new BlogRole(Roles.ShopManager)
new BlogRole { Role = Roles.Editor }, }), blogItem, () => {
new BlogRole { Role = Roles.Author, OwnOnly = true },
new BlogRole { Role = Roles.Contributor, OwnOnly = true },
new BlogRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _blogItemService.Post(blogItem); var result = _blogItemService.Post(blogItem);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
/// Returns full object /// Returns full object
/// Can only Admin, Editor, Author, Contributor /// Can only Admin, Editor, Author, Contributor
/// </summary> /// </summary>
/// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="blogId"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("{siteId}/{blogId}")] [HttpGet("{siteId}/{userId}/{blogId}")]
public async Task<IActionResult> Get([FromRoute] Guid siteId, [FromRoute] Guid blogId) { public async Task<IActionResult> Get([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] Guid blogId) {
var (blogItem, getBlogItemResult) = _blogCatalogDataProvider.Get(siteId, blogId); var (blogItem, getBlogItemResult) = _blogCatalogDataProvider.Get(siteId, userId, blogId);
if (!getBlogItemResult.IsSuccess || blogItem == null) if (!getBlogItemResult.IsSuccess || blogItem == null)
return getBlogItemResult.ToActionResult(); return getBlogItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<BlogDocument> { blogItem }, new BlogAuthorizationRequirement { return await AuthorizeAsync(new BlogAuthorizationRequirement(CrudActions.Read, new List<BlogRole> {
Action = CrudActions.Read, new BlogRole(Roles.Admin),
Roles = new List<BlogRole> { new BlogRole(Roles.Editor),
new BlogRole { Role = Roles.Admin }, new BlogRole(Roles.Author) { OwnOnly = true },
new BlogRole { Role = Roles.Editor }, new BlogRole(Roles.Contributor) { OwnOnly = true },
new BlogRole { Role = Roles.Author, OwnOnly = true }, new BlogRole(Roles.ShopManager)
new BlogRole { Role = Roles.Contributor, OwnOnly = true }, }), blogItem, () => {
new BlogRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _blogItemService.Get(blogItem); var result = _blogItemService.Get(blogItem);
return result.ToActionResult(); return result.ToActionResult();
} });
}
return Unauthorized(); /// <summary>
/// Returns localized object
/// </summary>
/// <param name="siteId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
[HttpGet("{siteId}")]
public IActionResult Get([FromRoute] Guid siteId, [FromQuery] GetBlogItemLocalizedRequestModel requestData) {
var result = _blogItemService.Get(siteId, requestData);
return result.ToActionResult();
} }
/// <summary> /// <summary>
/// Can only Admin, Editor, Author (own), Contributor (own, not yet pubblished) /// Can only Admin, Editor, Author (own), Contributor (own, not yet pubblished)
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="blogId"></param> /// <param name="blogId"></param>
/// <param name="requestData"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
[HttpPut("{siteId}/{blogId}")] [HttpPut("{siteId}/{userId}/{blogId}")]
public async Task<IActionResult> Update([FromRoute] Guid siteId, [FromRoute] Guid blogId, [FromBody] PutBlogItemRequestModel requestData) { public async Task<IActionResult> Update([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] Guid blogId, [FromBody] PutBlogItemRequestModel requestData) {
var (blogItem, getBlogItemResult) = _blogCatalogDataProvider.Get(siteId, blogId); var (blogItem, getBlogItemResult) = _blogCatalogDataProvider.Get(siteId, userId, blogId);
if (!getBlogItemResult.IsSuccess || blogItem == null) if (!getBlogItemResult.IsSuccess || blogItem == null)
return getBlogItemResult.ToActionResult(); return getBlogItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<BlogDocument> { blogItem }, new BlogAuthorizationRequirement { // construct domain object from model
Action = CrudActions.Update, var newBlogItem = requestData.ToDomainObject(siteId, userId, blogId);
Roles = new List<BlogRole> { newBlogItem.Created = blogItem.Created;
new BlogRole { Role = Roles.Admin }, newBlogItem.Categories = blogItem.Categories;
new BlogRole { Role = Roles.Editor },
new BlogRole { Role = Roles.Author, OwnOnly = true },
new BlogRole { Role = Roles.Contributor, OwnOnly = true, DenyPublished = true },
new BlogRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _blogItemService.Update(blogItem, requestData);
return result.ToActionResult();
}
return Unauthorized(); return await AuthorizeAsync(new BlogAuthorizationRequirement(CrudActions.Update, new List<BlogRole> {
new BlogRole(Roles.Admin),
new BlogRole(Roles.Editor),
new BlogRole(Roles.Author) { OwnOnly = true },
new BlogRole(Roles.Contributor) { OwnOnly = true, DenyPublished = true },
new BlogRole(Roles.ShopManager)
}), blogItem, () => {
var result = _blogItemService.Update(newBlogItem);
return result.ToActionResult();
});
} }
/// <summary> /// <summary>
/// Can only Admin, Editor, Author (own), Contributor (own, not yet pubblished) /// Can only Admin, Editor, Author (own), Contributor (own, not yet pubblished)
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="blogId"></param> /// <param name="blogId"></param>
/// <returns></returns> /// <returns></returns>
[HttpDelete("{siteId}/{blogId}")] [HttpDelete("{siteId}/{userId}/{blogId}")]
public async Task<IActionResult> Delete([FromRoute] Guid siteId, [FromRoute] Guid blogId) { public async Task<IActionResult> Delete([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] Guid blogId) {
var (blogItem, getBlogItemResult) = _blogCatalogDataProvider.Get(siteId, blogId); var (blogItem, getBlogItemResult) = _blogCatalogDataProvider.Get(siteId, userId, blogId);
if (!getBlogItemResult.IsSuccess || blogItem == null) if (!getBlogItemResult.IsSuccess || blogItem == null)
return getBlogItemResult.ToActionResult(); return getBlogItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<BlogDocument> { blogItem }, new BlogAuthorizationRequirement { return await AuthorizeAsync(new BlogAuthorizationRequirement(CrudActions.Delete, new List<BlogRole> {
Action = CrudActions.Delete, new BlogRole(Roles.Admin),
Roles = new List<BlogRole> { new BlogRole(Roles.Editor),
new BlogRole { Role = Roles.Admin }, new BlogRole(Roles.Author) { OwnOnly = true },
new BlogRole { Role = Roles.Editor }, new BlogRole(Roles.Contributor) { OwnOnly = true, DenyPublished = true },
new BlogRole { Role = Roles.Author, OwnOnly = true }, new BlogRole(Roles.ShopManager)
new BlogRole { Role = Roles.Contributor, OwnOnly = true, DenyPublished = true }, }), blogItem, () => {
new BlogRole { Role = Roles.ShopManager } var result = _blogItemService.Delete(blogItem);
}
})).Succeeded) {
var result = _blogCatalogDataProvider.Delete(blogItem.Id);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
} }

View File

@ -1,14 +1,9 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using DomainResults.Mvc; using DomainResults.Mvc;
using WeatherForecast.Services; using WeatherForecast.Services;
using WeatherForecast.Policies; using WeatherForecast.Models.Blog.Requests;
using Core.Enumerations;
using DataProviders.Collections;
using WeatherForecast.Models.Requests;
using WeatherForecast.Models.BlogItem.Requests;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -19,27 +14,18 @@ namespace WeatherForecast.Controllers;
[Route("api/[controller]")] [Route("api/[controller]")]
public class BlogItemsController : ControllerBase { public class BlogItemsController : ControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
private readonly IBlogItemsService _blogItemsService; private readonly IBlogItemsService _blogItemsService;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="authorizationService"></param>
/// <param name="blogCatalogDataProvider"></param>
/// <param name="blogItemsService"></param> /// <param name="blogItemsService"></param>
public BlogItemsController( public BlogItemsController(
IAuthorizationService authorizationService,
IBlogCatalogDataProvider blogCatalogDataProvider,
IBlogItemsService blogItemsService IBlogItemsService blogItemsService
) { ) {
_authorizationService = authorizationService;
_blogCatalogDataProvider = blogCatalogDataProvider;
_blogItemsService = blogItemsService; _blogItemsService = blogItemsService;
} }
#region Authless methods
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@ -47,9 +33,8 @@ public class BlogItemsController : ControllerBase {
/// <param name="requestData"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("{siteId}")] [HttpGet("{siteId}")]
public IActionResult Get([FromRoute] Guid siteId, [FromQuery] GetBlogItemsRequestModel requestData) { public IActionResult Get([FromRoute] Guid siteId, [FromQuery] GetBlogItemsLocalizedRequestModel requestData) {
var result = _blogItemsService.Get(siteId, requestData); var result = _blogItemsService.Get(siteId, requestData);
return result.ToActionResult(); return result.ToActionResult();
} }
#endregion
} }

View File

@ -9,6 +9,9 @@ using Core.Enumerations;
using WeatherForecast.Models.Category.Requests; using WeatherForecast.Models.Category.Requests;
using WeatherForecast.Models.CategoryItem.Requests; using WeatherForecast.Models.CategoryItem.Requests;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using WeatherForecast.Controllers.Abstractions;
using DataProviders.Collections;
using DomainObjects.Enumerations;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -17,24 +20,50 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
public class CategoryItemController : ControllerBase { public class CategoryItemController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService; private readonly ICategoryDataProvider _categoryDataProvider;
private readonly ICategoryItemService _categoryItemService; private readonly ICategoryItemService _categoryItemService;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="authorizationService"></param> /// <param name="authorizationService"></param>
/// <param name="categoryDataProvider"></param>
/// <param name="categoryItemService"></param> /// <param name="categoryItemService"></param>
public CategoryItemController( public CategoryItemController(
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
ICategoryDataProvider categoryDataProvider,
ICategoryItemService categoryItemService ICategoryItemService categoryItemService
) { ) : base (authorizationService) {
_authorizationService = authorizationService; _categoryDataProvider = categoryDataProvider;
_categoryItemService = categoryItemService; _categoryItemService = categoryItemService;
} }
/// <summary>
/// Create new site category
/// <para>
/// Allowed: Admin, Editor, Shop manager
/// </para>
/// </summary>
/// <param name="siteId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
[HttpPost("{siteId}")]
public async Task<IActionResult> Post([FromRoute] Guid siteId, [FromBody] PostCategoryItemRequestModel requestData) {
var category = requestData.ToDomainObject(siteId);
return await AuthorizeAsync(new CategoryAuthorizationRequirement(CrudActions.Create, new List<CategoryRole> {
new CategoryRole(Roles.Admin),
new CategoryRole(Roles.Editor),
new CategoryRole(Roles.ShopManager)
}), () => {
var result = _categoryItemService.Post(category);
return result.ToActionResult();
});
}
#region Authless methods #region Authless methods
/// <summary> /// <summary>
/// ///
@ -43,34 +72,19 @@ public class CategoryItemController : ControllerBase {
/// <param name="requestData"></param> /// <param name="requestData"></param>
[HttpGet("{siteId}")] [HttpGet("{siteId}")]
public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] GetCategoryItemSlugRequestModel requestData) { public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] GetCategoryItemSlugRequestModel requestData) {
var result = _categoryItemService.GetSlug(siteId, requestData);
var (category, getCategoryResult) = _categoryDataProvider.GetBySlug(siteId, requestData.Slug);
if (!getCategoryResult.IsSuccess || category == null)
return getCategoryResult.ToActionResult();
var locale = category.L10n.SingleOrDefault(x => x.Slug == requestData.Slug)?.Locale ?? Locales.Us;
var result = _categoryItemService.Get(category, locale);
return result.ToActionResult(); return result.ToActionResult();
} }
#endregion #endregion
/// <summary>
/// Can Admin, Editor, Shop manager
/// </summary>
/// <param name="siteId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
[HttpPost("{siteId}")]
public async Task<IActionResult> Post([FromRoute] Guid siteId, [FromBody] PostCategoryItemRequestModel requestData) {
if ((await _authorizationService.AuthorizeAsync(User, null, new CategoryAuthorizationRequirement {
Action = CrudActions.Create,
Roles = new List<CategoryRole> {
new CategoryRole { Role = Roles.Admin },
new CategoryRole { Role = Roles.Editor },
new CategoryRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _categoryItemService.Post(siteId, requestData);
return result.ToActionResult();
}
else {
return Unauthorized();
}
}
/// <summary> /// <summary>
/// Returns full object /// Returns full object
@ -81,22 +95,21 @@ public class CategoryItemController : ControllerBase {
/// <returns></returns> /// <returns></returns>
[HttpGet("{siteId}/{categoryId}")] [HttpGet("{siteId}/{categoryId}")]
public async Task<IActionResult> Get([FromRoute] Guid siteId, [FromRoute] Guid categoryId) { public async Task<IActionResult> Get([FromRoute] Guid siteId, [FromRoute] Guid categoryId) {
if ((await _authorizationService.AuthorizeAsync(User, null, new CategoryAuthorizationRequirement {
Action = CrudActions.Read, var (category, result) = _categoryDataProvider.Get(siteId, categoryId);
Roles = new List<CategoryRole> { if (!result.IsSuccess || category == null)
new CategoryRole { Role = Roles.Admin },
new CategoryRole { Role = Roles.Editor },
new CategoryRole { Role = Roles.Author },
new CategoryRole { Role = Roles.Contributor },
new CategoryRole { Role = Roles.ShopManager },
}
})).Succeeded) {
var result = _categoryItemService.Get(siteId, categoryId);
return result.ToActionResult(); return result.ToActionResult();
}
else { return await AuthorizeAsync(new CategoryAuthorizationRequirement(CrudActions.Read, new List<CategoryRole> {
return Unauthorized(); new CategoryRole(Roles.Admin),
} new CategoryRole(Roles.Editor),
new CategoryRole(Roles.Author),
new CategoryRole(Roles.Contributor),
new CategoryRole(Roles.ShopManager),
}), () => {
var result = _categoryItemService.Get(category, null);
return result.ToActionResult();
});
} }
/// <summary> /// <summary>
@ -108,19 +121,17 @@ public class CategoryItemController : ControllerBase {
/// <returns></returns> /// <returns></returns>
[HttpPut("{siteId}/{categoryId}")] [HttpPut("{siteId}/{categoryId}")]
public async Task<IActionResult> Update([FromRoute] Guid siteId, [FromRoute] Guid categoryId, [FromBody] PutCategoryItemRequestModel requestData) { public async Task<IActionResult> Update([FromRoute] Guid siteId, [FromRoute] Guid categoryId, [FromBody] PutCategoryItemRequestModel requestData) {
if ((await _authorizationService.AuthorizeAsync(User, null, new CategoryAuthorizationRequirement {
Action = CrudActions.Update,
Roles = new List<CategoryRole> {
new CategoryRole { Role = Roles.Admin },
new CategoryRole { Role = Roles.Editor },
new CategoryRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _categoryItemService.Update(siteId, categoryId, requestData);
return result.ToActionResult();
}
return Unauthorized(); var category = requestData.ToDomainObject(siteId, categoryId);
return await AuthorizeAsync(new CategoryAuthorizationRequirement(CrudActions.Update, new List<CategoryRole> {
new CategoryRole(Roles.Admin),
new CategoryRole(Roles.Editor),
new CategoryRole(Roles.ShopManager)
}), () => {
var result = _categoryItemService.Update(category);
return result.ToActionResult();
});
} }
/// <summary> /// <summary>
@ -131,16 +142,12 @@ public class CategoryItemController : ControllerBase {
/// <returns></returns> /// <returns></returns>
[HttpDelete("{siteId}/{categoryId}")] [HttpDelete("{siteId}/{categoryId}")]
public async Task<IActionResult> Delete([FromRoute] Guid siteId, [FromRoute] Guid categoryId) { public async Task<IActionResult> Delete([FromRoute] Guid siteId, [FromRoute] Guid categoryId) {
if ((await _authorizationService.AuthorizeAsync(User, null, new CategoryAuthorizationRequirement {
Action = CrudActions.Delete, return await AuthorizeAsync(new CategoryAuthorizationRequirement(CrudActions.Delete, new List<CategoryRole> {
Roles = new List<CategoryRole> { new CategoryRole(Roles.Admin)
new CategoryRole { Role = Roles.Admin } }), () => {
}
})).Succeeded) {
var result = _categoryItemService.Delete(siteId, categoryId); var result = _categoryItemService.Delete(siteId, categoryId);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
} }

View File

@ -15,20 +15,15 @@ namespace WeatherForecast.Controllers;
[Route("api/[controller]")] [Route("api/[controller]")]
public class CategoryItemsController : ControllerBase { public class CategoryItemsController : ControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly ICategoryItemsService _categoryItemsService; private readonly ICategoryItemsService _categoryItemsService;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="authorizationService"></param>
/// <param name="categoryItemsService"></param> /// <param name="categoryItemsService"></param>
public CategoryItemsController( public CategoryItemsController(
IAuthorizationService authorizationService,
ICategoryItemsService categoryItemsService ICategoryItemsService categoryItemsService
) { ) {
_authorizationService = authorizationService;
_categoryItemsService = categoryItemsService; _categoryItemsService = categoryItemsService;
} }

View File

@ -15,19 +15,15 @@ namespace WeatherForecast.Controllers;
[Route("api/[controller]")] [Route("api/[controller]")]
public class ContentController : ControllerBase { public class ContentController : ControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IContentService _contentService; private readonly IContentService _contentService;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="authorizationService"></param>
/// <param name="contentService"></param> /// <param name="contentService"></param>
public ContentController( public ContentController(
IAuthorizationService authorizationService,
IContentService contentService IContentService contentService
) { ) {
_authorizationService = authorizationService;
_contentService = contentService; _contentService = contentService;
} }

View File

@ -8,6 +8,8 @@ using DataProviders.Buckets;
using WeatherForecast.Services; using WeatherForecast.Services;
using WeatherForecast.Policies; using WeatherForecast.Policies;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using WeatherForecast.Controllers.Abstractions;
using Core.Enumerations;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -16,10 +18,8 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[AllowAnonymous] [AllowAnonymous]
[Route("api/[controller]")] [Route("api/[controller]")]
public class DkimController : ControllerBase { public class DkimController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IDkimBucketDataProvider _dkimBucketDataProvider; private readonly IDkimBucketDataProvider _dkimBucketDataProvider;
private readonly IDkimService _dkimService; private readonly IDkimService _dkimService;
@ -33,8 +33,7 @@ public class DkimController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IDkimBucketDataProvider dkimBucketDataProvider, IDkimBucketDataProvider dkimBucketDataProvider,
IDkimService dkimService IDkimService dkimService
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_dkimBucketDataProvider = dkimBucketDataProvider; _dkimBucketDataProvider = dkimBucketDataProvider;
_dkimService = dkimService; _dkimService = dkimService;
} }
@ -56,18 +55,12 @@ public class DkimController : ControllerBase {
var newFile = new BucketFile(Guid.NewGuid(), siteId, formFile.FileName, ms.ToArray(), formFile.ContentType); var newFile = new BucketFile(Guid.NewGuid(), siteId, formFile.FileName, ms.ToArray(), formFile.ContentType);
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new List<BucketFile> { newFile }, new DkimAuthorisationRequirement { return await AuthorizeAsync(new DkimAuthorisationRequirement(CrudActions.Create, new List<DkimRole> {
Roles = new List<DkimRole> { new DkimRole(Roles.Admin)
new DkimRole { Role = Roles.Admin } }), newFile, () => {
}
});
if(authorizationResult.Succeeded ) {
var result = _dkimService.Post(newFile); var result = _dkimService.Post(newFile);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -83,17 +76,11 @@ public class DkimController : ControllerBase {
if (!fileDownloadResult.IsSuccess || file == null) if (!fileDownloadResult.IsSuccess || file == null)
return fileDownloadResult.ToActionResult(); return fileDownloadResult.ToActionResult();
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new List<BucketFile> { file }, new DkimAuthorisationRequirement { return await AuthorizeAsync(new DkimAuthorisationRequirement(CrudActions.Delete, new List<DkimRole> {
Roles = new List<DkimRole> { new DkimRole(Roles.Admin)
new DkimRole { Role = Roles.Admin } }), file, () => {
}
});
if (authorizationResult.Succeeded) {
var result = _dkimService.Delete(siteId, fileId); var result = _dkimService.Delete(siteId, fileId);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
} }

View File

@ -8,6 +8,8 @@ using DataProviders.Buckets;
using DomainResults.Common; using DomainResults.Common;
using WeatherForecast.Policies; using WeatherForecast.Policies;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using WeatherForecast.Controllers.Abstractions;
using static System.Net.WebRequestMethods;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -16,9 +18,8 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]
public class ImageController : ControllerBase { public class ImageController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IImageBucketDataProvider _imageBucketDataProvider; private readonly IImageBucketDataProvider _imageBucketDataProvider;
private readonly IImageService _imageService; private readonly IImageService _imageService;
@ -32,16 +33,17 @@ public class ImageController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IImageBucketDataProvider imageBucketDataProvider, IImageBucketDataProvider imageBucketDataProvider,
IImageService imgeService IImageService imgeService
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_imageBucketDataProvider = imageBucketDataProvider; _imageBucketDataProvider = imageBucketDataProvider;
_imageService = imgeService; _imageService = imgeService;
} }
#region Post #region Post
/// <summary> /// <summary>
/// Site wide<br /> /// Site wide
/// <para>
/// Allowed: Admin, Shop Manager /// Allowed: Admin, Shop Manager
/// </para>
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="formFile"></param> /// <param name="formFile"></param>
@ -51,8 +53,10 @@ public class ImageController : ControllerBase {
await PostCore(siteId, null, formFile); await PostCore(siteId, null, formFile);
/// <summary> /// <summary>
/// Site user specific<br /> /// Site user specific
/// <para>
/// Allowed: Admin, Editor, Author, Contributor, Shop manager /// Allowed: Admin, Editor, Author, Contributor, Shop manager
/// </para>
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
@ -73,31 +77,26 @@ public class ImageController : ControllerBase {
if (userId != null) if (userId != null)
newFile.UserId = userId; newFile.UserId = userId;
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new List<BucketFile> { newFile }, new ImageAuthorisationRequirement { return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Create, new List<ImageRole> {
Action = CrudActions.Create, new ImageRole(Roles.Admin),
Roles = new List<ImageRole> { new ImageRole(Roles.Editor),
new ImageRole { Role = Roles.Admin }, new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole { Role = Roles.Editor }, new ImageRole(Roles.Contributor) { OwnOnly = true },
new ImageRole { Role = Roles.Author, OwnOnly = true }, new ImageRole(Roles.ShopManager)
new ImageRole { Role = Roles.Contributor, OwnOnly = true }, }), newFile, () => {
new ImageRole { Role = Roles.ShopManager }
}
});
if (authorizationResult.Succeeded) {
var result = _imageService.Post(newFile); var result = _imageService.Post(newFile);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
#endregion #endregion
#region Get #region Get
/// <summary> /// <summary>
/// Site user specific<br /> /// Site user specific
/// <para>
/// Allowed: Admin, Editor, Author (own), Contributor (own), Shop manager /// Allowed: Admin, Editor, Author (own), Contributor (own), Shop manager
/// https://www.c-sharpcorner.com/article/fileresult-in-asp-net-core-mvc2/ /// </para>
/// <see href="https://www.c-sharpcorner.com/article/fileresult-in-asp-net-core-mvc2/">fileresult-in-asp-net-core-mvc2</see>
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
@ -110,30 +109,25 @@ public class ImageController : ControllerBase {
if (!result.IsSuccess || file == null) if (!result.IsSuccess || file == null)
return result.ToActionResult(); return result.ToActionResult();
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new List<BucketFile> { file }, new ImageAuthorisationRequirement { return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Read, new List<ImageRole> {
Action = CrudActions.Read, new ImageRole(Roles.Admin),
Roles = new List<ImageRole> { new ImageRole(Roles.Editor),
new ImageRole { Role = Roles.Admin }, new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole { Role = Roles.Editor }, new ImageRole(Roles.Contributor) { OwnOnly = true },
new ImageRole { Role = Roles.Author, OwnOnly = true }, new ImageRole(Roles.ShopManager)
new ImageRole { Role = Roles.Contributor, OwnOnly = true }, }), file, () => {
new ImageRole { Role = Roles.ShopManager }
}
});
if (authorizationResult.Succeeded) {
var stream = new MemoryStream(file.Bytes); var stream = new MemoryStream(file.Bytes);
return new FileStreamResult(stream, file.ContentType) { return new FileStreamResult(stream, file.ContentType) {
FileDownloadName = file.Name FileDownloadName = file.Name
}; };
} });
return Unauthorized();
} }
/// <summary> /// <summary>
/// Site specific<br /> /// Site wide
/// <para>
/// Allowed everyone /// Allowed everyone
/// </para>
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="width"></param> /// <param name="width"></param>
@ -157,8 +151,10 @@ public class ImageController : ControllerBase {
#region Update #region Update
/// <summary> /// <summary>
/// Site specific<br /> /// Site specific
/// <para>
/// Allowed Admin, Shop Manager /// Allowed Admin, Shop Manager
/// </para>
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="fileId"></param> /// <param name="fileId"></param>
@ -169,7 +165,10 @@ public class ImageController : ControllerBase {
await UpdateCore(siteId, null, fileId, formFile); await UpdateCore(siteId, null, fileId, formFile);
/// <summary> /// <summary>
/// Site user specific
/// <para>
/// Can Admin, Editor, Author (own), Contributor (own, not yet pubblished), Shop manager /// Can Admin, Editor, Author (own), Contributor (own, not yet pubblished), Shop manager
/// </para>
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
@ -196,23 +195,16 @@ public class ImageController : ControllerBase {
if(userId != null) if(userId != null)
newFile.UserId = userId; newFile.UserId = userId;
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new List<BucketFile> { file }, new ImageAuthorisationRequirement { return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Update, new List<ImageRole> {
Action = CrudActions.Update, new ImageRole(Roles.Admin),
Roles = new List<ImageRole> { new ImageRole(Roles.Editor),
new ImageRole { Role = Roles.Admin }, new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole { Role = Roles.Editor }, new ImageRole(Roles.Contributor) { OwnOnly = true, DenyPublished = true },
new ImageRole { Role = Roles.Author, OwnOnly = true }, new ImageRole(Roles.ShopManager)
new ImageRole { Role = Roles.Contributor, OwnOnly = true, DenyPublished = true }, }), file, () => {
new ImageRole { Role = Roles.ShopManager }
}
});
if (authorizationResult.Succeeded) {
var result = _imageService.Update(siteId, userId, fileId, newFile); var result = _imageService.Update(siteId, userId, fileId, newFile);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
#endregion #endregion
@ -246,23 +238,16 @@ public class ImageController : ControllerBase {
if (!fileDownloadResult.IsSuccess || file == null) if (!fileDownloadResult.IsSuccess || file == null)
return fileDownloadResult.ToActionResult(); return fileDownloadResult.ToActionResult();
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new List<BucketFile> { file }, new ImageAuthorisationRequirement { return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Delete, new List<ImageRole> {
Action = CrudActions.Delete, new ImageRole(Roles.Admin),
Roles = new List<ImageRole> { new ImageRole(Roles.Editor),
new ImageRole { Role = Roles.Admin }, new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole { Role = Roles.Editor }, new ImageRole(Roles.Contributor) { OwnOnly = true, DenyPublished = true },
new ImageRole { Role = Roles.Author, OwnOnly = true }, new ImageRole(Roles.ShopManager)
new ImageRole { Role = Roles.Contributor, OwnOnly = true, DenyPublished = true }, }), file, () => {
new ImageRole { Role = Roles.ShopManager }
}
});
if (authorizationResult.Succeeded) {
var result = _imageService.Delete(siteId, userId, fileId); var result = _imageService.Delete(siteId, userId, fileId);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
#endregion #endregion
} }

View File

@ -5,7 +5,7 @@ using DomainResults.Common;
using DomainResults.Mvc; using DomainResults.Mvc;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using WeatherForecast.Controllers.Abstractions;
using WeatherForecast.Policies; using WeatherForecast.Policies;
using WeatherForecast.Services; using WeatherForecast.Services;
@ -16,9 +16,9 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[AllowAnonymous] [AllowAnonymous]
[Route("api/[controller]")] [Route("api/[controller]")]
public class ImagesController : ControllerBase { public class ImagesController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IImageBucketDataProvider _imageBucketDataProvider; private readonly IImageBucketDataProvider _imageBucketDataProvider;
private readonly IImageService _imageService; private readonly IImageService _imageService;
@ -32,8 +32,7 @@ public class ImagesController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IImageBucketDataProvider imageBucketDataProvider, IImageBucketDataProvider imageBucketDataProvider,
IImageService imageService IImageService imageService
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_imageBucketDataProvider = imageBucketDataProvider; _imageBucketDataProvider = imageBucketDataProvider;
_imageService = imageService; _imageService = imageService;
} }
@ -65,23 +64,15 @@ public class ImagesController : ControllerBase {
return newFile; return newFile;
}).ToList(); }).ToList();
return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Create, new List<ImageRole> {
var authorizationResult = await _authorizationService.AuthorizeAsync(User, newFiles, new ImageAuthorisationRequirement { new ImageRole(Roles.Admin),
Action = CrudActions.Create, new ImageRole(Roles.Editor),
Roles = new List<ImageRole> { new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole { Role = Roles.Admin }, new ImageRole(Roles.Contributor) { OwnOnly = true },
new ImageRole { Role = Roles.Editor }, new ImageRole(Roles.ShopManager)
new ImageRole { Role = Roles.Author, OwnOnly = true }, }), newFiles, () => {
new ImageRole { Role = Roles.Contributor, OwnOnly = true },
new ImageRole { Role = Roles.ShopManager }
}
});
if (authorizationResult.Succeeded) {
var result = _imageService.Post(newFiles); var result = _imageService.Post(newFiles);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
} }

View File

@ -9,6 +9,7 @@ using Core.Enumerations;
using DataProviders.Collections; using DataProviders.Collections;
using DomainObjects.Documents; using DomainObjects.Documents;
using WeatherForecast.Models.ShopCart.Requests; using WeatherForecast.Models.ShopCart.Requests;
using WeatherForecast.Controllers.Abstractions;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -18,9 +19,8 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[AllowAnonymous] [AllowAnonymous]
[Route("api/[controller]")] [Route("api/[controller]")]
public class ShopCartItemController : ControllerBase { public class ShopCartItemController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IShopCartDataProvider _shopCartDataProvider; private readonly IShopCartDataProvider _shopCartDataProvider;
private readonly IShopCartItemService _shopCartItemService; private readonly IShopCartItemService _shopCartItemService;
@ -34,8 +34,7 @@ public class ShopCartItemController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IShopCartDataProvider shopCartDataProvider, IShopCartDataProvider shopCartDataProvider,
IShopCartItemService shopCartItemService IShopCartItemService shopCartItemService
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_shopCartDataProvider = shopCartDataProvider; _shopCartDataProvider = shopCartDataProvider;
_shopCartItemService = shopCartItemService; _shopCartItemService = shopCartItemService;
} }
@ -50,15 +49,11 @@ public class ShopCartItemController : ControllerBase {
/// <returns></returns> /// <returns></returns>
[HttpPost("{siteId}/{userId}/{sku}")] [HttpPost("{siteId}/{userId}/{sku}")]
public async Task<IActionResult> Post([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] string sku, [FromBody] PostShopCartItemRequestModel requestData) { public async Task<IActionResult> Post([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] string sku, [FromBody] PostShopCartItemRequestModel requestData) {
if ((await _authorizationService.AuthorizeAsync(User, null, new ShopCartAuthorizationRequirement {
Action = CrudActions.Create,
})).Succeeded) { return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Create), () => {
var result = _shopCartItemService.Post(siteId, userId, sku, requestData); var result = _shopCartItemService.Post(siteId, userId, sku, requestData);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -76,14 +71,10 @@ public class ShopCartItemController : ControllerBase {
if (!getCartItemResult.IsSuccess || cartItem == null) if (!getCartItemResult.IsSuccess || cartItem == null)
return getCartItemResult.ToActionResult(); return getCartItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<ShopCartDocument> { cartItem }, new ShopCartAuthorizationRequirement { return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Read), cartItem, () => {
Action = CrudActions.Read
})).Succeeded) {
var result = _shopCartItemService.Get(cartItem, requestData); var result = _shopCartItemService.Get(cartItem, requestData);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -101,14 +92,10 @@ public class ShopCartItemController : ControllerBase {
if (!getCartItemResult.IsSuccess || cartItem == null) if (!getCartItemResult.IsSuccess || cartItem == null)
return getCartItemResult.ToActionResult(); return getCartItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<ShopCartDocument> { cartItem }, new ShopCartAuthorizationRequirement { return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Update), cartItem, () => {
Action = CrudActions.Update
})).Succeeded) {
var result = _shopCartItemService.Update(cartItem, requestData); var result = _shopCartItemService.Update(cartItem, requestData);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -125,13 +112,9 @@ public class ShopCartItemController : ControllerBase {
if (!getCartItemResult.IsSuccess || cartItem == null) if (!getCartItemResult.IsSuccess || cartItem == null)
return getCartItemResult.ToActionResult(); return getCartItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<ShopCartDocument> { cartItem }, new ShopCartAuthorizationRequirement { return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Delete), cartItem, () => {
Action = CrudActions.Delete
})).Succeeded) {
var result = _shopCartDataProvider.Delete(cartItem.Id); var result = _shopCartDataProvider.Delete(cartItem.Id);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
} }

View File

@ -8,6 +8,7 @@ using WeatherForecast.Policies;
using Core.Enumerations; using Core.Enumerations;
using DataProviders.Collections; using DataProviders.Collections;
using WeatherForecast.Models.ShopCart.Requests; using WeatherForecast.Models.ShopCart.Requests;
using WeatherForecast.Controllers.Abstractions;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -16,9 +17,8 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
public class ShopCartItemsController : ControllerBase { public class ShopCartItemsController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IShopCartDataProvider _shopCartDataProvider; private readonly IShopCartDataProvider _shopCartDataProvider;
private readonly IShopCartItemsService _shopCartItemsService; private readonly IShopCartItemsService _shopCartItemsService;
@ -32,8 +32,7 @@ public class ShopCartItemsController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IShopCartDataProvider shopCartDataProvider, IShopCartDataProvider shopCartDataProvider,
IShopCartItemsService shopCartItemsService IShopCartItemsService shopCartItemsService
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_shopCartDataProvider = shopCartDataProvider; _shopCartDataProvider = shopCartDataProvider;
_shopCartItemsService = shopCartItemsService; _shopCartItemsService = shopCartItemsService;
} }
@ -49,13 +48,9 @@ public class ShopCartItemsController : ControllerBase {
if (!getCartItemsResult.IsSuccess || cartItems == null) if (!getCartItemsResult.IsSuccess || cartItems == null)
return getCartItemsResult.ToActionResult(); return getCartItemsResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, cartItems, new ShopCartAuthorizationRequirement { return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Read), cartItems, () => {
Action = CrudActions.Read
})).Succeeded) {
var result = _shopCartItemsService.Get(cartItems, requestData); var result = _shopCartItemsService.Get(cartItems, requestData);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
} }

View File

@ -12,6 +12,7 @@ using DomainResults.Common;
using Extensions; using Extensions;
using DomainObjects.Documents.Posts; using DomainObjects.Documents.Posts;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using WeatherForecast.Controllers.Abstractions;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -20,9 +21,8 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
public class ShopItemController : ControllerBase { public class ShopItemController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider; private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly IShopItemService _shopItemService; private readonly IShopItemService _shopItemService;
@ -36,8 +36,7 @@ public class ShopItemController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IShopCatalogDataProvider shopCatalogDataProvider, IShopCatalogDataProvider shopCatalogDataProvider,
IShopItemService shopItemService IShopItemService shopItemService
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_shopCatalogDataProvider = shopCatalogDataProvider; _shopCatalogDataProvider = shopCatalogDataProvider;
_shopItemService = shopItemService; _shopItemService = shopItemService;
} }
@ -72,19 +71,13 @@ public class ShopItemController : ControllerBase {
var shopItem = requestData.ToDomainObject(sku, userId.Value, siteId); var shopItem = requestData.ToDomainObject(sku, userId.Value, siteId);
if ((await _authorizationService.AuthorizeAsync(User, new List<ShopDocument> { shopItem }, new ShopAuthorizationRequirement { return await AuthorizeAsync(new ShopAuthorizationRequirement(CrudActions.Create, new List<ShopRole> {
Action = CrudActions.Create, new ShopRole(Roles.Admin),
Roles = new List<ShopRole> { new ShopRole(Roles.ShopManager)
new ShopRole { Role = Roles.Admin }, }), shopItem, () => {
new ShopRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _shopItemService.Post(shopItem); var result = _shopItemService.Post(shopItem);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -101,18 +94,13 @@ public class ShopItemController : ControllerBase {
if (!getShopItemResult.IsSuccess || shopItem == null) if (!getShopItemResult.IsSuccess || shopItem == null)
return getShopItemResult.ToActionResult(); return getShopItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<ShopDocument> { shopItem }, new ShopAuthorizationRequirement { return await AuthorizeAsync(new ShopAuthorizationRequirement(CrudActions.Read, new List<ShopRole> {
Action = CrudActions.Read, new ShopRole(Roles.Admin),
Roles = new List<ShopRole> { new ShopRole(Roles.ShopManager)
new ShopRole { Role = Roles.Admin }, }), shopItem, () => {
new ShopRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _shopItemService.Get(shopItem); var result = _shopItemService.Get(shopItem);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -129,18 +117,13 @@ public class ShopItemController : ControllerBase {
if (!getShopItemResult.IsSuccess || shopItem == null) if (!getShopItemResult.IsSuccess || shopItem == null)
return getShopItemResult.ToActionResult(); return getShopItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<ShopDocument> { shopItem }, new ShopAuthorizationRequirement { return await AuthorizeAsync(new ShopAuthorizationRequirement(CrudActions.Update, new List<ShopRole> {
Action = CrudActions.Update, new ShopRole(Roles.Admin),
Roles = new List<ShopRole> { new ShopRole(Roles.ShopManager)
new ShopRole { Role = Roles.Admin }, }), shopItem, () => {
new ShopRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _shopItemService.Update(siteId, sku, requestData); var result = _shopItemService.Update(siteId, sku, requestData);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -156,17 +139,12 @@ public class ShopItemController : ControllerBase {
if (!getShopItemResult.IsSuccess || shopItem == null) if (!getShopItemResult.IsSuccess || shopItem == null)
return getShopItemResult.ToActionResult(); return getShopItemResult.ToActionResult();
if ((await _authorizationService.AuthorizeAsync(User, new List<ShopDocument> { shopItem }, new ShopAuthorizationRequirement { return await AuthorizeAsync(new ShopAuthorizationRequirement(CrudActions.Delete, new List<ShopRole> {
Action = CrudActions.Delete, new ShopRole(Roles.Admin),
Roles = new List<ShopRole> { new ShopRole(Roles.ShopManager)
new ShopRole { Role = Roles.Admin }, }), shopItem, () => {
new ShopRole { Role = Roles.ShopManager }
}
})).Succeeded) {
var result = _shopCatalogDataProvider.Delete(shopItem.Id); var result = _shopCatalogDataProvider.Delete(shopItem.Id);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
} }

View File

@ -12,6 +12,7 @@ using Core.Binders;
using Core.Enumerations; using Core.Enumerations;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using WeatherForecast.Policies; using WeatherForecast.Policies;
using WeatherForecast.Controllers.Abstractions;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers;
@ -20,10 +21,8 @@ namespace WeatherForecast.Controllers;
/// </summary> /// </summary>
[AllowAnonymous] [AllowAnonymous]
[Route("api/[controller]")] [Route("api/[controller]")]
public class TemplateController : ControllerBase { public class TemplateController : AuthorizationControllerBase {
private readonly IAuthorizationService _authorizationService;
private readonly ITemplateBucketDataProvider _templateBucketDataProvider; private readonly ITemplateBucketDataProvider _templateBucketDataProvider;
private readonly ITemplateService _templateService; private readonly ITemplateService _templateService;
@ -37,8 +36,7 @@ public class TemplateController : ControllerBase {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
ITemplateBucketDataProvider templateBucketDataProvider, ITemplateBucketDataProvider templateBucketDataProvider,
ITemplateService templateService ITemplateService templateService
) { ) : base (authorizationService) {
_authorizationService = authorizationService;
_templateBucketDataProvider = templateBucketDataProvider; _templateBucketDataProvider = templateBucketDataProvider;
_templateService = templateService; _templateService = templateService;
} }
@ -61,19 +59,12 @@ public class TemplateController : ControllerBase {
var newFile = new BucketFile(siteId, formFile.FileName, ms.ToArray(), formFile.ContentType); var newFile = new BucketFile(siteId, formFile.FileName, ms.ToArray(), formFile.ContentType);
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new List<BucketFile> { newFile }, new TemplateAuthorisationRequirement { return await AuthorizeAsync(new TemplateAuthorisationRequirement(CrudActions.Create, new List<TemplateRole> {
Action = CrudActions.Create, new TemplateRole(Roles.Admin)
Roles = new List<TemplateRole> { }), newFile, () => {
new TemplateRole { Role = Roles.Admin }
}
});
if (authorizationResult.Succeeded) {
var result = _templateService.Post(newFile); var result = _templateService.Post(newFile);
return result.ToActionResult(); return result.ToActionResult();
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -89,21 +80,14 @@ public class TemplateController : ControllerBase {
if (!result.IsSuccess || file == null) if (!result.IsSuccess || file == null)
return result.ToActionResult(); return result.ToActionResult();
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new List<BucketFile> { file }, new TemplateAuthorisationRequirement { return await AuthorizeAsync(new TemplateAuthorisationRequirement(CrudActions.Read, new List<TemplateRole> {
Action = CrudActions.Read, new TemplateRole(Roles.Admin)
Roles = new List<TemplateRole> { }), file, () => {
new TemplateRole { Role = Roles.Admin }
}
});
if (authorizationResult.Succeeded) {
var stream = new MemoryStream(file.Bytes); var stream = new MemoryStream(file.Bytes);
return new FileStreamResult(stream, file.ContentType) { return new FileStreamResult(stream, file.ContentType) {
FileDownloadName = file.Name FileDownloadName = file.Name
}; };
} });
return Unauthorized();
} }
/// <summary> /// <summary>
@ -114,7 +98,7 @@ public class TemplateController : ControllerBase {
/// <param name="requestData"></param> /// <param name="requestData"></param>
/// <param name="file"></param> /// <param name="file"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("{siteId}/{fileId}")] [HttpPut("{siteId}/{fileId}")]
public IActionResult Put([FromRoute] Guid siteId, [FromRoute] Guid fileId, [ModelBinder(typeof(JsonModelBinder<PutTemplateRequestModel>))] PutTemplateRequestModel requestData, IFormFile file) { public IActionResult Put([FromRoute] Guid siteId, [FromRoute] Guid fileId, [ModelBinder(typeof(JsonModelBinder<PutTemplateRequestModel>))] PutTemplateRequestModel requestData, IFormFile file) {
return BadRequest(); return BadRequest();
} }

View File

@ -1,12 +1,14 @@
using DomainObjects.Abstractions; using DomainObjects.Abstractions;
using WeatherForecast.Models.Content.Responses;
namespace WeatherForecast.Models.Abstractions { namespace WeatherForecast.Models.Abstractions
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
public abstract class AddressSectionModelBase<T> : PageSectionModelBase<T> { public abstract class AddressSectionModelBase<T> : PageSectionModelBase<T> {
/// <summary> /// <summary>
/// ///

View File

@ -2,15 +2,17 @@
using Core.Abstractions.Models; using Core.Abstractions.Models;
using DomainObjects.Abstractions; using DomainObjects.Abstractions;
using WeatherForecast.Models.Content.Responses;
using WeatherForecast.Models.Content.Responses.PageSections; using WeatherForecast.Models.Content.Responses.PageSections;
namespace WeatherForecast.Models.Abstractions { namespace WeatherForecast.Models.Abstractions
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
public abstract class PageModelBase<T> : ModelBase { public abstract class PageModelBase<T> : ModelBase {
/// <summary> /// <summary>
/// ///

View File

@ -1,37 +1,83 @@
using DomainObjects.Abstractions; using DomainObjects.Abstractions;
using Core.Abstractions.Models; using Core.Abstractions.Models;
using WeatherForecast.Models.Abstractions.PostItem.Responses; using Core.Enumerations;
using DomainObjects.Enumerations;
namespace WeatherForecast.Models.Abstractions { namespace WeatherForecast.Models.Abstractions {
//public class MediaAttachmentL10nRequestModel : RequestModelBase {
/// <summary> // /// <summary>
/// // ///
/// </summary> // /// </summary>
/// <typeparam name="T"></typeparam> // public Locales Locale { get; set; } = Locales.Unknown;
public abstract class PersonModelBase<T> : ModelBase {
/// <summary> // /// <summary>
/// // ///
/// </summary> // /// </summary>
public Guid Id { get; set; } // public string Alt { get; set; } = string.Empty;
/// <summary> // /// <summary>
/// // ///
/// </summary> // /// </summary>
public MediaAttachmentResponseModel? Image { get; set; } // public string? Target { get; set; }
/// <summary> // /// <summary>
/// // ///
/// </summary> // /// </summary>
public PersonModelBase() { } // public string? Title { get; set; }
/// <summary> // /// <summary>
/// // ///
/// </summary> // /// </summary>
/// <param name="person"></param> // public string? Description { get; set; }
public PersonModelBase(PersonBase<T> person) { //}
//if(person.Image != null)
// Image = new ImageModel(person.Image); //public class MediaAttachmentResponseModel : RequestModelBase {
}
} // /// <summary>
// ///
// /// </summary>
// public string Src { get; set; } = string.Empty;
// /// <summary>
// ///
// /// </summary>
// public MediaTypes MediaType { get; set; } = MediaTypes.Unknown;
// /// <summary>
// ///
// /// </summary>
// public List<MediaAttachmentL10nRequestModel> L10n { get; set; } = new List<MediaAttachmentL10nRequestModel>();
//}
///// <summary>
/////
///// </summary>
///// <typeparam name="T"></typeparam>
//public abstract class PersonModelBase<T> : ModelBase {
// /// <summary>
// ///
// /// </summary>
// public Guid Id { get; set; }
// /// <summary>
// ///
// /// </summary>
// public MediaAttachmentResponseModel? Image { get; set; }
// /// <summary>
// ///
// /// </summary>
// public PersonModelBase() { }
// /// <summary>
// ///
// /// </summary>
// /// <param name="person"></param>
// public PersonModelBase(PersonBase<T> person) {
// //if(person.Image != null)
// // Image = new ImageModel(person.Image);
// }
//}
} }

View File

@ -1,45 +0,0 @@
using Core.Abstractions.Models;
using DomainObjects.L10n;
namespace WeatherForecast.Models.Abstractions.PostItem.Responses {
/// <summary>
///
/// </summary>
public class MediaAttachmentL10nModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public string Locale { get; set; }
/// <summary>
///
/// </summary>
public string Alt { get; set; }
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? Description { get; set; }
/// <summary>
///
/// </summary>
/// <param name="imageL10n"></param>
public MediaAttachmentL10nModel(MediaAttachmentL10n imageL10n) {
Locale = imageL10n.Locale.Name;
Alt = imageL10n.Alt;
}
}
}

View File

@ -1,51 +0,0 @@
using Core.Abstractions.Models;
using DomainObjects;
using DomainObjects.Enumerations;
namespace WeatherForecast.Models.Abstractions.PostItem.Responses {
/// <summary>
///
/// </summary>
public class MediaAttachmentResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public List<MediaAttachmentL10nModel>? L10n { get; set; }
/// <summary>
///
/// </summary>
public string? Src { get; set; }
/// <summary>
///
/// </summary>
public string? Alt { get; set; }
/// <summary>
///
/// </summary>
/// <param name="image"></param>
public MediaAttachmentResponseModel(MediaAttachment image) {
L10n = image.L10n.Select(x => new MediaAttachmentL10nModel(x)).ToList();
}
/// <summary>
///
/// </summary>
/// <param name="mediaAttachment"></param>
/// <param name="locale"></param>
public MediaAttachmentResponseModel(MediaAttachment mediaAttachment, Locales locale) {
Src = mediaAttachment.Src;
var l10n = mediaAttachment.L10n.Single(x => x.Locale == locale);
if (l10n != null) {
Alt = l10n.Alt;
}
}
}
}

View File

@ -1,74 +0,0 @@
using Core.Abstractions.Models;
using DomainObjects.L10n;
namespace WeatherForecast.Models.Abstractions.PostItem.Responses {
/// <summary>
///
/// </summary>
public class PostItemL10nModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public string Locale { get; set; }
/// <summary>
///
/// </summary>
public string Slug { get; set; }
/// <summary>
///
/// </summary>
public string Description { get; set; }
/// <summary>
///
/// </summary>
public string Title { get; set; }
/// <summary>
///
/// </summary>
public string ShortText { get; set; }
/// <summary>
///
/// </summary>
public string? Text { get; set; }
/// <summary>
///
/// </summary>
public string PlainText { get; set; }
/// <summary>
///
/// </summary>
public string TextFormat { get; set; }
/// <summary>
///
/// </summary>
public List<string>? Badges { get; set; }
/// <summary>
///
/// </summary>
/// <param name="postItemL10n"></param>
public PostItemL10nModel(PostItemL10n postItemL10n) {
Locale = postItemL10n.Locale.Name;
Slug = postItemL10n.Slug;
Description = postItemL10n.Description;
Title = postItemL10n.Title;
ShortText = postItemL10n.ShortText;
PlainText = postItemL10n.PlainText;
Text = postItemL10n.Text;
TextFormat = postItemL10n.TextFormat.Name;
Badges = postItemL10n.Badges;
}
}
}

View File

@ -1,155 +0,0 @@
using DomainObjects.Abstractions;
using DomainObjects.Enumerations;
using Core.Abstractions.Models;
using WeatherForecast.Models.Category.Responses;
using DomainObjects.Documents.Categories;
namespace WeatherForecast.Models.Abstractions.PostItem.Responses
{
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class PostItemResponseModelBase<T> : ResponseModelBase {
/// <summary>
///
/// </summary>
public Guid Id { get; set; }
/// <summary>
///
/// </summary>
public Guid SiteId { get; set; }
/// <summary>
///
/// </summary>
public List<PostItemL10nModel>? L10n { get; set; }
#region Localized costrutor
/// <summary>
///
/// </summary>
public string? Slug { get; set; }
/// <summary>
///
/// </summary>
public string? Description { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? ShortText { get; set; }
/// <summary>
///
/// </summary>
public string? Text { get; set; }
/// <summary>
///
/// </summary>
public string? PlainText { get; set; }
/// <summary>
///
/// </summary>
public string? ContentType { get; set; }
/// <summary>
///
/// </summary>
public List<string>? Badges { get; set; }
#endregion
/// <summary>
///
/// </summary>
public List<MediaAttachmentResponseModel>? MediaAttachemnts { get; set; }
/// <summary>
///
/// </summary>
public AuthorModel? Author { get; set; }
/// <summary>
///
/// </summary>
public DateTime Created { get; set; }
/// <summary>
///
/// </summary>
public List<string>? Tags { get; set; }
/// <summary>
///
/// </summary>
public List<GetCategoryItemResponseModel>? Categories { get; set; }
/// <summary>
///
/// </summary>
public bool? FamilyFriendly { get; set; }
/// <summary>
///
/// </summary>
/// <param name="postItem"></param>
public PostItemResponseModelBase(PostItemBase<T> postItem) {
Id = postItem.Id;
SiteId = postItem.SiteId;
//Author = new AuthorModel(postItem.Author);
Created = postItem.Created;
Tags = postItem.Tags;
FamilyFriendly = postItem.FamilyFriendly;
}
/// <summary>
///
/// </summary>
/// <param name="postItem"></param>
/// <param name="categories"></param>
public PostItemResponseModelBase(PostItemBase<T> postItem, List<DomainObjects.Documents.Categories.Category> categories) : this(postItem) {
L10n = postItem.L10n.Select(x => new PostItemL10nModel(x)).ToList();
Categories = categories.Select(x => new GetCategoryItemResponseModel(x)).ToList();
MediaAttachemnts = postItem.MediaAttachments?.Select(x => new MediaAttachmentResponseModel(x)).ToList();
}
/// <summary>
///
/// </summary>
/// <param name="postItem"></param>
/// <param name="categories"></param>
/// <param name="locale"></param>
public PostItemResponseModelBase(PostItemBase<T> postItem, List<DomainObjects.Documents.Categories.Category> categories, Locales locale) : this(postItem) {
var postItemL10n = postItem.L10n.Single(x => x.Locale == locale);
if (postItemL10n != null) {
Slug = postItemL10n.Slug;
Badges = postItemL10n.Badges;
Title = postItemL10n.Title;
ShortText = postItemL10n.ShortText;
Text = postItemL10n.Text;
PlainText = postItemL10n.PlainText;
Badges = postItemL10n.Badges;
}
Categories = categories.Select(x => new GetCategoryItemResponseModel(x, locale)).ToList();
MediaAttachemnts = postItem.MediaAttachments?.Select(x => new MediaAttachmentResponseModel(x, locale)).ToList();
}
}
}

View File

@ -1,24 +0,0 @@
using DomainObjects;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class AuthorModel : PersonModelBase<Author> {
/// <summary>
///
/// </summary>
public string NickName { get; set; }
/// <summary>
///
/// </summary>
/// <param name="author"></param>
public AuthorModel(Author author) {
NickName = author.NickName;
}
}
}

View File

@ -2,12 +2,12 @@
using Core.Enumerations; using Core.Enumerations;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace WeatherForecast.Models.BlogItem.Requests { namespace WeatherForecast.Models.Blog.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class GetBlogItemSlugRequestModel : RequestModelBase, IValidatableObject { public class GetBlogItemLocalizedRequestModel : RequestModelBase, IValidatableObject {
/// <summary> /// <summary>
/// ///

View File

@ -4,12 +4,12 @@ using DomainObjects.Enumerations;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace WeatherForecast.Models.BlogItem.Requests { namespace WeatherForecast.Models.Blog.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class GetBlogItemsRequestModel : RequestModelBase, IValidatableObject { public class GetBlogItemsLocalizedRequestModel : RequestModelBase, IValidatableObject {
/// <summary> /// <summary>
/// ///
@ -34,7 +34,7 @@ namespace WeatherForecast.Models.BlogItem.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public Locales Locale { get; set; } = Locales.Us; public Locales Locale { get; set; } = Locales.Unknown;
/// <summary> /// <summary>
/// ///

View File

@ -157,7 +157,7 @@ namespace WeatherForecast.Models.Blog.Requests {
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public BlogDocument ToDomainObject(Guid userId, Guid siteId) => new() { public BlogDocument ToDomainObject(Guid siteId, Guid userId) => new() {
SiteId = siteId, SiteId = siteId,
L10n = L10n.Select(x => new PostItemL10n() { L10n = L10n.Select(x => new PostItemL10n() {

View File

@ -157,7 +157,8 @@ namespace WeatherForecast.Models.Blog.Requests {
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public BlogDocument ToDomainObject(Guid userId, Guid siteId) => new() { public BlogDocument ToDomainObject(Guid siteId, Guid userId, Guid blogId) => new() {
Id = blogId,
SiteId = siteId, SiteId = siteId,
L10n = L10n.Select(x => new PostItemL10n() { L10n = L10n.Select(x => new PostItemL10n() {

View File

@ -0,0 +1,343 @@
using Core.Enumerations;
using Core.Abstractions.Models;
using DomainObjects;
using DomainObjects.L10n;
using DomainObjects.Enumerations;
using DomainObjects.Documents.Posts;
using DomainObjects.Documents.Users;
using DomainObjects.Documents.Categories;
using DomainObjects.Documents.Categories.L10n;
namespace WeatherForecast.Models.Blog.Responses {
#region Media attachment
/// <summary>
///
/// </summary>
public class GetBlogItemMediaAttachmentL10nResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public string Locale { get; set; }
/// <summary>
///
/// </summary>
public string Alt { get; set; }
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? Description { get; set; }
/// <summary>
///
/// </summary>
/// <param name="imageL10n"></param>
public GetBlogItemMediaAttachmentL10nResponseModel(MediaAttachmentL10n imageL10n) {
Locale = imageL10n.Locale.Name;
Alt = imageL10n.Alt;
Target = imageL10n.Target;
Title = imageL10n.Title;
Description = imageL10n.Description;
}
}
/// <summary>
///
/// </summary>
public class GetBlogItemMediaAttachmentResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public string Src { get; set; }
/// <summary>
///
/// </summary>
public MediaTypes MediaType { get; set; }
/// <summary>
///
/// </summary>
public List<GetBlogItemMediaAttachmentL10nResponseModel>? L10n { get; set; }
/// <summary>
///
/// </summary>
/// <param name="image"></param>
public GetBlogItemMediaAttachmentResponseModel(MediaAttachment image) {
Src = image.Src;
MediaType = image.MediaType;
L10n = image.L10n.Select(x => new GetBlogItemMediaAttachmentL10nResponseModel(x)).ToList();
}
}
#endregion
#region Author
/// <summary>
///
/// </summary>
public class GetBlogItemAuthorModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public Guid Id { get; set; }
/// <summary>
///
/// </summary>
public GetBlogItemMediaAttachmentResponseModel? Avatar { get; set; }
/// <summary>
///
/// </summary>
public string NickName { get; set; }
/// <summary>
///
/// </summary>
/// <param name="author"></param>
public GetBlogItemAuthorModel(User author) {
Id = author.Id;
if (author.Avatar != null)
Avatar = new GetBlogItemMediaAttachmentResponseModel(author.Avatar);
NickName = author.Username;
}
}
#endregion
#region Category
/// <summary>
///
/// </summary>
public class GetBlogItemCategoryL10nResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public Locales Locale { get; set; }
/// <summary>
///
/// </summary>
public string Slug { get; set; }
/// <summary>
///
/// </summary>
public string Text { get; set; }
/// <summary>
///
/// </summary>
/// <param name="categoryL10n"></param>
public GetBlogItemCategoryL10nResponseModel(CategoryL10n categoryL10n) {
Locale = categoryL10n.Locale;
Slug = categoryL10n.Slug;
Text = categoryL10n.Text;
}
}
/// <summary>
///
/// </summary>
public class GetBlogItemCategoryResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public Guid Id { get; set; }
/// <summary>
///
/// </summary>
public Guid SiteId { get; set; }
/// <summary>
///
/// </summary>
public List<GetBlogItemCategoryL10nResponseModel>? L10n { get; set; }
/// <summary>
///
/// </summary>
/// <param name="category"></param>
public GetBlogItemCategoryResponseModel(Category category) {
Id = category.Id;
SiteId = category.SiteId;
L10n = category.L10n.Select(x => new GetBlogItemCategoryL10nResponseModel(x)).ToList();
}
}
#endregion
#region Blog item
/// <summary>
///
/// </summary>
public class GetBlogItemL10nResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public Locales Locale { get; set; }
/// <summary>
///
/// </summary>
public string Slug { get; set; }
/// <summary>
///
/// </summary>
public string Description { get; set; }
/// <summary>
///
/// </summary>
public string Title { get; set; }
/// <summary>
///
/// </summary>
public string ShortText { get; set; }
/// <summary>
///
/// </summary>
public string? Text { get; set; }
/// <summary>
///
/// </summary>
public string PlainText { get; set; }
/// <summary>
///
/// </summary>
public string TextFormat { get; set; }
/// <summary>
///
/// </summary>
public List<string>? Badges { get; set; }
/// <summary>
///
/// </summary>
/// <param name="postItemL10n"></param>
public GetBlogItemL10nResponseModel(PostItemL10n postItemL10n) {
Locale = postItemL10n.Locale;
Slug = postItemL10n.Slug;
Description = postItemL10n.Description;
Title = postItemL10n.Title;
Text = postItemL10n.Text;
TextFormat = postItemL10n.TextFormat.Name;
PlainText = postItemL10n.PlainText;
ShortText = postItemL10n.ShortText;
Badges = postItemL10n.Badges;
}
}
/// <summary>
///
/// </summary>
public class GetBlogItemResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public Guid Id { get; set; }
/// <summary>
///
/// </summary>
public Guid SiteId { get; set; }
/// <summary>
///
/// </summary>
public List<GetBlogItemL10nResponseModel> L10n { get; set; }
/// <summary>
///
/// </summary>
public List<GetBlogItemMediaAttachmentResponseModel>? MediaAttachemnts { get; set; }
/// <summary>
///
/// </summary>
public GetBlogItemAuthorModel Author { get; set; }
/// <summary>
///
/// </summary>
public DateTime Created { get; set; }
/// <summary>
///
/// </summary>
public List<string>? Tags { get; set; }
/// <summary>
///
/// </summary>
public List<GetBlogItemCategoryResponseModel> Categories { get; set; }
/// <summary>
///
/// </summary>
public bool? FamilyFriendly { get; set; }
/// <summary>
///
/// </summary>
public uint? ReadTime { get; set; }
/// <summary>
///
/// </summary>
public uint? Likes { get; set; }
/// <summary>
///
/// </summary>
/// <param name="blogItem"></param>
/// <param name="categories"></param>
/// <param name="author"></param>
public GetBlogItemResponseModel(BlogDocument blogItem, List<Category> categories, User author) {
Id = blogItem.Id;
SiteId = blogItem.SiteId;
L10n = blogItem.L10n.Select(x => new GetBlogItemL10nResponseModel(x)).ToList();
MediaAttachemnts = blogItem.MediaAttachments?.Select(x => new GetBlogItemMediaAttachmentResponseModel(x)).ToList();
Author = new GetBlogItemAuthorModel(author);
Created = blogItem.Created;
Tags = blogItem.Tags;
Categories = categories.Select(x => new GetBlogItemCategoryResponseModel(x)).ToList();
FamilyFriendly = blogItem.FamilyFriendly;
ReadTime = blogItem.ReadTime;
Likes = blogItem.Likes;
}
}
#endregion
}

View File

@ -0,0 +1,245 @@
using Core.Enumerations;
using Core.Abstractions.Models;
using DomainObjects;
using DomainObjects.Enumerations;
using DomainObjects.Documents.Posts;
using DomainObjects.Documents.Users;
using DomainObjects.Documents.Categories;
namespace WeatherForecast.Models.Blog.Responses {
#region Media attachment
/// <summary>
///
/// </summary>
public class GetBlogItemSlugMediaAttachmentResponseModel {
/// <summary>
///
/// </summary>
public string Src { get; set; }
/// <summary>
///
/// </summary>
public MediaTypes MediaType { get; set; }
/// <summary>
///
/// </summary>
public string? Alt { get; set; }
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? Description { get; set; }
/// <summary>
///
/// </summary>
/// <param name="mediaAttachment"></param>
/// <param name="locale"></param>
public GetBlogItemSlugMediaAttachmentResponseModel(MediaAttachment mediaAttachment, Locales locale) {
var l10n = mediaAttachment.L10n.Single(x => x.Locale == locale);
Src = mediaAttachment.Src;
MediaType = mediaAttachment.MediaType;
Alt = l10n.Alt;
Target = l10n.Target;
Title = l10n.Title;
Description = l10n.Description;
}
}
#endregion
#region Author
/// <summary>
///
/// </summary>
public class GetBlogItemSlugAuthorModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public GetBlogItemSlugMediaAttachmentResponseModel? Avatar { get; set; }
/// <summary>
///
/// </summary>
public string NickName { get; set; }
/// <summary>
///
/// </summary>
/// <param name="author"></param>
/// <param name="locale"></param>
public GetBlogItemSlugAuthorModel(User author, Locales locale) {
if(author.Avatar != null)
Avatar = new GetBlogItemSlugMediaAttachmentResponseModel(author.Avatar, locale);
NickName = author.Username;
}
}
#endregion
#region Category
/// <summary>
///
/// </summary>
public class GetBlogItemSlugCategoryResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public string Slug { get; set; }
/// <summary>
///
/// </summary>
public string Text { get; set; }
/// <summary>
///
/// </summary>
/// <param name="category"></param>
/// <param name="locale"></param>
public GetBlogItemSlugCategoryResponseModel(Category category, Locales locale) {
var l10n = category.L10n.Single(x => x.Locale == locale);
Slug = l10n.Slug;
Text = l10n.Text;
}
}
#endregion
#region Blog item
/// <summary>
///
/// </summary>
public class GetBlogItemSlugResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public string? Slug { get; set; }
/// <summary>
///
/// </summary>
public string? Description { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? ShortText { get; set; }
/// <summary>
///
/// </summary>
public string? Text { get; set; }
/// <summary>
///
/// </summary>
public string? PlainText { get; set; }
/// <summary>
///
/// </summary>
public string? ContentType { get; set; }
/// <summary>
///
/// </summary>
public List<string>? Badges { get; set; }
/// <summary>
///
/// </summary>
public List<GetBlogItemSlugMediaAttachmentResponseModel>? MediaAttachemnts { get; set; }
/// <summary>
///
/// </summary>
public GetBlogItemSlugAuthorModel? Author { get; set; }
/// <summary>
///
/// </summary>
public DateTime Created { get; set; }
/// <summary>
///
/// </summary>
public List<string>? Tags { get; set; }
/// <summary>
///
/// </summary>
public List<GetBlogItemSlugCategoryResponseModel> Categories { get; set; }
/// <summary>
///
/// </summary>
public bool? FamilyFriendly { get; set; }
/// <summary>
///
/// </summary>
public uint? ReadTime { get; set; }
/// <summary>
///
/// </summary>
public uint? Likes { get; set; }
/// <summary>
///
/// </summary>
/// <param name="blogItem"></param>
/// <param name="categories"></param>
/// <param name="author"></param>
/// <param name="locale"></param>
public GetBlogItemSlugResponseModel(BlogDocument blogItem, List<Category> categories, User author, Locales locale) {
var postItemL10n = blogItem.L10n.Single(x => x.Locale == locale);
Slug = postItemL10n.Slug;
Badges = postItemL10n.Badges;
Title = postItemL10n.Title;
ShortText = postItemL10n.ShortText;
Text = postItemL10n.Text;
PlainText = postItemL10n.PlainText;
Badges = postItemL10n.Badges;
Created = blogItem.Created;
Tags = blogItem.Tags;
Categories = categories.Select(x => new GetBlogItemSlugCategoryResponseModel(x, locale)).ToList();
MediaAttachemnts = blogItem.MediaAttachments?.Select(x => new GetBlogItemSlugMediaAttachmentResponseModel(x, locale)).ToList();
Author = new GetBlogItemSlugAuthorModel(author, locale);
ReadTime = blogItem.ReadTime;
Likes = blogItem.Likes;
}
}
#endregion
}

View File

@ -0,0 +1,19 @@
using Core.Models;
namespace WeatherForecast.Models.Blog.Responses {
/// <summary>
///
/// </summary>
public class GetBlogItemsSlugResponseModel : PaginationModelBase<GetBlogItemSlugResponseModel> {
/// <summary>
///
/// </summary>
/// <param name="currentPage"></param>
/// <param name="totalPages"></param>
/// <param name="items"></param>
public GetBlogItemsSlugResponseModel(int currentPage, int totalPages, List<GetBlogItemSlugResponseModel> items)
: base(currentPage, totalPages, items) { }
}
}

View File

@ -1,45 +0,0 @@
using WeatherForecast.Models.Abstractions.PostItem.Responses;
using DomainObjects.Enumerations;
using DomainObjects.Documents.Categories;
using DomainObjects.Documents.Posts;
namespace WeatherForecast.Models.Blog.Responses
{
/// <summary>
///
/// </summary>
public class GetBlogItemResponseModel : PostItemResponseModelBase<BlogDocument> {
/// <summary>
///
/// </summary>
public uint? ReadTime { get; set; }
/// <summary>
///
/// </summary>
public uint? Likes { get; set; }
/// <summary>
///
/// </summary>
/// <param name="blogItem"></param>
/// <param name="categories"></param>
public GetBlogItemResponseModel(BlogDocument blogItem, List<DomainObjects.Documents.Categories.Category> categories) : base(blogItem, categories) {
ReadTime = blogItem.ReadTime;
Likes = blogItem.Likes;
}
/// <summary>
///
/// </summary>
/// <param name="blogItem"></param>
/// <param name="categories"></param>
/// <param name="locale"></param>
public GetBlogItemResponseModel(BlogDocument blogItem, List<DomainObjects.Documents.Categories.Category> categories, Locales locale) : base(blogItem, categories, locale) {
ReadTime = blogItem.ReadTime;
Likes = blogItem.Likes;
}
}
}

View File

@ -1,69 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using Core.Abstractions;
using Core.Abstractions.Models;
using Core.Enumerations;
using DomainObjects.Enumerations;
using DomainObjects.Documents.Categories.L10n;
namespace WeatherForecast.Models.Category.Requests
{
/// <summary>
///
/// </summary>
public class CategoryL10nModel : RequestModelBase, IValidatableObject {
/// <summary>
///
/// </summary>
public string? Locale { get; set; }
/// <summary>
///
/// </summary>
public string? Slug { get; set; }
/// <summary>
///
/// </summary>
public string? Text { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public CategoryL10n ToDomainObject() {
if (HasValidationErrors()) throw new ValidationException();
return new CategoryL10n() {
Locale = Enumeration.FromDisplayName<Locales>(Locale),
Slug = Slug,
Text = Text
};
}
/// <summary>
///
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (string.IsNullOrWhiteSpace(Locale))
yield return new ValidationResult($"{nameof(Locale)} {Errors.NullOrWhiteSpace.Name}");
else if (Enumeration.FromDisplayName<Locales>(Locale) == null)
yield return new ValidationResult($"{nameof(Locale)} {Errors.WrongOrNotManaged}");
if (string.IsNullOrWhiteSpace(Slug))
yield return new ValidationResult($"{nameof(Slug)} {Errors.NullOrWhiteSpace.Name}");
if (string.IsNullOrWhiteSpace(Text))
yield return new ValidationResult($"{nameof(Text)} {Errors.NullOrWhiteSpace.Name}");
}
// https://www.meziantou.net/csharp-8-nullable-reference-types.htm
[MemberNotNullWhen(false, new[] { nameof(Locale), nameof(Slug), nameof(Text) })]
private bool HasValidationErrors() => Validate(new ValidationContext(this)).Any();
}
}

View File

@ -1,41 +0,0 @@
using Core.Abstractions.Models;
using Core.Enumerations;
using Extensions;
using System.ComponentModel.DataAnnotations;
using DomainObjects.Documents.Categories;
namespace WeatherForecast.Models.Category.Requests
{
/// <summary>
///
/// </summary>
public class PostCategoryItemRequestModel : RequestModelBase, IValidatableObject {
/// <summary>
///
/// </summary>
public List<CategoryL10nModel>? L10n { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public DomainObjects.Documents.Categories.Category ToDomainObject(Guid siteId) => new DomainObjects.Documents.Categories.Category() {
SiteId = siteId,
L10n = L10n.Select(x => x.ToDomainObject()).ToList()
};
/// <summary>
///
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (L10n.IsNullOrEmpty())
yield return new ValidationResult($"{nameof(L10n)} ${Errors.NullOrEmpty}");
}
}
}

View File

@ -1,41 +0,0 @@
using Core.Abstractions.Models;
using Core.Enumerations;
using Extensions;
using System.ComponentModel.DataAnnotations;
using DomainObjects.Documents.Categories;
namespace WeatherForecast.Models.Category.Requests
{
/// <summary>
///
/// </summary>
public class PutCategoryItemRequestModel : RequestModelBase, IValidatableObject {
/// <summary>
///
/// </summary>
public List<CategoryL10nModel>? L10n { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public DomainObjects.Documents.Categories.Category ToDomainObject(Guid siteId) => new DomainObjects.Documents.Categories.Category() {
SiteId = siteId,
L10n = L10n.Select(x => x.ToDomainObject()).ToList()
};
/// <summary>
///
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (L10n.IsNullOrEmpty())
yield return new ValidationResult($"{nameof(L10n)} ${Errors.NullOrEmpty}");
}
}
}

View File

@ -2,7 +2,7 @@
using Core.Enumerations; using Core.Enumerations;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace WeatherForecast.Models.CategoryItem.Requests { namespace WeatherForecast.Models.Categories.Requests {
/// <summary> /// <summary>
/// ///
@ -22,7 +22,6 @@ namespace WeatherForecast.Models.CategoryItem.Requests {
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (string.IsNullOrWhiteSpace(Slug)) if (string.IsNullOrWhiteSpace(Slug))
yield return new ValidationResult($"{Errors.NullOrWhiteSpace} {nameof(Slug)}"); yield return new ValidationResult($"{Errors.NullOrWhiteSpace} {nameof(Slug)}");
} }
} }
} }

View File

@ -3,7 +3,7 @@ using Core.Enumerations;
using DomainObjects.Enumerations; using DomainObjects.Enumerations;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace WeatherForecast.Models.CategoryItem.Requests { namespace WeatherForecast.Models.Categories.Requests {
/// <summary> /// <summary>
/// ///

View File

@ -0,0 +1,80 @@
using Core.Abstractions.Models;
using Core.Enumerations;
using Extensions;
using System.ComponentModel.DataAnnotations;
using DomainObjects.Documents.Categories;
using Core.Abstractions;
using DomainObjects.Documents.Categories.L10n;
using DomainObjects.Enumerations;
using System.Diagnostics.CodeAnalysis;
using static System.Net.Mime.MediaTypeNames;
namespace WeatherForecast.Models.Categories.Requests
{
/// <summary>
///
/// </summary>
public class PostCategoryL10nModel : RequestModelBase {
/// <summary>
///
/// </summary>
public Locales Locale { get; set; } = Locales.Unknown;
/// <summary>
///
/// </summary>
public string Slug { get; set; } = string.Empty;
/// <summary>
///
/// </summary>
public string Text { get; set; } = string.Empty;
}
/// <summary>
///
/// </summary>
public class PostCategoryItemRequestModel : RequestModelBase, IValidatableObject {
/// <summary>
///
/// </summary>
public List<PostCategoryL10nModel> L10n { get; set; } = new List<PostCategoryL10nModel>();
/// <summary>
///
/// </summary>
/// <returns></returns>
public DomainObjects.Documents.Categories.Category ToDomainObject(Guid siteId) => new DomainObjects.Documents.Categories.Category() {
SiteId = siteId,
L10n = L10n.Select(x => new CategoryL10n() {
Locale = x.Locale,
Slug = x.Slug,
Text = x.Text
}).ToList()
};
/// <summary>
///
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (L10n.IsNullOrEmpty())
yield return new ValidationResult($"{nameof(L10n)} ${Errors.NullOrEmpty}");
foreach(var res in L10n) {
if (res.Locale == Locales.Unknown)
yield return new ValidationResult($"{nameof(res.Locale)} {Errors.UnableToParse.Name}");
if (string.IsNullOrWhiteSpace(res.Slug))
yield return new ValidationResult($"{nameof(res.Slug)} {Errors.NullOrWhiteSpace.Name}");
if (string.IsNullOrWhiteSpace(res.Text))
yield return new ValidationResult($"{nameof(res.Text)} {Errors.NullOrWhiteSpace.Name}");
}
}
}
}

View File

@ -0,0 +1,80 @@
using System.ComponentModel.DataAnnotations;
using DomainObjects.Enumerations;
using DomainObjects.Documents.Categories.L10n;
using Extensions;
using Core.Abstractions.Models;
using Core.Enumerations;
namespace WeatherForecast.Models.Categories.Requests {
/// <summary>
///
/// </summary>
public class PutCategoryL10nModel : RequestModelBase {
/// <summary>
///
/// </summary>
public Locales Locale { get; set; } = Locales.Unknown;
/// <summary>
///
/// </summary>
public string Slug { get; set; } = string.Empty;
/// <summary>
///
/// </summary>
public string Text { get; set; } = string.Empty;
}
/// <summary>
///
/// </summary>
public class PutCategoryItemRequestModel : RequestModelBase, IValidatableObject {
/// <summary>
///
/// </summary>
public List<PutCategoryL10nModel> L10n { get; set; } = new List<PutCategoryL10nModel>();
/// <summary>
///
/// </summary>
/// <returns></returns>
public DomainObjects.Documents.Categories.Category ToDomainObject(Guid siteId, Guid categoryId) => new DomainObjects.Documents.Categories.Category() {
Id = categoryId,
SiteId = siteId,
L10n = L10n.Select(x => new CategoryL10n() {
Locale = x.Locale,
Slug = x.Slug,
Text = x.Text
}).ToList()
};
/// <summary>
///
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (L10n.IsNullOrEmpty())
yield return new ValidationResult($"{nameof(L10n)} ${Errors.NullOrEmpty}");
foreach (var res in L10n) {
if (res.Locale == Locales.Unknown)
yield return new ValidationResult($"{nameof(res.Locale)} {Errors.UnableToParse.Name}");
if (string.IsNullOrWhiteSpace(res.Slug))
yield return new ValidationResult($"{nameof(res.Slug)} {Errors.NullOrWhiteSpace.Name}");
if (string.IsNullOrWhiteSpace(res.Text))
yield return new ValidationResult($"{nameof(res.Text)} {Errors.NullOrWhiteSpace.Name}");
}
}
}
}

View File

@ -1,7 +1,7 @@
using Core.Abstractions.Models; using Core.Abstractions.Models;
using DomainObjects.Documents.Categories.L10n; using DomainObjects.Documents.Categories.L10n;
namespace WeatherForecast.Models.Category.Responses namespace WeatherForecast.Models.Categories.Responses
{ {
/// <summary> /// <summary>

View File

@ -1,14 +1,44 @@
using Core.Abstractions.Models; using Core.Abstractions.Models;
using DomainObjects.Enumerations; using DomainObjects.Enumerations;
using DomainObjects.Documents.Categories; using DomainObjects.Documents.Categories.L10n;
namespace WeatherForecast.Models.Category.Responses namespace WeatherForecast.Models.Categories.Responses {
{
/// <summary>
///
/// </summary>
public class GetCategoryItemL10nResponseModel : ResponseModelBase {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class GetCategoryItemResponseModel : ResponseModelBase { public string Locale { get; set; }
/// <summary>
///
/// </summary>
public string Slug { get; set; }
/// <summary>
///
/// </summary>
public string Text { get; set; }
/// <summary>
///
/// </summary>
/// <param name="categoryL10n"></param>
public GetCategoryItemL10nResponseModel(CategoryL10n categoryL10n) {
Locale = categoryL10n.Locale.Name;
Slug = categoryL10n.Slug;
Text = categoryL10n.Text;
}
}
/// <summary>
///
/// </summary>
public class GetCategoryItemResponseModel : ResponseModelBase {
/// <summary> /// <summary>
/// ///
@ -33,7 +63,7 @@ namespace WeatherForecast.Models.Category.Responses
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<CategoryL10nModel>? L10n { get; set; } public List<GetCategoryItemL10nResponseModel>? L10n { get; set; }
/// <summary> /// <summary>
/// ///
@ -43,7 +73,7 @@ namespace WeatherForecast.Models.Category.Responses
Id = category.Id; Id = category.Id;
SiteId = category.SiteId; SiteId = category.SiteId;
L10n = category.L10n.Select(x => new CategoryL10nModel(x)).ToList(); L10n = category.L10n.Select(x => new GetCategoryItemL10nResponseModel(x)).ToList();
} }
/// <summary> /// <summary>

View File

@ -1,27 +0,0 @@
using DomainObjects;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class CommentModel {
/// <summary>
///
/// </summary>
public AuthorModel? Author { get; set; }
/// <summary>
///
/// </summary>
public string? Comment { get; set; }
/// <summary>
///
/// </summary>
public List<CommentModel>? Responses { get; set; }
}
}

View File

@ -0,0 +1,32 @@
using DomainObjects;
namespace WeatherForecast.Models.Content.Responses
{
/// <summary>
///
/// </summary>
public class FormItemModel
{
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? PlaceHolder { get; set; }
/// <summary>
///
/// </summary>
/// <param name="formItem"></param>
public FormItemModel(FormItem formItem)
{
Title = formItem.Title;
PlaceHolder = formItem.PlaceHolder;
}
}
}

View File

@ -1,8 +1,60 @@
using Core.Abstractions.Models; using Core.Abstractions.Models;
using DomainObjects;
using DomainObjects.Documents; using DomainObjects.Documents;
using WeatherForecast.Models.Content.Responses.Pages; using WeatherForecast.Models.Content.Responses.Pages;
namespace WeatherForecast.Models.Content.Responses { namespace WeatherForecast.Models.Content.Responses
{
/// <summary>
///
/// </summary>
public class LocalizationModel {
/// <summary>
///
/// </summary>
public string? TimeZone { get; set; }
/// <summary>
///
/// </summary>
public string? Locale { get; set; }
/// <summary>
///
/// </summary>
public string? DateFormat { get; set; }
/// <summary>
///
/// </summary>
public string? TimeFormat { get; set; }
/// <summary>
///
/// </summary>
public string? Currency { get; set; }
/// <summary>
///
/// </summary>
public string? CurrencySymbol { get; set; }
/// <summary>
///
/// </summary>
/// <param name="localization"></param>
public LocalizationModel(Localization localization) {
TimeZone = localization.TimeZone;
Locale = localization.Locale;
DateFormat = localization.DateFormat;
TimeFormat = localization.TimeFormat;
Currency = localization.Currency;
CurrencySymbol = localization.CurrencySymbol;
}
}
/// <summary> /// <summary>
/// ///

View File

@ -0,0 +1,40 @@
using DomainObjects;
namespace WeatherForecast.Models.Content.Responses
{
/// <summary>
///
/// </summary>
public class HeaderModel
{
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public Dictionary<string, string>? Link { get; set; }
/// <summary>
///
/// </summary>
public Dictionary<string, string>? Meta { get; set; }
/// <summary>
///
/// </summary>
/// <param name="header"></param>
public HeaderModel(Header header)
{
Title = header.Title;
Link = header.Link;
Meta = header.Meta;
}
}
}

View File

@ -0,0 +1,32 @@
using DomainObjects;
namespace WeatherForecast.Models.Content.Responses
{
/// <summary>
///
/// </summary>
public class LinkModel
{
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public string? AnchorText { get; set; }
/// <summary>
///
/// </summary>
/// <param name="link"></param>
public LinkModel(Link link)
{
Target = link.Target;
AnchorText = link.AnchorText;
}
}
}

View File

@ -0,0 +1,59 @@
using Core.Abstractions.Models;
using Core.Enumerations;
using DomainObjects.Enumerations;
namespace WeatherForecast.Models.Content.Responses {
/// <summary>
///
/// </summary>
public class MediaAttachmentL10nRequestModel : RequestModelBase {
/// <summary>
///
/// </summary>
public Locales Locale { get; set; } = Locales.Unknown;
/// <summary>
///
/// </summary>
public string Alt { get; set; } = string.Empty;
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? Description { get; set; }
}
/// <summary>
///
/// </summary>
public class MediaAttachmentResponseModel : RequestModelBase {
/// <summary>
///
/// </summary>
public string Src { get; set; } = string.Empty;
/// <summary>
///
/// </summary>
public MediaTypes MediaType { get; set; } = MediaTypes.Unknown;
/// <summary>
///
/// </summary>
public List<MediaAttachmentL10nRequestModel> L10n { get; set; } = new List<MediaAttachmentL10nRequestModel>();
}
}

View File

@ -0,0 +1,43 @@
using DomainObjects;
namespace WeatherForecast.Models.Content.Responses
{
/// <summary>
///
/// </summary>
public class MenuItemModel
{
/// <summary>
///
/// </summary>
public string? Icon { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public List<MenuItemModel>? ChildItems { get; set; }
/// <summary>
///
/// </summary>
/// <param name="menuItem"></param>
public MenuItemModel(MenuItem menuItem)
{
Title = menuItem.Title;
Target = menuItem.Target;
ChildItems = menuItem.ChildItems?.Select(x => new MenuItemModel(x)).ToList();
}
}
}

View File

@ -1,12 +1,13 @@
using DomainObjects.PageSections; using DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.Content.Responses.PageSections { namespace WeatherForecast.Models.Content.Responses.PageSections
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CallToActionSectionModel : PageSectionModelBase<CallToActionSection> { public class CallToActionSectionModel : PageSectionModelBase<CallToActionSection> {
/// <summary> /// <summary>
/// ///

View File

@ -3,12 +3,13 @@
using DomainObjects.PageSections; using DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.Content.Responses.PageSections { namespace WeatherForecast.Models.Content.Responses.PageSections
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CartProductsSectionModel : PageSectionModelBase<ProductsSection> { public class CartProductsSectionModel : PageSectionModelBase<ProductsSection> {
/// <summary> /// <summary>
/// ///

View File

@ -1,12 +1,13 @@
using DomainObjects.PageSections; using DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.Content.Responses.PageSections { namespace WeatherForecast.Models.Content.Responses.PageSections
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CheckoutSummarySectionModel : PageSectionModelBase<SummarySection> { public class CheckoutSummarySectionModel : PageSectionModelBase<SummarySection> {
/// <summary> /// <summary>
/// ///

View File

@ -1,8 +1,40 @@
using DomainObjects.PageSections; using DomainObjects;
using DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.Content.Responses.PageSections { namespace WeatherForecast.Models.Content.Responses.PageSections {
/// <summary>
///
/// </summary>
public class FeatureModel {
/// <summary>
///
/// </summary>
public string Icon { get; set; }
/// <summary>
///
/// </summary>
public string Title { get; set; }
/// <summary>
///
/// </summary>
public string Text { get; set; }
/// <summary>
///
/// </summary>
/// <param name="feature"></param>
public FeatureModel(Feature feature) {
Icon = feature.Icon;
Title = feature.Title;
Text = feature.Text;
}
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@ -1,12 +1,13 @@
using DomainObjects.PageSections; using DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.Content.Responses.PageSections { namespace WeatherForecast.Models.Content.Responses.PageSections
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class PaymentSectionModel : PageSectionModelBase<PaymentSection> { public class PaymentSectionModel : PageSectionModelBase<PaymentSection> {
/// <summary> /// <summary>
/// ///

View File

@ -1,8 +1,74 @@
using DomainObjects.PageSections; using DomainObjects;
using DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.Content.Responses.PageSections { namespace WeatherForecast.Models.Content.Responses.PageSections {
/// <summary>
///
/// </summary>
public class ReviewerModel {
/// <summary>
///
/// </summary>
public Guid Id { get; set; }
/// <summary>
///
/// </summary>
public MediaAttachmentResponseModel? Image { get; set; }
/// <summary>
///
/// </summary>
public string FullName { get; set; }
/// <summary>
///
/// </summary>
public string Position { get; set; }
/// <summary>
///
/// </summary>
/// <param name="reviewer"></param>
public ReviewerModel(Reviewer reviewer) {
FullName = reviewer.FullName;
Position = reviewer.Position;
//if (reviewer.Image != null)
// Image = new ImageModel(reviewer.Image);
}
}
/// <summary>
///
/// </summary>
public class TestimonialModel {
/// <summary>
///
/// </summary>
public string Text { get; set; }
/// <summary>
///
/// </summary>
public ReviewerModel Reviewer { get; set; }
/// <summary>
///
/// </summary>
/// <param name="testimonial"></param>
public TestimonialModel(Testimonial testimonial) {
Text = testimonial.Text;
Reviewer = new ReviewerModel(testimonial.Reviewer);
}
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@ -1,13 +1,13 @@
using DomainObjects.PageSections; using DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.Abstractions.PostItem.Responses;
namespace WeatherForecast.Models.Content.Responses.PageSections { namespace WeatherForecast.Models.Content.Responses.PageSections
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class TitleSectionModel : PageSectionModelBase<TitleSection> { public class TitleSectionModel : PageSectionModelBase<TitleSection> {
/// <summary> /// <summary>
/// ///

View File

@ -2,12 +2,13 @@
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.Content.Responses.PageSections; using WeatherForecast.Models.Content.Responses.PageSections;
namespace WeatherForecast.Models.Content.Responses.Pages { namespace WeatherForecast.Models.Content.Responses.Pages
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ShopCheckoutPageModel : PageModelBase<ShopCheckoutPage> { public class ShopCheckoutPageModel : PageModelBase<ShopCheckoutPage> {
/// <summary> /// <summary>
/// ///

View File

@ -1,12 +1,13 @@
using DomainObjects.Pages; using DomainObjects.Pages;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.Content.Responses.Pages { namespace WeatherForecast.Models.Content.Responses.Pages
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class SignInPageModel : PageModelBase<SignInPage> { public class SignInPageModel : PageModelBase<SignInPage> {
/// <summary> /// <summary>
/// ///

View File

@ -1,12 +1,13 @@
using DomainObjects.Pages; using DomainObjects.Pages;
using WeatherForecast.Models.Abstractions; using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.Content.Responses.Pages { namespace WeatherForecast.Models.Content.Responses.Pages
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class SignUpPageModel : PageModelBase<SignUpPage> { public class SignUpPageModel : PageModelBase<SignUpPage> {
/// <summary> /// <summary>
/// ///

View File

@ -0,0 +1,36 @@
namespace WeatherForecast.Models.Content.Responses
{
/// <summary>
///
/// </summary>
public class RouteModel
{
/// <summary>
///
/// </summary>
public string Target { get; set; }
/// <summary>
///
/// </summary>
public string? Component { get; set; }
/// <summary>
///
/// </summary>
public List<RouteModel>? ChildRoutes { get; set; }
/// <summary>
///
/// </summary>
/// <param name="route"></param>
public RouteModel(DomainObjects.Route route)
{
Target = route.Target;
Component = route.Component;
ChildRoutes = route.ChildRoutes?.Select(x => new RouteModel(x)).ToList();
}
}
}

View File

@ -1,35 +0,0 @@
using DomainObjects;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class FeatureModel {
/// <summary>
///
/// </summary>
public string Icon { get; set; }
/// <summary>
///
/// </summary>
public string Title { get; set; }
/// <summary>
///
/// </summary>
public string Text { get; set; }
/// <summary>
///
/// </summary>
/// <param name="feature"></param>
public FeatureModel(Feature feature) {
Icon = feature.Icon;
Title = feature.Title;
Text = feature.Text;
}
}
}

View File

@ -1,29 +0,0 @@
using DomainObjects;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class FormItemModel {
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? PlaceHolder { get; set; }
/// <summary>
///
/// </summary>
/// <param name="formItem"></param>
public FormItemModel(FormItem formItem) {
Title = formItem.Title;
PlaceHolder = formItem.PlaceHolder;
}
}
}

View File

@ -1,37 +0,0 @@
using DomainObjects;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class HeaderModel {
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public Dictionary<string, string>? Link { get; set; }
/// <summary>
///
/// </summary>
public Dictionary<string, string>? Meta { get; set; }
/// <summary>
///
/// </summary>
/// <param name="header"></param>
public HeaderModel(Header header) {
Title = header.Title;
Link = header.Link;
Meta = header.Meta;
}
}
}

View File

@ -1,29 +0,0 @@
using DomainObjects;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class LinkModel {
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public string? AnchorText { get; set; }
/// <summary>
///
/// </summary>
/// <param name="link"></param>
public LinkModel(Link link) {
Target = link.Target;
AnchorText = link.AnchorText;
}
}
}

View File

@ -1,54 +0,0 @@
using DomainObjects;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class LocalizationModel {
/// <summary>
///
/// </summary>
public string? TimeZone { get; set; }
/// <summary>
///
/// </summary>
public string? Locale { get; set; }
/// <summary>
///
/// </summary>
public string? DateFormat { get; set; }
/// <summary>
///
/// </summary>
public string? TimeFormat { get; set; }
/// <summary>
///
/// </summary>
public string? Currency { get; set; }
/// <summary>
///
/// </summary>
public string? CurrencySymbol { get; set; }
/// <summary>
///
/// </summary>
/// <param name="localization"></param>
public LocalizationModel(Localization localization) {
TimeZone = localization.TimeZone;
Locale = localization.Locale;
DateFormat = localization.DateFormat;
TimeFormat = localization.TimeFormat;
Currency = localization.Currency;
CurrencySymbol = localization.CurrencySymbol;
}
}
}

View File

@ -1,40 +0,0 @@
using DomainObjects;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class MenuItemModel {
/// <summary>
///
/// </summary>
public string? Icon { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public List<MenuItemModel>? ChildItems { get; set; }
/// <summary>
///
/// </summary>
/// <param name="menuItem"></param>
public MenuItemModel(MenuItem menuItem) {
Title = menuItem.Title;
Target = menuItem.Target;
ChildItems = menuItem.ChildItems?.Select(x => new MenuItemModel(x)).ToList();
}
}
}

View File

@ -1,30 +0,0 @@
using DomainObjects;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class ReviewerModel : PersonModelBase<Reviewer> {
/// <summary>
///
/// </summary>
public string FullName { get; set; }
/// <summary>
///
/// </summary>
public string Position { get; set; }
/// <summary>
///
/// </summary>
/// <param name="reviewer"></param>
public ReviewerModel(Reviewer reviewer) : base(reviewer) {
FullName = reviewer.FullName;
Position = reviewer.Position;
}
}
}

View File

@ -1,33 +0,0 @@
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class RouteModel {
/// <summary>
///
/// </summary>
public string Target { get; set; }
/// <summary>
///
/// </summary>
public string? Component { get; set; }
/// <summary>
///
/// </summary>
public List<RouteModel>? ChildRoutes { get; set; }
/// <summary>
///
/// </summary>
/// <param name="route"></param>
public RouteModel(DomainObjects.Route route) {
Target = route.Target;
Component = route.Component;
ChildRoutes = route.ChildRoutes?.Select(x => new RouteModel(x)).ToList();
}
}
}

View File

@ -65,7 +65,7 @@ namespace WeatherForecast.Models.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class PostShopItemL10nRequestModel { public class PostShopItemL10nRequestModel : RequestModelBase {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@ -270,13 +270,13 @@ namespace WeatherForecast.Models.Requests {
} }
if (string.IsNullOrWhiteSpace(BrandName)) if (string.IsNullOrWhiteSpace(BrandName))
yield return new ValidationResult($"{nameof(BrandName)} {Errors.NullOrWhiteSpace}"); yield return new ValidationResult($"{nameof(BrandName)} {Errors.NullOrWhiteSpace.Name}");
if (Price == 0) if (Price == 0)
yield return new ValidationResult($"{nameof(Price)} {Errors.NullOrEmpty.Name}"); yield return new ValidationResult($"{nameof(Price)} {Errors.NullOrEmpty.Name}");
if (Quantity == 0) if (Quantity == 0)
yield return new ValidationResult($"{nameof(Quantity)} {Errors.NullOrEmpty}"); yield return new ValidationResult($"{nameof(Quantity)} {Errors.NullOrEmpty.Name}");
} }
} }
} }

View File

@ -1,29 +1,31 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Core.Enumerations;
using Extensions;
using DomainObjects.Documents.Posts; using DomainObjects.Documents.Posts;
using Core.Abstractions.Models;
using Core.Abstractions;
using DomainObjects.Enumerations; using DomainObjects.Enumerations;
using DomainObjects.L10n; using DomainObjects.L10n;
using DomainObjects; using DomainObjects;
using Core.Enumerations;
using Core.Abstractions.Models;
using Core.Abstractions;
using System.Collections.Generic;
namespace WeatherForecast.Models.Requests { namespace WeatherForecast.Models.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class PutMediaAttachmentL10nRequestModel { public class PutMediaAttachmentL10nRequestModel : RequestModelBase {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Locale { get; set; } public Locales Locale { get; set; } = Locales.Unknown;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Alt { get; set; } public string Alt { get; set; } = string.Empty;
/// <summary> /// <summary>
/// ///
@ -39,113 +41,62 @@ namespace WeatherForecast.Models.Requests {
/// ///
/// </summary> /// </summary>
public string? Description { get; set; } public string? Description { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public MediaAttachmentL10n ToDomainObject() {
return new MediaAttachmentL10n() {
Locale = Enumeration.FromDisplayName<Locales>(Locale),
Alt = Alt
};
}
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class PutMediaAttachmentRequestModel : RequestModelBase, IValidatableObject { public class PutMediaAttachmentRequestModel : RequestModelBase {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Src { get; set; } public string Src { get; set; } = string.Empty;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? MediaType { get; set; } public MediaTypes MediaType { get; set; } = MediaTypes.Unknown;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<PutMediaAttachmentL10nRequestModel>? L10n { get; set; } public List<PutMediaAttachmentL10nRequestModel> L10n { get; set; } = new List<PutMediaAttachmentL10nRequestModel>();
/// <summary>
///
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public MediaAttachment ToDomainObject() {
return new MediaAttachment {
Src = Src,
MediaType = Enumeration.FromDisplayName<MediaTypes>(MediaType),
L10n = L10n.Select(x => x.ToDomainObject()).ToList()
};
}
/// <summary>
///
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (string.IsNullOrWhiteSpace(Src))
yield return new ValidationResult($"{nameof(Src)} {Errors.NullOrWhiteSpace}");
if (string.IsNullOrWhiteSpace(MediaType))
yield return new ValidationResult($"{nameof(MediaType)} {Errors.NullOrWhiteSpace}");
if (L10n.IsNullOrEmpty())
yield return new ValidationResult($"{nameof(L10n)} {Errors.NullOrEmpty}");
else {
foreach (var res in L10n) {
if (string.IsNullOrWhiteSpace(res.Locale))
yield return new ValidationResult($"{nameof(res.Locale)} {Errors.NullOrWhiteSpace.Name}");
else if (Enumeration.FromDisplayName<Locales>(res.Locale) == null)
yield return new ValidationResult($"{nameof(res.Locale)} {Errors.WrongOrNotManaged}");
if (string.IsNullOrWhiteSpace(res.Alt))
yield return new ValidationResult($"{nameof(res.Alt)} {Errors.NullOrWhiteSpace.Name}");
}
}
}
} }
public class PutShopItemL10nRequestModel { /// <summary>
///
/// </summary>
public class PutShopItemL10nRequestModel : RequestModelBase {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Locale { get; set; } public Locales Locale { get; set; } = Locales.Unknown;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Slug { get; set; } public string Slug { get; set; } = string.Empty;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Description { get; set; } public string Description { get; set; } = string.Empty;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Title { get; set; } public string Title { get; set; } = string.Empty;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? ShortText { get; set; } public string ShortText { get; set; } = string.Empty;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Text { get; set; } public string Text { get; set; } = string.Empty;
/// <summary> /// <summary>
/// ///
@ -155,33 +106,14 @@ namespace WeatherForecast.Models.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? TextFormat { get; set; } public TextFormat TextFormat { get; set; } = TextFormat.Unknown;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<string>? Badges { get; set; } public List<string>? Badges { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public PostItemL10n ToDomainObject() {
return new PostItemL10n() {
Locale = Enumeration.FromDisplayName<Locales>(Locale),
Slug = Slug,
Description = Description,
Title = Title,
Text = Text,
ShortText = ShortText,
// TODO: create plain text creation logic
PlainText = "TODO",
TextFormat = Enumeration.FromDisplayName<TextFormat>(TextFormat),
Badges = Badges
};
}
} }
@ -193,17 +125,17 @@ namespace WeatherForecast.Models.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<PutShopItemL10nRequestModel>? L10n { get; set; } public List<PutShopItemL10nRequestModel> L10n { get; set; } = new List<PutShopItemL10nRequestModel>();
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<PutMediaAttachmentRequestModel>? MediaAttachments { get; set; } public List<PutMediaAttachmentRequestModel> MediaAttachments { get; set; } = new List<PutMediaAttachmentRequestModel>();
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<Guid>? Categories { get; set; } public List<Guid> Categories { get; set; } = new List<Guid>();
/// <summary> /// <summary>
/// ///
@ -218,7 +150,7 @@ namespace WeatherForecast.Models.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? BrandName { get; set; } public string BrandName { get; set; } = string.Empty;
/// <summary> /// <summary>
/// ///
@ -228,7 +160,7 @@ namespace WeatherForecast.Models.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public decimal? Price { get; set; } public decimal Price { get; set; }
/// <summary> /// <summary>
/// ///
@ -238,7 +170,7 @@ namespace WeatherForecast.Models.Requests {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public uint? Quantity { get; set; } public uint Quantity { get; set; }
/// <summary> /// <summary>
/// ///
@ -248,8 +180,34 @@ namespace WeatherForecast.Models.Requests {
Sku = sku, Sku = sku,
SiteId = siteId, SiteId = siteId,
L10n = L10n.Select(x => x.ToDomainObject()).ToList(), L10n = L10n.Select(x => new PostItemL10n() {
MediaAttachments = MediaAttachments?.Select(x => x.ToDomainObject()).ToList(), Locale = x.Locale,
Slug = x.Slug,
Description = x.Description,
Title = x.Title,
Text = x.Text,
ShortText = x.ShortText,
// TODO: create plain text creation logic
PlainText = "TODO",
TextFormat = x.TextFormat,
Badges = x.Badges
}).ToList(),
MediaAttachments = MediaAttachments.Select(x => new MediaAttachment {
Src = x.Src,
MediaType = x.MediaType,
L10n = x.L10n.Select(y => new MediaAttachmentL10n() {
Locale = y.Locale,
Alt = y.Alt,
Target = y.Target,
Titile = y.Title,
Description = y.Description
}).ToList()
}).ToList(),
Author = userId, Author = userId,
Created = DateTime.UtcNow, Created = DateTime.UtcNow,
Tags = Tags, Tags = Tags,
@ -257,9 +215,9 @@ namespace WeatherForecast.Models.Requests {
BrandName = BrandName, BrandName = BrandName,
Rating = Rating, Rating = Rating,
Price = Price.Value, Price = Price,
NewPrice = NewPrice, NewPrice = NewPrice,
Quantity = Quantity.Value Quantity = Quantity
}; };
@ -269,48 +227,63 @@ namespace WeatherForecast.Models.Requests {
/// <param name="validationContext"></param> /// <param name="validationContext"></param>
/// <returns></returns> /// <returns></returns>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (L10n.IsNullOrEmpty()) if (L10n.Count == 0)
yield return new ValidationResult($"{nameof(L10n)} {Errors.NullOrEmpty}"); yield return new ValidationResult($"{nameof(L10n)} {Errors.NullOrEmpty.Name}");
else {
foreach (var item in L10n) {
if (string.IsNullOrWhiteSpace(item.Locale))
yield return new ValidationResult($"{nameof(item.Locale)} {Errors.NullOrWhiteSpace.Name}");
else if (Enumeration.FromDisplayName<Locales>(item.Locale) == null)
yield return new ValidationResult($"{nameof(item.Locale)} {Errors.WrongOrNotManaged}");
if (string.IsNullOrWhiteSpace(item.Slug)) foreach (var item in L10n) {
yield return new ValidationResult($"{nameof(item.Slug)} {Errors.NullOrWhiteSpace.Name}"); if (item.Locale == Locales.Unknown)
yield return new ValidationResult($"{nameof(item.Locale)} {Errors.UnableToParse.Name}");
if (string.IsNullOrWhiteSpace(item.Description)) if (string.IsNullOrWhiteSpace(item.Slug))
yield return new ValidationResult($"{nameof(item.Description)} {Errors.NullOrWhiteSpace.Name}"); yield return new ValidationResult($"{nameof(item.Slug)} {Errors.NullOrWhiteSpace.Name}");
if (string.IsNullOrWhiteSpace(item.Title)) if (string.IsNullOrWhiteSpace(item.Description))
yield return new ValidationResult($"{nameof(item.Title)} {Errors.NullOrWhiteSpace.Name}"); yield return new ValidationResult($"{nameof(item.Description)} {Errors.NullOrWhiteSpace.Name}");
if (string.IsNullOrWhiteSpace(item.Text)) if (string.IsNullOrWhiteSpace(item.Title))
yield return new ValidationResult($"{nameof(item.Text)} {Errors.NullOrWhiteSpace.Name}"); yield return new ValidationResult($"{nameof(item.Title)} {Errors.NullOrWhiteSpace.Name}");
if (string.IsNullOrWhiteSpace(item.ShortText)) if (string.IsNullOrWhiteSpace(item.Text))
yield return new ValidationResult($"{nameof(item.ShortText)} {Errors.NullOrWhiteSpace.Name}"); yield return new ValidationResult($"{nameof(item.Text)} {Errors.NullOrWhiteSpace.Name}");
if (string.IsNullOrWhiteSpace(item.TextFormat)) if (string.IsNullOrWhiteSpace(item.ShortText))
yield return new ValidationResult($"{nameof(item.TextFormat)} {Errors.NullOrWhiteSpace.Name}"); yield return new ValidationResult($"{nameof(item.ShortText)} {Errors.NullOrWhiteSpace.Name}");
else if (Enumeration.FromDisplayName<TextFormat>(item.TextFormat) == null)
yield return new ValidationResult($"{nameof(item.TextFormat)} {Errors.WrongOrNotManaged}"); if (item.TextFormat == TextFormat.Unknown)
} yield return new ValidationResult($"{nameof(item.TextFormat)} {Errors.UnableToParse.Name}");
} }
if (MediaAttachments.IsNullOrEmpty())
yield return new ValidationResult($"{nameof(MediaAttachments)} {Errors.NullOrEmpty}"); if (MediaAttachments.Count == 0)
yield return new ValidationResult($"{nameof(MediaAttachments)} {Errors.NullOrEmpty.Name}");
foreach (var att in MediaAttachments) {
if (string.IsNullOrWhiteSpace(att.Src))
yield return new ValidationResult($"{nameof(att.Src)} {Errors.NullOrWhiteSpace.Name}");
if (att.MediaType == MediaTypes.Unknown)
yield return new ValidationResult($"{nameof(att.MediaType)} {Errors.UnableToParse.Name}");
if (att.L10n.Count == 0)
yield return new ValidationResult($"{nameof(att.L10n)} {Errors.NullOrEmpty.Name}");
foreach (var res in att.L10n) {
if (res.Locale == Locales.Unknown)
yield return new ValidationResult($"{nameof(res.Locale)} {Errors.UnableToParse.Name}");
if (string.IsNullOrWhiteSpace(res.Alt))
yield return new ValidationResult($"{nameof(res.Alt)} {Errors.NullOrWhiteSpace.Name}");
}
}
if (string.IsNullOrWhiteSpace(BrandName)) if (string.IsNullOrWhiteSpace(BrandName))
yield return new ValidationResult($"{nameof(BrandName)} {Errors.NullOrWhiteSpace}"); yield return new ValidationResult($"{nameof(BrandName)} {Errors.NullOrWhiteSpace}");
if (Price == null || (Price != null && Price == 0)) if (Price == 0)
yield return new ValidationResult($"{nameof(Price)} {Errors.NullOrEmpty.Name}"); yield return new ValidationResult($"{nameof(Price)} {Errors.NullOrEmpty.Name}");
if (Quantity == null || (Quantity != null && Quantity == 0)) if (Quantity == 0)
yield return new ValidationResult($"{nameof(Quantity)} {Errors.NullOrEmpty}"); yield return new ValidationResult($"{nameof(Quantity)} {Errors.NullOrEmpty.Name}");
} }
} }
} }

View File

@ -1,15 +1,169 @@
using DomainObjects.Documents.Categories; using Core.Abstractions.Models;
using DomainObjects;
using DomainObjects.Documents.Categories;
using DomainObjects.Documents.Posts; using DomainObjects.Documents.Posts;
using DomainObjects.Enumerations; using DomainObjects.Enumerations;
using WeatherForecast.Models.Abstractions.PostItem.Responses; using DomainObjects.L10n;
namespace WeatherForecast.Models.Shop.Responses namespace WeatherForecast.Models.Shop.Responses {
{ /// <summary>
///
/// </summary>
public class GetShopItemMediaAttachmentL10nResponseModel {
/// <summary>
///
/// </summary>
public string Locale { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class GetShopItemResponseModel : PostItemResponseModelBase<ShopDocument> { public string Alt { get; set; }
/// <summary>
///
/// </summary>
public string? Target { get; set; }
/// <summary>
///
/// </summary>
public string? Title { get; set; }
/// <summary>
///
/// </summary>
public string? Description { get; set; }
/// <summary>
///
/// </summary>
/// <param name="imageL10n"></param>
public GetShopItemMediaAttachmentL10nResponseModel(MediaAttachmentL10n imageL10n) {
Locale = imageL10n.Locale.Name;
Alt = imageL10n.Alt;
}
}
/// <summary>
///
/// </summary>
public class GetShopItemMediaAttachmentResponseModel {
/// <summary>
///
/// </summary>
public List<GetShopItemMediaAttachmentL10nResponseModel>? L10n { get; set; }
/// <summary>
///
/// </summary>
public string? Src { get; set; }
/// <summary>
///
/// </summary>
public string? Alt { get; set; }
/// <summary>
///
/// </summary>
/// <param name="image"></param>
public GetShopItemMediaAttachmentResponseModel(MediaAttachment image) {
L10n = image.L10n.Select(x => new GetShopItemMediaAttachmentL10nResponseModel(x)).ToList();
}
/// <summary>
///
/// </summary>
/// <param name="mediaAttachment"></param>
/// <param name="locale"></param>
public GetShopItemMediaAttachmentResponseModel(MediaAttachment mediaAttachment, Locales locale) {
Src = mediaAttachment.Src;
var l10n = mediaAttachment.L10n.Single(x => x.Locale == locale);
if (l10n != null) {
Alt = l10n.Alt;
}
}
}
/// <summary>
///
/// </summary>
public class GetShopItemL10nResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public string Locale { get; set; }
/// <summary>
///
/// </summary>
public string Slug { get; set; }
/// <summary>
///
/// </summary>
public string Description { get; set; }
/// <summary>
///
/// </summary>
public string Title { get; set; }
/// <summary>
///
/// </summary>
public string ShortText { get; set; }
/// <summary>
///
/// </summary>
public string? Text { get; set; }
/// <summary>
///
/// </summary>
public string PlainText { get; set; }
/// <summary>
///
/// </summary>
public string TextFormat { get; set; }
/// <summary>
///
/// </summary>
public List<string>? Badges { get; set; }
/// <summary>
///
/// </summary>
/// <param name="postItemL10n"></param>
public GetShopItemL10nResponseModel(PostItemL10n postItemL10n) {
Locale = postItemL10n.Locale.Name;
Slug = postItemL10n.Slug;
Description = postItemL10n.Description;
Title = postItemL10n.Title;
ShortText = postItemL10n.ShortText;
PlainText = postItemL10n.PlainText;
Text = postItemL10n.Text;
TextFormat = postItemL10n.TextFormat.Name;
Badges = postItemL10n.Badges;
}
}
/// <summary>
///
/// </summary>
public class GetShopItemResponseModel : ResponseModelBase {
/// <summary> /// <summary>
/// ///
@ -41,7 +195,7 @@ namespace WeatherForecast.Models.Shop.Responses
/// </summary> /// </summary>
/// <param name="shopCatalogItem"></param> /// <param name="shopCatalogItem"></param>
/// <param name="categories"></param> /// <param name="categories"></param>
public GetShopItemResponseModel(ShopDocument shopCatalogItem, List<DomainObjects.Documents.Categories.Category> categories) : base(shopCatalogItem, categories) { public GetShopItemResponseModel(ShopDocument shopCatalogItem, List<DomainObjects.Documents.Categories.Category> categories) {
Sku = shopCatalogItem.Sku; Sku = shopCatalogItem.Sku;
Rating = shopCatalogItem.Rating; Rating = shopCatalogItem.Rating;
Price = shopCatalogItem.Price; Price = shopCatalogItem.Price;
@ -55,7 +209,7 @@ namespace WeatherForecast.Models.Shop.Responses
/// <param name="shopCatalogItem"></param> /// <param name="shopCatalogItem"></param>
/// <param name="categories"></param> /// <param name="categories"></param>
/// <param name="locale"></param> /// <param name="locale"></param>
public GetShopItemResponseModel(ShopDocument shopCatalogItem, List<DomainObjects.Documents.Categories.Category> categories, Locales locale) : base(shopCatalogItem, categories, locale) { public GetShopItemResponseModel(ShopDocument shopCatalogItem, List<DomainObjects.Documents.Categories.Category> categories, Locales locale) {
Sku = shopCatalogItem.Sku; Sku = shopCatalogItem.Sku;
Rating = shopCatalogItem.Rating; Rating = shopCatalogItem.Rating;
Price = shopCatalogItem.Price; Price = shopCatalogItem.Price;

View File

@ -1,96 +1,178 @@
using Core.Abstractions.Models; using Core.Abstractions.Models;
using DomainObjects;
using DomainObjects.Documents; using DomainObjects.Documents;
using DomainObjects.Documents.Posts; using DomainObjects.Documents.Posts;
using DomainObjects.Enumerations; using DomainObjects.Enumerations;
using WeatherForecast.Models.Abstractions.PostItem.Responses; using DomainObjects.L10n;
namespace WeatherForecast.Models.ShopCart.Responses namespace WeatherForecast.Models.ShopCart.Responses {
{
/// <summary>
///
/// </summary>
public class GetMediaAttachmentL10nModel : ResponseModelBase {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class GetShopCartItemResponseModel : ResponseModelBase public string Locale { get; set; }
{
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string Slug { get; set; } public string Alt { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string Sku { get; set; } public string? Target { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public MediaAttachmentResponseModel? Image { get; set; } public string? Title { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string Title { get; set; } public string? Description { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string BrandName { get; set; } /// <param name="imageL10n"></param>
public GetMediaAttachmentL10nModel(MediaAttachmentL10n imageL10n) {
/// <summary> Locale = imageL10n.Locale.Name;
/// Alt = imageL10n.Alt;
/// </summary>
public string ShortText { get; set; }
/// <summary>
///
/// </summary>
public DateTime Created { get; set; }
/// <summary>
///
/// </summary>
public decimal Price { get; set; }
/// <summary>
///
/// </summary>
public decimal? NewPrice { get; set; }
/// <summary>
///
/// </summary>
public uint? Quantity { get; set; }
/// <summary>
///
/// </summary>
/// <param name="shopItem"></param>
/// <param name="shopCartItem"></param>
/// <param name="locale"></param>
public GetShopCartItemResponseModel(ShopDocument shopItem, ShopCartDocument shopCartItem, Locales locale)
{
Sku = shopItem.Sku;
BrandName = shopItem.BrandName;
Created = shopItem.Created;
Price = shopItem.Price;
NewPrice = shopItem.NewPrice;
Quantity = shopCartItem.Quantity;
var l10n = shopItem.L10n.SingleOrDefault(x => x.Locale == locale);
if (l10n != null)
{
Slug = l10n.Slug;
Title = l10n.Title;
ShortText = l10n.ShortText;
}
if (shopItem.MediaAttachments != null)
Image = new MediaAttachmentResponseModel(shopItem.MediaAttachments.First(), locale);
}
} }
}
/// <summary>
///
/// </summary>
public class GetMediaAttachmentResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public List<GetMediaAttachmentL10nModel>? L10n { get; set; }
/// <summary>
///
/// </summary>
public string? Src { get; set; }
/// <summary>
///
/// </summary>
public string? Alt { get; set; }
/// <summary>
///
/// </summary>
/// <param name="image"></param>
public GetMediaAttachmentResponseModel(MediaAttachment image) {
L10n = image.L10n.Select(x => new GetMediaAttachmentL10nModel(x)).ToList();
}
/// <summary>
///
/// </summary>
/// <param name="mediaAttachment"></param>
/// <param name="locale"></param>
public GetMediaAttachmentResponseModel(MediaAttachment mediaAttachment, Locales locale) {
Src = mediaAttachment.Src;
var l10n = mediaAttachment.L10n.Single(x => x.Locale == locale);
if (l10n != null) {
Alt = l10n.Alt;
}
}
}
/// <summary>
///
/// </summary>
public class GetShopCartItemResponseModel : ResponseModelBase {
/// <summary>
///
/// </summary>
public string Slug { get; set; }
/// <summary>
///
/// </summary>
public string Sku { get; set; }
/// <summary>
///
/// </summary>
public GetMediaAttachmentResponseModel? Image { get; set; }
/// <summary>
///
/// </summary>
public string Title { get; set; }
/// <summary>
///
/// </summary>
public string BrandName { get; set; }
/// <summary>
///
/// </summary>
public string ShortText { get; set; }
/// <summary>
///
/// </summary>
public DateTime Created { get; set; }
/// <summary>
///
/// </summary>
public decimal Price { get; set; }
/// <summary>
///
/// </summary>
public decimal? NewPrice { get; set; }
/// <summary>
///
/// </summary>
public uint? Quantity { get; set; }
/// <summary>
///
/// </summary>
/// <param name="shopItem"></param>
/// <param name="shopCartItem"></param>
/// <param name="locale"></param>
public GetShopCartItemResponseModel(ShopDocument shopItem, ShopCartDocument shopCartItem, Locales locale) {
Sku = shopItem.Sku;
BrandName = shopItem.BrandName;
Created = shopItem.Created;
Price = shopItem.Price;
NewPrice = shopItem.NewPrice;
Quantity = shopCartItem.Quantity;
var l10n = shopItem.L10n.SingleOrDefault(x => x.Locale == locale);
if (l10n != null) {
Slug = l10n.Slug;
Title = l10n.Title;
ShortText = l10n.ShortText;
}
if (shopItem.MediaAttachments != null)
Image = new GetMediaAttachmentResponseModel(shopItem.MediaAttachments.First(), locale);
}
}
} }

View File

@ -1,29 +0,0 @@
using DomainObjects;
namespace WeatherForecast.Models {
/// <summary>
///
/// </summary>
public class TestimonialModel {
/// <summary>
///
/// </summary>
public string Text { get; set; }
/// <summary>
///
/// </summary>
public ReviewerModel Reviewer { get; set; }
/// <summary>
///
/// </summary>
/// <param name="testimonial"></param>
public TestimonialModel(Testimonial testimonial) {
Text = testimonial.Text;
Reviewer = new ReviewerModel(testimonial.Reviewer);
}
}
}

View File

@ -10,6 +10,14 @@ namespace WeatherForecast.Policies.Abstractions {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public CrudActions Action { get; init; } public CrudActions Action { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="action"></param>
public AuthorizationRequirementBase(CrudActions action) {
Action = action;
}
} }
} }

View File

@ -6,6 +6,7 @@ using WeatherForecast.Policies.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using DomainObjects.Documents.Posts; using DomainObjects.Documents.Posts;
using Core.Enumerations;
namespace WeatherForecast.Policies; namespace WeatherForecast.Policies;
@ -69,7 +70,7 @@ public class BlogRole {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public Roles Role { get; init; } public Roles Role { get; private set; }
/// <summary> /// <summary>
/// ///
@ -80,12 +81,33 @@ public class BlogRole {
/// ///
/// </summary> /// </summary>
public bool OwnOnly { get; init; } = false; public bool OwnOnly { get; init; } = false;
/// <summary>
///
/// </summary>
/// <param name="role"></param>
public BlogRole(Roles role) {
Role = role;
}
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class BlogAuthorizationRequirement : AuthorizationRequirementBase { public class BlogAuthorizationRequirement : AuthorizationRequirementBase {
public List<BlogRole> Roles { get; init; }
/// <summary>
///
/// </summary>
public List<BlogRole> Roles { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="crudAction"></param>
/// <param name="roles"></param>
public BlogAuthorizationRequirement(CrudActions crudAction, List<BlogRole> roles): base (crudAction) {
Roles = roles;
}
} }

View File

@ -55,13 +55,37 @@ public class CategoryAuthorizationHandler : AuthorizationHandlerBase<CategoryAut
/// ///
/// </summary> /// </summary>
public class CategoryRole { public class CategoryRole {
public Roles Role { get; init; }
/// <summary>
///
/// </summary>
public Roles Role { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="role"></param>
public CategoryRole(Roles role) {
Role = role;
}
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CategoryAuthorizationRequirement : AuthorizationRequirementBase { public class CategoryAuthorizationRequirement : AuthorizationRequirementBase {
public List<CategoryRole> Roles { get; init; }
/// <summary>
///
/// </summary>
public List<CategoryRole> Roles { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="action"></param>
/// <param name="roles"></param>
public CategoryAuthorizationRequirement(CrudActions action, List<CategoryRole> roles) : base(action) {
Roles = roles;
}
} }

View File

@ -1,4 +1,5 @@
using DataProviders.Buckets; using Core.Enumerations;
using DataProviders.Buckets;
using DataProviders.Collections; using DataProviders.Collections;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using FileSecurityService; using FileSecurityService;
@ -65,15 +66,23 @@ namespace WeatherForecast.Policies {
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class DkimRole { public class DkimRole {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public Roles Role { get; init; } public Roles Role { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="role"></param>
public DkimRole(Roles role) {
Role = role;
}
} }
/// <summary> /// <summary>
@ -84,6 +93,15 @@ namespace WeatherForecast.Policies {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<DkimRole> Roles { get; init; } public List<DkimRole> Roles { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="crudAction"></param>
/// <param name="roles"></param>
public DkimAuthorisationRequirement(CrudActions crudAction, List<DkimRole> roles) : base (crudAction) {
Roles = roles;
}
} }
} }

View File

@ -80,7 +80,7 @@ public class ImageRole {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public Roles Role { get; init; } public Roles Role { get; private set; }
/// <summary> /// <summary>
/// ///
@ -91,6 +91,14 @@ public class ImageRole {
/// ///
/// </summary> /// </summary>
public bool OwnOnly { get; init; } = false; public bool OwnOnly { get; init; } = false;
/// <summary>
///
/// </summary>
/// <param name="role"></param>
public ImageRole(Roles role) {
Role = role;
}
} }
/// <summary> /// <summary>
@ -101,6 +109,15 @@ public class ImageAuthorisationRequirement : AuthorizationRequirementBase {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<ImageRole> Roles { get; init; } public List<ImageRole> Roles { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="action"></param>
/// <param name="roles"></param>
public ImageAuthorisationRequirement(CrudActions action, List<ImageRole> roles) : base(action) {
Roles = roles;
}
} }

View File

@ -1,4 +1,5 @@
using CryptoProvider; using Core.Enumerations;
using CryptoProvider;
using DataProviders.Collections; using DataProviders.Collections;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@ -61,7 +62,16 @@ public class PasswordChangeRequirement : AuthorizationRequirementBase {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string OldPassword { get; init; } public string OldPassword { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="crudAction"></param>
/// <param name="oldPassword"></param>
public PasswordChangeRequirement(CrudActions crudAction, string oldPassword) :base (crudAction) {
OldPassword = oldPassword;
}
} }

View File

@ -61,7 +61,15 @@ namespace WeatherForecast.Policies
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public Roles Role { get; init; } public Roles Role { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="role"></param>
public ShopRole(Roles role) {
Role = role;
}
} }
/// <summary> /// <summary>
@ -72,7 +80,15 @@ namespace WeatherForecast.Policies
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<ShopRole> Roles { get; init; } public List<ShopRole> Roles { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="action"></param>
/// <param name="roles"></param>
public ShopAuthorizationRequirement(CrudActions action, List<ShopRole> roles) : base(action) {
Roles = roles;
}
} }
} }

View File

@ -1,4 +1,5 @@
using DataProviders.Collections; using Core.Enumerations;
using DataProviders.Collections;
using DomainObjects.Documents; using DomainObjects.Documents;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@ -54,5 +55,12 @@ namespace WeatherForecast.Policies {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ShopCartAuthorizationRequirement : AuthorizationRequirementBase { } public class ShopCartAuthorizationRequirement : AuthorizationRequirementBase {
/// <summary>
///
/// </summary>
/// <param name="action"></param>
public ShopCartAuthorizationRequirement(CrudActions action) : base(action) { }
}
} }

View File

@ -1,4 +1,5 @@
using DataProviders.Buckets; using Core.Enumerations;
using DataProviders.Buckets;
using DataProviders.Collections; using DataProviders.Collections;
using DomainObjects.Documents.Users; using DomainObjects.Documents.Users;
using FileSecurityService; using FileSecurityService;
@ -73,7 +74,15 @@ namespace WeatherForecast.Policies {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public Roles Role { get; init; } public Roles Role { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="role"></param>
public TemplateRole(Roles role) {
Role = role;
}
} }
/// <summary> /// <summary>
@ -84,6 +93,15 @@ namespace WeatherForecast.Policies {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<TemplateRole> Roles { get; init; } public List<TemplateRole> Roles { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="action"></param>
/// <param name="roles"></param>
public TemplateAuthorisationRequirement(CrudActions action, List<TemplateRole> roles) : base(action) {
Roles = roles;
}
} }
} }

View File

@ -2,11 +2,11 @@
using DataProviders.Collections; using DataProviders.Collections;
using WeatherForecast.Services.Abstractions;
using WeatherForecast.Models.Blog.Responses;
using WeatherForecast.Models.Blog.Requests;
using DomainObjects.Documents.Posts; using DomainObjects.Documents.Posts;
using WeatherForecast.Models.BlogItem.Requests;
using WeatherForecast.Services.Abstractions;
using WeatherForecast.Models.Blog.Requests;
using WeatherForecast.Models.Blog.Responses;
namespace WeatherForecast.Services namespace WeatherForecast.Services
{ {
@ -36,15 +36,21 @@ namespace WeatherForecast.Services
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="requestData"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
(GetBlogItemResponseModel?, IDomainResult) GetSlug(Guid siteId, GetBlogItemSlugRequestModel requestData); (GetBlogItemSlugResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemLocalizedRequestModel requestData);
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="blogItem"></param> /// <param name="blogItem"></param>
/// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
(Guid?, IDomainResult) Update(BlogDocument blogItem, PutBlogItemRequestModel requestData); (Guid?, IDomainResult) Update(BlogDocument blogItem);
/// <summary>
///
/// </summary>
/// <param name="blogItem"></param>
/// <returns></returns>
IDomainResult Delete(BlogDocument blogItem);
} }
/// <summary> /// <summary>
@ -53,6 +59,7 @@ namespace WeatherForecast.Services
public class BlogItemService : PostItemServiceBase<BlogItemService>, IBlogItemService { public class BlogItemService : PostItemServiceBase<BlogItemService>, IBlogItemService {
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider; private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
private readonly IUserDataProvider _userDataProvider;
/// <summary> /// <summary>
/// ///
@ -60,12 +67,15 @@ namespace WeatherForecast.Services
/// <param name="logger"></param> /// <param name="logger"></param>
/// <param name="blogCatalogDataProvider"></param> /// <param name="blogCatalogDataProvider"></param>
/// <param name="categoryDataProvider"></param> /// <param name="categoryDataProvider"></param>
/// <param name="userDataProvider"></param>
public BlogItemService( public BlogItemService(
ILogger<BlogItemService> logger, ILogger<BlogItemService> logger,
IBlogCatalogDataProvider blogCatalogDataProvider, IBlogCatalogDataProvider blogCatalogDataProvider,
ICategoryDataProvider categoryDataProvider ICategoryDataProvider categoryDataProvider,
IUserDataProvider userDataProvider
) : base(logger, categoryDataProvider) { ) : base(logger, categoryDataProvider) {
_blogCatalogDataProvider = blogCatalogDataProvider; _blogCatalogDataProvider = blogCatalogDataProvider;
_userDataProvider = userDataProvider;
} }
/// <summary> /// <summary>
@ -96,16 +106,19 @@ namespace WeatherForecast.Services
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="item"></param> /// <param name="blogItem"></param>
/// <returns></returns> /// <returns></returns>
public (GetBlogItemResponseModel?, IDomainResult) Get(BlogDocument item) { public (GetBlogItemResponseModel?, IDomainResult) Get(BlogDocument blogItem) {
var (categories, getCategoryResult) = _categoryDataProvider.GetMany(item.SiteId, item.Categories); var (categories, getCategoryResult) = _categoryDataProvider.GetMany(blogItem.SiteId, blogItem.Categories);
if (!getCategoryResult.IsSuccess || categories == null) if (!getCategoryResult.IsSuccess || categories == null)
return IDomainResult.Failed<GetBlogItemResponseModel?>(); return IDomainResult.Failed<GetBlogItemResponseModel?>();
return IDomainResult.Success(new GetBlogItemResponseModel(item, categories)); var (author, getAuthor) = _userDataProvider.Get(blogItem.Author);
if (!getAuthor.IsSuccess || author == null)
return IDomainResult.Failed<GetBlogItemResponseModel?>();
return IDomainResult.Success(new GetBlogItemResponseModel(blogItem, categories, author));
} }
/// <summary> /// <summary>
@ -114,47 +127,48 @@ namespace WeatherForecast.Services
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="requestData"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
public (GetBlogItemResponseModel?, IDomainResult) GetSlug(Guid siteId, GetBlogItemSlugRequestModel requestData) { public (GetBlogItemSlugResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemLocalizedRequestModel requestData) {
var (blog, getBlogItemResult) = _blogCatalogDataProvider.GetBySlug(siteId, requestData.Slug); var (blog, getBlogItemResult) = _blogCatalogDataProvider.GetBySlug(siteId, requestData.Slug);
if (!getBlogItemResult.IsSuccess || blog == null) if (!getBlogItemResult.IsSuccess || blog == null)
return IDomainResult.Failed<GetBlogItemResponseModel?>(); return IDomainResult.Failed<GetBlogItemSlugResponseModel?>();
var (categories, getCategoryResult) = _categoryDataProvider.GetMany(blog.SiteId, blog.Categories); var (categories, getCategoryResult) = _categoryDataProvider.GetMany(blog.SiteId, blog.Categories);
if (!getCategoryResult.IsSuccess || categories == null) if (!getCategoryResult.IsSuccess || categories == null)
return IDomainResult.Failed<GetBlogItemResponseModel?>(); return IDomainResult.Failed<GetBlogItemSlugResponseModel?>();
var locale = blog.L10n.Single(x => x.Slug == requestData.Slug).Locale; var locale = blog.L10n.Single(x => x.Slug == requestData.Slug).Locale;
return IDomainResult.Success(new GetBlogItemResponseModel(blog, categories, locale)); return IDomainResult.Success(new GetBlogItemLocalizedResponseModel(blog, categories, locale));
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="blogItem"></param> /// <param name="blogItem"></param>
/// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
public (Guid?, IDomainResult) Update(BlogDocument blogItem, PutBlogItemRequestModel requestData) { public (Guid?, IDomainResult) Update(BlogDocument blogItem) {
// construct domain object from model // will create default category if no categories are specified blogItem.Categories
var newItem = requestData.ToDomainObject(blogItem.Author, blogItem.SiteId); var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(blogItem.SiteId, blogItem.Categories);
newItem.Id = blogItem.Id;
newItem.Created = blogItem.Created;
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(blogItem.SiteId, requestData.Categories);
if (!addCategoriesResult.IsSuccess || categories == null) if (!addCategoriesResult.IsSuccess || categories == null)
return (null, addCategoriesResult); return (null, addCategoriesResult);
blogItem.Categories = categories; blogItem.Categories = categories;
if (!blogItem.Equals(newItem)) { var (id, updateResult) = _blogCatalogDataProvider.Update(blogItem);
var (id, updateResult) = _blogCatalogDataProvider.Update(newItem); if (!updateResult.IsSuccess || id == null)
if (!updateResult.IsSuccess || id == null) return (null, updateResult);
return (null, updateResult);
}
return IDomainResult.Success(blogItem.Id); return IDomainResult.Success(blogItem.Id);
} }
/// <summary>
///
/// </summary>
/// <param name="blogItem"></param>
/// <returns></returns>
public IDomainResult Delete(BlogDocument blogItem) =>
_blogCatalogDataProvider.Delete(blogItem.Id);
} }
} }

View File

@ -1,12 +1,11 @@
using DomainResults.Common; using DomainResults.Common;
using Core.Abstractions; using Core.Abstractions;
using Core.Enumerations;
using DataProviders.Collections; using DataProviders.Collections;
using WeatherForecast.Models.Blog.Requests;
using WeatherForecast.Models.Blog.Responses; using WeatherForecast.Models.Blog.Responses;
using DomainObjects.Enumerations;
using WeatherForecast.Models.BlogItem.Requests;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -21,7 +20,7 @@ namespace WeatherForecast.Services {
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="requestData"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
(GetBlogItemsResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemsRequestModel requestData); (GetBlogItemsSlugResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemsLocalizedRequestModel requestData);
} }
/// <summary> /// <summary>
@ -53,26 +52,24 @@ namespace WeatherForecast.Services {
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="requestData"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
public (GetBlogItemsResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemsRequestModel requestData) { public (GetBlogItemsSlugResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemsLocalizedRequestModel requestData) {
var (items, result) = _blogCatalogDataProvider.GetAll(siteId, requestData.CurrentPage > 0 ? ((requestData.CurrentPage - 1) * requestData.ItemsPerPage) : 0, requestData.ItemsPerPage); var (items, result) = _blogCatalogDataProvider.GetAll(siteId, requestData.CurrentPage > 0 ? ((requestData.CurrentPage - 1) * requestData.ItemsPerPage) : 0, requestData.ItemsPerPage);
if (!result.IsSuccess || items == null) if (!result.IsSuccess || items == null)
return (null, result); return (null, result);
var blogItems = new List<GetBlogItemResponseModel>(); var blogItems = new List<GetBlogItemSlugResponseModel>();
foreach (var item in items) { foreach (var item in items) {
var (categories, getCategoryResult) = _categoryDataProvider.GetMany(siteId, item.Categories); var (categories, getCategoryResult) = _categoryDataProvider.GetMany(siteId, item.Categories);
if (!getCategoryResult.IsSuccess || categories == null) if (!getCategoryResult.IsSuccess || categories == null)
return IDomainResult.Failed<GetBlogItemsResponseModel?>(); return IDomainResult.Failed<GetBlogItemsSlugResponseModel?>();
blogItems.Add(new GetBlogItemResponseModel(item, categories, requestData.Locale)); blogItems.Add(new GetBlogItemLocalizedResponseModel(item, categories, requestData.Locale));
} }
return blogItems.Count > 0 return blogItems.Count > 0
? IDomainResult.Success(new GetBlogItemsResponseModel(requestData.CurrentPage, 0, blogItems)) ? IDomainResult.Success(new GetBlogItemsResponseModel(requestData.CurrentPage, 0, blogItems))
: IDomainResult.NotFound<GetBlogItemsResponseModel?>(); : IDomainResult.NotFound<GetBlogItemsSlugResponseModel?>();
} }
} }
} }

View File

@ -8,6 +8,7 @@ using WeatherForecast.Models.Category.Requests;
using WeatherForecast.Models.Category.Responses; using WeatherForecast.Models.Category.Responses;
using DomainObjects.Enumerations; using DomainObjects.Enumerations;
using WeatherForecast.Models.CategoryItem.Requests; using WeatherForecast.Models.CategoryItem.Requests;
using DomainObjects.Documents.Categories;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -19,35 +20,24 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="category"></param>
/// <param name="requestModel"></param>
/// <returns></returns> /// <returns></returns>
(Guid?, IDomainResult) Post(Guid siteId, PostCategoryItemRequestModel requestModel); (Guid?, IDomainResult) Post(Category category);
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="category"></param>
/// <param name="categoryId"></param> /// <param name="locale"></param>
/// <returns></returns> /// <returns></returns>
(GetCategoryItemResponseModel?, IDomainResult) Get(Guid siteId, Guid categoryId); (GetCategoryItemResponseModel?, IDomainResult) Get(Category category, Locales? locale);
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="category"></param>
/// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
(GetCategoryItemResponseModel?, IDomainResult) GetSlug(Guid siteId, GetCategoryItemSlugRequestModel requestData); (Guid?, IDomainResult) Update(Category category);
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="categoryId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
(Guid?, IDomainResult) Update(Guid siteId, Guid categoryId, PutCategoryItemRequestModel requestData);
/// <summary> /// <summary>
/// ///
@ -80,18 +70,15 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="category"></param>
/// <param name="requestModel"></param>
/// <returns></returns> /// <returns></returns>
public (Guid?, IDomainResult) Post(Guid siteId, PostCategoryItemRequestModel requestModel) { public (Guid?, IDomainResult) Post(Category category) {
try { try {
var item = requestModel.ToDomainObject(siteId); var (_, getResult) = _categoryDataProvider.GetBySlugs(category.SiteId, category.L10n.Select(x => x.Slug).ToList());
var (_, getResult) = _categoryDataProvider.GetBySlugs(item.SiteId, item.L10n.Select(x => x.Slug).ToList());
if (getResult.IsSuccess) if (getResult.IsSuccess)
return IDomainResult.Failed<Guid?>(); return IDomainResult.Failed<Guid?>();
var (id, insertResult) = _categoryDataProvider.Insert(item); var (id, insertResult) = _categoryDataProvider.Insert(category);
if (!insertResult.IsSuccess) if (!insertResult.IsSuccess)
return IDomainResult.Failed<Guid?>(); return IDomainResult.Failed<Guid?>();
@ -107,64 +94,30 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="category"></param>
/// <param name="categoryId"></param> /// <param name="locale"></param>
/// <returns></returns> /// <returns></returns>
public (GetCategoryItemResponseModel?, IDomainResult) Get(Guid siteId, Guid categoryId) { public (GetCategoryItemResponseModel?, IDomainResult) Get(Category category, Locales? locale) {
try { return locale != null
var (item, result) = _categoryDataProvider.Get(siteId, categoryId); ? IDomainResult.Success(new GetCategoryItemResponseModel(category, locale))
if (!result.IsSuccess || item == null) : IDomainResult.Success(new GetCategoryItemResponseModel(category));
return (null, result);
return IDomainResult.Success(new GetCategoryItemResponseModel(item));
}
catch (Exception ex) {
_logger.LogError(ex, "Unhandled exception");
return IDomainResult.Failed<GetCategoryItemResponseModel?>(ex.Message);
}
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="category"></param>
/// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
public (GetCategoryItemResponseModel?, IDomainResult) GetSlug(Guid siteId, GetCategoryItemSlugRequestModel requestData) { public (Guid?, IDomainResult) Update(Category category) {
try { try {
var (item, result) = _categoryDataProvider.GetBySlug(siteId, requestData.Slug); var (item, result) = _categoryDataProvider.Get(category.SiteId, category.Id);
if (!result.IsSuccess || item == null) if (!result.IsSuccess || item == null)
return (null, result); return (null, result);
var locale = item.L10n.SingleOrDefault(x => x.Slug == requestData.Slug)?.Locale ?? Locales.Us; if (!item.Equals(category)) {
var (id, updateResult) = _categoryDataProvider.Update(category);
return IDomainResult.Success(new GetCategoryItemResponseModel(item, locale));
}
catch (Exception ex) {
_logger.LogError(ex, "Unhandled exception");
return IDomainResult.Failed<GetCategoryItemResponseModel?>(ex.Message);
}
}
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="categoryId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
public (Guid?, IDomainResult) Update(Guid siteId, Guid categoryId, PutCategoryItemRequestModel requestData) {
try {
var (item, result) = _categoryDataProvider.Get(siteId, categoryId);
if (!result.IsSuccess || item == null)
return (null, result);
// construct domain object from model
var newItem = requestData.ToDomainObject(item.SiteId);
newItem.Id = item.Id;
if (!item.Equals(newItem)) {
var (id, updateResult) = _categoryDataProvider.Update(newItem);
if (!updateResult.IsSuccess || id == null) if (!updateResult.IsSuccess || id == null)
return (null, updateResult); return (null, updateResult);
} }

View File

@ -21,7 +21,7 @@ namespace WeatherForecast.Services {
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="requestDat"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
(List<GetCategoryItemResponseModel>?, IDomainResult) Get(Guid siteId, GetCategoryItemsRequestModel requestData); (List<GetCategoryItemResponseModel>?, IDomainResult) Get(Guid siteId, GetCategoryItemsRequestModel requestData);
@ -56,7 +56,7 @@ namespace WeatherForecast.Services {
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="locale"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
public (List<GetCategoryItemResponseModel>?, IDomainResult) Get(Guid siteId, GetCategoryItemsRequestModel requestData) { public (List<GetCategoryItemResponseModel>?, IDomainResult) Get(Guid siteId, GetCategoryItemsRequestModel requestData) {
try { try {

View File

@ -17,7 +17,7 @@ namespace WeatherForecast.Services {
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="locale"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
(GetContentResponseModel?, IDomainResult) GetContent(Guid siteId, GetContentRequestModel requestData); (GetContentResponseModel?, IDomainResult) GetContent(Guid siteId, GetContentRequestModel requestData);
} }

View File

@ -29,7 +29,7 @@ public interface IShopCartItemService {
/// ///
/// </summary> /// </summary>
/// <param name="cartItem"></param> /// <param name="cartItem"></param>
/// <param name="locale"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
(GetShopCartItemResponseModel?, IDomainResult) Get(ShopCartDocument cartItem, GetShopCartItemRequestModel requestData); (GetShopCartItemResponseModel?, IDomainResult) Get(ShopCartDocument cartItem, GetShopCartItemRequestModel requestData);

View File

@ -20,7 +20,7 @@ namespace WeatherForecast.Services
/// ///
/// </summary> /// </summary>
/// <param name="cartItems"></param> /// <param name="cartItems"></param>
/// <param name="locale"></param> /// <param name="requestData"></param>
/// <returns></returns> /// <returns></returns>
(List<GetShopCartItemResponseModel>?, IDomainResult) Get(List<ShopCartDocument> cartItems, GetShopCartItemsController requestData); (List<GetShopCartItemResponseModel>?, IDomainResult) Get(List<ShopCartDocument> cartItems, GetShopCartItemsController requestData);
} }

View File

@ -22,11 +22,7 @@ namespace WeatherForecast.Services {
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="siteId"></param>
/// <param name="category"></param> /// <param name="requestData"></param>
/// <param name="currentPage"></param>
/// <param name="itemsPerPage"></param>
/// <param name="locale"></param>
/// <param name="searchText"></param>
/// <returns></returns> /// <returns></returns>
(GetShopItemsResponseModel?, IDomainResult) Get(Guid siteId, GetShopItemsRequestModel requestData); (GetShopItemsResponseModel?, IDomainResult) Get(Guid siteId, GetShopItemsRequestModel requestData);

View File

@ -3,4 +3,4 @@ WiredTiger 10.0.2: (December 21, 2021)
WiredTiger version WiredTiger version
major=10,minor=0,patch=2 major=10,minor=0,patch=2
file:WiredTiger.wt file:WiredTiger.wt
access_pattern_hint=none,allocation_size=4KB,app_metadata=,assert=(commit_timestamp=none,durable_timestamp=none,read_timestamp=none,write_timestamp=off),block_allocation=best,block_compressor=,cache_resident=false,checksum=on,collator=,columns=,dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=,huffman_value=,id=0,ignore_in_memory_cache_size=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=S,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,readonly=false,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,tiered_object=false,tiered_storage=(auth_token=,bucket=,bucket_prefix=,cache_directory=,local_retention=300,name=,object_target_size=0),value_format=S,verbose=[],version=(major=1,minor=1),write_timestamp_usage=none,checkpoint=(WiredTigerCheckpoint.118734=(addr="018381e4bd87c4eb8481e4a37fee9f8581e424811b00808080e3027fc0e3010fc0",order=118734,time=1678822225,size=81920,newest_start_durable_ts=0,oldest_start_ts=0,newest_txn=1306,newest_stop_durable_ts=0,newest_stop_ts=-1,newest_stop_txn=-11,prepare=0,write_gen=356701,run_write_gen=354752)),checkpoint_backup_info=,checkpoint_lsn=(50,460160) access_pattern_hint=none,allocation_size=4KB,app_metadata=,assert=(commit_timestamp=none,durable_timestamp=none,read_timestamp=none,write_timestamp=off),block_allocation=best,block_compressor=,cache_resident=false,checksum=on,collator=,columns=,dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=,huffman_value=,id=0,ignore_in_memory_cache_size=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=S,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,readonly=false,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,tiered_object=false,tiered_storage=(auth_token=,bucket=,bucket_prefix=,cache_directory=,local_retention=300,name=,object_target_size=0),value_format=S,verbose=[],version=(major=1,minor=1),write_timestamp_usage=none,checkpoint=(WiredTigerCheckpoint.121117=(addr="018081e42f982df28181e4a30456e28281e43b45267c808080e3022fc0e3010fc0",order=121117,time=1679264073,size=81920,newest_start_durable_ts=0,oldest_start_ts=0,newest_txn=534,newest_stop_durable_ts=0,newest_stop_ts=-1,newest_stop_txn=-11,prepare=0,write_gen=363869,run_write_gen=363077)),checkpoint_backup_info=,checkpoint_lsn=(56,191744)

Some files were not shown because too many files have changed in this diff Show More