From cf3b10549c82f0ce2462e314bba9d294929412db Mon Sep 17 00:00:00 2001 From: Hamid Reza Mohammadi Date: Mon, 17 May 2021 12:39:39 +0430 Subject: [PATCH] switching back to httpclient instead of direct db access in GanjooRazor --- GanjooRazor/Pages/Index.cshtml.cs | 63 +++++---- GanjooRazor/Pages/_HashiehaPage.cshtml.cs | 37 +++-- GanjooRazor/Pages/_SimiPage.cshtml.cs | 32 ++--- GanjooRazor/Pages/_VaznPage.cshtml.cs | 30 ++-- GanjooRazor/Startup.cs | 161 +--------------------- GanjooRazor/appsettings.json | 4 +- 6 files changed, 80 insertions(+), 247 deletions(-) diff --git a/GanjooRazor/Pages/Index.cshtml.cs b/GanjooRazor/Pages/Index.cshtml.cs index cdd09af6..8e0946dd 100644 --- a/GanjooRazor/Pages/Index.cshtml.cs +++ b/GanjooRazor/Pages/Index.cshtml.cs @@ -4,8 +4,10 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using RMuseum.Models.Auth.Memory; using RMuseum.Models.Ganjoor; using RMuseum.Models.Ganjoor.ViewModels; @@ -32,37 +34,27 @@ namespace GanjooRazor.Pages /// private readonly IConfiguration _configuration; - /// - /// IAppUserService instance - /// - private readonly IAppUserService _appUserService; - - /// - /// ganjoor service - /// - private readonly IGanjoorService _ganjoorService; - /// /// HttpClient instance /// private readonly HttpClient _httpClient; + private readonly IMemoryCache _memoryCache; + /// /// constructor /// /// - /// - /// /// + /// public IndexModel(IConfiguration configuration, - IAppUserService appUserService, - IGanjoorService ganjoorService, - HttpClient httpClient) + HttpClient httpClient, + IMemoryCache memoryCache + ) { _configuration = configuration; - _appUserService = appUserService; - _ganjoorService = ganjoorService; _httpClient = httpClient; + _memoryCache = memoryCache; } [BindProperty] @@ -212,7 +204,6 @@ namespace GanjooRazor.Pages } ), Encoding.UTF8, "application/json"); - await _ganjoorService.CacheCleanForPageById(poemId); var response = await secureClient.PostAsync($"{APIRoot.Url}/api/ganjoor/comment", stringContent); if (response.StatusCode == HttpStatusCode.OK) { @@ -280,7 +271,6 @@ namespace GanjooRazor.Pages { if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response)) { - await _ganjoorService.CacheCleanForComment(id); var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/ganjoor/comment?id={id}"); if (response.StatusCode != HttpStatusCode.OK) @@ -305,7 +295,6 @@ namespace GanjooRazor.Pages { if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response)) { - await _ganjoorService.CacheCleanForComment(id); var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/comment/{id}", new StringContent(JsonConvert.SerializeObject(comment), Encoding.UTF8, "application/json")); if (response.StatusCode != HttpStatusCode.OK) { @@ -468,7 +457,16 @@ namespace GanjooRazor.Pages private async Task preparePoets() { - Poets = new List((await _ganjoorService.GetPoets(true, false)).Result); + var cacheKey = $"/api/ganjoor/poets?includeBio=false"; + if (!_memoryCache.TryGetValue(cacheKey, out List poets)) + { + var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets?includeBio=false"); + response.EnsureSuccessStatusCode(); + poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>(); + _memoryCache.Set(cacheKey, poets); + } + + Poets = poets; } /// @@ -491,23 +489,26 @@ namespace GanjooRazor.Pages if (!string.IsNullOrEmpty(Request.Query["p"])) { - var pageUrlRes = await _ganjoorService.GetPageUrlById(int.Parse(Request.Query["p"])); - return Redirect(pageUrlRes.Result); + var pageUrlResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/pageurl?id={Request.Query["p"]}"); + pageUrlResponse.EnsureSuccessStatusCode(); + var pageUrl = JsonConvert.DeserializeObject(await pageUrlResponse.Content.ReadAsStringAsync()); + return Redirect(pageUrl); } await preparePoets(); if (!IsHomePage) { - var pageRes = await _ganjoorService.GetPageByUrl(Request.Path, true); - if(string.IsNullOrEmpty(pageRes.ExceptionString)) + var pageQuery = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/page?url={Request.Path}"); + if (!pageQuery.IsSuccessStatusCode) { - if(pageRes.Result == null) + if (pageQuery.StatusCode == HttpStatusCode.NotFound) { return NotFound(); } } - GanjoorPage = pageRes.Result; + pageQuery.EnsureSuccessStatusCode(); + GanjoorPage = JObject.Parse(await pageQuery.Content.ReadAsStringAsync()).ToObject(); GanjoorPage.HtmlText = GanjoorPage.HtmlText.Replace("https://ganjoor.net/", "/").Replace("http://ganjoor.net/", "/"); switch (GanjoorPage.GanjoorPageType) { @@ -528,7 +529,13 @@ namespace GanjooRazor.Pages if (IsPoemPage) { - Banner = (await _ganjoorService.GetARandomActiveSiteBanner()).Result; + var bannerQuery = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/site/banner"); + bannerQuery.EnsureSuccessStatusCode(); + string bannerResponse = await bannerQuery.Content.ReadAsStringAsync(); + if (!string.IsNullOrEmpty(bannerResponse)) + { + Banner = JObject.Parse(bannerResponse).ToObject(); + } } } diff --git a/GanjooRazor/Pages/_HashiehaPage.cshtml.cs b/GanjooRazor/Pages/_HashiehaPage.cshtml.cs index fa97f519..02ed0c2f 100644 --- a/GanjooRazor/Pages/_HashiehaPage.cshtml.cs +++ b/GanjooRazor/Pages/_HashiehaPage.cshtml.cs @@ -1,10 +1,13 @@ using DNTPersianUtils.Core; using Microsoft.AspNetCore.Mvc.RazorPages; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using RMuseum.Models.Auth.ViewModel; using RMuseum.Models.Ganjoor.ViewModels; -using RSecurityBackend.Models.Auth.ViewModels; using RSecurityBackend.Models.Generic; using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace GanjooRazor.Pages @@ -25,20 +28,15 @@ namespace GanjooRazor.Pages string filterUserId = Request.Query["userid"]; + string url = $"{APIRoot.Url}/api/ganjoor/comments?PageNumber={pageNumber}&PageSize=20"; string htmlText = ""; if (!string.IsNullOrEmpty(filterUserId)) { - RServiceResult userInfo = await _appUserService.GetUserInformation(Guid.Parse(filterUserId)); + var responseUserProfile = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/user/profile/{filterUserId}"); + responseUserProfile.EnsureSuccessStatusCode(); + + GanjoorUserPublicProfile profile = JsonConvert.DeserializeObject(await responseUserProfile.Content.ReadAsStringAsync()); - GanjoorUserPublicProfile profile = new GanjoorUserPublicProfile() - { - Id = (Guid)userInfo.Result.Id, - NickName = userInfo.Result.NickName, - Bio = userInfo.Result.Bio, - Website = userInfo.Result.Website, - RImageId = userInfo.Result.RImageId - }; - ViewData["Title"] = $"گنجور » حاشیه‌های {profile.NickName}"; @@ -63,19 +61,18 @@ namespace GanjooRazor.Pages htmlText += $"{Environment.NewLine}"; htmlText += $"
{Environment.NewLine}"; + url += $"&filterUserId={filterUserId}"; - } - var commentsRes = await _ganjoorService.GetRecentComments(new PagingParameterModel() - { - PageNumber = pageNumber, - PageSize = 20 - }, - string.IsNullOrEmpty(filterUserId) ? Guid.Empty : Guid.Parse(filterUserId), true); + var response = await _httpClient.GetAsync(url); - PaginationMetadata paginationMetadata = commentsRes.Result.PagingMeta; - GanjoorCommentFullViewModel[] comments = commentsRes.Result.Items; + + response.EnsureSuccessStatusCode(); + + string paginnationMetadata = response.Headers.GetValues("paging-headers").FirstOrDefault(); + PaginationMetadata paginationMetadata = JsonConvert.DeserializeObject(paginnationMetadata); + var comments = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>(); foreach (var comment in comments) diff --git a/GanjooRazor/Pages/_SimiPage.cshtml.cs b/GanjooRazor/Pages/_SimiPage.cshtml.cs index b5c0dc00..eabd9528 100644 --- a/GanjooRazor/Pages/_SimiPage.cshtml.cs +++ b/GanjooRazor/Pages/_SimiPage.cshtml.cs @@ -7,7 +7,6 @@ using RSecurityBackend.Models.Generic; using System; using System.Collections.Generic; using System.Linq; -using System.Net.Http; using System.Threading.Tasks; namespace GanjooRazor.Pages @@ -35,20 +34,12 @@ namespace GanjooRazor.Pages string metre = Request.Query["v"]; string rhyme = Request.Query["g"]; - var poemsRes = - ( - await _ganjoorService.GetSimilarPoems - ( - new PagingParameterModel() - { - PageNumber = pageNumber, - PageSize = 20 - }, - metre, - rhyme, - null - ) - ).Result; + string url = $"{APIRoot.Url}/api/ganjoor/poems/similar?PageNumber={pageNumber}&PageSize=20&metre={metre}&rhyme={rhyme}"; + var response = await _httpClient.GetAsync(url); + + response.EnsureSuccessStatusCode(); + + var poems = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>(); GanjoorPage.Title = "شعرهای "; @@ -65,10 +56,7 @@ namespace GanjooRazor.Pages - - - - foreach (var poem in poemsRes.Items) + foreach (var poem in poems) { htmlText += $"
{Environment.NewLine}

