diff --git a/src/ClientApp/.env b/src/ClientApp/.env index 6ce384e..040f640 100644 --- a/src/ClientApp/.env +++ b/src/ClientApp/.env @@ -1 +1,2 @@ BROWSER=none +REACT_APP_SITEID=404c8232-9048-4519-bfba-6e78dc7005ca \ No newline at end of file diff --git a/src/ClientApp/src/models/responses.ts b/src/ClientApp/src/models/responses.ts index edd8155..1c98c8c 100644 --- a/src/ClientApp/src/models/responses.ts +++ b/src/ClientApp/src/models/responses.ts @@ -41,6 +41,7 @@ export interface GetShopCartItemResponseModel { // Static content response model export interface GetContentResponseModel extends ResponseModel { + siteName: string, siteUrl: string, diff --git a/src/ClientApp/src/store/reducers/BlogFeatured.ts b/src/ClientApp/src/store/reducers/BlogFeatured.ts index e18b892..933ce09 100644 --- a/src/ClientApp/src/store/reducers/BlogFeatured.ts +++ b/src/ClientApp/src/store/reducers/BlogFeatured.ts @@ -22,7 +22,11 @@ type KnownAction = RequestAction | ReceiveAction export const actionCreators = { requestBlogFeatured: (props?: GetBlogFeaturedRequestModel): AppThunkAction => (dispatch, getState) => { - Get>('https://localhost:7151/api/BlogFeatured', props?.pathParams, props?.searchParams) + const locale = getState().content?.localization.locale + + const searchParams = {...props?.pathParams, locale} + + Get>(`https://localhost:7151/api/BlogItems/Featured/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) .then(response => response) .then(data => { if(data) diff --git a/src/ClientApp/src/store/reducers/Content.ts b/src/ClientApp/src/store/reducers/Content.ts index d6bb4b5..bde1757 100644 --- a/src/ClientApp/src/store/reducers/Content.ts +++ b/src/ClientApp/src/store/reducers/Content.ts @@ -23,7 +23,7 @@ type KnownAction = RequestAction | ReceiveAction; export const actionCreators = { requestContent: (props?: GetContentRequestModel): AppThunkAction => (dispatch, getState) => { - Get>('https://localhost:7151/api/Content/404c8232-9048-4519-bfba-6e78dc7005ca', props?.pathParams, props?.searchParams) + Get>(`https://localhost:7151/api/Content/${process.env.REACT_APP_SITEID}`, props?.pathParams, props?.searchParams) .then(response => response) .then((data) => { if(data) { diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 0bb0489..5c19e68 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/CryptoProvider/CryptoProvider.csproj b/src/CryptoProvider/CryptoProvider.csproj index 5115f29..c7da115 100644 --- a/src/CryptoProvider/CryptoProvider.csproj +++ b/src/CryptoProvider/CryptoProvider.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/src/DataProviders/Collections/BlogCatalogDataProvider.cs b/src/DataProviders/Collections/BlogCatalogDataProvider.cs index 85dc4d4..b7f558a 100644 --- a/src/DataProviders/Collections/BlogCatalogDataProvider.cs +++ b/src/DataProviders/Collections/BlogCatalogDataProvider.cs @@ -16,6 +16,7 @@ namespace DataProviders.Collections (List?, IDomainResult) GetBySlugs(Guid siteId, List slugs); (List?, IDomainResult) GetMany(Guid siteId, List blogIds); (List?, IDomainResult) GetAll(Guid siteId, int skip, int take); + (int?, IDomainResult) Count(Guid siteId); (Guid?, IDomainResult) Update(BlogDocument blogItem); IDomainResult Delete(Guid id); IDomainResult DeleteMany(Guid siteId, List blogIds); @@ -61,6 +62,11 @@ namespace DataProviders.Collections public (List?, IDomainResult) GetAll(Guid siteId, int skip, int take) => GetWithPredicate(x => x.SiteId == siteId, x => x); + public (int?, IDomainResult) Count(Guid siteId) { + var (list, result) = GetWithPredicate(x => x.SiteId == siteId, x => x.Id); + return (list?.Count, result); + } + public (Guid?, IDomainResult) Update(BlogDocument blogItem) => UpdateWithPredicate(blogItem, x => x.Id == blogItem.Id); diff --git a/src/DataProviders/Collections/CategoryDataProvider.cs b/src/DataProviders/Collections/CategoryDataProvider.cs index 0d7774d..a51d23f 100644 --- a/src/DataProviders/Collections/CategoryDataProvider.cs +++ b/src/DataProviders/Collections/CategoryDataProvider.cs @@ -20,6 +20,7 @@ namespace DataProviders.Collections (Category?, IDomainResult) GetBySlug(Guid siteId, string slug); (List?, IDomainResult) GetBySlugs(Guid siteId, List slugs); (List?, IDomainResult) GetAll(Guid siteId); + (int?, IDomainResult) Count(Guid siteId); (Guid?, IDomainResult) Update(Category obj); IDomainResult Delete(Guid id); IDomainResult DeleteAll(Guid siteId); @@ -81,6 +82,11 @@ namespace DataProviders.Collections public (List?, IDomainResult) GetAll(Guid siteId) => GetWithPredicate(x => x.SiteId == siteId, x => x); + public (int?, IDomainResult) Count(Guid siteId) { + var (list, result) = GetWithPredicate(x => x.SiteId == siteId, x => x.Id); + return (list?.Count, result); + } + public (Guid?, IDomainResult) Update(Category obj) => UpdateWithPredicate(obj, x => x.Id == obj.Id); diff --git a/src/DataProviders/DataProviders.csproj b/src/DataProviders/DataProviders.csproj index db96c11..1d33227 100644 --- a/src/DataProviders/DataProviders.csproj +++ b/src/DataProviders/DataProviders.csproj @@ -7,11 +7,11 @@ - - - - - + + + + + diff --git a/src/DataProviders/Mappings.cs b/src/DataProviders/Mappings.cs index 8be2a38..47d9c63 100644 --- a/src/DataProviders/Mappings.cs +++ b/src/DataProviders/Mappings.cs @@ -121,6 +121,9 @@ namespace DataProviders if (!BsonClassMap.IsClassMapRegistered(typeof(Localization))) { BsonClassMap.RegisterClassMap(cm => { cm.AutoMap(); + + cm.GetMemberMap(c => c.Locale) + .SetSerializer(new EnumerationSerializer()); }); } @@ -328,10 +331,11 @@ namespace DataProviders #region Content + if (!BsonClassMap.IsClassMapRegistered(typeof(ContentDocument))) { BsonClassMap.RegisterClassMap(cm => { cm.AutoMap(); - + //cm.GetMemberMap(c => c.Event) // .SetSerializer(new EnumerationSerializer()); }); diff --git a/src/DomainObjects/Documents/Users/User.cs b/src/DomainObjects/Documents/Users/User.cs index c481284..6de7988 100644 --- a/src/DomainObjects/Documents/Users/User.cs +++ b/src/DomainObjects/Documents/Users/User.cs @@ -1,6 +1,5 @@ using CryptoProvider; using DomainObjects.Abstractions; -using DomainObjects.Documents.Sites; using DomainObjects.Enumerations; namespace DomainObjects.Documents.Users; diff --git a/src/DomainObjects/L10n/PostItemL10n.cs b/src/DomainObjects/L10n/PostItemL10n.cs index a706878..b550550 100644 --- a/src/DomainObjects/L10n/PostItemL10n.cs +++ b/src/DomainObjects/L10n/PostItemL10n.cs @@ -17,6 +17,7 @@ public class PostItemL10n : DomainObjectBase { public override int GetHashCode() { unchecked { int hash = 17; + hash = hash * 23 + Locale.GetHashCode(); hash = hash * 23 + Slug.GetHashCode(); hash = hash * 23 + Description.GetHashCode(); @@ -24,7 +25,10 @@ public class PostItemL10n : DomainObjectBase { hash = hash * 23 + Text.GetHashCode(); hash = hash * 23 + TextFormat.GetHashCode(); hash = hash * 23 + ShortText.GetHashCode(); - hash = hash * 23 + Badges.Sum(x => x.GetHashCode()); + + if(Badges != null) + hash = hash * 23 + Badges.GetHashCode(); + return hash; } } diff --git a/src/DomainObjects/Localization.cs b/src/DomainObjects/Localization.cs index 7c76152..57ec343 100644 --- a/src/DomainObjects/Localization.cs +++ b/src/DomainObjects/Localization.cs @@ -1,4 +1,5 @@ using DomainObjects.Abstractions; +using DomainObjects.Enumerations; namespace DomainObjects; @@ -6,7 +7,7 @@ public class Localization : DomainObjectBase { public string? TimeZone { get; set; } - public string? Locale { get; set; } + public Locales Locale { get; set; } public string? DateFormat { get; set; } diff --git a/src/EmailProvider/EmailProvider.csproj b/src/EmailProvider/EmailProvider.csproj index 968de17..488237a 100644 --- a/src/EmailProvider/EmailProvider.csproj +++ b/src/EmailProvider/EmailProvider.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/FileSecurityService/FileSecurityService.csproj b/src/FileSecurityService/FileSecurityService.csproj index b1fa739..33aa3cb 100644 --- a/src/FileSecurityService/FileSecurityService.csproj +++ b/src/FileSecurityService/FileSecurityService.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/src/ImageProvider/ImageProvider.csproj b/src/ImageProvider/ImageProvider.csproj index 9e91a62..9eceb1d 100644 --- a/src/ImageProvider/ImageProvider.csproj +++ b/src/ImageProvider/ImageProvider.csproj @@ -7,11 +7,11 @@ - - - + + + - + diff --git a/src/ReverseProxy/ReverseProxy.csproj b/src/ReverseProxy/ReverseProxy.csproj index 4ad9845..0e491fe 100644 --- a/src/ReverseProxy/ReverseProxy.csproj +++ b/src/ReverseProxy/ReverseProxy.csproj @@ -10,7 +10,7 @@ - - + + diff --git a/src/Tests/Core/CoreTests.csproj b/src/Tests/Core/CoreTests.csproj index 623460c..7610dd5 100644 --- a/src/Tests/Core/CoreTests.csproj +++ b/src/Tests/Core/CoreTests.csproj @@ -8,14 +8,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/Tests/Extensions/ExtensionsTests.csproj b/src/Tests/Extensions/ExtensionsTests.csproj index 91922b7..a80b221 100644 --- a/src/Tests/Extensions/ExtensionsTests.csproj +++ b/src/Tests/Extensions/ExtensionsTests.csproj @@ -9,15 +9,15 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/WeatherForecast/Controllers/Abstractions/AuthorizationControllerBase.cs b/src/WeatherForecast/Controllers/Abstractions/AuthorizationControllerBase.cs index c4bccdd..b680cdc 100644 --- a/src/WeatherForecast/Controllers/Abstractions/AuthorizationControllerBase.cs +++ b/src/WeatherForecast/Controllers/Abstractions/AuthorizationControllerBase.cs @@ -1,11 +1,13 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using System.Security.Claims; namespace WeatherForecast.Controllers.Abstractions { /// /// /// + [ApiController] public class AuthorizationControllerBase : ControllerBase { private readonly IAuthorizationService _authorizationService; @@ -24,12 +26,13 @@ namespace WeatherForecast.Controllers.Abstractions { /// /// /// + /// /// /// /// - protected async Task AuthorizeAsync(TRequirement requirement, Func businessLogic) + protected async Task AuthorizeAsync(ClaimsPrincipal user, TRequirement requirement, Func businessLogic) where TRequirement : IAuthorizationRequirement { - var authorizationResult = await _authorizationService.AuthorizeAsync(User, null, requirement); + var authorizationResult = await _authorizationService.AuthorizeAsync(user, null, requirement); if (authorizationResult.Succeeded) { return businessLogic(); @@ -43,13 +46,14 @@ namespace WeatherForecast.Controllers.Abstractions { /// /// /// + /// /// /// /// /// - public async Task AuthorizeAsync(TRequirement requirement, TResource resource, Func businessLogic) + public async Task AuthorizeAsync(ClaimsPrincipal user, TRequirement requirement, TResource resource, Func businessLogic) where TRequirement : IAuthorizationRequirement { - var authorizationResult = await _authorizationService.AuthorizeAsync(User, resource, requirement); + var authorizationResult = await _authorizationService.AuthorizeAsync(user, resource, requirement); if (authorizationResult.Succeeded) { return businessLogic(); diff --git a/src/WeatherForecast/Controllers/AccountController.cs b/src/WeatherForecast/Controllers/AccountController.cs index f3a35c4..e553598 100644 --- a/src/WeatherForecast/Controllers/AccountController.cs +++ b/src/WeatherForecast/Controllers/AccountController.cs @@ -15,7 +15,6 @@ namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] public class AccountController : AuthorizationControllerBase { @@ -111,7 +110,7 @@ public class AccountController : AuthorizationControllerBase { if (!getUserResult.IsSuccess || user == null) return BadRequest(); - return await AuthorizeAsync(new PasswordChangeRequirement(CrudActions.Update, + return await AuthorizeAsync(User, new PasswordChangeRequirement(CrudActions.Update, requestData.OldPassword ), user, () => { var result = _accountService.PasswordChange(user, requestData); diff --git a/src/WeatherForecast/Controllers/BlogItemController.cs b/src/WeatherForecast/Controllers/BlogItemController.cs index 2812cb2..55fa46f 100644 --- a/src/WeatherForecast/Controllers/BlogItemController.cs +++ b/src/WeatherForecast/Controllers/BlogItemController.cs @@ -12,13 +12,13 @@ using DataProviders.Collections; using DomainObjects.Documents.Users; using WeatherForecast.Controllers.Abstractions; +using DomainObjects.Documents.Posts; namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] public class BlogItemController : AuthorizationControllerBase { @@ -52,13 +52,13 @@ public class BlogItemController : AuthorizationControllerBase { var blogItem = requestData.ToDomainObject(siteId, userId); - return await AuthorizeAsync(new BlogAuthorizationRequirement(CrudActions.Create, new List { + return await AuthorizeAsync(User, new BlogAuthorizationRequirement(CrudActions.Create, new List { new BlogRole(Roles.Admin), new BlogRole(Roles.Editor), new BlogRole(Roles.Author) { OwnOnly = true }, new BlogRole(Roles.Contributor) { OwnOnly = true }, new BlogRole(Roles.ShopManager) - }), blogItem, () => { + }), new List { blogItem }, () => { var result = _blogItemService.Post(blogItem); return result.ToActionResult(); }); @@ -79,13 +79,13 @@ public class BlogItemController : AuthorizationControllerBase { if (!getBlogItemResult.IsSuccess || blogItem == null) return getBlogItemResult.ToActionResult(); - return await AuthorizeAsync(new BlogAuthorizationRequirement(CrudActions.Read, new List { + return await AuthorizeAsync(User, new BlogAuthorizationRequirement(CrudActions.Read, new List { new BlogRole(Roles.Admin), new BlogRole(Roles.Editor), new BlogRole(Roles.Author) { OwnOnly = true }, new BlogRole(Roles.Contributor) { OwnOnly = true }, new BlogRole(Roles.ShopManager) - }), blogItem, () => { + }), new List { blogItem }, () => { var result = _blogItemService.Get(blogItem); return result.ToActionResult(); }); @@ -123,13 +123,13 @@ public class BlogItemController : AuthorizationControllerBase { newBlogItem.Created = blogItem.Created; newBlogItem.Categories = blogItem.Categories; - return await AuthorizeAsync(new BlogAuthorizationRequirement(CrudActions.Update, new List { + return await AuthorizeAsync(User, new BlogAuthorizationRequirement(CrudActions.Update, new List { 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, () => { + }), new List { blogItem }, () => { var result = _blogItemService.Update(newBlogItem); return result.ToActionResult(); }); @@ -149,13 +149,13 @@ public class BlogItemController : AuthorizationControllerBase { if (!getBlogItemResult.IsSuccess || blogItem == null) return getBlogItemResult.ToActionResult(); - return await AuthorizeAsync(new BlogAuthorizationRequirement(CrudActions.Delete, new List { + return await AuthorizeAsync(User, new BlogAuthorizationRequirement(CrudActions.Delete, new List { 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, () => { + }), new List { blogItem }, () => { var result = _blogItemService.Delete(blogItem); return result.ToActionResult(); }); diff --git a/src/WeatherForecast/Controllers/BlogItemsController.cs b/src/WeatherForecast/Controllers/BlogItemsController.cs index dd9e8b4..69a55ca 100644 --- a/src/WeatherForecast/Controllers/BlogItemsController.cs +++ b/src/WeatherForecast/Controllers/BlogItemsController.cs @@ -10,10 +10,11 @@ namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] public class BlogItemsController : ControllerBase { + private const string _featured = "Featured"; + private readonly IBlogItemsService _blogItemsService; /// @@ -37,4 +38,16 @@ public class BlogItemsController : ControllerBase { var result = _blogItemsService.Get(siteId, requestData); return result.ToActionResult(); } + + /// + /// + /// + /// + /// + /// + [HttpGet($"{_featured}/{{siteId}}")] + public IActionResult GetFeatured([FromRoute] Guid siteId, [FromQuery] GetBlogItemsLocalizedRequestModel requestData) { + var result = _blogItemsService.Get(siteId, requestData); + return result.ToActionResult(); + } } diff --git a/src/WeatherForecast/Controllers/CategoryItemController.cs b/src/WeatherForecast/Controllers/CategoryItemController.cs index 9ee548d..1d05120 100644 --- a/src/WeatherForecast/Controllers/CategoryItemController.cs +++ b/src/WeatherForecast/Controllers/CategoryItemController.cs @@ -6,19 +6,18 @@ using DomainResults.Mvc; using WeatherForecast.Services; using WeatherForecast.Policies; using Core.Enumerations; -using WeatherForecast.Models.Category.Requests; -using WeatherForecast.Models.CategoryItem.Requests; + using DomainObjects.Documents.Users; using WeatherForecast.Controllers.Abstractions; using DataProviders.Collections; using DomainObjects.Enumerations; +using WeatherForecast.Models.Categories.Requests; namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] public class CategoryItemController : AuthorizationControllerBase { @@ -54,7 +53,7 @@ public class CategoryItemController : AuthorizationControllerBase { var category = requestData.ToDomainObject(siteId); - return await AuthorizeAsync(new CategoryAuthorizationRequirement(CrudActions.Create, new List { + return await AuthorizeAsync(User, new CategoryAuthorizationRequirement(CrudActions.Create, new List { new CategoryRole(Roles.Admin), new CategoryRole(Roles.Editor), new CategoryRole(Roles.ShopManager) @@ -64,28 +63,6 @@ public class CategoryItemController : AuthorizationControllerBase { }); } - #region Authless methods - /// - /// - /// - /// - /// - [HttpGet("{siteId}")] - public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] GetCategoryItemSlugRequestModel 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(); - } - #endregion - - - /// /// Returns full object /// Can Admin, Editor, Author, Contributor, Shop manager @@ -100,7 +77,7 @@ public class CategoryItemController : AuthorizationControllerBase { if (!result.IsSuccess || category == null) return result.ToActionResult(); - return await AuthorizeAsync(new CategoryAuthorizationRequirement(CrudActions.Read, new List { + return await AuthorizeAsync(User, new CategoryAuthorizationRequirement(CrudActions.Read, new List { new CategoryRole(Roles.Admin), new CategoryRole(Roles.Editor), new CategoryRole(Roles.Author), @@ -112,6 +89,24 @@ public class CategoryItemController : AuthorizationControllerBase { }); } + /// + /// + /// + /// + /// + [HttpGet("{siteId}")] + public IActionResult Get([FromRoute] Guid siteId, [FromQuery] GetCategoryItemLocalizedRequestModel 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(); + } + /// /// Can Admin, Editor, Shop manager /// @@ -124,7 +119,7 @@ public class CategoryItemController : AuthorizationControllerBase { var category = requestData.ToDomainObject(siteId, categoryId); - return await AuthorizeAsync(new CategoryAuthorizationRequirement(CrudActions.Update, new List { + return await AuthorizeAsync(User, new CategoryAuthorizationRequirement(CrudActions.Update, new List { new CategoryRole(Roles.Admin), new CategoryRole(Roles.Editor), new CategoryRole(Roles.ShopManager) @@ -143,7 +138,7 @@ public class CategoryItemController : AuthorizationControllerBase { [HttpDelete("{siteId}/{categoryId}")] public async Task Delete([FromRoute] Guid siteId, [FromRoute] Guid categoryId) { - return await AuthorizeAsync(new CategoryAuthorizationRequirement(CrudActions.Delete, new List { + return await AuthorizeAsync(User, new CategoryAuthorizationRequirement(CrudActions.Delete, new List { new CategoryRole(Roles.Admin) }), () => { var result = _categoryItemService.Delete(siteId, categoryId); diff --git a/src/WeatherForecast/Controllers/CategoryItemsController.cs b/src/WeatherForecast/Controllers/CategoryItemsController.cs index 50ae88c..85ad04c 100644 --- a/src/WeatherForecast/Controllers/CategoryItemsController.cs +++ b/src/WeatherForecast/Controllers/CategoryItemsController.cs @@ -4,30 +4,31 @@ using Microsoft.AspNetCore.Authorization; using DomainResults.Mvc; using WeatherForecast.Services; -using WeatherForecast.Models.CategoryItem.Requests; +using WeatherForecast.Models.Cetegories.Requests; +using WeatherForecast.Controllers.Abstractions; namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] -public class CategoryItemsController : ControllerBase { +public class CategoryItemsController : AuthorizationControllerBase { private readonly ICategoryItemsService _categoryItemsService; /// /// /// + /// /// public CategoryItemsController( + IAuthorizationService authorizationService, ICategoryItemsService categoryItemsService - ) { + ) : base (authorizationService) { _categoryItemsService = categoryItemsService; } - #region Authless methods /// /// /// @@ -35,10 +36,9 @@ public class CategoryItemsController : ControllerBase { /// /// [HttpGet("{siteId}")] - public IActionResult Get([FromRoute] Guid siteId, [FromQuery] GetCategoryItemsRequestModel reuestData) { + public IActionResult Get([FromRoute] Guid siteId, [FromQuery] GetCategoryItemsLocalizedRequestModel reuestData) { var result = _categoryItemsService.Get(siteId, reuestData); return result.ToActionResult(); } - #endregion } diff --git a/src/WeatherForecast/Controllers/ContentController.cs b/src/WeatherForecast/Controllers/ContentController.cs index 256ae5f..179e1e0 100644 --- a/src/WeatherForecast/Controllers/ContentController.cs +++ b/src/WeatherForecast/Controllers/ContentController.cs @@ -5,25 +5,27 @@ using DomainResults.Mvc; using WeatherForecast.Services; using WeatherForecast.Models.Content.Requests; +using WeatherForecast.Controllers.Abstractions; namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] -public class ContentController : ControllerBase { +public class ContentController : AuthorizationControllerBase { private readonly IContentService _contentService; /// /// /// + /// /// public ContentController( + IAuthorizationService authorizationService, IContentService contentService - ) { + ) : base (authorizationService) { _contentService = contentService; } diff --git a/src/WeatherForecast/Controllers/DkimController.cs b/src/WeatherForecast/Controllers/DkimController.cs index 2e266d6..77d2401 100644 --- a/src/WeatherForecast/Controllers/DkimController.cs +++ b/src/WeatherForecast/Controllers/DkimController.cs @@ -16,7 +16,6 @@ namespace WeatherForecast.Controllers; /// /// /// -[AllowAnonymous] [Route("api/[controller]")] public class DkimController : AuthorizationControllerBase { @@ -55,7 +54,7 @@ public class DkimController : AuthorizationControllerBase { var newFile = new BucketFile(Guid.NewGuid(), siteId, formFile.FileName, ms.ToArray(), formFile.ContentType); - return await AuthorizeAsync(new DkimAuthorisationRequirement(CrudActions.Create, new List { + return await AuthorizeAsync(User, new DkimAuthorisationRequirement(CrudActions.Create, new List { new DkimRole(Roles.Admin) }), newFile, () => { var result = _dkimService.Post(newFile); @@ -76,7 +75,7 @@ public class DkimController : AuthorizationControllerBase { if (!fileDownloadResult.IsSuccess || file == null) return fileDownloadResult.ToActionResult(); - return await AuthorizeAsync(new DkimAuthorisationRequirement(CrudActions.Delete, new List { + return await AuthorizeAsync(User, new DkimAuthorisationRequirement(CrudActions.Delete, new List { new DkimRole(Roles.Admin) }), file, () => { var result = _dkimService.Delete(siteId, fileId); diff --git a/src/WeatherForecast/Controllers/ImageController.cs b/src/WeatherForecast/Controllers/ImageController.cs index 8754727..7c12400 100644 --- a/src/WeatherForecast/Controllers/ImageController.cs +++ b/src/WeatherForecast/Controllers/ImageController.cs @@ -17,7 +17,6 @@ namespace WeatherForecast.Controllers; /// /// [Route("api/[controller]")] -[ApiController] public class ImageController : AuthorizationControllerBase { private readonly IImageBucketDataProvider _imageBucketDataProvider; @@ -77,7 +76,7 @@ public class ImageController : AuthorizationControllerBase { if (userId != null) newFile.UserId = userId; - return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Create, new List { + return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Create, new List { new ImageRole(Roles.Admin), new ImageRole(Roles.Editor), new ImageRole(Roles.Author) { OwnOnly = true }, @@ -109,7 +108,7 @@ public class ImageController : AuthorizationControllerBase { if (!result.IsSuccess || file == null) return result.ToActionResult(); - return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Read, new List { + return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Read, new List { new ImageRole(Roles.Admin), new ImageRole(Roles.Editor), new ImageRole(Roles.Author) { OwnOnly = true }, @@ -195,7 +194,7 @@ public class ImageController : AuthorizationControllerBase { if(userId != null) newFile.UserId = userId; - return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Update, new List { + return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Update, new List { new ImageRole(Roles.Admin), new ImageRole(Roles.Editor), new ImageRole(Roles.Author) { OwnOnly = true }, @@ -238,7 +237,7 @@ public class ImageController : AuthorizationControllerBase { if (!fileDownloadResult.IsSuccess || file == null) return fileDownloadResult.ToActionResult(); - return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Delete, new List { + return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Delete, new List { new ImageRole(Roles.Admin), new ImageRole(Roles.Editor), new ImageRole(Roles.Author) { OwnOnly = true }, diff --git a/src/WeatherForecast/Controllers/ImagesController.cs b/src/WeatherForecast/Controllers/ImagesController.cs index b3d269e..420ab33 100644 --- a/src/WeatherForecast/Controllers/ImagesController.cs +++ b/src/WeatherForecast/Controllers/ImagesController.cs @@ -14,7 +14,6 @@ namespace WeatherForecast.Controllers; /// /// /// -[AllowAnonymous] [Route("api/[controller]")] public class ImagesController : AuthorizationControllerBase { @@ -64,7 +63,7 @@ public class ImagesController : AuthorizationControllerBase { return newFile; }).ToList(); - return await AuthorizeAsync(new ImageAuthorisationRequirement(CrudActions.Create, new List { + return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Create, new List { new ImageRole(Roles.Admin), new ImageRole(Roles.Editor), new ImageRole(Roles.Author) { OwnOnly = true }, diff --git a/src/WeatherForecast/Controllers/InitializationController.cs b/src/WeatherForecast/Controllers/InitializationController.cs index 5bff5ed..9caaeea 100644 --- a/src/WeatherForecast/Controllers/InitializationController.cs +++ b/src/WeatherForecast/Controllers/InitializationController.cs @@ -1,6 +1,8 @@ using DomainResults.Mvc; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using WeatherForecast.Controllers.Abstractions; using WeatherForecast.Models.Initialization.Requests; using WeatherForecast.Services; @@ -10,18 +12,19 @@ namespace WeatherForecast.Controllers; /// /// [Route("api/[controller]")] -[ApiController] -public class InitializationController : ControllerBase { +public class InitializationController : AuthorizationControllerBase { private readonly IInitializationService _initializationService; /// /// /// + /// /// public InitializationController( + IAuthorizationService authorizationService, IInitializationService initializationService - ) { + ) : base(authorizationService) { _initializationService = initializationService; } diff --git a/src/WeatherForecast/Controllers/ShopCartItemController.cs b/src/WeatherForecast/Controllers/ShopCartItemController.cs index 40400e7..ef5bfea 100644 --- a/src/WeatherForecast/Controllers/ShopCartItemController.cs +++ b/src/WeatherForecast/Controllers/ShopCartItemController.cs @@ -17,7 +17,6 @@ namespace WeatherForecast.Controllers; /// /// /// -[AllowAnonymous] [Route("api/[controller]")] public class ShopCartItemController : AuthorizationControllerBase { @@ -50,7 +49,7 @@ public class ShopCartItemController : AuthorizationControllerBase { [HttpPost("{siteId}/{userId}/{sku}")] public async Task Post([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] string sku, [FromBody] PostShopCartItemRequestModel requestData) { - return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Create), () => { + return await AuthorizeAsync(User, new ShopCartAuthorizationRequirement(CrudActions.Create), () => { var result = _shopCartItemService.Post(siteId, userId, sku, requestData); return result.ToActionResult(); }); @@ -65,13 +64,13 @@ public class ShopCartItemController : AuthorizationControllerBase { /// /// [HttpGet("{siteId}/{userId}/{sku}")] - public async Task Get([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] string sku, [FromQuery] GetShopCartItemRequestModel requestData) { + public async Task Get([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] string sku, [FromQuery] GetShopCartItemLocalizedRequestModel requestData) { var (cartItem, getCartItemResult) = _shopCartDataProvider.Get(siteId, userId, sku); if (!getCartItemResult.IsSuccess || cartItem == null) return getCartItemResult.ToActionResult(); - return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Read), cartItem, () => { + return await AuthorizeAsync(User, new ShopCartAuthorizationRequirement(CrudActions.Read), cartItem, () => { var result = _shopCartItemService.Get(cartItem, requestData); return result.ToActionResult(); }); @@ -92,7 +91,7 @@ public class ShopCartItemController : AuthorizationControllerBase { if (!getCartItemResult.IsSuccess || cartItem == null) return getCartItemResult.ToActionResult(); - return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Update), cartItem, () => { + return await AuthorizeAsync(User, new ShopCartAuthorizationRequirement(CrudActions.Update), cartItem, () => { var result = _shopCartItemService.Update(cartItem, requestData); return result.ToActionResult(); }); @@ -112,7 +111,7 @@ public class ShopCartItemController : AuthorizationControllerBase { if (!getCartItemResult.IsSuccess || cartItem == null) return getCartItemResult.ToActionResult(); - return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Delete), cartItem, () => { + return await AuthorizeAsync(User, new ShopCartAuthorizationRequirement(CrudActions.Delete), cartItem, () => { var result = _shopCartDataProvider.Delete(cartItem.Id); return result.ToActionResult(); }); diff --git a/src/WeatherForecast/Controllers/ShopCartItemsController.cs b/src/WeatherForecast/Controllers/ShopCartItemsController.cs index 7296761..ef92534 100644 --- a/src/WeatherForecast/Controllers/ShopCartItemsController.cs +++ b/src/WeatherForecast/Controllers/ShopCartItemsController.cs @@ -15,7 +15,6 @@ namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] public class ShopCartItemsController : AuthorizationControllerBase { @@ -42,13 +41,13 @@ public class ShopCartItemsController : AuthorizationControllerBase { /// /// [HttpGet("{siteId}/{userId}")] - public async Task Get([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromQuery] GetShopCartItemsController requestData) { + public async Task Get([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromQuery] GetShopCartItemsLocalizedRequestModel requestData) { var (cartItems, getCartItemsResult) = _shopCartDataProvider.GetAll(siteId, userId); if (!getCartItemsResult.IsSuccess || cartItems == null) return getCartItemsResult.ToActionResult(); - return await AuthorizeAsync(new ShopCartAuthorizationRequirement(CrudActions.Read), cartItems, () => { + return await AuthorizeAsync(User, new ShopCartAuthorizationRequirement(CrudActions.Read), cartItems, () => { var result = _shopCartItemsService.Get(cartItems, requestData); return result.ToActionResult(); }); diff --git a/src/WeatherForecast/Controllers/ShopItemController.cs b/src/WeatherForecast/Controllers/ShopItemController.cs index d4cf11a..db0be77 100644 --- a/src/WeatherForecast/Controllers/ShopItemController.cs +++ b/src/WeatherForecast/Controllers/ShopItemController.cs @@ -19,7 +19,6 @@ namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] public class ShopItemController : AuthorizationControllerBase { @@ -41,20 +40,6 @@ public class ShopItemController : AuthorizationControllerBase { _shopItemService = shopItemService; } - #region Authless methods - /// - /// - /// - /// - /// - /// - [HttpGet("{siteId}")] - public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] string slug) { - var result = _shopItemService.GetSlug(siteId, slug); - return result.ToActionResult(); - } - #endregion - /// /// Can Admin, Shop manager /// @@ -71,7 +56,7 @@ public class ShopItemController : AuthorizationControllerBase { var shopItem = requestData.ToDomainObject(sku, userId.Value, siteId); - return await AuthorizeAsync(new ShopAuthorizationRequirement(CrudActions.Create, new List { + return await AuthorizeAsync(User, new ShopAuthorizationRequirement(CrudActions.Create, new List { new ShopRole(Roles.Admin), new ShopRole(Roles.ShopManager) }), shopItem, () => { @@ -94,7 +79,7 @@ public class ShopItemController : AuthorizationControllerBase { if (!getShopItemResult.IsSuccess || shopItem == null) return getShopItemResult.ToActionResult(); - return await AuthorizeAsync(new ShopAuthorizationRequirement(CrudActions.Read, new List { + return await AuthorizeAsync(User, new ShopAuthorizationRequirement(CrudActions.Read, new List { new ShopRole(Roles.Admin), new ShopRole(Roles.ShopManager) }), shopItem, () => { @@ -103,6 +88,18 @@ public class ShopItemController : AuthorizationControllerBase { }); } + /// + /// + /// + /// + /// + /// + [HttpGet("{siteId}")] + public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] string slug) { + var result = _shopItemService.GetSlug(siteId, slug); + return result.ToActionResult(); + } + /// /// Can Admin, Shop manager /// @@ -117,7 +114,7 @@ public class ShopItemController : AuthorizationControllerBase { if (!getShopItemResult.IsSuccess || shopItem == null) return getShopItemResult.ToActionResult(); - return await AuthorizeAsync(new ShopAuthorizationRequirement(CrudActions.Update, new List { + return await AuthorizeAsync(User, new ShopAuthorizationRequirement(CrudActions.Update, new List { new ShopRole(Roles.Admin), new ShopRole(Roles.ShopManager) }), shopItem, () => { @@ -139,7 +136,7 @@ public class ShopItemController : AuthorizationControllerBase { if (!getShopItemResult.IsSuccess || shopItem == null) return getShopItemResult.ToActionResult(); - return await AuthorizeAsync(new ShopAuthorizationRequirement(CrudActions.Delete, new List { + return await AuthorizeAsync(User, new ShopAuthorizationRequirement(CrudActions.Delete, new List { new ShopRole(Roles.Admin), new ShopRole(Roles.ShopManager) }), shopItem, () => { diff --git a/src/WeatherForecast/Controllers/ShopItemsController.cs b/src/WeatherForecast/Controllers/ShopItemsController.cs index 6228a81..683d6d2 100644 --- a/src/WeatherForecast/Controllers/ShopItemsController.cs +++ b/src/WeatherForecast/Controllers/ShopItemsController.cs @@ -6,17 +6,16 @@ using DomainResults.Mvc; using WeatherForecast.Services; using DataProviders.Collections; using WeatherForecast.Models.Shop.Requests; +using WeatherForecast.Controllers.Abstractions; namespace WeatherForecast.Controllers; /// /// /// -[ApiController] [Route("api/[controller]")] -public class ShopItemsController : ControllerBase { +public class ShopItemsController : AuthorizationControllerBase { - private readonly IAuthorizationService _authorizationService; private readonly IShopCatalogDataProvider _shopCatalogDataProvider; private readonly IShopItemsService _shopItemsService; @@ -30,8 +29,7 @@ public class ShopItemsController : ControllerBase { IAuthorizationService authorizationService, IShopCatalogDataProvider shopCatalogDataProvider, IShopItemsService shopCatalogService - ) { - _authorizationService = authorizationService; + ) : base (authorizationService) { _shopCatalogDataProvider = shopCatalogDataProvider; _shopItemsService = shopCatalogService; } @@ -44,7 +42,7 @@ public class ShopItemsController : ControllerBase { /// /// [HttpGet("{siteId}")] - public IActionResult Get([FromRoute] Guid siteId, [FromQuery] GetShopItemsRequestModel requestData) { + public IActionResult Get([FromRoute] Guid siteId, [FromQuery] GetShopItemsLocalizedRequestModel requestData) { var result = _shopItemsService.Get(siteId, requestData); return result.ToActionResult(); } diff --git a/src/WeatherForecast/Controllers/TemplateController.cs b/src/WeatherForecast/Controllers/TemplateController.cs index d74fffa..df61f66 100644 --- a/src/WeatherForecast/Controllers/TemplateController.cs +++ b/src/WeatherForecast/Controllers/TemplateController.cs @@ -19,7 +19,6 @@ namespace WeatherForecast.Controllers; /// /// /// -[AllowAnonymous] [Route("api/[controller]")] public class TemplateController : AuthorizationControllerBase { @@ -59,7 +58,7 @@ public class TemplateController : AuthorizationControllerBase { var newFile = new BucketFile(siteId, formFile.FileName, ms.ToArray(), formFile.ContentType); - return await AuthorizeAsync(new TemplateAuthorisationRequirement(CrudActions.Create, new List { + return await AuthorizeAsync(User, new TemplateAuthorisationRequirement(CrudActions.Create, new List { new TemplateRole(Roles.Admin) }), newFile, () => { var result = _templateService.Post(newFile); @@ -80,7 +79,7 @@ public class TemplateController : AuthorizationControllerBase { if (!result.IsSuccess || file == null) return result.ToActionResult(); - return await AuthorizeAsync(new TemplateAuthorisationRequirement(CrudActions.Read, new List { + return await AuthorizeAsync(User, new TemplateAuthorisationRequirement(CrudActions.Read, new List { new TemplateRole(Roles.Admin) }), file, () => { var stream = new MemoryStream(file.Bytes); diff --git a/src/WeatherForecast/Controllers/UtilsController.cs b/src/WeatherForecast/Controllers/UtilsController.cs index 3882c21..cadbf8b 100644 --- a/src/WeatherForecast/Controllers/UtilsController.cs +++ b/src/WeatherForecast/Controllers/UtilsController.cs @@ -3,8 +3,10 @@ using CryptoProvider; using DomainResults.Mvc; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using WeatherForecast.Controllers.Abstractions; using WeatherForecast.Models.Initialization.Requests; using WeatherForecast.Models.Utils.Requests; using WeatherForecast.Services; @@ -16,8 +18,15 @@ namespace WeatherForecast.Controllers; /// /// [Route("api/[controller]")] -[ApiController] -public class UtilsController : ControllerBase { +public class UtilsController : AuthorizationControllerBase { + + /// + /// + /// + /// + public UtilsController( + IAuthorizationService authorizationService + ) : base(authorizationService) { } /// /// diff --git a/src/WeatherForecast/Controllers/WeatherForecastController.cs b/src/WeatherForecast/Controllers/WeatherForecastController.cs index acaf9da..97f58b8 100644 --- a/src/WeatherForecast/Controllers/WeatherForecastController.cs +++ b/src/WeatherForecast/Controllers/WeatherForecastController.cs @@ -1,5 +1,7 @@ +using DomainObjects.Documents.Users; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; - +using WeatherForecast.Controllers.Abstractions; using WeatherForecast.Models.WeatherForecast.Responses; namespace WeatherForecast.Controllers; @@ -7,9 +9,8 @@ namespace WeatherForecast.Controllers; /// /// /// -[ApiController] -[Route("[controller]")] -public class WeatherForecastController : ControllerBase { +[Route("api/[controller]")] +public class WeatherForecastController : AuthorizationControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; @@ -17,7 +18,9 @@ public class WeatherForecastController : ControllerBase { /// /// /// - public WeatherForecastController() { } + public WeatherForecastController( + IAuthorizationService authorizationService + ) : base (authorizationService) { } #region Authless methods diff --git a/src/WeatherForecast/Models/Blog/Requests/GetBlogItemsLocalizedRequestModel.cs b/src/WeatherForecast/Models/Blog/Requests/GetBlogItemsLocalizedRequestModel.cs index f7c3f35..d649d40 100644 --- a/src/WeatherForecast/Models/Blog/Requests/GetBlogItemsLocalizedRequestModel.cs +++ b/src/WeatherForecast/Models/Blog/Requests/GetBlogItemsLocalizedRequestModel.cs @@ -42,6 +42,13 @@ namespace WeatherForecast.Models.Blog.Requests { /// /// public IEnumerable Validate(ValidationContext validationContext) { + + if (CurrentPage < 1) + yield return new ValidationResult($"{Errors.WrongOrNotManaged} {nameof(CurrentPage)}"); + + if (ItemsPerPage < 1) + yield return new ValidationResult($"{Errors.WrongOrNotManaged} {nameof(ItemsPerPage)}"); + if (Locale == Locales.Unknown) yield return new ValidationResult($"{Errors.UnableToParse} {nameof(Locale)}"); } diff --git a/src/WeatherForecast/Models/Blog/Requests/PostBlogItemRequestModel.cs b/src/WeatherForecast/Models/Blog/Requests/PostBlogItemRequestModel.cs index a841130..336818d 100644 --- a/src/WeatherForecast/Models/Blog/Requests/PostBlogItemRequestModel.cs +++ b/src/WeatherForecast/Models/Blog/Requests/PostBlogItemRequestModel.cs @@ -183,7 +183,7 @@ namespace WeatherForecast.Models.Blog.Requests { Locale = y.Locale, Alt = y.Alt, Target = y.Target, - Titile = y.Title, + Title = y.Title, Description = y.Description }).ToList() }).ToList(), diff --git a/src/WeatherForecast/Models/Blog/Requests/PutBlogItemRequestModel.cs b/src/WeatherForecast/Models/Blog/Requests/PutBlogItemRequestModel.cs index 23d3332..62d4ccb 100644 --- a/src/WeatherForecast/Models/Blog/Requests/PutBlogItemRequestModel.cs +++ b/src/WeatherForecast/Models/Blog/Requests/PutBlogItemRequestModel.cs @@ -183,7 +183,7 @@ namespace WeatherForecast.Models.Blog.Requests { Locale = y.Locale, Alt = y.Alt, Target = y.Target, - Titile = y.Title, + Title = y.Title, Description = y.Description }).ToList() }).ToList(), diff --git a/src/WeatherForecast/Models/Blog/Responses/GetBlogItemSlugResponseModel.cs b/src/WeatherForecast/Models/Blog/Responses/GetBlogItemLocalizedResponseModel.cs similarity index 96% rename from src/WeatherForecast/Models/Blog/Responses/GetBlogItemSlugResponseModel.cs rename to src/WeatherForecast/Models/Blog/Responses/GetBlogItemLocalizedResponseModel.cs index 7bd5f0f..e4f2d88 100644 --- a/src/WeatherForecast/Models/Blog/Responses/GetBlogItemSlugResponseModel.cs +++ b/src/WeatherForecast/Models/Blog/Responses/GetBlogItemLocalizedResponseModel.cs @@ -132,7 +132,7 @@ namespace WeatherForecast.Models.Blog.Responses { /// /// /// - public class GetBlogItemSlugResponseModel : ResponseModelBase { + public class GetBlogItemLocalizedResponseModel : ResponseModelBase { /// /// @@ -221,7 +221,7 @@ namespace WeatherForecast.Models.Blog.Responses { /// /// /// - public GetBlogItemSlugResponseModel(BlogDocument blogItem, List categories, User author, Locales locale) { + public GetBlogItemLocalizedResponseModel(BlogDocument blogItem, List categories, User author, Locales locale) { var postItemL10n = blogItem.L10n.Single(x => x.Locale == locale); diff --git a/src/WeatherForecast/Models/Blog/Responses/GetBlogItemResponseModel.cs b/src/WeatherForecast/Models/Blog/Responses/GetBlogItemResponseModel.cs index 9f4fb06..43ff31a 100644 --- a/src/WeatherForecast/Models/Blog/Responses/GetBlogItemResponseModel.cs +++ b/src/WeatherForecast/Models/Blog/Responses/GetBlogItemResponseModel.cs @@ -19,7 +19,7 @@ namespace WeatherForecast.Models.Blog.Responses { /// /// /// - public string Locale { get; set; } + public Locales Locale { get; set; } /// /// @@ -46,7 +46,7 @@ namespace WeatherForecast.Models.Blog.Responses { /// /// public GetBlogItemMediaAttachmentL10nResponseModel(MediaAttachmentL10n imageL10n) { - Locale = imageL10n.Locale.Name; + Locale = imageL10n.Locale; Alt = imageL10n.Alt; Target = imageL10n.Target; Title = imageL10n.Title; diff --git a/src/WeatherForecast/Models/Blog/Responses/GetBlogItemsSlugResponseModel.cs b/src/WeatherForecast/Models/Blog/Responses/GetBlogItemsLocalizedResponseModel.cs similarity index 58% rename from src/WeatherForecast/Models/Blog/Responses/GetBlogItemsSlugResponseModel.cs rename to src/WeatherForecast/Models/Blog/Responses/GetBlogItemsLocalizedResponseModel.cs index 4b05ba6..b62d22c 100644 --- a/src/WeatherForecast/Models/Blog/Responses/GetBlogItemsSlugResponseModel.cs +++ b/src/WeatherForecast/Models/Blog/Responses/GetBlogItemsLocalizedResponseModel.cs @@ -5,7 +5,7 @@ namespace WeatherForecast.Models.Blog.Responses { /// /// /// - public class GetBlogItemsSlugResponseModel : PaginationModelBase { + public class GetBlogItemsLocalizedResponseModel : PaginationModelBase { /// /// @@ -13,7 +13,7 @@ namespace WeatherForecast.Models.Blog.Responses { /// /// /// - public GetBlogItemsSlugResponseModel(int currentPage, int totalPages, List items) + public GetBlogItemsLocalizedResponseModel(int currentPage, int totalPages, List items) : base(currentPage, totalPages, items) { } } } diff --git a/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemSlugRequestModel.cs b/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemLocalizedRequestModel.cs similarity index 87% rename from src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemSlugRequestModel.cs rename to src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemLocalizedRequestModel.cs index 0153028..fd70cbc 100644 --- a/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemSlugRequestModel.cs +++ b/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemLocalizedRequestModel.cs @@ -7,7 +7,7 @@ namespace WeatherForecast.Models.Categories.Requests { /// /// /// - public class GetCategoryItemSlugRequestModel : RequestModelBase, IValidatableObject { + public class GetCategoryItemLocalizedRequestModel : RequestModelBase, IValidatableObject { /// /// diff --git a/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemsLocalizedRequestModel.cs b/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemsLocalizedRequestModel.cs new file mode 100644 index 0000000..40d7d9b --- /dev/null +++ b/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemsLocalizedRequestModel.cs @@ -0,0 +1,45 @@ +using Core.Abstractions.Models; +using Core.Enumerations; +using DomainObjects.Enumerations; +using System.ComponentModel.DataAnnotations; + +namespace WeatherForecast.Models.Cetegories.Requests { + + /// + /// + /// + public class GetCategoryItemsLocalizedRequestModel : RequestModelBase, IValidatableObject { + + /// + /// + /// + public int CurrentPage { get; set; } = 1; + + /// + /// + /// + public int ItemsPerPage { get; set; } = 8; + + /// + /// + /// + public Locales Locale { get; set; } = Locales.Unknown; + + /// + /// + /// + /// + /// + public IEnumerable Validate(ValidationContext validationContext) { + + if (CurrentPage > 0) + yield return new ValidationResult($"{Errors.WrongOrNotManaged} {nameof(CurrentPage)}"); + + if (ItemsPerPage > 0) + yield return new ValidationResult($"{Errors.WrongOrNotManaged} {nameof(ItemsPerPage)}"); + + if (Locale == Locales.Unknown) + yield return new ValidationResult($"{Errors.UnableToParse} {nameof(Locale)}"); + } + } +} diff --git a/src/WeatherForecast/Models/Cetegories/Responses/CategoryL10nModel.cs b/src/WeatherForecast/Models/Cetegories/Responses/CategoryL10nModel.cs deleted file mode 100644 index 01ea46e..0000000 --- a/src/WeatherForecast/Models/Cetegories/Responses/CategoryL10nModel.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Core.Abstractions.Models; -using DomainObjects.Documents.Categories.L10n; - -namespace WeatherForecast.Models.Categories.Responses -{ - - /// - /// - /// - public class CategoryL10nModel : ResponseModelBase { - - /// - /// - /// - public string Locale { get; set; } - - /// - /// - /// - public string Slug { get; set; } - - /// - /// - /// - public string Text { get; set; } - - /// - /// - /// - /// - public CategoryL10nModel(CategoryL10n categoryL10n) { - Locale = categoryL10n.Locale.Name; - Slug = categoryL10n.Slug; - Text = categoryL10n.Text; - } - } -} diff --git a/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemLocalizedResponseModel.cs b/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemLocalizedResponseModel.cs new file mode 100644 index 0000000..e90363b --- /dev/null +++ b/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemLocalizedResponseModel.cs @@ -0,0 +1,49 @@ +using Core.Abstractions.Models; +using DomainObjects.Documents.Categories; +using DomainObjects.Enumerations; +using WeatherForecast.Models.Categories.Responses; + +namespace WeatherForecast.Models.Cetegories.Responses { + + /// + /// + /// + public class GetCategoryItemLocalizedResponseModel : ResponseModelBase { + + /// + /// + /// + public Guid Id { get; set; } + + /// + /// + /// + public Guid SiteId { get; set; } + + + /// + /// + /// + public string Slug { get; set; } + + /// + /// + /// + public string Text { get; set; } + + /// + /// + /// + /// + /// + public GetCategoryItemLocalizedResponseModel(Category category, Locales locale) { + + var l10n = category.L10n.Single(x => x.Locale == locale); + + Id = category.Id; + SiteId = category.SiteId; + Slug = l10n.Slug; + Text = l10n.Text; + } + } +} diff --git a/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemResponseModel.cs b/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemResponseModel.cs index dd31e6c..0497c3c 100644 --- a/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemResponseModel.cs +++ b/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemResponseModel.cs @@ -1,6 +1,7 @@ using Core.Abstractions.Models; using DomainObjects.Enumerations; using DomainObjects.Documents.Categories.L10n; +using DomainObjects.Documents.Categories; namespace WeatherForecast.Models.Categories.Responses { @@ -12,7 +13,7 @@ namespace WeatherForecast.Models.Categories.Responses { /// /// /// - public string Locale { get; set; } + public Locales Locale { get; set; } /// /// @@ -29,7 +30,7 @@ namespace WeatherForecast.Models.Categories.Responses { /// /// public GetCategoryItemL10nResponseModel(CategoryL10n categoryL10n) { - Locale = categoryL10n.Locale.Name; + Locale = categoryL10n.Locale; Slug = categoryL10n.Slug; Text = categoryL10n.Text; } @@ -69,7 +70,7 @@ namespace WeatherForecast.Models.Categories.Responses { /// /// /// - public GetCategoryItemResponseModel(DomainObjects.Documents.Categories.Category category) { + public GetCategoryItemResponseModel(Category category) { Id = category.Id; SiteId = category.SiteId; @@ -81,7 +82,7 @@ namespace WeatherForecast.Models.Categories.Responses { /// /// /// - public GetCategoryItemResponseModel(DomainObjects.Documents.Categories.Category category, Locales locale) { + public GetCategoryItemResponseModel(Category category, Locales locale) { Id = category.Id; SiteId = category.SiteId; diff --git a/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemsLocalizedResponseModel.cs b/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemsLocalizedResponseModel.cs new file mode 100644 index 0000000..77bb5fb --- /dev/null +++ b/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemsLocalizedResponseModel.cs @@ -0,0 +1,21 @@ +using Core.Abstractions.Models; +using Core.Models; +using WeatherForecast.Models.Blog.Responses; + +namespace WeatherForecast.Models.Cetegories.Responses { + + /// + /// + /// + public class GetCategoryItemsLocalizedResponseModel : PaginationModelBase { + + /// + /// + /// + /// + /// + /// + public GetCategoryItemsLocalizedResponseModel(int currentPage, int totalPages, List items) + : base(currentPage, totalPages, items) { } + } +} diff --git a/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemsResponseModel.cs b/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemsResponseModel.cs new file mode 100644 index 0000000..4617ad5 --- /dev/null +++ b/src/WeatherForecast/Models/Cetegories/Responses/GetCategoryItemsResponseModel.cs @@ -0,0 +1,20 @@ +using Core.Models; +using WeatherForecast.Models.Categories.Responses; + +namespace WeatherForecast.Models.Cetegories.Responses; + +/// +/// +/// +public class GetCategoryItemsResponseModel : PaginationModelBase { + + /// + /// + /// + /// + /// + /// + public GetCategoryItemsResponseModel(int currentPage, int totalPages, List items) + : base(currentPage, totalPages, items) { } +} + diff --git a/src/WeatherForecast/Models/Content/Responses/GetContentResponseModel.cs b/src/WeatherForecast/Models/Content/Responses/GetContentResponseModel.cs index a1b64ef..ea9b08c 100644 --- a/src/WeatherForecast/Models/Content/Responses/GetContentResponseModel.cs +++ b/src/WeatherForecast/Models/Content/Responses/GetContentResponseModel.cs @@ -1,6 +1,7 @@ using Core.Abstractions.Models; using DomainObjects; using DomainObjects.Documents; +using DomainObjects.Enumerations; using WeatherForecast.Models.Content.Responses.Pages; namespace WeatherForecast.Models.Content.Responses @@ -19,7 +20,7 @@ namespace WeatherForecast.Models.Content.Responses /// /// /// - public string? Locale { get; set; } + public Locales? Locale { get; set; } /// /// diff --git a/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemsRequestModel.cs b/src/WeatherForecast/Models/Shop/Requests/GetShopItemLocalizedRequestModel.cs similarity index 79% rename from src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemsRequestModel.cs rename to src/WeatherForecast/Models/Shop/Requests/GetShopItemLocalizedRequestModel.cs index 47831a6..4a29b01 100644 --- a/src/WeatherForecast/Models/Cetegories/Requests/GetCategoryItemsRequestModel.cs +++ b/src/WeatherForecast/Models/Shop/Requests/GetShopItemLocalizedRequestModel.cs @@ -3,12 +3,12 @@ using Core.Enumerations; using DomainObjects.Enumerations; using System.ComponentModel.DataAnnotations; -namespace WeatherForecast.Models.Categories.Requests { +namespace WeatherForecast.Models.Shop.Requests { /// /// /// - public class GetCategoryItemsRequestModel : RequestModelBase { + public class GetShopItemLocalizedRequestModel : RequestModelBase, IValidatableObject { /// /// @@ -22,8 +22,7 @@ namespace WeatherForecast.Models.Categories.Requests { /// public IEnumerable Validate(ValidationContext validationContext) { if (Locale == Locales.Unknown) - yield return new ValidationResult($"{Errors.UnableToParse.Name} {(nameof(Locales))}"); - + yield return new ValidationResult($"{Errors.UnableToParse} {nameof(Locale)}"); } } } diff --git a/src/WeatherForecast/Models/Shop/Requests/GetShopItemsRequestModel.cs b/src/WeatherForecast/Models/Shop/Requests/GetShopItemsLocalizedRequestModel.cs similarity index 75% rename from src/WeatherForecast/Models/Shop/Requests/GetShopItemsRequestModel.cs rename to src/WeatherForecast/Models/Shop/Requests/GetShopItemsLocalizedRequestModel.cs index bef5fc3..fecd1f1 100644 --- a/src/WeatherForecast/Models/Shop/Requests/GetShopItemsRequestModel.cs +++ b/src/WeatherForecast/Models/Shop/Requests/GetShopItemsLocalizedRequestModel.cs @@ -8,7 +8,7 @@ namespace WeatherForecast.Models.Shop.Requests { /// /// /// - public class GetShopItemsRequestModel : RequestModelBase, IValidatableObject { + public class GetShopItemsLocalizedRequestModel : RequestModelBase, IValidatableObject { /// /// /// @@ -40,6 +40,12 @@ namespace WeatherForecast.Models.Shop.Requests { /// /// public IEnumerable Validate(ValidationContext validationContext) { + if (CurrentPage < 1) + yield return new ValidationResult($"{Errors.WrongOrNotManaged} {nameof(CurrentPage)}"); + + if (ItemsPerPage < 1) + yield return new ValidationResult($"{Errors.WrongOrNotManaged} {nameof(ItemsPerPage)}"); + if (Locale == Locales.Unknown) yield return new ValidationResult($"{Errors.UnableToParse} {nameof(Locale)}"); } diff --git a/src/WeatherForecast/Models/Shop/Requests/PostShopItemRequestModel.cs b/src/WeatherForecast/Models/Shop/Requests/PostShopItemRequestModel.cs index d9e38f6..8d62c1c 100644 --- a/src/WeatherForecast/Models/Shop/Requests/PostShopItemRequestModel.cs +++ b/src/WeatherForecast/Models/Shop/Requests/PostShopItemRequestModel.cs @@ -197,7 +197,7 @@ namespace WeatherForecast.Models.Requests { Locale = y.Locale, Alt = y.Alt, Target = y.Target, - Titile = y.Title, + Title = y.Title, Description = y.Description }).ToList() }).ToList(), diff --git a/src/WeatherForecast/Models/Shop/Requests/PutShopItemRequestModel.cs b/src/WeatherForecast/Models/Shop/Requests/PutShopItemRequestModel.cs index 6e792d8..affc086 100644 --- a/src/WeatherForecast/Models/Shop/Requests/PutShopItemRequestModel.cs +++ b/src/WeatherForecast/Models/Shop/Requests/PutShopItemRequestModel.cs @@ -202,7 +202,7 @@ namespace WeatherForecast.Models.Requests { Locale = y.Locale, Alt = y.Alt, Target = y.Target, - Titile = y.Title, + Title = y.Title, Description = y.Description }).ToList() }).ToList(), diff --git a/src/WeatherForecast/Models/Shop/Responses/GetShopItemLocalizedResponseModel.cs b/src/WeatherForecast/Models/Shop/Responses/GetShopItemLocalizedResponseModel.cs new file mode 100644 index 0000000..3d4c233 --- /dev/null +++ b/src/WeatherForecast/Models/Shop/Responses/GetShopItemLocalizedResponseModel.cs @@ -0,0 +1,271 @@ +using Core.Abstractions.Models; +using Core.Enumerations; +using DnsClient; +using DomainObjects; +using DomainObjects.Documents.Categories; +using DomainObjects.Documents.Posts; +using DomainObjects.Documents.Sites; +using DomainObjects.Documents.Users; +using DomainObjects.Enumerations; + + +namespace WeatherForecast.Models.Shop.Responses { + + #region Media attachments + /// + /// + /// + public class GetShopItemLocalizedMediaAttachmentResponseModel { + + /// + /// + /// + public string Alt { get; set; } + + /// + /// + /// + public string? Target { get; set; } + + /// + /// + /// + public string? Title { get; set; } + + /// + /// + /// + public string? Description { get; set; } + + + + /// + /// + /// + public string Src { get; set; } + + /// + /// + /// + public MediaTypes MediaType { get; set; } + + /// + /// + /// + /// + /// + public GetShopItemLocalizedMediaAttachmentResponseModel(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 + /// + /// + /// + public class GetShopItemLocalizedAuthorModel : ResponseModelBase { + + /// + /// + /// + public GetShopItemLocalizedMediaAttachmentResponseModel? Avatar { get; set; } + + /// + /// + /// + public string NickName { get; set; } + + /// + /// + /// + /// + /// + public GetShopItemLocalizedAuthorModel(User author, Locales locale) { + + if (author.Avatar != null) + Avatar = new GetShopItemLocalizedMediaAttachmentResponseModel(author.Avatar, locale); + + NickName = author.Username; + } + } + #endregion + + #region Category + /// + /// + /// + public class GetShopItemLocalizedCategoryResponseModel : ResponseModelBase { + + /// + /// + /// + public string Slug { get; set; } + + /// + /// + /// + public string Text { get; set; } + + /// + /// + /// + /// + /// + public GetShopItemLocalizedCategoryResponseModel(Category category, Locales locale) { + + var l10n = category.L10n.Single(x => x.Locale == locale); + + Slug = l10n.Slug; + Text = l10n.Text; + } + } + #endregion + + + /// + /// + /// + public class GetShopItemLocalizedResponseModel : ResponseModelBase { + + /// + /// + /// + public Guid Id { get; set; } + + /// + /// + /// + public Guid SiteId { get; set; } + + + + + + /// + /// + /// + public string Slug { get; set; } + + /// + /// + /// + public string Description { get; set; } + + /// + /// + /// + public string Title { get; set; } + + /// + /// + /// + public string ShortText { get; set; } + + /// + /// + /// + public string? Text { get; set; } + + /// + /// + /// + public string PlainText { get; set; } + + /// + /// + /// + public TextFormat TextFormat { get; set; } + + /// + /// + /// + public List? Badges { get; set; } + + /// + /// + /// + public List Categories { get; set; } + + /// + /// + /// + public List? MediaAttachemnts { get; set; } + + /// + /// + /// + public GetShopItemLocalizedAuthorModel Author { get; set; } + + + /// + /// + /// + public string Sku { get; set; } + + /// + /// + /// + public decimal? Rating { get; set; } + + /// + /// + /// + public decimal Price { get; set; } + + /// + /// + /// + public decimal? NewPrice { get; set; } + + /// + /// + /// + public uint? Quantity { get; set; } + + /// + /// + /// + /// + /// + /// + /// + public GetShopItemLocalizedResponseModel(ShopDocument shopItem, List categories, User author, Locales locale) { + + var postItemL10n = shopItem.L10n.Single(x => x.Locale == locale); + + Id = shopItem.Id; + SiteId = shopItem.SiteId; + + Slug = postItemL10n.Slug; + Description = postItemL10n.Description; + Title = postItemL10n.Title; + ShortText = postItemL10n.ShortText; + Text = postItemL10n.Text; + PlainText = postItemL10n.PlainText; + TextFormat = postItemL10n.TextFormat; + Badges = postItemL10n.Badges; + + Categories = categories.Select(x => new GetShopItemLocalizedCategoryResponseModel(x, locale)).ToList(); + MediaAttachemnts = shopItem.MediaAttachments?.Select(x => new GetShopItemLocalizedMediaAttachmentResponseModel(x, locale)).ToList(); + + Author = new GetShopItemLocalizedAuthorModel(author, locale); + + Sku = shopItem.Sku; + Rating = shopItem.Rating; + Price = shopItem.Price; + NewPrice = shopItem.NewPrice; + Quantity = shopItem.Quantity; + } + } +} diff --git a/src/WeatherForecast/Models/Shop/Responses/GetShopItemResponseModel.cs b/src/WeatherForecast/Models/Shop/Responses/GetShopItemResponseModel.cs index a3d738b..54ef6d5 100644 --- a/src/WeatherForecast/Models/Shop/Responses/GetShopItemResponseModel.cs +++ b/src/WeatherForecast/Models/Shop/Responses/GetShopItemResponseModel.cs @@ -1,11 +1,19 @@ using Core.Abstractions.Models; +using Core.Enumerations; using DomainObjects; using DomainObjects.Documents.Categories; +using DomainObjects.Documents.Categories.L10n; using DomainObjects.Documents.Posts; +using DomainObjects.Documents.Users; using DomainObjects.Enumerations; using DomainObjects.L10n; + +using WeatherForecast.Models.Blog.Responses; + namespace WeatherForecast.Models.Shop.Responses { + + #region Media attachment /// /// /// @@ -13,7 +21,7 @@ namespace WeatherForecast.Models.Shop.Responses { /// /// /// - public string Locale { get; set; } + public Locales Locale { get; set; } /// /// @@ -40,7 +48,7 @@ namespace WeatherForecast.Models.Shop.Responses { /// /// public GetShopItemMediaAttachmentL10nResponseModel(MediaAttachmentL10n imageL10n) { - Locale = imageL10n.Locale.Name; + Locale = imageL10n.Locale; Alt = imageL10n.Alt; } @@ -59,37 +67,127 @@ namespace WeatherForecast.Models.Shop.Responses { /// /// /// - public string? Src { get; set; } + public string Src { get; set; } /// /// /// - public string? Alt { get; set; } + public MediaTypes MediaType { get; set; } /// /// /// /// public GetShopItemMediaAttachmentResponseModel(MediaAttachment image) { + Src = image.Src; + MediaType = image.MediaType; L10n = image.L10n.Select(x => new GetShopItemMediaAttachmentL10nResponseModel(x)).ToList(); } + } + #endregion + + #region Author + /// + /// + /// + public class GetShopItemAuthorModel : ResponseModelBase { /// /// /// - /// - /// - public GetShopItemMediaAttachmentResponseModel(MediaAttachment mediaAttachment, Locales locale) { - Src = mediaAttachment.Src; + public Guid Id { get; set; } - var l10n = mediaAttachment.L10n.Single(x => x.Locale == locale); + /// + /// + /// + public GetShopItemMediaAttachmentResponseModel? Avatar { get; set; } - if (l10n != null) { - Alt = l10n.Alt; - } + /// + /// + /// + public string NickName { get; set; } + + /// + /// + /// + /// + public GetShopItemAuthorModel(User author) { + Id = author.Id; + + if (author.Avatar != null) + Avatar = new GetShopItemMediaAttachmentResponseModel(author.Avatar); + + NickName = author.Username; + } + } + #endregion + + #region Category + /// + /// + /// + public class GetShopItemCategoryL10nResponseModel : ResponseModelBase { + + /// + /// + /// + public Locales Locale { get; set; } + + /// + /// + /// + public string Slug { get; set; } + + /// + /// + /// + public string Text { get; set; } + + /// + /// + /// + /// + public GetShopItemCategoryL10nResponseModel(CategoryL10n categoryL10n) { + Locale = categoryL10n.Locale; + Slug = categoryL10n.Slug; + Text = categoryL10n.Text; } } + /// + /// + /// + public class GetShopItemCategoryResponseModel : ResponseModelBase { + + /// + /// + /// + public Guid Id { get; set; } + + /// + /// + /// + public Guid SiteId { get; set; } + + /// + /// + /// + public List? L10n { get; set; } + + /// + /// + /// + /// + public GetShopItemCategoryResponseModel(Category category) { + Id = category.Id; + SiteId = category.SiteId; + + L10n = category.L10n.Select(x => new GetShopItemCategoryL10nResponseModel(x)).ToList(); + } + } + #endregion + + #region Shop item /// /// /// @@ -98,7 +196,7 @@ namespace WeatherForecast.Models.Shop.Responses { /// /// /// - public string Locale { get; set; } + public Locales Locale { get; set; } /// /// @@ -146,7 +244,7 @@ namespace WeatherForecast.Models.Shop.Responses { /// /// public GetShopItemL10nResponseModel(PostItemL10n postItemL10n) { - Locale = postItemL10n.Locale.Name; + Locale = postItemL10n.Locale; Slug = postItemL10n.Slug; Description = postItemL10n.Description; Title = postItemL10n.Title; @@ -165,6 +263,49 @@ namespace WeatherForecast.Models.Shop.Responses { /// public class GetShopItemResponseModel : ResponseModelBase { + /// + /// + /// + public Guid Id { get; set; } + + + /// + /// + /// + public Guid SiteId { get; set; } + + + /// + /// + /// + public List L10n { get; set; } + + /// + /// + /// + public List? MediaAttachemnts { get; set; } + + /// + /// + /// + public GetShopItemAuthorModel Author { get; set; } + + + /// + /// + /// + public DateTime Created { get; set; } + + /// + /// + /// + public List? Tags { get; set; } + + /// + /// + /// + public List Categories { get; set; } + /// /// /// @@ -193,28 +334,24 @@ namespace WeatherForecast.Models.Shop.Responses { /// /// /// - /// + /// /// - public GetShopItemResponseModel(ShopDocument shopCatalogItem, List categories) { - Sku = shopCatalogItem.Sku; - Rating = shopCatalogItem.Rating; - Price = shopCatalogItem.Price; - NewPrice = shopCatalogItem.NewPrice; - Quantity = shopCatalogItem.Quantity; - } - - /// - /// - /// - /// - /// - /// - public GetShopItemResponseModel(ShopDocument shopCatalogItem, List categories, Locales locale) { - Sku = shopCatalogItem.Sku; - Rating = shopCatalogItem.Rating; - Price = shopCatalogItem.Price; - NewPrice = shopCatalogItem.NewPrice; - Quantity = shopCatalogItem.Quantity; + /// + public GetShopItemResponseModel(ShopDocument shopItem, List categories, User author) { + Id = shopItem.Id; + SiteId = shopItem.SiteId; + L10n = shopItem.L10n.Select(x => new GetShopItemL10nResponseModel(x)).ToList(); + MediaAttachemnts = shopItem.MediaAttachments?.Select(x => new GetShopItemMediaAttachmentResponseModel(x)).ToList(); + Author = new GetShopItemAuthorModel(author); + Created = shopItem.Created; + Tags = shopItem.Tags; + Categories = categories.Select(x => new GetShopItemCategoryResponseModel(x)).ToList(); + Sku = shopItem.Sku; + Rating = shopItem.Rating; + Price = shopItem.Price; + NewPrice = shopItem.NewPrice; + Quantity = shopItem.Quantity; } } + #endregion } diff --git a/src/WeatherForecast/Models/Shop/Responses/GetShopItemsLocalizedResponseModel.cs b/src/WeatherForecast/Models/Shop/Responses/GetShopItemsLocalizedResponseModel.cs new file mode 100644 index 0000000..46929f7 --- /dev/null +++ b/src/WeatherForecast/Models/Shop/Responses/GetShopItemsLocalizedResponseModel.cs @@ -0,0 +1,18 @@ +using Core.Models; + +namespace WeatherForecast.Models.Shop.Responses { + /// + /// + /// + public class GetShopItemsLocalizedResponseModel : PaginationModelBase { + + /// + /// + /// + /// + /// + /// + public GetShopItemsLocalizedResponseModel(int currentPage, int totalPages, List items) + : base(currentPage, totalPages, items) { } + } +} diff --git a/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemRequestModel.cs b/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemLocalizedRequestModel.cs similarity index 89% rename from src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemRequestModel.cs rename to src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemLocalizedRequestModel.cs index 4027d79..254cbc6 100644 --- a/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemRequestModel.cs +++ b/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemLocalizedRequestModel.cs @@ -9,7 +9,7 @@ namespace WeatherForecast.Models.ShopCart.Requests /// /// /// - public class GetShopCartItemRequestModel : RequestModelBase, IValidatableObject + public class GetShopCartItemLocalizedRequestModel : RequestModelBase, IValidatableObject { /// diff --git a/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemsController.cs b/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemsController.cs deleted file mode 100644 index 1e59bc5..0000000 --- a/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemsController.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Core.Abstractions.Models; -using Core.Enumerations; -using DomainObjects.Enumerations; -using System.ComponentModel.DataAnnotations; - -namespace WeatherForecast.Models.ShopCart.Requests -{ - - /// - /// - /// - public class GetShopCartItemsController : RequestModelBase, IValidatableObject - { - - /// - /// - /// - public Locales Locale { get; set; } = Locales.Us; - - /// - /// - /// - /// - /// - public IEnumerable Validate(ValidationContext validationContext) - { - if (Locale == Locales.Unknown) - yield return new ValidationResult($"{Errors.UnableToParse.Name} {nameof(Locales)}"); - - } - } -} diff --git a/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemsLocalizedRequestModel.cs b/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemsLocalizedRequestModel.cs new file mode 100644 index 0000000..03f0fa1 --- /dev/null +++ b/src/WeatherForecast/Models/ShopCart/Requests/GetShopCartItemsLocalizedRequestModel.cs @@ -0,0 +1,45 @@ +using Core.Abstractions.Models; +using Core.Enumerations; +using DomainObjects.Enumerations; +using System.ComponentModel.DataAnnotations; + +namespace WeatherForecast.Models.ShopCart.Requests { + + /// + /// + /// + public class GetShopCartItemsLocalizedRequestModel : RequestModelBase, IValidatableObject { + + /// + /// + /// + public int CurrentPage { get; set; } = 1; + + /// + /// + /// + public int ItemsPerPage { get; set; } = 8; + + /// + /// + /// + public Locales Locale { get; set; } = Locales.Us; + + /// + /// + /// + /// + /// + public IEnumerable Validate(ValidationContext validationContext) { + + if (CurrentPage > 0) + yield return new ValidationResult($"{Errors.WrongOrNotManaged} {nameof(CurrentPage)}"); + + if (ItemsPerPage > 0) + yield return new ValidationResult($"{Errors.WrongOrNotManaged} {nameof(ItemsPerPage)}"); + + if (Locale == Locales.Unknown) + yield return new ValidationResult($"{Errors.UnableToParse.Name} {nameof(Locales)}"); + } + } +} diff --git a/src/WeatherForecast/Models/ShopCart/Requests/PostShopCartItemRequestModel.cs b/src/WeatherForecast/Models/ShopCart/Requests/PostShopCartItemRequestModel.cs index 6974158..a2a46aa 100644 --- a/src/WeatherForecast/Models/ShopCart/Requests/PostShopCartItemRequestModel.cs +++ b/src/WeatherForecast/Models/ShopCart/Requests/PostShopCartItemRequestModel.cs @@ -11,41 +11,25 @@ namespace WeatherForecast.Models.ShopCart.Requests /// /// /// - public class PostShopCartItemRequestModel : RequestModelBase, IValidatableObject + public class PostShopCartItemRequestModel : RequestModelBase { /// /// /// - public uint? Quantity { get; set; } + public uint Quantity { get; set; } /// /// /// /// - public ShopCartDocument ToDomainObject(string sku, Guid userId, Guid siteId) - { + public ShopCartDocument ToDomainObject(string sku, Guid userId, Guid siteId) => new ShopCartDocument() { + Sku = sku, + UserId = userId, + SiteId = siteId, - return new ShopCartDocument() - { - Sku = sku, - UserId = userId, - SiteId = siteId, - - Quantity = Quantity.Value, - Created = DateTime.UtcNow - }; - } - - /// - /// - /// - /// - /// - public IEnumerable Validate(ValidationContext validationContext) - { - if (Quantity == null || Quantity != null && Quantity == 0) - yield return new ValidationResult($"{nameof(Quantity)} {Errors.NullOrEmpty}"); - } + Quantity = Quantity, + Created = DateTime.UtcNow + }; } } diff --git a/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemLocalizedResponseModel.cs b/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemLocalizedResponseModel.cs new file mode 100644 index 0000000..b92b0f8 --- /dev/null +++ b/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemLocalizedResponseModel.cs @@ -0,0 +1,149 @@ +using Core.Abstractions.Models; +using Core.Enumerations; +using DomainObjects; +using DomainObjects.Documents; +using DomainObjects.Documents.Posts; +using DomainObjects.Enumerations; +using DomainObjects.L10n; + +namespace WeatherForecast.Models.ShopCart.Responses { + + #region Media attachment + + /// + /// + /// + public class GetShopCartItemLocalizedMediaAttachmentResponseModel : ResponseModelBase { + + /// + /// + /// + public string Src { get; set; } + + /// + /// + /// + public MediaTypes MediaType { get; set; } + + /// + /// + /// + public string? Alt { get; set; } + + /// + /// + /// + public string? Target { get; set; } + + /// + /// + /// + public string? Title { get; set; } + + /// + /// + /// + public string? Description { get; set; } + + /// + /// + /// + /// + /// + public GetShopCartItemLocalizedMediaAttachmentResponseModel(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 Shop cart item + /// + /// + /// + public class GetShopCartItemLocalizedResponseModel : ResponseModelBase { + + /// + /// + /// + public string Slug { get; set; } + + /// + /// + /// + public string Sku { get; set; } + + /// + /// + /// + public GetShopCartItemLocalizedMediaAttachmentResponseModel? Image { get; set; } + + /// + /// + /// + public string Title { get; set; } + + /// + /// + /// + public string BrandName { get; set; } + + /// + /// + /// + public string ShortText { get; set; } + + /// + /// + /// + public DateTime Created { get; set; } + + /// + /// + /// + public decimal Price { get; set; } + + /// + /// + /// + public decimal? NewPrice { get; set; } + + /// + /// + /// + public uint? Quantity { get; set; } + + /// + /// + /// + /// + /// + /// + public GetShopCartItemLocalizedResponseModel(ShopDocument shopItem, ShopCartDocument shopCartItem, Locales locale) { + var l10n = shopItem.L10n.Single(x => x.Locale == locale); + + Sku = shopItem.Sku; + BrandName = shopItem.BrandName; + Created = shopItem.Created; + Price = shopItem.Price; + NewPrice = shopItem.NewPrice; + Quantity = shopCartItem.Quantity; + + Slug = l10n.Slug; + Title = l10n.Title; + ShortText = l10n.ShortText; + + var mediaAttachment = shopItem.MediaAttachments?.FirstOrDefault(); + if (mediaAttachment != null) + Image = new GetShopCartItemLocalizedMediaAttachmentResponseModel(mediaAttachment, locale); + } + } + #endregion +} diff --git a/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemResponseModel.cs b/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemResponseModel.cs index 8012744..dadb165 100644 --- a/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemResponseModel.cs +++ b/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemResponseModel.cs @@ -1,4 +1,5 @@ using Core.Abstractions.Models; +using Core.Enumerations; using DomainObjects; using DomainObjects.Documents; using DomainObjects.Documents.Posts; @@ -11,12 +12,12 @@ namespace WeatherForecast.Models.ShopCart.Responses { /// /// /// - public class GetMediaAttachmentL10nModel : ResponseModelBase { + public class GetShopCartItemMediaAttachmentL10nModel : ResponseModelBase { /// /// /// - public string Locale { get; set; } + public Locales Locale { get; set; } /// /// @@ -42,21 +43,24 @@ namespace WeatherForecast.Models.ShopCart.Responses { /// /// /// - public GetMediaAttachmentL10nModel(MediaAttachmentL10n imageL10n) { - Locale = imageL10n.Locale.Name; + public GetShopCartItemMediaAttachmentL10nModel(MediaAttachmentL10n imageL10n) { + Locale = imageL10n.Locale; Alt = imageL10n.Alt; + Target = imageL10n.Target; + Title = imageL10n.Title; + Description = imageL10n.Description; } } /// /// /// - public class GetMediaAttachmentResponseModel : ResponseModelBase { + public class GetShopCartItemMediaAttachmentResponseModel : ResponseModelBase { /// /// /// - public List? L10n { get; set; } + public List? L10n { get; set; } /// /// @@ -66,52 +70,35 @@ namespace WeatherForecast.Models.ShopCart.Responses { /// /// /// - public string? Alt { get; set; } - - /// - /// - /// - /// - public GetMediaAttachmentResponseModel(MediaAttachment image) { - L10n = image.L10n.Select(x => new GetMediaAttachmentL10nModel(x)).ToList(); - } + public MediaTypes MediaType { get; set; } /// /// /// /// - /// - public GetMediaAttachmentResponseModel(MediaAttachment mediaAttachment, Locales locale) { + public GetShopCartItemMediaAttachmentResponseModel(MediaAttachment mediaAttachment) { Src = mediaAttachment.Src; - - var l10n = mediaAttachment.L10n.Single(x => x.Locale == locale); - - if (l10n != null) { - Alt = l10n.Alt; - } + MediaType = mediaAttachment.MediaType; + L10n = mediaAttachment.L10n.Select(x => new GetShopCartItemMediaAttachmentL10nModel(x)).ToList(); } } + /// /// /// - public class GetShopCartItemResponseModel : ResponseModelBase { + public class GetShopCartItemL10nResponseModel : ResponseModelBase { + + /// + /// + /// + public Locales Locale { get; set; } /// /// /// public string Slug { get; set; } - /// - /// - /// - public string Sku { get; set; } - - /// - /// - /// - public GetMediaAttachmentResponseModel? Image { get; set; } - /// /// /// @@ -120,12 +107,62 @@ namespace WeatherForecast.Models.ShopCart.Responses { /// /// /// - public string BrandName { get; set; } + public string ShortText { get; set; } /// /// /// - public string ShortText { get; set; } + /// + public GetShopCartItemL10nResponseModel(PostItemL10n postItem) { + + Locale = postItem.Locale; + Slug = postItem.Slug; + Title = postItem.Title; + ShortText = postItem.ShortText; + } + + } + + + + /// + /// + /// + public class GetShopCartItemResponseModel : ResponseModelBase { + + /// + /// + /// + public Guid Id { get; set; } + + /// + /// + /// + public Guid SiteId { get; set; } + + + /// + /// + /// + public string Sku { get; set; } + + /// + /// + /// + public List L10n { get; set; } + + + /// + /// + /// + public GetShopCartItemMediaAttachmentResponseModel? Image { get; set; } + + + + /// + /// + /// + public string BrandName { get; set; } /// /// @@ -152,8 +189,12 @@ namespace WeatherForecast.Models.ShopCart.Responses { /// /// /// - /// - public GetShopCartItemResponseModel(ShopDocument shopItem, ShopCartDocument shopCartItem, Locales locale) { + public GetShopCartItemResponseModel(ShopDocument shopItem, ShopCartDocument shopCartItem) { + + Id = shopCartItem.Id; + SiteId = shopCartItem.SiteId; + + L10n = shopItem.L10n.Select(x => new GetShopCartItemL10nResponseModel(x)).ToList(); Sku = shopItem.Sku; BrandName = shopItem.BrandName; @@ -162,16 +203,11 @@ namespace WeatherForecast.Models.ShopCart.Responses { 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; - } + var mediaAttachmet = shopItem.MediaAttachments?.FirstOrDefault(); - if (shopItem.MediaAttachments != null) - Image = new GetMediaAttachmentResponseModel(shopItem.MediaAttachments.First(), locale); + if (mediaAttachmet != null) + Image = new GetShopCartItemMediaAttachmentResponseModel(mediaAttachmet); } } diff --git a/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemsLocalizedResponseModel.cs b/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemsLocalizedResponseModel.cs new file mode 100644 index 0000000..17ed4f6 --- /dev/null +++ b/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemsLocalizedResponseModel.cs @@ -0,0 +1,19 @@ +using Core.Models; + +namespace WeatherForecast.Models.ShopCart.Responses { + + /// + /// + /// + public class GetShopCartItemsLocalizedResponseModel : PaginationModelBase { + + /// + /// + /// + /// + /// + /// + public GetShopCartItemsLocalizedResponseModel(int currentPage, int totalPages, List items) + : base(currentPage, totalPages, items) { } + } +} diff --git a/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemsResponseModels.cs b/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemsResponseModels.cs new file mode 100644 index 0000000..291dc78 --- /dev/null +++ b/src/WeatherForecast/Models/ShopCart/Responses/GetShopCartItemsResponseModels.cs @@ -0,0 +1,19 @@ +using Core.Models; + +namespace WeatherForecast.Models.ShopCart.Responses { + + /// + /// + /// + public class GetShopCartItemsResponseModels : PaginationModelBase { + + /// + /// + /// + /// + /// + /// + public GetShopCartItemsResponseModels(int currentPage, int totalPages, List items) + : base(currentPage, totalPages, items) { } + } + } diff --git a/src/WeatherForecast/Services/Abstractions/PostItemServiceBase.cs b/src/WeatherForecast/Services/Abstractions/PostItemServiceBase.cs index d12df22..e8b8992 100644 --- a/src/WeatherForecast/Services/Abstractions/PostItemServiceBase.cs +++ b/src/WeatherForecast/Services/Abstractions/PostItemServiceBase.cs @@ -9,21 +9,22 @@ namespace WeatherForecast.Services.Abstractions { /// public abstract class PostItemServiceBase : ServiceBase { - /// - /// - /// - protected readonly ICategoryDataProvider _categoryDataProvider; + private protected readonly ICategoryDataProvider _categoryDataProvider; + private protected readonly IUserDataProvider _userDataProvider; /// /// /// /// /// + /// public PostItemServiceBase( ILogger logger, - ICategoryDataProvider categoryDataProvider + ICategoryDataProvider categoryDataProvider, + IUserDataProvider userDataProvider ) : base(logger) { _categoryDataProvider = categoryDataProvider; + _userDataProvider = userDataProvider; } /// diff --git a/src/WeatherForecast/Services/BlogItemService.cs b/src/WeatherForecast/Services/BlogItemService.cs index f67a499..47cc902 100644 --- a/src/WeatherForecast/Services/BlogItemService.cs +++ b/src/WeatherForecast/Services/BlogItemService.cs @@ -36,7 +36,7 @@ namespace WeatherForecast.Services /// /// /// - (GetBlogItemSlugResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemLocalizedRequestModel requestData); + (GetBlogItemLocalizedResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemLocalizedRequestModel requestData); /// /// @@ -73,7 +73,7 @@ namespace WeatherForecast.Services IBlogCatalogDataProvider blogCatalogDataProvider, ICategoryDataProvider categoryDataProvider, IUserDataProvider userDataProvider - ) : base(logger, categoryDataProvider) { + ) : base(logger, categoryDataProvider, userDataProvider) { _blogCatalogDataProvider = blogCatalogDataProvider; _userDataProvider = userDataProvider; } @@ -127,19 +127,23 @@ namespace WeatherForecast.Services /// /// /// - public (GetBlogItemSlugResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemLocalizedRequestModel requestData) { + public (GetBlogItemLocalizedResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemLocalizedRequestModel requestData) { - var (blog, getBlogItemResult) = _blogCatalogDataProvider.GetBySlug(siteId, requestData.Slug); - if (!getBlogItemResult.IsSuccess || blog == null) - return IDomainResult.Failed(); + var (blogItem, getBlogItemResult) = _blogCatalogDataProvider.GetBySlug(siteId, requestData.Slug); + if (!getBlogItemResult.IsSuccess || blogItem == null) + return IDomainResult.Failed(); - var (categories, getCategoryResult) = _categoryDataProvider.GetMany(blog.SiteId, blog.Categories); + var (categories, getCategoryResult) = _categoryDataProvider.GetMany(blogItem.SiteId, blogItem.Categories); if (!getCategoryResult.IsSuccess || categories == null) - return IDomainResult.Failed(); + return IDomainResult.Failed(); - var locale = blog.L10n.Single(x => x.Slug == requestData.Slug).Locale; + var (author, getAuthor) = _userDataProvider.Get(blogItem.Author); + if (!getAuthor.IsSuccess || author == null) + return IDomainResult.Failed(); - return IDomainResult.Success(new GetBlogItemLocalizedResponseModel(blog, categories, locale)); + var locale = blogItem.L10n.Single(x => x.Slug == requestData.Slug).Locale; + + return IDomainResult.Success(new GetBlogItemLocalizedResponseModel(blogItem, categories, author, locale)); } /// diff --git a/src/WeatherForecast/Services/BlogItemsService.cs b/src/WeatherForecast/Services/BlogItemsService.cs index 9e1ac8b..048a43c 100644 --- a/src/WeatherForecast/Services/BlogItemsService.cs +++ b/src/WeatherForecast/Services/BlogItemsService.cs @@ -6,6 +6,7 @@ using DataProviders.Collections; using WeatherForecast.Models.Blog.Requests; using WeatherForecast.Models.Blog.Responses; +using DomainObjects.Documents.Categories; namespace WeatherForecast.Services { @@ -20,7 +21,7 @@ namespace WeatherForecast.Services { /// /// /// - (GetBlogItemsSlugResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemsLocalizedRequestModel requestData); + (GetBlogItemsLocalizedResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemsLocalizedRequestModel requestData); } /// @@ -30,6 +31,7 @@ namespace WeatherForecast.Services { private readonly IBlogCatalogDataProvider _blogCatalogDataProvider; private readonly ICategoryDataProvider _categoryDataProvider; + private readonly IUserDataProvider _userDataProvider; /// /// @@ -37,13 +39,16 @@ namespace WeatherForecast.Services { /// /// /// + /// public BlogItemsService( ILogger logger, IBlogCatalogDataProvider blogCatalogDataProvider, - ICategoryDataProvider categoryDataProvider + ICategoryDataProvider categoryDataProvider, + IUserDataProvider userDataProvider ) : base(logger) { _blogCatalogDataProvider = blogCatalogDataProvider; _categoryDataProvider = categoryDataProvider; + _userDataProvider = userDataProvider; } /// @@ -52,24 +57,37 @@ namespace WeatherForecast.Services { /// /// /// - 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); - if (!result.IsSuccess || items == null) + public (GetBlogItemsLocalizedResponseModel?, IDomainResult) Get(Guid siteId, GetBlogItemsLocalizedRequestModel requestData) { + + var (count, getCountResult) = _blogCatalogDataProvider.Count(siteId); + if (!getCountResult.IsSuccess || count == null) + return (null, getCountResult); + + var skip = (requestData.CurrentPage - 1) * requestData.ItemsPerPage; + var take = requestData.ItemsPerPage; + + var totalPages = (int)Math.Ceiling((decimal)count / take); + + var (blogitems, result) = _blogCatalogDataProvider.GetAll(siteId, skip, take); + if (!result.IsSuccess || blogitems == null) return (null, result); - var blogItems = new List(); - foreach (var item in items) { - var (categories, getCategoryResult) = _categoryDataProvider.GetMany(siteId, item.Categories); + var response = new List(); + foreach (var blogItem in blogitems) { + var (categories, getCategoryResult) = _categoryDataProvider.GetMany(siteId, blogItem.Categories); if (!getCategoryResult.IsSuccess || categories == null) - return IDomainResult.Failed(); + _logger.LogWarning($"Blog item has unkonwn categories {string.Join(',', blogItem.Categories)}"); - blogItems.Add(new GetBlogItemLocalizedResponseModel(item, categories, requestData.Locale)); + var (author, getAuthor) = _userDataProvider.Get(blogItem.Author); + if (!getAuthor.IsSuccess || author == null) + return IDomainResult.Failed(); + + response.Add(new GetBlogItemLocalizedResponseModel(blogItem, categories ?? new List(), author, requestData.Locale)); } - return blogItems.Count > 0 - ? IDomainResult.Success(new GetBlogItemsResponseModel(requestData.CurrentPage, 0, blogItems)) - : IDomainResult.NotFound(); + return response.Count > 0 + ? IDomainResult.Success(new GetBlogItemsLocalizedResponseModel(requestData.CurrentPage, totalPages, response)) + : IDomainResult.NotFound(); } } } diff --git a/src/WeatherForecast/Services/CategoryItemService.cs b/src/WeatherForecast/Services/CategoryItemService.cs index abc6dc9..8d55dce 100644 --- a/src/WeatherForecast/Services/CategoryItemService.cs +++ b/src/WeatherForecast/Services/CategoryItemService.cs @@ -4,10 +4,10 @@ using DataProviders.Collections; using Core.Abstractions; -using WeatherForecast.Models.Category.Requests; -using WeatherForecast.Models.Category.Responses; +using WeatherForecast.Models.Categories.Requests; +using WeatherForecast.Models.Categories.Responses; using DomainObjects.Enumerations; -using WeatherForecast.Models.CategoryItem.Requests; + using DomainObjects.Documents.Categories; namespace WeatherForecast.Services { diff --git a/src/WeatherForecast/Services/CategoryItemsService.cs b/src/WeatherForecast/Services/CategoryItemsService.cs index d12ae78..89623bd 100644 --- a/src/WeatherForecast/Services/CategoryItemsService.cs +++ b/src/WeatherForecast/Services/CategoryItemsService.cs @@ -3,12 +3,9 @@ using DataProviders.Collections; using Core.Abstractions; -using Core.Enumerations; - -using WeatherForecast.Models.Category.Responses; -using DomainObjects.Enumerations; -using WeatherForecast.Models.CategoryItem.Requests; +using WeatherForecast.Models.Cetegories.Responses; +using WeatherForecast.Models.Cetegories.Requests; namespace WeatherForecast.Services { @@ -23,14 +20,7 @@ namespace WeatherForecast.Services { /// /// /// - (List?, IDomainResult) Get(Guid siteId, GetCategoryItemsRequestModel requestData); - - /// - /// - /// - /// - /// - IDomainResult Delete(Guid siteId); + (GetCategoryItemsLocalizedResponseModel?, IDomainResult) Get(Guid siteId, GetCategoryItemsLocalizedRequestModel requestData); } /// @@ -58,33 +48,23 @@ namespace WeatherForecast.Services { /// /// /// - public (List?, IDomainResult) Get(Guid siteId, GetCategoryItemsRequestModel requestData) { - try { - var (items, result) = _categoryDataProvider.GetAll(siteId); + public (GetCategoryItemsLocalizedResponseModel?, IDomainResult) Get(Guid siteId, GetCategoryItemsLocalizedRequestModel requestData) { + + var (count, getCountResult) = _categoryDataProvider.Count(siteId); + if (!getCountResult.IsSuccess || count == null) + return (null, getCountResult); + + var skip = (requestData.CurrentPage - 1) * requestData.ItemsPerPage; + var take = requestData.ItemsPerPage; + + var totalPages = (int)Math.Ceiling((decimal)count / take); + + var (items, result) = _categoryDataProvider.GetAll(siteId); if (!result.IsSuccess || items == null) return (null, result); - return IDomainResult.Success(items.Select(x => new GetCategoryItemResponseModel(x, requestData.Locale)).ToList()); - } - catch (Exception ex) { - _logger.LogError(ex, "Unhandled exception"); - return IDomainResult.Failed?>(ex.Message); - } - } - - /// - /// - /// - /// - /// - public IDomainResult Delete(Guid siteId) { - try { - return _categoryDataProvider.DeleteAll(siteId); - } - catch (Exception ex) { - _logger.LogError(ex, "Unhandled exception"); - return IDomainResult.Failed(ex.Message); - } + return IDomainResult.Success(new GetCategoryItemsLocalizedResponseModel(requestData.CurrentPage, totalPages, items.Select(x => + new GetCategoryItemLocalizedResponseModel(x, requestData.Locale)).ToList())); } } } diff --git a/src/WeatherForecast/Services/ContentService.cs b/src/WeatherForecast/Services/ContentService.cs index 8b585c4..90061ce 100644 --- a/src/WeatherForecast/Services/ContentService.cs +++ b/src/WeatherForecast/Services/ContentService.cs @@ -48,17 +48,11 @@ namespace WeatherForecast.Services { /// /// public (GetContentResponseModel?, IDomainResult) GetContent(Guid siteId, GetContentRequestModel requestData) { - try { - var (content, result) = _contentDataProvider.Get(siteId); - if (!result.IsSuccess || content == null) - return (null, result); + var (content, result) = _contentDataProvider.Get(siteId); + if (!result.IsSuccess || content == null) + return (null, result); - return IDomainResult.Success(new GetContentResponseModel(content.Single(x => x.Localization.Locale == requestData.Locale.Name))); - } - catch (Exception ex) { - _logger.LogError(ex, "Unhandled exception"); - return IDomainResult.Failed(ex.Message); - } + return IDomainResult.Success(new GetContentResponseModel(content.Single(x => x.Localization.Locale == requestData.Locale))); } } } diff --git a/src/WeatherForecast/Services/ShopCartItemService.cs b/src/WeatherForecast/Services/ShopCartItemService.cs index e36ca3c..9e16299 100644 --- a/src/WeatherForecast/Services/ShopCartItemService.cs +++ b/src/WeatherForecast/Services/ShopCartItemService.cs @@ -31,7 +31,7 @@ public interface IShopCartItemService { /// /// /// - (GetShopCartItemResponseModel?, IDomainResult) Get(ShopCartDocument cartItem, GetShopCartItemRequestModel requestData); + (GetShopCartItemLocalizedResponseModel?, IDomainResult) Get(ShopCartDocument cartItem, GetShopCartItemLocalizedRequestModel requestData); /// /// @@ -96,7 +96,7 @@ public class ShopCartItemService : ServiceBase, IShopCartIt /// /// /// - public (GetShopCartItemResponseModel?, IDomainResult) Get(ShopCartDocument cartItem, GetShopCartItemRequestModel requestData) { + public (GetShopCartItemLocalizedResponseModel?, IDomainResult) Get(ShopCartDocument cartItem, GetShopCartItemLocalizedRequestModel requestData) { var (item, result) = _shopCatalogDataProvider.Get(cartItem.SiteId, cartItem.Sku); if (!result.IsSuccess || item == null) { @@ -104,10 +104,10 @@ public class ShopCartItemService : ServiceBase, IShopCartIt if (!delteResult.IsSuccess) return (null, delteResult); - return IDomainResult.NotFound(); + return IDomainResult.NotFound(); } else - return IDomainResult.Success(new GetShopCartItemResponseModel(item, cartItem, requestData.Locale)); + return IDomainResult.Success(new GetShopCartItemLocalizedResponseModel(item, cartItem, requestData.Locale)); } /// diff --git a/src/WeatherForecast/Services/ShopCartItemsService.cs b/src/WeatherForecast/Services/ShopCartItemsService.cs index 5c46cf9..c6a045a 100644 --- a/src/WeatherForecast/Services/ShopCartItemsService.cs +++ b/src/WeatherForecast/Services/ShopCartItemsService.cs @@ -22,7 +22,7 @@ namespace WeatherForecast.Services /// /// /// - (List?, IDomainResult) Get(List cartItems, GetShopCartItemsController requestData); + (List?, IDomainResult) Get(List cartItems, GetShopCartItemsLocalizedRequestModel requestData); } /// @@ -54,9 +54,9 @@ namespace WeatherForecast.Services /// /// /// - public (List?, IDomainResult) Get(List cartItems, GetShopCartItemsController requestData) { + public (List?, IDomainResult) Get(List cartItems, GetShopCartItemsLocalizedRequestModel requestData) { - var items = new List(); + var items = new List(); foreach (var cartItem in cartItems) { var (item, result) = _shopCatalogDataProvider.Get(cartItem.Id, cartItem.Sku); if (!result.IsSuccess || item == null) { @@ -65,12 +65,12 @@ namespace WeatherForecast.Services return (null, delteResult); } else - items.Add(new GetShopCartItemResponseModel(item, cartItem, requestData.Locale)); + items.Add(new GetShopCartItemLocalizedResponseModel(item, cartItem, requestData.Locale)); } return items.Count > 0 ? IDomainResult.Success(items) - : IDomainResult.NotFound?>(); + : IDomainResult.NotFound?>(); } } } diff --git a/src/WeatherForecast/Services/ShopItemService.cs b/src/WeatherForecast/Services/ShopItemService.cs index 678eff3..ce2d581 100644 --- a/src/WeatherForecast/Services/ShopItemService.cs +++ b/src/WeatherForecast/Services/ShopItemService.cs @@ -7,6 +7,7 @@ using WeatherForecast.Services.Abstractions; using WeatherForecast.Models.Shop.Responses; using DomainObjects.Enumerations; using DomainObjects.Documents.Posts; +using WeatherForecast.Models.Blog.Responses; namespace WeatherForecast.Services { @@ -36,7 +37,7 @@ namespace WeatherForecast.Services /// /// /// - (GetShopItemResponseModel?, IDomainResult) GetSlug(Guid siteId, string slug); + (GetShopItemLocalizedResponseModel?, IDomainResult) GetSlug(Guid siteId, string slug); /// /// @@ -55,17 +56,20 @@ namespace WeatherForecast.Services private readonly IShopCatalogDataProvider _shopCatalogDataProvider; + /// /// /// /// /// /// + /// public ShopItemService( ILogger logger, IShopCatalogDataProvider shopCatalogDataProvider, - ICategoryDataProvider categoryDataProvider - ) : base(logger, categoryDataProvider) { + ICategoryDataProvider categoryDataProvider, + IUserDataProvider userDataProvider + ) : base(logger, categoryDataProvider, userDataProvider) { _shopCatalogDataProvider = shopCatalogDataProvider; } @@ -106,7 +110,11 @@ namespace WeatherForecast.Services if (!getCategoryResult.IsSuccess || categories == null) return IDomainResult.Failed(); - return IDomainResult.Success(new GetShopItemResponseModel(shopItem, categories)); + var (author, getAuthor) = _userDataProvider.Get(shopItem.Author); + if (!getAuthor.IsSuccess || author == null) + return IDomainResult.Failed(); + + return IDomainResult.Success(new GetShopItemResponseModel(shopItem, categories, author)); } /// @@ -115,24 +123,28 @@ namespace WeatherForecast.Services /// /// /// - public (GetShopItemResponseModel?, IDomainResult) GetSlug(Guid siteId, string slug) { + public (GetShopItemLocalizedResponseModel?, IDomainResult) GetSlug(Guid siteId, string slug) { try { - var (item, result) = _shopCatalogDataProvider.GetBySlug(siteId, slug); + var (shopItem, result) = _shopCatalogDataProvider.GetBySlug(siteId, slug); - if (!result.IsSuccess || item == null) + if (!result.IsSuccess || shopItem == null) return (null, result); - var locale = item.L10n.SingleOrDefault(x => x.Slug == slug)?.Locale ?? Locales.Us; + var locale = shopItem.L10n.SingleOrDefault(x => x.Slug == slug)?.Locale ?? Locales.Us; - var (categories, getCategoryResult) = _categoryDataProvider.GetMany(siteId, item.Categories); + var (categories, getCategoryResult) = _categoryDataProvider.GetMany(siteId, shopItem.Categories); if (!getCategoryResult.IsSuccess || categories == null) - return IDomainResult.Failed(); + return IDomainResult.Failed(); - return IDomainResult.Success(new GetShopItemResponseModel(item, categories, locale)); + var (author, getAuthor) = _userDataProvider.Get(shopItem.Author); + if (!getAuthor.IsSuccess || author == null) + return IDomainResult.Failed(); + + return IDomainResult.Success(new GetShopItemLocalizedResponseModel(shopItem, categories, author, locale)); } catch (Exception ex) { _logger.LogError(ex, "Unhandled exception"); - return IDomainResult.Failed(ex.Message); + return IDomainResult.Failed(ex.Message); } } diff --git a/src/WeatherForecast/Services/ShopItemsService.cs b/src/WeatherForecast/Services/ShopItemsService.cs index 943de16..830da10 100644 --- a/src/WeatherForecast/Services/ShopItemsService.cs +++ b/src/WeatherForecast/Services/ShopItemsService.cs @@ -3,13 +3,9 @@ using DataProviders.Collections; using Core.Abstractions; -using Core.Enumerations; -using WeatherForecast.Models; - -using WeatherForecast.Models.Shop.Responses; -using DomainObjects.Enumerations; using WeatherForecast.Models.Shop.Requests; +using WeatherForecast.Models.Shop.Responses; namespace WeatherForecast.Services { @@ -24,7 +20,7 @@ namespace WeatherForecast.Services { /// /// /// - (GetShopItemsResponseModel?, IDomainResult) Get(Guid siteId, GetShopItemsRequestModel requestData); + (GetShopItemsLocalizedResponseModel?, IDomainResult) Get(Guid siteId, GetShopItemsLocalizedRequestModel requestData); /// /// @@ -41,6 +37,7 @@ namespace WeatherForecast.Services { private readonly IShopCatalogDataProvider _shopCatalogDataProvider; private readonly ICategoryDataProvider _categoryDataProvider; + private readonly IUserDataProvider _userDataProvider; /// /// @@ -48,13 +45,16 @@ namespace WeatherForecast.Services { /// /// /// + /// public ShopItemsService( ILogger logger, IShopCatalogDataProvider shopCatalogDataprovider, - ICategoryDataProvider categoryDataProvider + ICategoryDataProvider categoryDataProvider, + IUserDataProvider userDataProvider ) : base(logger) { _shopCatalogDataProvider = shopCatalogDataprovider; _categoryDataProvider = categoryDataProvider; + _userDataProvider = userDataProvider; } /// @@ -63,30 +63,34 @@ namespace WeatherForecast.Services { /// /// /// - public (GetShopItemsResponseModel?, IDomainResult) Get(Guid siteId, GetShopItemsRequestModel requestData) { + public (GetShopItemsLocalizedResponseModel?, IDomainResult) Get(Guid siteId, GetShopItemsLocalizedRequestModel requestData) { try { - var (items, result) = _shopCatalogDataProvider.GetAll(siteId, requestData.CurrentPage > 0 ? ((requestData.CurrentPage - 1) * requestData.ItemsPerPage) : 0, requestData.ItemsPerPage); + var (items, result) = _shopCatalogDataProvider.GetAll(siteId, (requestData.CurrentPage - 1) * requestData.ItemsPerPage, requestData.ItemsPerPage); if (!result.IsSuccess || items == null) return (null, result); - var shopItems = new List(); + var shopItems = new List(); foreach (var item in items) { var (categories, getCategoryResult) = _categoryDataProvider.GetMany(siteId, item.Categories); if (!getCategoryResult.IsSuccess || categories == null) - return IDomainResult.Failed(); + return IDomainResult.Failed(); - shopItems.Add(new GetShopItemResponseModel(item, categories, requestData.Locale)); + var (author, getAuthor) = _userDataProvider.Get(item.Author); + if (!getAuthor.IsSuccess || author == null) + return IDomainResult.Failed(); + + shopItems.Add(new GetShopItemLocalizedResponseModel(item, categories, author, requestData.Locale)); } return shopItems.Count > 0 - ? IDomainResult.Success(new GetShopItemsResponseModel(requestData.CurrentPage, 0, shopItems)) - : IDomainResult.NotFound(); + ? IDomainResult.Success(new GetShopItemsLocalizedResponseModel(requestData.CurrentPage, 0, shopItems)) + : IDomainResult.NotFound(); } catch (Exception ex) { _logger.LogError(ex, "Unhandled exception"); - return IDomainResult.Failed(ex.Message); + return IDomainResult.Failed(ex.Message); } } diff --git a/src/WeatherForecast/Startup.cs b/src/WeatherForecast/Startup.cs index cc1d5d4..ba654e0 100644 --- a/src/WeatherForecast/Startup.cs +++ b/src/WeatherForecast/Startup.cs @@ -13,6 +13,10 @@ using ImageProvider.Extensions; using Core.Middlewares; using Microsoft.AspNetCore.Authorization; using WeatherForecast.Policies; +using static System.Runtime.InteropServices.JavaScript.JSType; +using DomainObjects.Enumerations; +using System.Security.Claims; +using System.Net; namespace WeatherForecast { @@ -63,13 +67,40 @@ namespace WeatherForecast { options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.RequireHttpsMetadata = false; - options.SaveToken = false; + options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(appSettings.JwtConfig.Secret)), ValidateIssuer = false, ValidateAudience = false }; + options.Events = new JwtBearerEvents { + OnMessageReceived = context => { + + return Task.CompletedTask; + }, + OnTokenValidated = context => { + var claims = context.Principal.Identity as ClaimsIdentity; + if (!claims.Claims.Any()) + context.Fail("This token has no claims."); + return Task.CompletedTask; + }, + OnChallenge = context => { + if (context.AuthenticateFailure != null) + throw new Exception("Authenticate failure."); + + + throw new Exception ("You are unauthorized to access this resource."); + }, + OnAuthenticationFailed = context => { + + return Task.FromException(context.Exception); + }, + OnForbidden = context => { + return Task.CompletedTask; + } + }; + }); } #endregion @@ -146,8 +177,9 @@ namespace WeatherForecast { Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"", Name = "Authorization", In = ParameterLocation.Header, - Type = SecuritySchemeType.ApiKey, - Scheme = "Bearer" + Type = SecuritySchemeType.Http, //We set the scheme type to http since we're using bearer authentication + Scheme = "Bearer", + BearerFormat = "JWT", }); config.AddSecurityRequirement(new OpenApiSecurityRequirement() @@ -157,8 +189,8 @@ namespace WeatherForecast { { Reference = new OpenApiReference { - Type = ReferenceType.SecurityScheme, - Id = "Bearer" + Type = ReferenceType.SecurityScheme, + Id = "Bearer" //The name of the previously defined security scheme. }, Scheme = "oauth2", Name = "Bearer", @@ -170,6 +202,9 @@ namespace WeatherForecast { }); // c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); //This line + + + config.MapType(() => new OpenApiSchema { Type = "string" }); }); #endregion } diff --git a/src/WeatherForecast/WeatherForecast.csproj b/src/WeatherForecast/WeatherForecast.csproj index c63337b..8911ed4 100644 --- a/src/WeatherForecast/WeatherForecast.csproj +++ b/src/WeatherForecast/WeatherForecast.csproj @@ -20,16 +20,16 @@ - - - - + + + + - + diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml index 5fb2e27..e3ce710 100644 --- a/src/docker-compose.override.yml +++ b/src/docker-compose.override.yml @@ -22,6 +22,9 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:7151;http://+:5133 + ports: + - "7151:7151" + - "5133:5133" volumes: - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro diff --git a/src/docker-compose/mongo/data/db/WiredTiger.turtle b/src/docker-compose/mongo/data/db/WiredTiger.turtle index a03a640..0f7a5bb 100644 --- a/src/docker-compose/mongo/data/db/WiredTiger.turtle +++ b/src/docker-compose/mongo/data/db/WiredTiger.turtle @@ -3,4 +3,4 @@ WiredTiger 10.0.2: (December 21, 2021) WiredTiger version major=10,minor=0,patch=2 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.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) +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.123211=(addr="018081e4f52354c18181e493d377368281e4a22aa0f5808080e301ffc0e3010fc0",order=123211,time=1679862041,size=81920,newest_start_durable_ts=0,oldest_start_ts=0,newest_txn=154,newest_stop_durable_ts=0,newest_stop_ts=-1,newest_stop_txn=-11,prepare=0,write_gen=370276,run_write_gen=370143)),checkpoint_backup_info=,checkpoint_lsn=(70,62976) diff --git a/src/docker-compose/mongo/data/db/WiredTiger.wt b/src/docker-compose/mongo/data/db/WiredTiger.wt index 7ed62a1..63bbedd 100644 Binary files a/src/docker-compose/mongo/data/db/WiredTiger.wt and b/src/docker-compose/mongo/data/db/WiredTiger.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-2--4715807334585891142.wt b/src/docker-compose/mongo/data/db/collection-2--4715807334585891142.wt index 72f2eb2..ad024d4 100644 Binary files a/src/docker-compose/mongo/data/db/collection-2--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/collection-2--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-2--4748285384625290805.wt b/src/docker-compose/mongo/data/db/collection-2--4748285384625290805.wt index 0c21068..e038b6f 100644 Binary files a/src/docker-compose/mongo/data/db/collection-2--4748285384625290805.wt and b/src/docker-compose/mongo/data/db/collection-2--4748285384625290805.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-4--4715807334585891142.wt b/src/docker-compose/mongo/data/db/collection-4--4715807334585891142.wt index adc036f..f7c1c00 100644 Binary files a/src/docker-compose/mongo/data/db/collection-4--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/collection-4--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-4--4748285384625290805.wt b/src/docker-compose/mongo/data/db/collection-4--4748285384625290805.wt index 231f253..930a50a 100644 Binary files a/src/docker-compose/mongo/data/db/collection-4--4748285384625290805.wt and b/src/docker-compose/mongo/data/db/collection-4--4748285384625290805.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-4-597769541568262742.wt b/src/docker-compose/mongo/data/db/collection-4-597769541568262742.wt index e366af8..7fa2117 100644 Binary files a/src/docker-compose/mongo/data/db/collection-4-597769541568262742.wt and b/src/docker-compose/mongo/data/db/collection-4-597769541568262742.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-6--4748285384625290805.wt b/src/docker-compose/mongo/data/db/collection-6--4748285384625290805.wt index fdc3728..2cc4fca 100644 Binary files a/src/docker-compose/mongo/data/db/collection-6--4748285384625290805.wt and b/src/docker-compose/mongo/data/db/collection-6--4748285384625290805.wt differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2022-11-28T02-00-19Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2022-11-28T02-00-19Z-00000 deleted file mode 100644 index 334801d..0000000 Binary files a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2022-11-28T02-00-19Z-00000 and /dev/null differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-22T19-47-49Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-22T19-47-49Z-00000 new file mode 100644 index 0000000..f81cb5b Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-22T19-47-49Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T08-53-59Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T08-53-59Z-00000 new file mode 100644 index 0000000..544071a Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T08-53-59Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T17-38-57Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T17-38-57Z-00000 new file mode 100644 index 0000000..8be98d8 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T17-38-57Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T17-53-41Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T17-53-41Z-00000 new file mode 100644 index 0000000..801c321 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T17-53-41Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T18-37-36Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T18-37-36Z-00000 new file mode 100644 index 0000000..32de588 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-23T18-37-36Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T10-33-55Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T10-33-55Z-00000 new file mode 100644 index 0000000..58f8ec9 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T10-33-55Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T18-37-05Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T18-37-05Z-00000 new file mode 100644 index 0000000..ece9667 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T18-37-05Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T19-48-21Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T19-48-21Z-00000 new file mode 100644 index 0000000..c49b483 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-24T19-48-21Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T16-09-38Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T16-09-38Z-00000 new file mode 100644 index 0000000..5517ea7 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T16-09-38Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T20-51-15Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T20-51-15Z-00000 new file mode 100644 index 0000000..8126df1 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T20-51-15Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T21-02-12Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T21-02-12Z-00000 new file mode 100644 index 0000000..2e467b9 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-25T21-02-12Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-26T08-52-41Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-26T08-52-41Z-00000 new file mode 100644 index 0000000..f9c355a Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-26T08-52-41Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-26T19-38-40Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-26T19-38-40Z-00000 new file mode 100644 index 0000000..9f0a67d Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-03-26T19-38-40Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.interim b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.interim index 1d74d8f..03b9bf0 100644 Binary files a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.interim and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.interim differ diff --git a/src/docker-compose/mongo/data/db/index-3--4715807334585891142.wt b/src/docker-compose/mongo/data/db/index-3--4715807334585891142.wt index 924ea9d..b068ede 100644 Binary files a/src/docker-compose/mongo/data/db/index-3--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/index-3--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/index-3--4748285384625290805.wt b/src/docker-compose/mongo/data/db/index-3--4748285384625290805.wt index c9feda3..7bfb068 100644 Binary files a/src/docker-compose/mongo/data/db/index-3--4748285384625290805.wt and b/src/docker-compose/mongo/data/db/index-3--4748285384625290805.wt differ diff --git a/src/docker-compose/mongo/data/db/index-5--4715807334585891142.wt b/src/docker-compose/mongo/data/db/index-5--4715807334585891142.wt index 55876ca..b1269e7 100644 Binary files a/src/docker-compose/mongo/data/db/index-5--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/index-5--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/index-5--4748285384625290805.wt b/src/docker-compose/mongo/data/db/index-5--4748285384625290805.wt index 11d7e89..7ffd615 100644 Binary files a/src/docker-compose/mongo/data/db/index-5--4748285384625290805.wt and b/src/docker-compose/mongo/data/db/index-5--4748285384625290805.wt differ diff --git a/src/docker-compose/mongo/data/db/index-6--4715807334585891142.wt b/src/docker-compose/mongo/data/db/index-6--4715807334585891142.wt index 9c042b6..64cd141 100644 Binary files a/src/docker-compose/mongo/data/db/index-6--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/index-6--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000056 b/src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000070 similarity index 99% rename from src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000056 rename to src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000070 index 2bb7da0..b7f8d62 100644 Binary files a/src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000056 and b/src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000070 differ diff --git a/src/docker-compose/mongo/data/db/sizeStorer.wt b/src/docker-compose/mongo/data/db/sizeStorer.wt index cf18b7c..715ba7d 100644 Binary files a/src/docker-compose/mongo/data/db/sizeStorer.wt and b/src/docker-compose/mongo/data/db/sizeStorer.wt differ