From ec7982471e63af9f7fce40845bc8199fb8117a08 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Sat, 13 Jul 2024 21:59:55 +0200 Subject: [PATCH] Fixed controller adding from Api library --- .gitignore | 1 - DatabaseTest/.gitignore | 1 - DatabaseTest/Controllers/TestController.cs | 4 +- DatabaseTest/DatabaseContext.cs | 2 +- DatabaseTest/Program.cs | 12 +-- DatabaseTest/test.db | Bin 45056 -> 0 bytes HopFrame.Api/ControllerExtensions.cs | 13 --- HopFrame.Api/Extensions/MvcExtensions.cs | 86 ++++++++++++++++++ .../Extensions/ServiceCollectionExtensions.cs | 15 +++ 9 files changed, 108 insertions(+), 26 deletions(-) delete mode 100644 DatabaseTest/test.db delete mode 100644 HopFrame.Api/ControllerExtensions.cs create mode 100644 HopFrame.Api/Extensions/MvcExtensions.cs create mode 100644 HopFrame.Api/Extensions/ServiceCollectionExtensions.cs diff --git a/.gitignore b/.gitignore index add57be..9a682c8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,3 @@ bin/ obj/ /packages/ riderModule.iml -/_ReSharper.Caches/ \ No newline at end of file diff --git a/DatabaseTest/.gitignore b/DatabaseTest/.gitignore index 15d40be..ab7b4dc 100644 --- a/DatabaseTest/.gitignore +++ b/DatabaseTest/.gitignore @@ -2,4 +2,3 @@ bin Migrations appsettings.Development.json -test.db diff --git a/DatabaseTest/Controllers/TestController.cs b/DatabaseTest/Controllers/TestController.cs index 148829b..1b78deb 100644 --- a/DatabaseTest/Controllers/TestController.cs +++ b/DatabaseTest/Controllers/TestController.cs @@ -1,4 +1,3 @@ -using HopFrame.Api.Controller; using HopFrame.Security.Authorization; using HopFrame.Security.Claims; using Microsoft.AspNetCore.Mvc; @@ -6,7 +5,8 @@ using Microsoft.AspNetCore.Mvc; namespace DatabaseTest.Controllers; [ApiController] -public class TestController(DatabaseContext context, ITokenContext userContext) : SecurityController(context) { +[Route("test")] +public class TestController(ITokenContext userContext) : ControllerBase { [HttpGet("permissions"), Authorized] public ActionResult> Permissions() { diff --git a/DatabaseTest/DatabaseContext.cs b/DatabaseTest/DatabaseContext.cs index e386a1b..c43f7e8 100644 --- a/DatabaseTest/DatabaseContext.cs +++ b/DatabaseTest/DatabaseContext.cs @@ -7,6 +7,6 @@ public class DatabaseContext : HopDbContextBase { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); - optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\DatabaseTest\\test.db;Mode=ReadWrite;"); + optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\DatabaseTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); } } \ No newline at end of file diff --git a/DatabaseTest/Program.cs b/DatabaseTest/Program.cs index 8cc3933..845e92a 100644 --- a/DatabaseTest/Program.cs +++ b/DatabaseTest/Program.cs @@ -1,22 +1,18 @@ using DatabaseTest; -using HopFrame.Api; -using HopFrame.Api.Controller; -using HopFrame.Security.Authentication; +using HopFrame.Api.Extensions; using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); // Add services to the container. -builder.Services.AddControllers() - .AddController>(); +builder.Services.AddControllers(); +builder.Services.AddHopFrame(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddDbContext(); -builder.Services.AddHopFrameAuthentication(); -//builder.Logging.AddFilter>(options => options == LogLevel.None); builder.Services.AddSwaggerGen(c => { c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { @@ -51,7 +47,7 @@ if (app.Environment.IsDevelopment()) { app.UseSwaggerUI(); } -//app.UseHttpsRedirection(); +app.UseHttpsRedirection(); app.UseAuthorization(); diff --git a/DatabaseTest/test.db b/DatabaseTest/test.db deleted file mode 100644 index 37ca2d0ac8c2dd92207a2eecccaa9064bdbcf99e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45056 zcmeI*+fUn890zba;Tj6wTSTR89%vE>ocex2s#ca|TnY)$q$`@H%#Kf5uOSX`D5ZO% zl`8Fhf5xW%4cqgiNmC!Xw>|B3kK1F9orGK(P*A0bR$qf1U(Y$ePi%*rW1Bm>TV8|k zWxsx4H+Y5lfMHqY7SA&bbDj26v~PE#bY!GGL0{Rf@$*KnGpR>EOmqJ+iNpyr^9T3y z^vmg|*Pc%orXFAWI&m^}`@9V?9|91700bZa0SG|gJrg+1O^zpLXW6GG4cn=ZwYq;) z3!1}3dM~q@&+z%x&$lxCTyy3ezc8KPX*ZX(56B#!&)m!N*&OW)TU&fOm%WqUTiwX! z`MI6j#r7sUdmG!Ud;9$D%>Hs~>n}*zKB_e4c)D(8Ewgu)MrVbfRQGBP&#$&~p*ggd zrt8FR5OZ-3;i^#=qVE~$3Wbp@3>xPy>;3t* z7hmA9I5C#InLN)UDrixPUM5esMw>fB5NYK7hol-bhhx1S&6ypLXu7ZH{U+^g2B73m zYII*ZZ&wHl_lEcokuQy1v?nx+QzUedj}gexZKip3S?Q z`PD)`w~?iJZD+FiHeF}!JbB!IB(+z%5Pz+1SI;>NPw%ngNyA{D=A!6}#mtx6-u=2A z9?-$M7c~6($-tShUXg+8bZpMjd}9acw>c-FE~R$JJ9XbZDmCuXb3xbHr*)2_XPAxH zSn?a=yd!F0K1FHZ>^S{2nFv2orfDDJeqp%3=l~rAAOHafKmY;|fB*y_009U<00LK2 z;KNwlNXnwDiiV^}nrcZ#tFF;Zi7DeFHg0tmtE#0K#f_@h@a#&oJVB$1albL#-*kWu z0uX=z1Rwwb2tWV=5P$##AOL|YFEAT7*nu?xvDvsadA6jd5+H2bW3vtwPZPh zqv@6)I+{ZyyF_eJ3cnf)q9I5MFPST{ydvu{BB-(= z2{sXJK{XWJaa38c$w_wZSim0U&P1Q`;|F!O~P!P|L1LGtp#07Bx*N znTADgjK6$NlDZ-rDN)faLy@T6%ZWnTF(gybWLL0MT^CeMHwDv_%7U!RWlOXTTe0=a z=Ok+@qLfliN!Bfk<`n9gx=~g%M-w#5mFTq#Wg3%WI)dxSZn>=Jwrk68k&~gCT6q6| zbp8Je?gjUpdmc`rg8&2|009U<00Izz00bZa0SG|gasrFP)PRgE#0%^&6&T@T`*(+_ ze~8f)7lx@mIBWl}%)Gi>WLO&l5P$##AOHafKmY;|fB*y_a3utOEPP^-^f34TSB^?{ zir$f5BjMPsitUoBV;>38tdvUvXGzPXb9Zw!l?1sPn~$D2zMIP&ANv`9+gr=t*z|45 z*Vn7}w{P~|zu$b8fTGgt6jYh2G|Mzhn|+1&)mEA4*qdb{U)49ZOWyJRzGNMyYsY)* zIg;LNc)JhkPjdd|`a?6Tu95Z4lDOMfrk=+UoVEYI;_&_dO6;~M1Oy-e0SG_<0uX=z z1Rwwb2tXhdSRAHCBWnL2rkdfb{r^wsLI45~fB*y_009U<00Izz00bcL&Ix?VjwUCW xbo4(0dap?s-2VUXI~O4e3;_s000Izz00bZa0SG_<0uX?}#R3!Y(this IMvcBuilder builder) where TController : ControllerBase { - //TODO: Change implementation method - return builder.AddApplicationPart(typeof(TController).Assembly); - } - -} \ No newline at end of file diff --git a/HopFrame.Api/Extensions/MvcExtensions.cs b/HopFrame.Api/Extensions/MvcExtensions.cs new file mode 100644 index 0000000..d176de7 --- /dev/null +++ b/HopFrame.Api/Extensions/MvcExtensions.cs @@ -0,0 +1,86 @@ +//Source: https://gist.github.com/damianh/5d69be0e3004024f03b6cc876d7b0bd3 + +using System.Reflection; +using Microsoft.AspNetCore.Mvc.ApplicationParts; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.Extensions.DependencyInjection; +using IMvcCoreBuilder = Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder; + +namespace HopFrame.Api.Extensions; + +public static class MvcExtensions { + /// + /// Finds the appropriate controllers + /// + /// The manager for the parts + /// The controller types that are allowed. + public static void UseSpecificControllers(this ApplicationPartManager partManager, params Type[] controllerTypes) { + partManager.FeatureProviders.Add(new InternalControllerFeatureProvider()); + //partManager.ApplicationParts.Clear(); + partManager.ApplicationParts.Add(new SelectedControllersApplicationParts(controllerTypes)); + } + + /// + /// Only allow selected controllers + /// + /// The builder that configures mvc core + /// The controller types that are allowed. + public static IMvcCoreBuilder + UseSpecificControllers(this IMvcCoreBuilder mvcCoreBuilder, params Type[] controllerTypes) => + mvcCoreBuilder.ConfigureApplicationPartManager(partManager => + partManager.UseSpecificControllers(controllerTypes)); + + /// + /// Only instantiates selected controllers, not all of them. Prevents application scanning for controllers. + /// + private class SelectedControllersApplicationParts : ApplicationPart, IApplicationPartTypeProvider { + public SelectedControllersApplicationParts() { + Name = "Only allow selected controllers"; + } + + public SelectedControllersApplicationParts(Type[] types) { + Types = types.Select(x => x.GetTypeInfo()).ToArray(); + } + + public override string Name { get; } + + public IEnumerable Types { get; } + } + + /// + /// Ensure that internal controllers are also allowed. The default ControllerFeatureProvider hides internal controllers, but this one allows it. + /// + private class InternalControllerFeatureProvider : ControllerFeatureProvider { + private const string ControllerTypeNameSuffix = "Controller"; + + /// + /// Determines if a given is a controller. The default ControllerFeatureProvider hides internal controllers, but this one allows it. + /// + /// The candidate. + /// true if the type is a controller; otherwise false. + protected override bool IsController(TypeInfo typeInfo) { + if (!typeInfo.IsClass) { + return false; + } + + if (typeInfo.IsAbstract) { + return false; + } + + if (typeInfo.ContainsGenericParameters) { + return false; + } + + if (typeInfo.IsDefined(typeof(Microsoft.AspNetCore.Mvc.NonControllerAttribute))) { + return false; + } + + if (!typeInfo.Name.EndsWith(ControllerTypeNameSuffix, StringComparison.OrdinalIgnoreCase) && + !typeInfo.IsDefined(typeof(Microsoft.AspNetCore.Mvc.ControllerAttribute))) { + return false; + } + + return true; + } + } +} \ No newline at end of file diff --git a/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs b/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..6d0e3d2 --- /dev/null +++ b/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,15 @@ +using HopFrame.Api.Controller; +using HopFrame.Database; +using HopFrame.Security.Authentication; +using Microsoft.Extensions.DependencyInjection; + +namespace HopFrame.Api.Extensions; + +public static class ServiceCollectionExtensions { + + public static void AddHopFrame(this IServiceCollection services) where TDbContext : HopDbContextBase { + services.AddMvcCore().UseSpecificControllers(typeof(SecurityController)); + services.AddHopFrameAuthentication(); + } + +}