{poem.FullTitle}{Environment.NewLine}

{Environment.NewLine}" + $"
 
{Environment.NewLine}" @@ -85,8 +73,10 @@ namespace GanjooRazor.Pages htmlText += "

"; - PaginationMetadata paginationMetadata = poemsRes.PagingMeta; - + string paginnationMetadata = response.Headers.GetValues("paging-headers").FirstOrDefault(); + + PaginationMetadata paginationMetadata = JsonConvert.DeserializeObject(paginnationMetadata); + if (paginationMetadata.totalPages > 1) { GanjoorPage.Title += $" - صفحهٔ {pageNumber.ToPersianNumbers()}"; diff --git a/GanjooRazor/Pages/_VaznPage.cshtml.cs b/GanjooRazor/Pages/_VaznPage.cshtml.cs index 378f47be..1046fd7a 100644 --- a/GanjooRazor/Pages/_VaznPage.cshtml.cs +++ b/GanjooRazor/Pages/_VaznPage.cshtml.cs @@ -29,22 +29,16 @@ namespace GanjooRazor.Pages } string metre = Request.Query["v"]; - int? poetId = string.IsNullOrEmpty(Request.Query["a"]) ? null : int.Parse(Request.Query["a"]); + int poetId = string.IsNullOrEmpty(Request.Query["a"]) ? 0 : int.Parse(Request.Query["a"]); - var poemsRes = await _ganjoorService.GetSimilarPoems - ( - new PagingParameterModel() - { - PageNumber = pageNumber, - PageSize = 20 - }, - metre: metre, - rhyme: "", - poetId: poetId - ); + string url = $"{APIRoot.Url}/api/ganjoor/poems/similar?PageNumber={pageNumber}&PageSize=20&metre={metre}&poetId={poetId}"; + + var response = await _httpClient.GetAsync(url); + + response.EnsureSuccessStatusCode(); GanjoorPage.Title = "شعرهای "; - if (poetId != null) + if (poetId != 0) { GanjoorPage.Title += $"{Poets.Where(p => p.Id == poetId).Single().Name} "; } @@ -56,7 +50,7 @@ namespace GanjooRazor.Pages string htmlText = ""; - if (poetId != null) + if (poetId != 0) { htmlText += $"

