1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

Migrated to .NET Core 5.0

This commit is contained in:
Uncled1023 2021-06-25 22:30:48 -07:00
parent 54376fcb1a
commit f5f2f4da86
55 changed files with 1575 additions and 1062 deletions

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>Teknik.Configuration</RootNamespace>
<AssemblyName>Teknik.Configuration</AssemblyName>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Teknik.ContentScanningService</AssemblyName>
<RootNamespace>Teknik.ContentScanningService</RootNamespace>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nClam" Version="4.0.1" />
<PackageReference Include="nClam" Version="5.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Teknik.GitService</AssemblyName>
<RootNamespace>Teknik.GitService</RootNamespace>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySql.Data" Version="8.0.13" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="MySql.Data" Version="8.0.25" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Teknik.IdentityServer</AssemblyName>
<RootNamespace>Teknik.IdentityServer</RootNamespace>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
@ -15,12 +15,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="IdentityServer4" Version="2.5.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.5.1" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="2.5.1" />
<PackageReference Include="Microsoft.AspNetCore.All" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
<PackageReference Include="IdentityServer4" Version="4.1.2" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="4.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
</ItemGroup>
<ItemGroup>

View File

@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -94,12 +93,7 @@ namespace Teknik.IdentityServer.Middleware
{
public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder builder, Config config)
{
var routes = new RouteBuilder(builder)
{
DefaultHandler = builder.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
};
return builder.UseMiddleware<ErrorHandlerMiddleware>(routes.Build());
return builder.UseMiddleware<ErrorHandlerMiddleware>();
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Teknik.Logging</AssemblyName>
<RootNamespace>Teknik.Logging</RootNamespace>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Teknik.MailService</AssemblyName>
<RootNamespace>Teknik.MailService</RootNamespace>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySql.Data" Version="8.0.13" />
<PackageReference Include="MySql.Data" Version="8.0.25" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>Teknik.ServiceWorker</RootNamespace>
<AssemblyName>Teknik.ServiceWorker</AssemblyName>
</PropertyGroup>

View File

@ -17,7 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.gitattributes = .gitattributes
.gitignore = .gitignore
global.json = global.json
Performance1.psess = Performance1.psess
README.md = README.md
EndProjectSection
EndProject
@ -31,7 +30,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceWorker", "ServiceWor
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityServer", "IdentityServer\IdentityServer.csproj", "{3434645B-B8B4-457A-8C85-342E6727CCEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContentScanningService", "ContentScanningService\ContentScanningService.csproj", "{491FE626-ABC8-4D00-8C7F-0849C357201A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ContentScanningService", "ContentScanningService\ContentScanningService.csproj", "{491FE626-ABC8-4D00-8C7F-0849C357201A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "5.0.7",
"commands": [
"dotnet-ef"
]
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@ using Teknik.Configuration;
using Teknik.Data;
using Microsoft.AspNetCore.Mvc;
using Teknik.Logging;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.API.Controllers
{

View File

@ -15,6 +15,7 @@ using Teknik.Data;
using Teknik.Filters;
using Teknik.Logging;
using Teknik.Utilities;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.API.V1.Controllers
{

View File

@ -16,6 +16,7 @@ using Teknik.Data;
using Teknik.Filters;
using Teknik.Logging;
using Teknik.Utilities;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.API.V1.Controllers
{

View File

@ -21,6 +21,7 @@ using Teknik.Data;
using Teknik.Filters;
using Teknik.Logging;
using Teknik.Utilities;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.API.V1.Controllers
{

View File

@ -20,6 +20,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Teknik.Logging;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.Blog.Controllers
{

View File

@ -8,6 +8,7 @@ using Teknik.Data;
using Teknik.Filters;
using Teknik.Utilities;
using Teknik.Logging;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.Dev.Controllers
{

View File

@ -21,6 +21,7 @@ using Teknik.Logging;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Diagnostics;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.Paste.Controllers
{

View File

@ -22,6 +22,7 @@ using System.Text;
using System.Threading.Tasks;
using Microsoft.SyndicationFeed;
using Teknik.Logging;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.RSS.Controllers
{

View File

@ -14,6 +14,7 @@ using Teknik.Data;
using Teknik.Filters;
using Teknik.Logging;
using Teknik.Utilities;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.Shortener.Controllers
{

View File

@ -23,6 +23,7 @@ using Microsoft.AspNetCore.Http;
using Teknik.Logging;
using Teknik.Areas.Users.Models;
using Teknik.ContentScanningService;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.Upload.Controllers
{
@ -259,7 +260,7 @@ namespace Teknik.Areas.Upload.Controllers
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
premiumAccount = userInfo.AccountType == AccountType.Premium;
}
if (!premiumAccount && upload.User != null)
if (!premiumAccount && upload.UserId != null)
{
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, upload.User.Username);
premiumAccount = userInfo.AccountType == AccountType.Premium;

View File

@ -135,5 +135,12 @@ namespace Teknik.Areas.Upload
return false;
}
public static Models.Upload GetUpload(TeknikEntities db, string url)
{
Models.Upload upload = db.Uploads.Where(up => up.Url == url).FirstOrDefault();
return upload;
}
}
}

View File

@ -36,6 +36,7 @@ using System.Security.Cryptography;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Http;
using IdentityServer4.Models;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.Users.Controllers
{

View File

@ -15,18 +15,24 @@ namespace Teknik.Areas.Users.Utility
{
public static class IdentityHelper
{
public static async Task<string> GetAccessToken(Config config)
public static async Task GetAccessToken(this HttpClient client, Config config)
{
return await GetAccessToken(config.UserConfig.IdentityServerConfig.Authority, config.UserConfig.IdentityServerConfig.ClientId, config.UserConfig.IdentityServerConfig.ClientSecret, "auth-api");
var token = await client.GetAccessToken(config.UserConfig.IdentityServerConfig.Authority, config.UserConfig.IdentityServerConfig.ClientId, config.UserConfig.IdentityServerConfig.ClientSecret, "auth-api");
client.SetBearerToken(token);
}
public static async Task<string> GetAccessToken(string authority, string clientId, string secret, string scope)
public static async Task<string> GetAccessToken(this HttpClient client, string authority, string clientId, string secret, string scope)
{
var disco = await DiscoveryClient.GetAsync(authority);
var disco = await client.GetDiscoveryDocumentAsync(authority);
if (disco.IsError) throw new Exception(disco.Error);
var tokenClient = new TokenClient(disco.TokenEndpoint, clientId, secret);
var tokenResponse = await tokenClient.RequestClientCredentialsAsync(scope);
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = clientId,
ClientSecret = secret,
Scope = scope
});
if (tokenResponse.IsError) throw new Exception(tokenResponse.Error);
@ -42,7 +48,7 @@ namespace Teknik.Areas.Users.Utility
public static async Task<IdentityResult> Get(Config config, Uri url)
{
var client = new HttpClient();
client.SetBearerToken(await GetAccessToken(config));
await client.GetAccessToken(config);
var content = await client.GetStringAsync(url);
if (!string.IsNullOrEmpty(content))
@ -56,7 +62,8 @@ namespace Teknik.Areas.Users.Utility
public static async Task<IdentityResult> Post(Config config, Uri url, object data)
{
var client = new HttpClient();
client.SetBearerToken(await GetAccessToken(config));
await client.GetAccessToken(config);
var response = await client.PostAsJsonAsync(url, data);
if (response.IsSuccessStatusCode)

View File

@ -32,6 +32,7 @@ using System.Net.Http;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.Users.Utility
{

View File

@ -24,6 +24,7 @@ using Teknik.Logging;
using Teknik.Models;
using Teknik.Utilities;
using Teknik.Utilities.Cryptography;
using Teknik.Utilities.Routing;
namespace Teknik.Areas.Vault.Controllers
{

View File

@ -52,7 +52,7 @@ namespace Teknik.Controllers
[HttpGet]
[AllowAnonymous]
[ResponseCache(Duration = 31536000, Location = ResponseCacheLocation.Any)]
public IActionResult Favicon([FromServices] IHostingEnvironment env)
public IActionResult Favicon([FromServices] IWebHostEnvironment env)
{
string imageFile = FileHelper.MapPath(env, Constants.FAVICON_PATH);
FileStream fs = new FileStream(imageFile, FileMode.Open, FileAccess.Read);
@ -63,7 +63,7 @@ namespace Teknik.Controllers
[HttpGet]
[AllowAnonymous]
[ResponseCache(Duration = 31536000, Location = ResponseCacheLocation.Any)]
public IActionResult Logo([FromServices] IHostingEnvironment env)
public IActionResult Logo([FromServices] IWebHostEnvironment env)
{
string imageFile = FileHelper.MapPath(env, Constants.LOGO_PATH);
FileStream fs = new FileStream(imageFile, FileMode.Open, FileAccess.Read);
@ -73,7 +73,7 @@ namespace Teknik.Controllers
// Get the Robots.txt
[HttpGet]
[AllowAnonymous]
public IActionResult Robots([FromServices] IHostingEnvironment env)
public IActionResult Robots([FromServices] IWebHostEnvironment env)
{
string dataDir = (string)AppDomain.CurrentDomain.GetData("DataDirectory");
string file = Path.Combine(dataDir, Constants.ROBOTS_PATH);

View File

@ -69,9 +69,9 @@ namespace Teknik.Data
// User
modelBuilder.Entity<User>()
.HasKey(u => u.UserId);
modelBuilder.Entity<User>().OwnsOne(u => u.UserSettings);
modelBuilder.Entity<User>().OwnsOne(u => u.BlogSettings);
modelBuilder.Entity<User>().OwnsOne(u => u.UploadSettings);
modelBuilder.Entity<User>().OwnsOne(u => u.UserSettings, us => us.ToTable("Users"));
modelBuilder.Entity<User>().OwnsOne(u => u.BlogSettings, bs => bs.ToTable("Users"));
modelBuilder.Entity<User>().OwnsOne(u => u.UploadSettings, us => us.ToTable("Users"));
modelBuilder.Entity<User>().HasMany(u => u.Features).WithOne(u => u.User);
modelBuilder.Entity<User>().HasMany(u => u.Uploads).WithOne(u => u.User);
modelBuilder.Entity<User>().HasMany(u => u.Pastes).WithOne(u => u.User);
@ -116,9 +116,9 @@ namespace Teknik.Data
modelBuilder.Entity<InviteCode>().ToTable("InviteCodes");
modelBuilder.Entity<UserFeature>().ToTable("UserFeatures");
// User Settings
modelBuilder.Entity<UserSettings>().ToTable("Users");
modelBuilder.Entity<BlogSettings>().ToTable("Users");
modelBuilder.Entity<UploadSettings>().ToTable("Users");
//modelBuilder.Entity<UserSettings>().ToTable("Users");
//modelBuilder.Entity<BlogSettings>().ToTable("Users");
//modelBuilder.Entity<UploadSettings>().ToTable("Users");
// Features
modelBuilder.Entity<Feature>().ToTable("Features");
// Blogs

View File

@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Teknik.Utilities.Routing;
namespace Teknik.Filters
{

View File

@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Teknik.Configuration;
using Teknik.Utilities;
using Teknik.Utilities.Routing;
namespace Teknik.Middleware
{

View File

@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Teknik.Configuration;
using Teknik.Utilities;
using Teknik.Utilities.Routing;
namespace Teknik.Middleware
{

View File

@ -2,7 +2,6 @@
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -25,15 +24,13 @@ namespace Teknik.Middleware
public class ErrorHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly IRouter _router;
public ErrorHandlerMiddleware(RequestDelegate next, IRouter router)
public ErrorHandlerMiddleware(RequestDelegate next)
{
_next = next;
_router = router;
}
public async Task Invoke(HttpContext httpContext, ILogger<Logger> logger, Config config, TeknikEntities dbContext)
public async Task Invoke(HttpContext httpContext, ILogger<Logger> logger, Config config, TeknikEntities dbContext, ErrorController errorController)
{
var statusCodeFeature = new StatusCodePagesFeature();
httpContext.Features.Set<IStatusCodePagesFeature>(statusCodeFeature);
@ -64,17 +61,13 @@ namespace Teknik.Middleware
// Detect if there is a response code or exception occured
if ((httpContext.Response.StatusCode >= 400 && httpContext.Response.StatusCode <= 600) || exception != null)
{
RouteData routeData = new RouteData();
routeData.DataTokens.Add("area", "Error");
routeData.Values.Add("controller", "Error");
routeData.Routers.Add(_router);
var routeData = httpContext.GetRouteData() ?? new RouteData();
var context = new ControllerContext();
context.HttpContext = httpContext;
context.RouteData = routeData;
context.ActionDescriptor = new Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor();
ErrorController errorController = new ErrorController(logger, config, dbContext);
errorController.ControllerContext = context;
if (httpContext.Response.StatusCode == 500 || exception != null)
@ -94,13 +87,7 @@ namespace Teknik.Middleware
{
public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder builder, Config config)
{
var routes = new RouteBuilder(builder)
{
DefaultHandler = builder.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
};
routes.BuildRoutes(config);
return builder.UseMiddleware<ErrorHandlerMiddleware>(routes.Build());
return builder.UseMiddleware<ErrorHandlerMiddleware>();
}
}
}

View File

@ -6,7 +6,9 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using Teknik.Configuration;
using Teknik.Logging;
@ -16,17 +18,32 @@ namespace Teknik
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior",
true);
BuildWebHost(args).Build().Run();
}
public static IWebHost BuildWebHost(string[] args)
public static IHostBuilder BuildWebHost(string[] args)
{
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true)
.AddCommandLine(args)
.Build();
return Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(config =>
{
config.AddJsonFile("appsettings.json", optional: true);
config.AddCommandLine(args);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging((hostingContext, logging) =>
{
string baseDir = hostingContext.HostingEnvironment.ContentRootPath;
string dataDir = Path.Combine(baseDir, "App_Data");
logging.AddProvider(new LoggerProvider(Config.Load(dataDir)));
logging.AddFilter<ConsoleLoggerProvider>("Microsoft.AspNetCore.Routing", LogLevel.Trace);
});
return WebHost.CreateDefaultBuilder(args)
/*
.UseConfiguration(config)
.UseIISIntegration()
.UseStartup<Startup>()
@ -35,8 +52,8 @@ namespace Teknik
string baseDir = hostingContext.HostingEnvironment.ContentRootPath;
string dataDir = Path.Combine(baseDir, "App_Data");
logging.AddProvider(new LoggerProvider(Config.Load(dataDir)));
})
.Build();
});
*/
}
}
}

View File

@ -8,10 +8,10 @@ by editing this MSBuild file. In order to learn more about this please visit htt
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>https://dev.teknik.io/</SiteUrlToLaunchAfterPublish>
<SiteUrlToLaunchAfterPublish>https://dev.teknik.io/Home</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>True</ExcludeApp_Data>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<ProjectGuid>1e52f0d0-9e89-4022-a905-c685ef3564e1</ProjectGuid>
<SelfContained>false</SelfContained>
<_IsPortable>true</_IsPortable>

View File

@ -11,7 +11,7 @@
"TeknikCore": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "?sub=www",
"launchUrl": "Home",
"environmentVariables": {
"ASPNETCORE_URLS": "https://localhost:8050",
"ASPNETCORE_ENVIRONMENT": "Development"
@ -22,7 +22,7 @@
"launchBrowser": true,
"launchUrl": "?sub=www",
"environmentVariables": {
"ASPNETCORE_URLS": "https://localhost:5050",
"ASPNETCORE_URLS": "https://localhost:8050",
"ASPNETCORE_ENVIRONMENT": "Production"
}
},

View File

@ -1,844 +0,0 @@
using Microsoft.AspNetCore.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Teknik.Configuration;
using Teknik.Utilities;
namespace Teknik
{
public static class Routes
{
public static void BuildRoutes(this IRouteBuilder routes, Config config)
{
routes.BuildDefaultRoutes(config);
routes.BuildAboutRoutes(config);
routes.BuildAbuseRoutes(config);
routes.BuildAdminRoutes(config);
routes.BuildAPIRoutes(config);
routes.BuildBlogRoutes(config);
routes.BuildContactRoutes(config);
routes.BuildDevRoutes(config);
routes.BuildErrorRoutes(config);
routes.BuildFAQRoutes(config);
routes.BuildHelpRoutes(config);
routes.BuildHomeRoutes(config);
routes.BuildPasteRoutes(config);
routes.BuildPodcastRoutes(config);
routes.BuildPrivacyRoutes(config);
routes.BuildRSSRoutes(config);
routes.BuildShortenerRoutes(config);
routes.BuildStatsRoutes(config);
routes.BuildTOSRoutes(config);
routes.BuildUploadRoutes(config);
routes.BuildUserRoutes(config);
routes.BuildVaultRoutes(config);
}
public static void BuildDefaultRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Default.Favicon",
domains: new List<string>() { config.Host, config.ShortenerConfig.ShortenerHost },
subDomains: new List<string>() { "*" },
template: "favicon.ico",
defaults: new { area = "Default", controller = "Default", action = "Favicon" }
);
routes.MapSubdomainRoute(
name: "Default.Logo",
domains: new List<string>() { config.Host, config.ShortenerConfig.ShortenerHost },
subDomains: new List<string>() { "*" },
template: "logo.svg",
defaults: new { area = "Default", controller = "Default", action = "Logo" }
);
routes.MapSubdomainRoute(
name: "Default.Robots",
domains: new List<string>() { config.Host, config.ShortenerConfig.ShortenerHost },
subDomains: new List<string>() { "*" },
template: "robots.txt",
defaults: new { area = "Default", controller = "Default", action = "Robots" }
);
routes.MapSubdomainRoute(
name: "Default.NotFound",
domains: new List<string>() { config.Host, config.ShortenerConfig.ShortenerHost },
subDomains: new List<string>() { "*" },
template: "{url}",
defaults: new { area = "Error", controller = "Error", action = "Http404" },
constraints: new { url = "{*url}" }
);
}
public static void BuildAboutRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "About.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "about" },
template: "",
defaults: new { area = "About", controller = "About", action = "Index" }
);
}
public static void BuildAbuseRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Abuse.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "abuse" },
template: "",
defaults: new { area = "Abuse", controller = "Abuse", action = "Index" }
);
}
public static void BuildAdminRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Admin.Dashboard",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "admin" },
template: "",
defaults: new { area = "Admin", controller = "Admin", action = "Dashboard" }
);
routes.MapSubdomainRoute(
name: "Admin.UserSearch",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "admin" },
template: "Search/Users",
defaults: new { area = "Admin", controller = "Admin", action = "UserSearch" }
);
routes.MapSubdomainRoute(
name: "Admin.UploadSearch",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "admin" },
template: "Search/Uploads",
defaults: new { area = "Admin", controller = "Admin", action = "UploadSearch" }
);
routes.MapSubdomainRoute(
name: "Admin.PasteSearch",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "admin" },
template: "Search/Pastes",
defaults: new { area = "Admin", controller = "Admin", action = "PasteSearch" }
);
routes.MapSubdomainRoute(
name: "Admin.ShortenedUrlSearch",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "admin" },
template: "Search/ShortenedUrls",
defaults: new { area = "Admin", controller = "Admin", action = "ShortenedUrlSearch" }
);
routes.MapSubdomainRoute(
name: "Admin.UserInfo",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "admin" },
template: "User/{username}",
defaults: new { area = "Admin", controller = "Admin", action = "UserInfo", username = string.Empty }
);
routes.MapSubdomainRoute(
name: "Admin.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "admin" },
template: "Action/{action}",
defaults: new { area = "Admin", controller = "Admin", action = "Dashboard" }
);
}
public static void BuildAPIRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "API.v1.Claims",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "api" },
template: "v1/Claims",
defaults: new { area = "API", controller = "AccountAPIv1", action = "GetClaims" }
);
routes.MapSubdomainRoute(
name: "API.v1.Upload",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "api" },
template: "v1/Upload",
defaults: new { area = "API", controller = "UploadAPIv1", action = "Upload" }
);
routes.MapSubdomainRoute(
name: "API.v1.Paste",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "api" },
template: "v1/Paste",
defaults: new { area = "API", controller = "PasteAPIv1", action = "Paste" }
);
routes.MapSubdomainRoute(
name: "API.v1.Shorten",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "api" },
template: "v1/Shorten",
defaults: new { area = "API", controller = "ShortenAPIv1", action = "Shorten" }
);
routes.MapSubdomainRoute(
name: "API.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "api" },
template: "",
defaults: new { area = "API", controller = "API", action = "Index" }
);
}
public static void BuildBlogRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Blog.Blog",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "blog" },
template: "{username}",
defaults: new { area = "Blog", controller = "Blog", action = "Blog", username = string.Empty }
);
routes.MapSubdomainRoute(
name: "Blog.New",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "blog" },
template: "{username}/New",
defaults: new { area = "Blog", controller = "Blog", action = "NewPost", username = string.Empty }
);
routes.MapSubdomainRoute(
name: "Blog.Edit",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "blog" },
template: "{username}/Edit/{id}",
defaults: new { area = "Blog", controller = "Blog", action = "EditPost", username = string.Empty, id = -1 }
);
routes.MapSubdomainRoute(
name: "Blog.Post",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "blog" },
template: "{username}/p/{id}",
defaults: new { area = "Blog", controller = "Blog", action = "Post", username = string.Empty, id = -1 }
);
routes.MapSubdomainRoute(
name: "Blog.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "blog" },
template: "Action/{action}",
defaults: new { area = "Blog", controller = "Blog", action = "Blog" }
);
}
public static void BuildContactRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Contact.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "contact" },
template: "",
defaults: new { area = "Contact", controller = "Contact", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Contact.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "contact" },
template: "Action/{action}",
defaults: new { area = "Contact", controller = "Contact", action = "Index" }
);
}
public static void BuildDevRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Dev.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "dev" },
template: "",
defaults: new { area = "Dev", controller = "Dev", action = "Index" }
);
}
public static void BuildErrorRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Error.HttpError",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "error" },
template: "{statusCode:int}",
defaults: new { area = "Error", controller = "Error", action = "HttpError", statusCode = 500 }
);
routes.MapSubdomainRoute(
name: "Error.Http401",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "error" },
template: "401",
defaults: new { area = "Error", controller = "Error", action = "Http401" }
);
routes.MapSubdomainRoute(
name: "Error.Http403",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "error" },
template: "403",
defaults: new { area = "Error", controller = "Error", action = "Http403" }
);
routes.MapSubdomainRoute(
name: "Error.Http404",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "error" },
template: "404",
defaults: new { area = "Error", controller = "Error", action = "Http404" }
);
routes.MapSubdomainRoute(
name: "Error.Http500",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "error" },
template: "500",
defaults: new { area = "Error", controller = "Error", action = "Http500" }
);
routes.MapSubdomainRoute(
name: "Error.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "error" },
template: "Action/{action}",
defaults: new { area = "Error", controller = "Error", action = "HttpError" }
);
}
public static void BuildFAQRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "FAQ.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "faq" },
template: "",
defaults: new { area = "FAQ", controller = "FAQ", action = "Index" }
);
}
public static void BuildHelpRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Help.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "",
defaults: new { area = "Help", controller = "Help", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Help.API",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "API/{version?}/{service?}",
defaults: new { area = "Help", controller = "Help", action = "API" }
);
routes.MapSubdomainRoute(
name: "Help.Blog",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "Blog",
defaults: new { area = "Help", controller = "Help", action = "Blog" }
);
routes.MapSubdomainRoute(
name: "Help.Git",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "Git",
defaults: new { area = "Help", controller = "Help", action = "Git" }
);
routes.MapSubdomainRoute(
name: "Help.IRC",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "IRC",
defaults: new { area = "Help", controller = "Help", action = "IRC" }
);
routes.MapSubdomainRoute(
name: "Help.Mail",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "Mail",
defaults: new { area = "Help", controller = "Help", action = "Mail" }
);
routes.MapSubdomainRoute(
name: "Help.Markdown",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "Markdown",
defaults: new { area = "Help", controller = "Help", action = "Markdown" }
);
routes.MapSubdomainRoute(
name: "Help.Mumble",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "Mumble",
defaults: new { area = "Help", controller = "Help", action = "Mumble" }
);
routes.MapSubdomainRoute(
name: "Help.RSS",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "RSS",
defaults: new { area = "Help", controller = "Help", action = "RSS" }
);
routes.MapSubdomainRoute(
name: "Help.Tools",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "Tools",
defaults: new { area = "Help", controller = "Help", action = "Tools" }
);
routes.MapSubdomainRoute(
name: "Help.Upload",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "help" },
template: "Upload",
defaults: new { area = "Help", controller = "Help", action = "Upload" }
);
}
public static void BuildHomeRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Home.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "www", string.Empty },
template: "",
defaults: new { area = "Home", controller = "Home", action = "Index" }
);
}
public static void BuildPasteRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Paste.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "paste", "p" },
template: "",
defaults: new { area = "Paste", controller = "Paste", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Paste.Simple",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "paste", "p" },
template: "Simple/{url}/{password?}",
defaults: new { area = "Paste", controller = "Paste", action = "ViewPaste", type = "Simple" }
);
routes.MapSubdomainRoute(
name: "Paste.Raw",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "paste", "p" },
template: "Raw/{url}/{password?}",
defaults: new { area = "Paste", controller = "Paste", action = "ViewPaste", type = "Raw" }
);
routes.MapSubdomainRoute(
name: "Paste.Download",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "paste", "p" },
template: "Download/{url}/{password?}",
defaults: new { area = "Paste", controller = "Paste", action = "ViewPaste", type = "Download" }
);
routes.MapSubdomainRoute(
name: "Paste.Edit",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "paste", "p" },
template: "Edit/{url}/{password?}",
defaults: new { area = "Paste", controller = "Paste", action = "Edit" }
);
routes.MapSubdomainRoute(
name: "Paste.Delete",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "paste", "p" },
template: "Delete",
defaults: new { area = "Paste", controller = "Paste", action = "Delete" }
);
routes.MapSubdomainRoute(
name: "Paste.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "paste", "p" },
template: "Action/{action}",
defaults: new { area = "Paste", controller = "Paste", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Paste.View",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "paste", "p" },
template: "{url}/{password?}",
defaults: new { area = "Paste", controller = "Paste", action = "ViewPaste", type = "Full" }
);
}
public static void BuildPodcastRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Podcast.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "podcast" },
template: "",
defaults: new { area = "Podcast", controller = "Podcast", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Podcast.View",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "podcast" },
template: "ep/{episode}",
defaults: new { area = "Podcast", controller = "Podcast", action = "View" }
);
routes.MapSubdomainRoute(
name: "Podcast.Download",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "podcast" },
template: "File/{episode}/{fileName}",
defaults: new { area = "Podcast", controller = "Podcast", action = "Download" }
);
routes.MapSubdomainRoute(
name: "Podcast.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "podcast" },
template: "Action/{action}",
defaults: new { area = "Podcast", controller = "Podcast", action = "Index" }
);
}
public static void BuildPrivacyRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Privacy.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "privacy" },
template: "",
defaults: new { area = "Privacy", controller = "Privacy", action = "Index" }
);
}
public static void BuildRSSRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "RSS.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "rss" },
template: "",
defaults: new { area = "RSS", controller = "RSS", action = "Index" }
);
routes.MapSubdomainRoute(
name: "RSS.Blog",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "rss" },
template: "Blog/{username?}",
defaults: new { area = "RSS", controller = "RSS", action = "Blog" }
);
routes.MapSubdomainRoute(
name: "RSS.Podcast",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "rss" },
template: "Podcast",
defaults: new { area = "RSS", controller = "RSS", action = "Podcast" }
);
}
public static void BuildShortenerRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Shortener.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "shorten", "s" },
template: "",
defaults: new { area = "Shortener", controller = "Shortener", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Shortener.Delete",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "shorten", "s" },
template: "Delete",
defaults: new { area = "Shortener", controller = "Shortener", action = "Delete" }
);
routes.MapSubdomainRoute(
name: "Shortener.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "shorten", "s" },
template: "Action/{action}",
defaults: new { area = "Shortener", controller = "Shortener", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Shortener.View",
domains: new List<string>() { config.ShortenerConfig.ShortenerHost, config.Host },
subDomains: new List<string>() { string.Empty, "shortened" },
template: "{url}",
defaults: new { area = "Shortener", controller = "Shortener", action = "RedirectToUrl" }
);
routes.MapSubdomainRoute(
name: "Shortener.Verify",
domains: new List<string>() { config.ShortenerConfig.ShortenerHost },
subDomains: new List<string>() { string.Empty },
template: "",
defaults: new { area = "Shortener", controller = "Shortener", action = "Verify" }
);
}
public static void BuildStatsRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Stats.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "stats" },
template: "",
defaults: new { area = "Stats", controller = "Stats", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Stats.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "stats" },
template: "Action/{action}",
defaults: new { area = "Stats", controller = "Stats", action = "Index" }
);
}
public static void BuildTOSRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "TOS.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "tos" },
template: "",
defaults: new { area = "TOS", controller = "TOS", action = "Index" }
);
}
public static void BuildUploadRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Upload.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "upload", "u" },
template: "",
defaults: new { area = "Upload", controller = "Upload", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Upload.GenerateDeleteKey",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "upload", "u", "user" },
template: "GenerateDeleteKey",
defaults: new { area = "Upload", controller = "Upload", action = "GenerateDeleteKey" }
);
routes.MapSubdomainRoute(
name: "Upload.Delete",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "upload", "u" },
template: "Delete",
defaults: new { area = "Upload", controller = "Upload", action = "Delete" }
);
routes.MapSubdomainRoute(
name: "Upload.Download",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "upload", "u" },
template: "{file}",
defaults: new { area = "Upload", controller = "Upload", action = "Download" }
);
routes.MapSubdomainRoute(
name: "Upload.DeleteByKey",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "upload", "u" },
template: "{file}/{key}",
defaults: new { area = "Upload", controller = "Upload", action = "DeleteByKey" }
);
routes.MapSubdomainRoute(
name: "Upload.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "upload", "u" },
template: "Action/{action}",
defaults: new { area = "Upload", controller = "Upload", action = "Index" }
);
}
public static void BuildUserRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "User.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "",
defaults: new { area = "User", controller = "User", action = "Index" }
);
routes.MapSubdomainRoute(
name: "User.GetPremium",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "GetPremium",
defaults: new { area = "User", controller = "User", action = "GetPremium" }
);
routes.MapSubdomainRoute(
name: "User.Register",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Register",
defaults: new { area = "User", controller = "User", action = "Register" }
);
routes.MapSubdomainRoute(
name: "User.Login",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Login",
defaults: new { area = "User", controller = "User", action = "Login" }
);
routes.MapSubdomainRoute(
name: "User.Logout",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Logout",
defaults: new { area = "User", controller = "User", action = "Logout" }
);
routes.MapSubdomainRoute(
name: "User.Settings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Settings",
defaults: new { area = "User", controller = "User", action = "Settings" }
);
routes.MapSubdomainRoute(
name: "User.AccountSettings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Settings/Account",
defaults: new { area = "User", controller = "User", action = "AccountSettings" }
);
routes.MapSubdomainRoute(
name: "User.SecuritySettings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Settings/Security",
defaults: new { area = "User", controller = "User", action = "SecuritySettings" }
);
routes.MapSubdomainRoute(
name: "User.ProfileSettings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Settings/Profile",
defaults: new { area = "User", controller = "User", action = "ProfileSettings" }
);
routes.MapSubdomainRoute(
name: "User.DeveloperSettings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Settings/Developer",
defaults: new { area = "User", controller = "User", action = "DeveloperSettings" }
);
routes.MapSubdomainRoute(
name: "User.InviteSettings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Settings/Invites",
defaults: new { area = "User", controller = "User", action = "InviteSettings" }
);
routes.MapSubdomainRoute(
name: "User.BlogSettings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Settings/Blog",
defaults: new { area = "User", controller = "User", action = "BlogSettings" }
);
routes.MapSubdomainRoute(
name: "User.UploadSettings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Settings/Uploads",
defaults: new { area = "User", controller = "User", action = "UploadSettings" }
);
routes.MapSubdomainRoute(
name: "User.ResetPassword",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "ResetPassword/{username?}",
defaults: new { area = "User", controller = "User", action = "ResetPassword" }
);
routes.MapSubdomainRoute(
name: "User.VerifyResetPassword",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "SetPassword/{username}",
defaults: new { area = "User", controller = "User", action = "VerifyResetPassword" }
);
routes.MapSubdomainRoute(
name: "User.VerifyRecoveryEmail",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "VerifyEmail/{username}",
defaults: new { area = "User", controller = "User", action = "VerifyRecoveryEmail" }
);
routes.MapSubdomainRoute(
name: "User.ViewServiceData",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "ServiceData",
defaults: new { area = "User", controller = "User", action = "ViewServiceData" }
);
routes.MapSubdomainRoute(
name: "User.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "account" },
template: "Action/{action}",
defaults: new { area = "User", controller = "User", action = "Index" }
);
routes.MapSubdomainRoute(
name: "User.ViewProfile",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "user" },
template: "{username?}",
defaults: new { area = "User", controller = "User", action = "ViewProfile" }
);
routes.MapSubdomainRoute(
name: "User.PGPKey",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "user" },
template: "{username}/PGP",
defaults: new { area = "User", controller = "User", action = "ViewRawPGP" }
);
}
public static void BuildVaultRoutes(this IRouteBuilder routes, Config config)
{
routes.MapSubdomainRoute(
name: "Vault.Index",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "vault", "v" },
template: "",
defaults: new { area = "Vault", controller = "Vault", action = "Index" }
);
routes.MapSubdomainRoute(
name: "Vault.NewVault",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "vault", "v" },
template: "Create",
defaults: new { area = "Vault", controller = "Vault", action = "NewVault" }
);
routes.MapSubdomainRoute(
name: "Vault.NewVaultFromService",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "vault", "v" },
template: "Create/{type}",
defaults: new { area = "Vault", controller = "Vault", action = "NewVaultFromService" }
);
routes.MapSubdomainRoute(
name: "Vault.EditVault",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "vault", "v" },
template: "Edit/{url}",
defaults: new { area = "Vault", controller = "Vault", action = "EditVault" }
);
routes.MapSubdomainRoute(
name: "Vault.Delete",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "vault", "v" },
template: "Delete",
defaults: new { area = "Vault", controller = "Vault", action = "Delete" }
);
routes.MapSubdomainRoute(
name: "Vault.ViewVault",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "vault", "v" },
template: "v/{id}",
defaults: new { area = "Vault", controller = "Vault", action = "ViewVault" }
);
routes.MapSubdomainRoute(
name: "Vault.Action",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "vault", "v" },
template: "Action/{action}",
defaults: new { area = "Vault", controller = "Vault", action = "Index" }
);
}
}
}

