From 44b391d496de0aa7bbb3521bbba13c5c1526791b Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Mon, 10 Aug 2026 18:12:59 +0100 Subject: [PATCH] Activity protection --- Directory.Build.props | 1 + .../Business/ActivityApiController.cs | 3 +- .../NativeConfidentialController.cs | 8 ++--- src/Yavsc.Blogs.Tests/BlogApiTests.cs | 32 +++++++++++++++++++ src/Yavsc.Org/Extensions/HostingExtensions.cs | 3 ++ .../Services/GoogleApis/CalendarManager.cs | 2 +- 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 873845c4..aec8c990 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,5 +11,6 @@ from without conflicting names. --> true + NU1701, NU1901, NU1902 diff --git a/src/Yavsc.Api/Controllers/Business/ActivityApiController.cs b/src/Yavsc.Api/Controllers/Business/ActivityApiController.cs index f6b215e7..d2da2ea7 100644 --- a/src/Yavsc.Api/Controllers/Business/ActivityApiController.cs +++ b/src/Yavsc.Api/Controllers/Business/ActivityApiController.cs @@ -15,7 +15,6 @@ namespace Yavsc.Controllers { [Produces("application/json")] [Route("api/activity")] - [AllowAnonymous] public class ActivityApiController : Controller { private ApplicationDbContext _context; @@ -88,7 +87,7 @@ namespace Yavsc.Controllers } // POST: api/ActivityApi - [HttpPost,Authorize("AdministratorOnly")] + [HttpPost, Authorize("AdministratorOnly")] public async Task PostActivity([FromBody] Activity activity) { if (!ModelState.IsValid) diff --git a/src/Yavsc.Api/Controllers/NativeConfidentialController.cs b/src/Yavsc.Api/Controllers/NativeConfidentialController.cs index 01cd8478..4e771830 100644 --- a/src/Yavsc.Api/Controllers/NativeConfidentialController.cs +++ b/src/Yavsc.Api/Controllers/NativeConfidentialController.cs @@ -1,15 +1,15 @@  -using System; -using System.Linq; + using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; -using Yavsc.Helpers; + using Yavsc.Models; using Yavsc.Models.Identity; using Yavsc.Server.Helpers; +#nullable enable + [Authorize, Route("~/api/gcm")] public class NativeConfidentialController : Controller { diff --git a/src/Yavsc.Blogs.Tests/BlogApiTests.cs b/src/Yavsc.Blogs.Tests/BlogApiTests.cs index 35d67fbe..bf0758c6 100644 --- a/src/Yavsc.Blogs.Tests/BlogApiTests.cs +++ b/src/Yavsc.Blogs.Tests/BlogApiTests.cs @@ -148,6 +148,38 @@ public sealed class BlogApiTests : IClassFixture Assert.Equal(created.Id, doc.RootElement[0].GetProperty("id").GetInt64()); } + [Fact] + public async Task PostBlog_sets_AuthorId_on_created_post_and_list_entry() + { + ResetDatabase(); + using var http = NewClient(subject: "tester"); + + var draft = new BlogPost + { + Id = 0, + Title = "Billet avec auteur", + AuthorId = "payload-attacker", + Article = "Contenu de test.", + DateCreated = DateTime.UtcNow, + DateModified = DateTime.UtcNow + }; + + var postResponse = await http.PostAsJsonAsync("/api/v1/blog", draft); + Assert.Equal(HttpStatusCode.Created, postResponse.StatusCode); + + var created = await postResponse.Content.ReadFromJsonAsync(); + Assert.NotNull(created); + Assert.Equal("tester", created!.AuthorId); + + var listResponse = await http.GetAsync("/api/v1/blog"); + Assert.Equal(HttpStatusCode.OK, listResponse.StatusCode); + + using var doc = JsonDocument.Parse(await listResponse.Content.ReadAsStringAsync()); + Assert.Equal(JsonValueKind.Array, doc.RootElement.ValueKind); + Assert.Equal(1, doc.RootElement.GetArrayLength()); + Assert.Equal("tester", doc.RootElement[0].GetProperty("authorId").GetString()); + } + [Fact] public async Task GetBlog_returns_401_when_no_token_is_provided() { diff --git a/src/Yavsc.Org/Extensions/HostingExtensions.cs b/src/Yavsc.Org/Extensions/HostingExtensions.cs index b3f90639..0cae23a7 100644 --- a/src/Yavsc.Org/Extensions/HostingExtensions.cs +++ b/src/Yavsc.Org/Extensions/HostingExtensions.cs @@ -1189,6 +1189,8 @@ ADD COLUMN IF NOT EXISTS ""Moderated"" boolean NOT NULL DEFAULT FALSE;"); } } +#nullable enable + static void LoadGoogleConfig(IConfigurationRoot configuration) { string? googleClientFile = configuration["Authentication:Google:GoogleWebClientJson"]; @@ -1204,6 +1206,7 @@ ADD COLUMN IF NOT EXISTS ""Moderated"" boolean NOT NULL DEFAULT FALSE;"); Config.GServiceAccount = JsonConvert.DeserializeObject(safile.OpenText().ReadToEnd()); } } +#nullable disable public static IApplicationBuilder ConfigureFileServerApp(this IApplicationBuilder app, bool enableDirectoryBrowsing = false) diff --git a/src/Yavsc.Server/Services/GoogleApis/CalendarManager.cs b/src/Yavsc.Server/Services/GoogleApis/CalendarManager.cs index 00f5a9b2..f91b3393 100644 --- a/src/Yavsc.Server/Services/GoogleApis/CalendarManager.cs +++ b/src/Yavsc.Server/Services/GoogleApis/CalendarManager.cs @@ -197,7 +197,7 @@ namespace Yavsc.Services if (credential.IsCreateScopedRequired) { credential = credential.CreateScoped(scopesCalendar); - }/* + }/* var credential = await GoogleHelpers.GetCredentialForApi(new string [] { scopeCalendar }); if (credential.IsCreateScopedRequired) {