{Environment.NewLine}"; htmlText += $"

{Environment.NewLine}"; @@ -65,9 +59,9 @@ namespace GanjooRazor.Pages htmlText += $"

{Environment.NewLine}"; } + var poems = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>(); - - foreach (var poem in poemsRes.Result.Items) + foreach (var poem in poems) { htmlText += $"
{Environment.NewLine}

{poem.FullTitle}{Environment.NewLine}

{Environment.NewLine}" + $"
 
{Environment.NewLine}" @@ -84,7 +78,9 @@ namespace GanjooRazor.Pages htmlText += "

"; - PaginationMetadata paginationMetadata = poemsRes.Result.PagingMeta; + string paginnationMetadata = response.Headers.GetValues("paging-headers").FirstOrDefault(); + + PaginationMetadata paginationMetadata = JsonConvert.DeserializeObject(paginnationMetadata); string queryPoetId = poetId == 0 ? "" : $"&a={poetId}"; diff --git a/GanjooRazor/Startup.cs b/GanjooRazor/Startup.cs index 0bd78faa..6ce8f143 100644 --- a/GanjooRazor/Startup.cs +++ b/GanjooRazor/Startup.cs @@ -42,9 +42,10 @@ namespace GanjooRazor { services.AddHttpClient(); + services.AddMemoryCache(); services.AddSingleton( - HtmlEncoder.Create(allowedRanges: new[] { UnicodeRanges.BasicLatin, + HtmlEncoder.Create(allowedRanges: new[] { UnicodeRanges.BasicLatin, UnicodeRanges.Arabic })); services.AddRazorPages(options => @@ -52,162 +53,6 @@ namespace GanjooRazor options.Conventions.AddPageRoute("/index", "{*url}"); }); - services.AddDbContextPool( - options => options.UseSqlServer( - Configuration.GetConnectionString("DefaultConnection"), - providerOptions => providerOptions.EnableRetryOnFailure() - ) - ); - - Audit.Core.Configuration.JsonSettings.ContractResolver = AuditNetEnvironmentSkippingContractResolver.Instance; - Audit.Core.Configuration.DataProvider = new RAuditDataProvider(Configuration.GetConnectionString("DefaultConnection")); - - services.AddIdentityCore( - options => - { - // Password settings. - options.Password.RequireDigit = true; - options.Password.RequireLowercase = true; - options.Password.RequireNonAlphanumeric = false; - options.Password.RequireUppercase = false; - options.Password.RequiredLength = 6; - options.Password.RequiredUniqueChars = 1; - - // Lockout settings. - options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); - options.Lockout.MaxFailedAccessAttempts = 5; - options.Lockout.AllowedForNewUsers = true; - - // User settings. - options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; - options.User.RequireUniqueEmail = false; - } - ).AddErrorDescriber(); - - - new IdentityBuilder(typeof(RAppUser), typeof(RAppRole), services) - .AddRoleManager>() - .AddSignInManager>() - .AddEntityFrameworkStores() - .AddErrorDescriber(); - - services.AddAuthentication(options => - { - options.DefaultScheme = "bearer"; - }).AddJwtBearer("bearer", options => - { - options.TokenValidationParameters = new TokenValidationParameters - { - ValidateAudience = false, - ValidAudience = "Everyone", - ValidateIssuer = true, - ValidIssuer = "Ganjoor", - - ValidateIssuerSigningKey = true, - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes($"{Configuration.GetSection("Security")["Secret"]}")), - - ValidateLifetime = true, //validate the expiration and not before values in the token - - ClockSkew = TimeSpan.Zero - }; - - options.Events = new JwtBearerEvents - { - OnAuthenticationFailed = context => - { - if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) - { - context.Response.Headers.Add("Token-Expired", "true"); - } - return Task.CompletedTask; - } - }; - - }); - - services.AddAuthorization(options => - { - //this is the default policy to make sure the use session has not yet been deleted by him/her from another client - //or by an admin (Authorize with no policy should fail on deleted sessions) - var defPolicy = new AuthorizationPolicyBuilder(); - defPolicy.Requirements.Add(new UserGroupPermissionRequirement("null", "null")); - options.DefaultPolicy = defPolicy.Build(); - - - foreach (SecurableItem Item in RMuseumSecurableItem.Items) - { - foreach (SecurableItemOperation Operation in Item.Operations) - { - options.AddPolicy($"{Item.ShortName}:{Operation.ShortName}", policy => policy.Requirements.Add(new UserGroupPermissionRequirement(Item.ShortName, Operation.ShortName))); - } - } - }); - - services.AddMemoryCache(); - - - - //security context maps to main db context - services.AddTransient, RMuseumDbContext>(); - - //captcha service - services.AddTransient(); - - - //generic image file service - services.AddTransient(); - - //app user services - services.AddTransient(); - - //user groups services - services.AddTransient(); - - //audit service - services.AddTransient(); - - //user permission checker - services.AddTransient(); - - //secret generator - services.AddTransient(); - - // email service - services.AddTransient(); - services.Configure(Configuration); - - //picture file service - services.AddTransient(); - - //messaging service - services.AddTransient(); - - //artifact service - services.AddTransient(); - - //audio service - services.AddTransient(); - - //ganjoor service - services.AddTransient(); - - //music catalogue service - services.AddTransient(); - - //long running job service - services.AddTransient(); - - //upload limit for IIS - services.Configure(options => - { - options.MaxRequestBodySize = int.Parse(Configuration.GetSection("IIS")["UploadLimit"]); - }); - - - services.AddHostedService(); - services.AddSingleton(); - - } @@ -222,8 +67,6 @@ namespace GanjooRazor app.UseRouting(); - app.UseAuthentication(); - app.UseAuthorization(); app.UseEndpoints(endpoints => diff --git a/GanjooRazor/appsettings.json b/GanjooRazor/appsettings.json index c7e253c7..3b721e74 100644 --- a/GanjooRazor/appsettings.json +++ b/GanjooRazor/appsettings.json @@ -8,8 +8,8 @@ }, "AllowedHosts": "*", "GoogleAnalyticsCode": "", - "APIRoot": "http://localhost:3439", - "GlobalAPIRoot": "http://localhost:3439", + "APIRoot": "https://ganjgah.ir", + "GlobalAPIRoot": "https://ganjgah.ir", "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=museum;Trusted_Connection=True;MultipleActiveResultSets=true" },