View File

@ -1,56 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Teknik.Data;
using Teknik.Utilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Teknik.Logging;
using System.IO;
using Microsoft.Extensions.Logging;
using Teknik.Configuration;
using Teknik.Middleware;
using Microsoft.AspNetCore.ResponseCompression;
using System.IO.Compression;
using System.Text;
using Microsoft.AspNetCore.Authentication.Cookies;
using IdentityServer4.Models;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Teknik.Attributes;
using Teknik.Filters;
using Microsoft.Net.Http.Headers;
using Teknik.Areas.Users.Models;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authentication;
using IdentityModel;
using Teknik.Security;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Authorization;
using System.Text.Encodings.Web;
using Microsoft.Extensions.Hosting;
using Teknik.Tracking;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Teknik.Logging;
using Teknik.Utilities.Routing;
namespace Teknik
{
public class Startup
{
public Startup(IHostingEnvironment env)
public Startup(IWebHostEnvironment env)
{
Environment = env;
}
public IHostingEnvironment Environment { get; }
public IWebHostEnvironment Environment { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
@ -80,23 +66,26 @@ namespace Teknik
if (config.DevEnvironment)
{
Environment.EnvironmentName = EnvironmentName.Development;
Environment.EnvironmentName = Environments.Development;
}
else
{
Environment.EnvironmentName = EnvironmentName.Production;
Environment.EnvironmentName = Environments.Production;
}
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = (Environment.IsDevelopment()) ? StatusCodes.Status307TemporaryRedirect : StatusCodes.Status308PermanentRedirect;
#if DEBUG
options.HttpsPort = 5050;
options.HttpsPort = 8050;
#else
options.HttpsPort = 443;
#endif
});
services.AddControllersWithViews()
.AddControllersAsServices();
services.AddHostedService<TrackingService>();
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
@ -124,7 +113,6 @@ namespace Teknik
options.Cookie.Name = "TeknikWeb";
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict;
options.Cookie.Expiration = TimeSpan.FromDays(30);
options.ExpireTimeSpan = TimeSpan.FromDays(30);
});
@ -154,9 +142,6 @@ namespace Teknik
options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict;
});
// Core MVC
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddTransient<CookieEventHandler>();
services.AddAuthentication(options =>
@ -179,7 +164,6 @@ namespace Teknik
{
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict;
options.Cookie.Expiration = TimeSpan.FromDays(30);
options.ExpireTimeSpan = TimeSpan.FromDays(30);
options.Cookie.Name = "TeknikWebAuth";
options.Cookie.Domain = CookieHelper.GenerateCookieDomain(config.Host, false, Environment.IsDevelopment());
@ -237,22 +221,26 @@ namespace Teknik
options.AddPolicy("FullAPI", p =>
{
p.AddAuthenticationSchemes("Bearer");
p.AddAuthenticationSchemes("AuthToken");
p.RequireScope("teknik-api.read");
p.RequireScope("teknik-api.write");
});
options.AddPolicy("ReadAPI", p =>
{
p.AddAuthenticationSchemes("Bearer");
p.AddAuthenticationSchemes("AuthToken");
p.RequireScope("teknik-api.read");
});
options.AddPolicy("WriteAPI", p =>
{
p.AddAuthenticationSchemes("Bearer");
p.AddAuthenticationSchemes("AuthToken");
p.RequireScope("teknik-api.write");
});
options.AddPolicy("AnyAPI", p =>
{
p.AddAuthenticationSchemes("Bearer");
p.AddAuthenticationSchemes("AuthToken");
p.RequireScope("teknik-api.read", "teknik-api.write");
});
});
@ -270,6 +258,18 @@ namespace Teknik
// Create and Migrate the database
dbContext.Database.Migrate();
// Setup static files and cache them client side
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers[HeaderNames.CacheControl] = "public,max-age=" + 31536000;
}
});
// Initiate Routing
app.UseRouting();
// Setup the HttpContext
app.UseHttpContextSetup();
@ -307,25 +307,17 @@ namespace Teknik
app.UseCSP();
app.UseSecurityHeaders();
// Setup static files and cache them client side
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers[HeaderNames.CacheControl] = "public,max-age=" + 31536000;
}
});
// Enable Cookie Policy
app.UseCookiePolicy();
// Authorize all the things!
app.UseAuthentication();
app.UseAuthorization();
// And finally, let's use MVC
app.UseMvc(routes =>
app.UseEndpoints(endpoints =>
{
routes.BuildRoutes(config);
endpoints.BuildEndpoints(config.Host, config.ShortenerConfig?.ShortenerHost);
});
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<UserSecretsId>aspnet-TeknikCore-BE9563D1-0DFB-4141-903C-287B23FF22C7</UserSecretsId>
<RootNamespace>Teknik</RootNamespace>
<AssemblyName>Teknik</AssemblyName>
@ -25,31 +25,35 @@
<None Remove="Areas\Home\Data\**" />
</ItemGroup>
<ItemGroup>
<Content Remove="App_Data\endpointMappings.json" />
</ItemGroup>
<ItemGroup>
<None Remove=".eslintrc" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IdentityServer4" Version="2.5.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.5.1" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="2.5.1" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="1.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.6" PrivateAssets="all">
<PackageReference Include="IdentityServer4" Version="4.1.2" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="4.1.2" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="5.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.7" PrivateAssets="all">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.2.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" PrivateAssets="All" />
<PackageReference Include="nClam" Version="4.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="QRCoder" Version="1.3.6" />
<PackageReference Include="TwoStepsAuthenticator" Version="1.3.2" />
<PackageReference Include="nClam" Version="5.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="QRCoder" Version="1.4.1" />
<PackageReference Include="TwoStepsAuthenticator" Version="1.4.1" />
</ItemGroup>
<ItemGroup>
@ -79,6 +83,12 @@
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<None Include="App_Data\endpointMappings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Configuration\Configuration.csproj" />
<ProjectReference Include="..\ContentScanningService\ContentScanningService.csproj" />

View File

@ -29,7 +29,7 @@
<br />
<div class="row">
<div class="col-sm-5 col-sm-offset-1 text-left text-muted">
&copy; Teknik 2013-2020 | <a href="@Url.SubRouteUrl("faq", "FAQ.Index")">FAQ</a> | <a href="@Url.SubRouteUrl("privacy", "Privacy.Index")">Privacy</a> | <a href="@Url.SubRouteUrl("tos", "TOS.Index")">TOS</a> | <a href="@Url.SubRouteUrl("abuse", "Abuse.Index")">Abuse</a> | <a href="@Url.SubRouteUrl("stats", "Stats.Index")">Statistics</a>
&copy; Teknik 2013-2021 | <a href="@Url.SubRouteUrl("faq", "FAQ.Index")">FAQ</a> | <a href="@Url.SubRouteUrl("privacy", "Privacy.Index")">Privacy</a> | <a href="@Url.SubRouteUrl("tos", "TOS.Index")">TOS</a> | <a href="@Url.SubRouteUrl("abuse", "Abuse.Index")">Abuse</a> | <a href="@Url.SubRouteUrl("stats", "Stats.Index")">Statistics</a>
</div>
<div class="col-sm-5 text-right text-muted">
<div id="pagetime" style="display:none;">

View File

@ -3,9 +3,10 @@
@using Teknik.Configuration
@using Teknik.Utilities
@using Teknik.Utilities.TagHelpers
@using Teknik.Utilities.Routing
@using Microsoft.AspNetCore.Http.Extensions
@inject Microsoft.AspNetCore.Hosting.IHostingEnvironment HostingEnvironment
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment
@inject Config Config
@addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Teknik.Tracking</AssemblyName>
<RootNamespace>Teknik.Tracking</RootNamespace>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
@ -13,8 +13,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -34,8 +34,8 @@ namespace Teknik.Utilities
{
if (!bufferOutput)
{
var bufferingFeature = context.HttpContext.Features.Get<IHttpBufferingFeature>();
bufferingFeature?.DisableResponseBuffering();
var bufferingFeature = context.HttpContext.Features.Get<IHttpResponseBodyFeature>();
bufferingFeature?.DisableBuffering();
}
return responseDelegate(context.HttpContext.Response);

View File

@ -7,6 +7,7 @@ namespace Teknik.Utilities
public const string LOGO_PATH = "images/logo-black.svg";
public const string FAVICON_PATH = "images/favicon.ico";
public const string ROBOTS_PATH = "robots.txt";
public const string ENDPOINT_MAPPING_PATH = "endpointMappings.json";
public const string LOG_FILE_NAME_PREFIX = "Teknik";
public const string LOG_FILE_EXT = ".log";

View File

@ -96,7 +96,7 @@ namespace Teknik.Utilities
return defaultExtension;
}
public static string MapPath(IHostingEnvironment env, string file)
public static string MapPath(IWebHostEnvironment env, string file)
{
var webRoot = env.WebRootPath;
return Path.Combine(webRoot, file);

View File

@ -1,29 +1,30 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace Teknik.Utilities
{
public enum IdentityClientScope
{
[DisplayName("openid")]
[Display(Name = "openid")]
[Description("The user identifier")]
[ReadOnly(true)]
openid,
[DisplayName("role")]
[Display(Name = "role")]
[Description("The user role")]
role,
[DisplayName("account-info")]
[Display(Name = "account-info")]
[Description("A user's account information")]
accountInfo,
[DisplayName("security-info")]
[Display(Name = "security-info")]
[Description("A user's security information")]
securityInfo,
[DisplayName("teknik-api.read")]
[Display(Name = "teknik-api.read")]
[Description("Read access to the Teknik API")]
teknikApiRead,
[DisplayName("teknik-api.write")]
[Display(Name = "teknik-api.write")]
[Description("Write access to the Teknik API")]
teknikApiWrite,
}

View File

@ -0,0 +1,100 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
namespace Teknik.Utilities.Routing
{
public static class EndpointHelper
{
public static void BuildEndpoints(this IEndpointRouteBuilder endpoints, string fullHost, string shortHost)
{
// Get the endpoint mappings
var mappings = GetEndpointMappings();
// Create a subdomain endpoint for each mapping
foreach (var mapping in mappings)
{
var domains = GetDomainsFromHostTypes(fullHost, shortHost, mapping.HostTypes);
var defaultObj = new ExpandoObject();
if (mapping.Defaults != null)
{
var defaults = mapping.Defaults as JObject;
foreach (var defaultVal in defaults)
{
defaultObj.TryAdd(defaultVal.Key, defaultVal.Value);
}
}
defaultObj.TryAdd("area", mapping.Area);
endpoints.MapSubdomainEndpoint(
name: mapping.Name,
domains: domains,
subDomains: mapping.SubDomains,
pattern: mapping.Pattern,
area: mapping.Area,
defaults: defaultObj,
adjustPattern: mapping.AdjustPattern ?? true
);
}
}
public static EndpointMapping GetEndpointMapping(string name)
{
var mappings = GetEndpointMappings();
return mappings.FirstOrDefault(m => m.Name == name);
}
public static List<EndpointMapping> GetEndpointMappings()
{
string dataDir = (string)AppDomain.CurrentDomain.GetData("DataDirectory");
string file = Path.Combine(dataDir, Constants.ENDPOINT_MAPPING_PATH);
if (File.Exists(file))
{
JsonSerializer serializer = new JsonSerializer();
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
using (var sr = new StreamReader(fs))
using (var jsonTextReader = new JsonTextReader(sr))
{
return (List<EndpointMapping>)serializer.Deserialize(jsonTextReader, typeof(List<EndpointMapping>));
}
}
return new List<EndpointMapping>();
}
private static List<string> GetDomainsFromHostTypes(string fullHost, string shortHost, List<HostType> hostTypes)
{
var domains = new List<string>();
if (hostTypes != null)
{
foreach (var hostType in hostTypes)
{
switch (hostType)
{
case HostType.Full:
if (!string.IsNullOrEmpty(fullHost) &&
!domains.Contains(fullHost))
domains.Add(fullHost);
break;
case HostType.Short:
if (!string.IsNullOrEmpty(shortHost) &&
!domains.Contains(shortHost))
domains.Add(shortHost);
break;
}
}
}
return domains;
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Teknik.Utilities.Routing
{
public class EndpointMapping
{
public string Name { get; set; }
public string Area { get; set; }
public string Pattern { get; set; }
public bool? AdjustPattern { get; set; }
public List<HostType> HostTypes { get; set; }
public List<string> SubDomains { get; set; }
public object Defaults { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Teknik.Utilities.Routing
{
public enum HostType
{
Full,
Short
}
}

View File

@ -0,0 +1,78 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using System.Dynamic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using System;
using System.Reflection;
using Microsoft.AspNetCore.Routing.Constraints;
namespace Teknik.Utilities.Routing
{
public static class SubdomainEndpointExtension
{
public static void MapSubdomainEndpoint(this IEndpointRouteBuilder routeBuilder, string name, string area, List<string> subDomains, List<string> domains, string pattern)
{
MapSubdomainEndpoint(routeBuilder, name, area, subDomains, domains, pattern, null, new { }, true);
}
public static void MapSubdomainEndpoint(this IEndpointRouteBuilder routeBuilder, string name, string area, List<string> subDomains, List<string> domains, string pattern, object defaults)
{
MapSubdomainEndpoint(routeBuilder, name, area, subDomains, domains, pattern, defaults, new { }, true);
}
public static void MapSubdomainEndpoint(this IEndpointRouteBuilder routeBuilder, string name, string area, List<string> subDomains, List<string> domains, string pattern, object defaults, bool adjustPattern)
{
MapSubdomainEndpoint(routeBuilder, name, area, subDomains, domains, pattern, defaults, new { }, adjustPattern);
}
public static void MapSubdomainEndpoint(this IEndpointRouteBuilder routeBuilder, string name, string area, List<string> subDomains, List<string> domains, string pattern, object defaults, object dataTokens, bool adjustPattern)
{
var env = routeBuilder.ServiceProvider.GetRequiredService<IWebHostEnvironment>();
if (env.EnvironmentName == Environments.Development)
{
// Prepend the area to the pattern
if (adjustPattern)
{
pattern = $"{area}/{pattern}";
}
routeBuilder.MapAreaControllerRoute(
name: name,
areaName: area,
pattern,
defaults: defaults,
dataTokens: dataTokens);
}
else
{
routeBuilder.MapAreaControllerRoute(
name: name,
areaName: area,
pattern.Trim('/'),
defaults: defaults,
dataTokens: dataTokens)
.RequireHost(BuildHosts(subDomains, domains));
}
}
private static string[] BuildHosts(List<string> subdomains, List<string> hosts)
{
var fullHosts = new List<string>();
foreach (var sub in subdomains)
{
foreach (var host in hosts)
{
fullHosts.Add($"{sub}.{host}");
}
}
return fullHosts.ToArray();
}
}
}

View File

@ -6,7 +6,7 @@ using System.Web;
using Microsoft.AspNetCore.Routing;
using Teknik.Utilities;
namespace Teknik.Utilities
namespace Teknik.Utilities.Routing
{
public class SubdomainRoute : Route
{

View File

@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
namespace Teknik.Utilities
namespace Teknik.Utilities.Routing
{
public static class SubdomainRouteExtension
{

View File

@ -1,12 +1,16 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Routing;
namespace Teknik.Utilities
namespace Teknik.Utilities.Routing
{
public static class UrlExtensions
{
@ -35,72 +39,33 @@ namespace Teknik.Utilities
/// <returns></returns>
public static string SubRouteUrl(this IUrlHelper url, string sub, string routeName, object routeValues, string hostOverride)
{
var linkGen = url.ActionContext.HttpContext.RequestServices.GetService<LinkGenerator>();
var env = url.ActionContext.HttpContext.RequestServices.GetService<IWebHostEnvironment>();
string host = url.ActionContext.HttpContext.Request.Host.Value;
string domain = host.GetDomain();
string rightUrl = string.Empty;
string domain = host;
// get current subdomain
string curSub = host.GetSubdomain();
// Grab the sub from parameters if it exists
string subParam = url.ActionContext.HttpContext.Request.Query["sub"]; // A subdomain specified as a query parameter takes precedence over the hostname unless on dev
// If the param is not being used, we will use the curSub
if (string.IsNullOrEmpty(subParam))
// Generate a new domain if we aren't in development
if (!env.IsEnvironment(Environments.Development) &&
!string.IsNullOrEmpty(sub))
{
if (url.ActionContext.HttpContext.Request.IsLocal())
{
subParam = sub;
}
else
{
// If we are on dev and no subparam, we need to set the subparam to the specified sub
subParam = (curSub == "dev") ? sub : string.Empty;
string firstSub = (curSub == "dev") ? "dev" : sub;
if (!string.IsNullOrEmpty(firstSub))
{
domain = firstSub + "." + domain;
}
}
domain = sub + "." + domain.GetDomain();
}
else
{
string firstSub = (curSub == "dev") ? "dev" : curSub;
if (!string.IsNullOrEmpty(firstSub))
{
domain = firstSub + "." + domain;
}
else
{
domain = host;
}
}
try
{
rightUrl = url.RouteUrl(new UrlRouteContext() { RouteName = routeName, Values = routeValues });
}
catch (ArgumentException ex)
{
}
string fullHost = string.Format("{0}://{1}", url.ActionContext.HttpContext.Request.Scheme, domain);
if (!string.IsNullOrEmpty(hostOverride))
var routeValueDict = new RouteValueDictionary(routeValues);
// Get the endpoint mapping
var mapping = EndpointHelper.GetEndpointMapping(routeName);
if (mapping != null &&
!routeValueDict.ContainsKey("area"))
{
fullHost = hostOverride.TrimEnd('/');
routeValueDict.TryAdd("area", mapping.Area);
}
string absoluteAction = string.Format("{0}{1}", fullHost, rightUrl);
if (!string.IsNullOrEmpty(subParam))
{
absoluteAction = absoluteAction.SetUrlParameter("sub", sub);
}
var path = linkGen.GetPathByAddress(url.ActionContext.HttpContext, routeName, routeValueDict);
return absoluteAction;
return $"{fullHost}{path}";
}
public static string GetUrlParameters(this string url)

View File

@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Caching.Memory;
@ -19,7 +18,7 @@ namespace Teknik.Utilities.TagHelpers
private const string VirtualFolder = "./wwwroot/";
private const string ConfigPath = "bundleconfig.json";
private readonly IHostingEnvironment _env;
private readonly IWebHostEnvironment _env;
private readonly IMemoryCache _cache;
@ -31,7 +30,7 @@ namespace Teknik.Utilities.TagHelpers
public string Src { get; set; }
public BundleTagHelper(IHostingEnvironment env, IMemoryCache cache)
public BundleTagHelper(IWebHostEnvironment env, IMemoryCache cache)
{
_env = env;
_cache = cache;

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Teknik.Utilities</AssemblyName>
<RootNamespace>Teknik.Utilities</RootNamespace>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;linux-arm;osx-x64</RuntimeIdentifiers>
@ -9,13 +9,15 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlSanitizer" Version="4.0.217" />
<PackageReference Include="Markdig" Version="0.17.1" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="HtmlSanitizer" Version="5.0.404" />
<PackageReference Include="Markdig" Version="0.25.0" />
<PackageReference Include="Mime-Detective" Version="0.0.6-beta4" />
<PackageReference Include="MySql.Data" Version="8.0.13" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.5" />
<PackageReference Include="MySql.Data" Version="8.0.25" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>

View File

@ -1,5 +1,5 @@
{
"sdk": {
"version": "2.2.401"
"version": "5.0.301"
}
}