Added backend
This commit is contained in:
148
gswi/Controllers/AuthController.cs
Normal file
148
gswi/Controllers/AuthController.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using gswi.Interface.Services;
|
||||
using gswi.Model.DTOs;
|
||||
using gswi.Share.Common;
|
||||
|
||||
namespace gswi.Controllers
|
||||
{
|
||||
[Route("api/auth")]
|
||||
[ApiController]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
private readonly IAuthService _authService;
|
||||
|
||||
public AuthController(
|
||||
IAuthService authServce
|
||||
)
|
||||
{
|
||||
_authService = authServce;
|
||||
}
|
||||
|
||||
/* Data requests */
|
||||
// Get /api/auth/users
|
||||
[HttpGet("users")]
|
||||
[Authorize]
|
||||
public async Task<List<AuthUserDTO>> GetAllAuthUsers()
|
||||
{
|
||||
return await _authService.GetAllAuthUsersAsync();
|
||||
}
|
||||
|
||||
// POST /api/auth/users/get/filtered
|
||||
[HttpPost("users/get/filtered")]
|
||||
[Authorize]
|
||||
public async Task<GetFilteredAuthUsersResultDTO> GetFilteredAuthUsers(AuthUserSelectCriterion selectCriterion)
|
||||
{
|
||||
return await _authService.GetFilteredAuthUsersAsync(selectCriterion);
|
||||
}
|
||||
|
||||
// Get /api/auth/users/get/<mail>
|
||||
[HttpGet("users/get/{email}")]
|
||||
[Authorize]
|
||||
public async Task<AuthUserDTO> GetUserFromEMail(string email)
|
||||
{
|
||||
return await _authService.GetAuthUserByEMailAsync(email);
|
||||
}
|
||||
|
||||
// Get /api/auth/users/find/<mail>
|
||||
[HttpGet("users/find/{email}")]
|
||||
[Authorize]
|
||||
public async Task<AuthUserDTO> FindUserFromEMail(string email)
|
||||
{
|
||||
return await _authService.FindAuthUserByEMailAsync(email);
|
||||
}
|
||||
|
||||
/* Auth requests */
|
||||
// POST /api/auth/register
|
||||
[HttpPost("register")]
|
||||
public async Task Register(AuthUserDTO userDTO)
|
||||
{
|
||||
await _authService.AddAuthUserAsync(userDTO);
|
||||
}
|
||||
|
||||
// POST /api/auth/register/<id>
|
||||
[HttpPost("register/{id}")]
|
||||
public async Task<bool> ConfirmEMail(string id)
|
||||
{
|
||||
return await _authService.ConfirmEMail(id);
|
||||
}
|
||||
|
||||
// POST /api/auth/login
|
||||
[HttpPost("login")]
|
||||
public async Task<TokenDTO> Login(AuthUserDTO userDTO)
|
||||
{
|
||||
return await _authService.Login(userDTO);
|
||||
}
|
||||
|
||||
// POST /api/auth/forgot-password
|
||||
[HttpPost("forgot-password")]
|
||||
public async Task ForgotPassword([FromBody] string email)
|
||||
{
|
||||
await _authService.ForgotPassword(email);
|
||||
}
|
||||
|
||||
// POST /api/auth/confirm-forgot-password
|
||||
[HttpPost("confirm-forgot-password")]
|
||||
public async Task<EMailStringDTO> ConfirmForgotPassword([FromBody] string id)
|
||||
{
|
||||
return await _authService.ConfirmForgotPassword(id);
|
||||
}
|
||||
|
||||
// POST /api/auth/reset-password
|
||||
[HttpPost("reset-password")]
|
||||
public async Task ResetPassword(ResetPasswordDTO rpDTO)
|
||||
{
|
||||
await _authService.ResetPassword(rpDTO);
|
||||
}
|
||||
|
||||
// POST /api/auth/update-user
|
||||
[HttpPost("update-user")]
|
||||
public async Task UpdateUser(UpdateUserDTO updateUserDTO)
|
||||
{
|
||||
await _authService.UpdateUser(updateUserDTO);
|
||||
}
|
||||
|
||||
// POST /api/auth/update-user-as-admin
|
||||
[HttpPost("update-user-as-admin")]
|
||||
[Authorize]
|
||||
public async Task UpdateUserAsAdmin(AdminUpdateUserDTO updateUserDTO)
|
||||
{
|
||||
await _authService.UpdateUserAsAdmin(updateUserDTO);
|
||||
}
|
||||
|
||||
// POST /api/auth/refresh
|
||||
[HttpPost("refresh")]
|
||||
public async Task<TokenDTO> Refresh(TokenDTO tokenDTO)
|
||||
{
|
||||
return await _authService.Refresh(tokenDTO);
|
||||
}
|
||||
|
||||
// POST /api/auth/revoke
|
||||
[HttpPost("revoke")]
|
||||
public async Task Revoke(TokenDTO tokenDTO)
|
||||
{
|
||||
await _authService.Revoke(tokenDTO);
|
||||
}
|
||||
|
||||
// POST /api/auth/delete-user
|
||||
[HttpPost("delete-user")]
|
||||
public async Task DeleteAuthUserAsync(AuthUserDTO userDTO)
|
||||
{
|
||||
await _authService.DeleteAuthUserAsync(userDTO);
|
||||
}
|
||||
|
||||
// POST /api/auth/delete-user
|
||||
[HttpPost("delete-user-by-mail/{mail}")]
|
||||
public async Task DeleteAuthUserByEMailAsync(string mail)
|
||||
{
|
||||
await _authService.DeleteAuthUserByEMailAsync(mail);
|
||||
}
|
||||
}
|
||||
}
|
92
gswi/Controllers/GUIController.cs
Normal file
92
gswi/Controllers/GUIController.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using gswi.Configuration;
|
||||
using gswi.Model.DTOs;
|
||||
using gswi.SMTP.Interface;
|
||||
using gswi.SMTP.Model;
|
||||
|
||||
namespace gswi.Controllers
|
||||
{
|
||||
[Route("api/gui")]
|
||||
[ApiController]
|
||||
public class GUIController : ControllerBase
|
||||
{
|
||||
private APISettings _apiSettings;
|
||||
private DatabaseSettings _databaseSettings;
|
||||
private AuthentificationSettings _authSettings;
|
||||
private EMailSettings _mailSettings;
|
||||
private FrontendSettings _frontendSettings;
|
||||
private IHostEnvironment _env;
|
||||
private readonly ISMTPClient _smtpClient;
|
||||
|
||||
public GUIController(
|
||||
APISettings apiSettings,
|
||||
DatabaseSettings databaseSettings,
|
||||
AuthentificationSettings authSettings,
|
||||
EMailSettings mailSettings,
|
||||
FrontendSettings frontendSettings,
|
||||
IHostEnvironment env,
|
||||
ISMTPClient smtpClient
|
||||
)
|
||||
{
|
||||
this._apiSettings = apiSettings;
|
||||
this._databaseSettings = databaseSettings;
|
||||
this._authSettings = authSettings;
|
||||
this._mailSettings = mailSettings;
|
||||
this._frontendSettings = frontendSettings;
|
||||
this._env = env;
|
||||
this._smtpClient = smtpClient;
|
||||
}
|
||||
|
||||
// GET /api/gui/api-version
|
||||
[HttpGet("api-version")]
|
||||
public ApiVersionDTO GetApiVersion()
|
||||
{
|
||||
return new ApiVersionDTO()
|
||||
{
|
||||
Major = this._apiSettings.ApiVersion.Major,
|
||||
Minor = this._apiSettings.ApiVersion.Minor,
|
||||
Micro = this._apiSettings.ApiVersion.Micro
|
||||
};
|
||||
}
|
||||
|
||||
// GET /api/gui/settings
|
||||
[HttpGet("settings")]
|
||||
[Authorize]
|
||||
public SettingsDTO GetSettingsDTO()
|
||||
{
|
||||
return new SettingsDTO()
|
||||
{
|
||||
ApiVersion = this._apiSettings.ApiVersion.ToString(),
|
||||
ConfigPath = this._env.ContentRootPath,
|
||||
WebBaseURL = this._frontendSettings.URL,
|
||||
ApiBaseURL = "",
|
||||
|
||||
TokenExpireTime = this._authSettings.TokenExpireTime,
|
||||
RefreshTokenExpireTime = this._authSettings.RefreshTokenExpireTime,
|
||||
|
||||
MailUser = this._mailSettings.Username,
|
||||
MailPort = this._mailSettings.MailServerPort,
|
||||
MailHost = this._mailSettings.MailServerAddress,
|
||||
MailTransceiver = this._mailSettings.FromName,
|
||||
MailTransceiverAddress = this._mailSettings.FromAddress
|
||||
};
|
||||
}
|
||||
|
||||
// POST /api/gui/send-test-mail/<email>
|
||||
[HttpPost("send-test-mail/{email}")]
|
||||
[Authorize]
|
||||
public async Task SendTestMail(string email)
|
||||
{
|
||||
await _smtpClient.SendEmailAsync(new EMail()
|
||||
{
|
||||
Receiver = email,
|
||||
Subject = $"Login counter Test E-Mail",
|
||||
Message = $"Login counter Test E-Mail"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
76
gswi/DataSeeder.cs
Normal file
76
gswi/DataSeeder.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using gswi.Data;
|
||||
using gswi.Model;
|
||||
|
||||
namespace gswi
|
||||
{
|
||||
public class DataSeeder
|
||||
{
|
||||
private readonly DatabaseContext _databaseContext;
|
||||
|
||||
public DataSeeder(DatabaseContext databaseContext)
|
||||
{
|
||||
_databaseContext = databaseContext;
|
||||
}
|
||||
|
||||
public void SeedData()
|
||||
{
|
||||
_databaseContext.Database.EnsureCreated();
|
||||
|
||||
if (!_databaseContext.AuthUsers.Any())
|
||||
{
|
||||
|
||||
var admin = new AuthUser()
|
||||
{
|
||||
FirstName = "Admin",
|
||||
LastName = "Administator",
|
||||
EMail = "admin@localhost",
|
||||
Password = ComputeHash("Administator", new SHA256CryptoServiceProvider()),
|
||||
AuthRole = AuthRoles.Admin
|
||||
};
|
||||
|
||||
var authUser = new AuthUser()
|
||||
{
|
||||
FirstName = "Max",
|
||||
LastName = "Mustermann",
|
||||
EMail = "max.mustermann@gmail.com",
|
||||
Password = ComputeHash("test1234", new SHA256CryptoServiceProvider()),
|
||||
};
|
||||
|
||||
var authUser1 = new AuthUser()
|
||||
{
|
||||
FirstName = "Max",
|
||||
LastName = "Tester",
|
||||
EMail = "max.mustermann@mustermail.com",
|
||||
Password = ComputeHash("test1234", new SHA256CryptoServiceProvider()),
|
||||
};
|
||||
|
||||
var authUser2 = new AuthUser()
|
||||
{
|
||||
FirstName = "Max",
|
||||
LastName = "Muster",
|
||||
EMail = "max.mustermann@yahoo.com",
|
||||
Password = ComputeHash("test1234", new SHA256CryptoServiceProvider()),
|
||||
};
|
||||
|
||||
_databaseContext.AuthUsers.Add(admin);
|
||||
_databaseContext.AuthUsers.Add(authUser);
|
||||
_databaseContext.AuthUsers.Add(authUser1);
|
||||
_databaseContext.AuthUsers.Add(authUser2);
|
||||
}
|
||||
_databaseContext.SaveChanges();
|
||||
}
|
||||
|
||||
public string ComputeHash(string input, HashAlgorithm algorithm)
|
||||
{
|
||||
Byte[] inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
Byte[] hashedBytes = algorithm.ComputeHash(inputBytes);
|
||||
return BitConverter.ToString(hashedBytes);
|
||||
}
|
||||
}
|
||||
}
|
55
gswi/Filters/CustomExceptionFilterAttribute.cs
Normal file
55
gswi/Filters/CustomExceptionFilterAttribute.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using NLog;
|
||||
using gswi.Model.Filters;
|
||||
|
||||
namespace gswi.Filters
|
||||
{
|
||||
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
|
||||
{
|
||||
|
||||
|
||||
private static Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public CustomExceptionFilterAttribute() { }
|
||||
|
||||
public override void OnException(ExceptionContext context)
|
||||
{
|
||||
context.Result = CreateJsonErrorResult(context);
|
||||
base.OnException(context);
|
||||
}
|
||||
|
||||
public JsonResult CreateJsonErrorResult(ExceptionContext context)
|
||||
{
|
||||
JsonResult result = null;
|
||||
|
||||
// create jsonresult
|
||||
var exception = context.Exception;
|
||||
if (exception is ServiceException)
|
||||
{
|
||||
var bex = exception as ServiceException;
|
||||
_logger.Error($"{bex.GetDetailedMessage()}");
|
||||
var error = new ErrorDto(bex.ErrorCode, bex.GetMessage());
|
||||
result = new JsonResult(error)
|
||||
{
|
||||
StatusCode = (int)HttpStatusCode.BadRequest
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var trackingId = Guid.NewGuid();
|
||||
string userMsg = $"Tracking Id: {trackingId}";
|
||||
_logger.Error(exception, userMsg);
|
||||
var error = new ErrorDto($"Tracking Id: {trackingId}");
|
||||
result = new JsonResult(error)
|
||||
{
|
||||
StatusCode = (int)HttpStatusCode.InternalServerError
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
30
gswi/HostExtensions.cs
Normal file
30
gswi/HostExtensions.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using gswi.Data;
|
||||
|
||||
namespace gswi
|
||||
{
|
||||
public static class HostExtensions
|
||||
{
|
||||
public static IHost SeedData(this IHost host)
|
||||
{
|
||||
using (var scope = host.Services.CreateScope())
|
||||
{
|
||||
var services = scope.ServiceProvider;
|
||||
var context = services.GetService<DatabaseContext>();
|
||||
|
||||
// now we have the DbContext. Run migrations
|
||||
context.Database.Migrate();
|
||||
|
||||
#if DEBUG
|
||||
// now that the database is up to date. Let's seed
|
||||
new DataSeeder(context).SeedData();
|
||||
#endif
|
||||
}
|
||||
|
||||
return host;
|
||||
}
|
||||
}
|
||||
}
|
54
gswi/JSONConverter/JsonCreationConverter.cs
Normal file
54
gswi/JSONConverter/JsonCreationConverter.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
|
||||
namespace gswi.JSONConverter
|
||||
{
|
||||
public abstract class JsonCreationConverter<T> : JsonConverter
|
||||
{
|
||||
static Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
protected abstract T Create(Type objectType, JObject jObject);
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(T).IsAssignableFrom(objectType);
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader,
|
||||
Type objectType,
|
||||
object existingValue,
|
||||
JsonSerializer serializer)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Load JObject from stream
|
||||
JObject jObject = JObject.Load(reader);
|
||||
|
||||
// Create target object based on JObject
|
||||
T target = Create(objectType, jObject);
|
||||
|
||||
// Populate the object properties
|
||||
serializer.Populate(jObject.CreateReader(), target);
|
||||
|
||||
return target;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
43
gswi/Program.cs
Normal file
43
gswi/Program.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NLog.Extensions.Logging;
|
||||
using gswi.Configuration;
|
||||
using System;
|
||||
|
||||
namespace gswi
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Configuration.HostExtensions.ChangeCurrentDirToProjectDir();
|
||||
var host = CreateHostBuilder(args).Build();
|
||||
host.LogHostingEnvironment<Program>();
|
||||
host.SeedData();
|
||||
host.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Configuration.HostExtensions.LogStartError(ex);
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
NLog.LogManager.Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
}).ConfigureLogging((hostCtx, loggingBuilder) =>
|
||||
{
|
||||
loggingBuilder.SetMinimumLevel(LogLevel.Trace);
|
||||
loggingBuilder.AddNLog($"nlog-{hostCtx.HostingEnvironment.EnvironmentName}.config");
|
||||
});
|
||||
}
|
||||
}
|
28
gswi/Properties/launchSettings.json
Normal file
28
gswi/Properties/launchSettings.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:50843",
|
||||
"sslPort": 44360
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchUrl": "weatherforecast",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"login_counter": {
|
||||
"commandName": "Project",
|
||||
"launchUrl": "weatherforecast",
|
||||
"environmentVariables": {
|
||||
"DOTNET_ENVIRONMENT": "development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||
}
|
||||
}
|
||||
}
|
186
gswi/Startup.cs
Normal file
186
gswi/Startup.cs
Normal file
@@ -0,0 +1,186 @@
|
||||
using System.Text;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using NLog.Extensions.Logging;
|
||||
using NLog;
|
||||
using gswi.Configuration;
|
||||
using gswi.CredentialManager;
|
||||
using gswi.Data;
|
||||
using gswi.Data.Repositories;
|
||||
using gswi.Filters;
|
||||
using gswi.Interface.Repositories;
|
||||
using gswi.Interface.Services;
|
||||
using gswi.Service;
|
||||
using gswi.SMTP.Interface;
|
||||
using gswi.SMTP.Service;
|
||||
using gswi.SignalR;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
|
||||
namespace gswi
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public IConfiguration Configuration { get; }
|
||||
private static Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public Startup(IHostEnvironment env)
|
||||
{
|
||||
try
|
||||
{
|
||||
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
|
||||
if (string.IsNullOrEmpty(environmentName))
|
||||
environmentName = "production";
|
||||
var builder = new ConfigurationBuilder().SetBasePath(env.ContentRootPath)
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
|
||||
.AddJsonFile($"appsettings.{System.Net.Dns.GetHostName()}.json", optional: true)
|
||||
.AddEnvironmentVariables();
|
||||
|
||||
Configuration = builder.Build();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddLogging(builder =>
|
||||
{
|
||||
builder.ClearProviders();
|
||||
builder.AddConfiguration(Configuration.GetSection("Logging"));
|
||||
builder.AddNLog();
|
||||
builder.AddConsole();
|
||||
});
|
||||
|
||||
var frontend = GetTypedSettingsFromSection<FrontendSettings>("Frontend");
|
||||
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("CorsPolicy", builder => builder.WithOrigins(frontend.URL)
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod()
|
||||
.AllowCredentials()
|
||||
.SetIsOriginAllowed((host) => true));
|
||||
});
|
||||
|
||||
var dbSettings = GetTypedSettingsFromSection<DatabaseSettings>("Database");
|
||||
var authSettings = GetTypedSettingsFromSection<AuthentificationSettings>("Authentification");
|
||||
var emailSettings = GetTypedSettingsFromSection<EMailSettings>("EMail");
|
||||
var apiSettings = GetTypedSettingsFromSection<APISettings>("API");
|
||||
emailSettings.Credentials = Base64.Decode(emailSettings.Credentials);
|
||||
|
||||
services.AddSingleton(dbSettings);
|
||||
services.AddSingleton(authSettings);
|
||||
services.AddSingleton(emailSettings);
|
||||
services.AddSingleton(apiSettings);
|
||||
services.AddSingleton(GetTypedSettingsFromSection<FrontendSettings>("Frontend"));
|
||||
|
||||
services.AddDbContextPool<DatabaseContext>(opt => opt.UseMySql(
|
||||
Base64.DecodeConnectionString(dbSettings.ConnectionString, dbSettings.Credentials),
|
||||
new MySqlServerVersion(new Version(10, 3, 32))
|
||||
));
|
||||
|
||||
services.AddTransient<IAuthService, AuthServiceImpl>();
|
||||
services.AddTransient<ISMTPClient, SMTPClientImpl>();
|
||||
|
||||
services.AddScoped<IUnitOfWork>((s) => s.GetRequiredService<DatabaseContext>());
|
||||
services.AddScoped<IAuthUserRepository>((s) => new AuthUserRepositoryImpl((DatabaseContext)s.GetService<IUnitOfWork>()));
|
||||
|
||||
services.AddSignalR();
|
||||
|
||||
services.AddAuthentication(opt =>
|
||||
{
|
||||
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
}).AddJwtBearer(opt =>
|
||||
{
|
||||
opt.RequireHttpsMetadata = false;
|
||||
opt.SaveToken = true;
|
||||
opt.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
|
||||
ValidIssuer = authSettings.Issuer,
|
||||
ValidAudience = authSettings.Audience,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authSettings.SecretKey))
|
||||
};
|
||||
});
|
||||
|
||||
services.AddControllers()
|
||||
.AddNewtonsoftJson(options =>
|
||||
{
|
||||
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
|
||||
// options.SerializerSettings.TypeNameHandling = TypeNameHandling.All;
|
||||
});
|
||||
|
||||
services.AddControllers(options =>
|
||||
{
|
||||
options.Filters.Add(typeof(CustomExceptionFilterAttribute));
|
||||
});
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder gswi, IWebHostEnvironment env, ILoggerFactory loggerFactory)
|
||||
{
|
||||
gswi.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||
{
|
||||
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
|
||||
});
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
gswi.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
NLog.LogManager.LoadConfiguration($"nlog-{env.EnvironmentName}.config");
|
||||
|
||||
gswi.UseCors("CorsPolicy");
|
||||
|
||||
var apiSettings = GetTypedSettingsFromSection<APISettings>("API");
|
||||
if (apiSettings.RedirectToHTTPS)
|
||||
{
|
||||
gswi.UseHttpsRedirection();
|
||||
}
|
||||
|
||||
gswi.UseRouting();
|
||||
|
||||
gswi.UseAuthentication();
|
||||
gswi.UseAuthorization();
|
||||
|
||||
gswi.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapHub<NotifyHub>("/notify");
|
||||
});
|
||||
}
|
||||
|
||||
protected SettingType GetTypedSettingsFromSection<SettingType>(string sectionName) where SettingType : new()
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = new SettingType();
|
||||
Configuration.GetSection(sectionName).Bind(settings);
|
||||
return settings;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e);
|
||||
return new SettingType();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
gswi/appsettings.json
Normal file
18
gswi/appsettings.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"RedirectToHTTPS": true,
|
||||
"ApiVersion": {
|
||||
"Major": "HEAD",
|
||||
"Minor": "0",
|
||||
"Micro": "0"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
43
gswi/gswi.csproj
Normal file
43
gswi/gswi.csproj
Normal file
@@ -0,0 +1,43 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>gswi</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="nlog-production.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="nlog-staging.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="nlog-development.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Target Name="BeforeBuildEvent" BeforeTargets="BeforeBuild">
|
||||
<Exec Command="powershell -executionpolicy remotesigned -File ./update-version.ps1" Condition="'$(OS)' == 'Windows_NT'"/>
|
||||
<Exec Command="pwsh -executionpolicy remotesigned -File ./update-version.ps1" Condition="$([MSBuild]::IsOSPlatform('Linux'))"/>
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.2"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.2"/>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0"/>
|
||||
<PackageReference Include="NLog" Version="4.7.13"/>
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0"/>
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\gswi.Service\gswi.Service.csproj"/>
|
||||
<ProjectReference Include="..\gswi.Data\gswi.Data.csproj"/>
|
||||
<ProjectReference Include="..\gswi.Configuration\gswi.Configuration.csproj"/>
|
||||
<ProjectReference Include="..\gswi.Model\gswi.Model.csproj"/>
|
||||
<ProjectReference Include="..\gswi.Interface\gswi.Interface.csproj"/>
|
||||
<ProjectReference Include="..\gswi.CredentialManager\gswi.CredentialManager.csproj"/>
|
||||
<ProjectReference Include="..\gswi.SMTP.Model\gswi.SMTP.Model.csproj"/>
|
||||
<ProjectReference Include="..\gswi.SMTP.Interface\gswi.SMTP.Interface.csproj"/>
|
||||
<ProjectReference Include="..\gswi.SMTP.Service\gswi.SMTP.Service.csproj"/>
|
||||
<ProjectReference Include="..\gswi.SignalR\gswi.SignalR.csproj"/>
|
||||
<ProjectReference Include="..\gswi.Share.Common\gswi.Share.Common.csproj"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
26
gswi/nlog-development.config
Normal file
26
gswi/nlog-development.config
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true"
|
||||
internalLogLevel="Warn"
|
||||
internalLogFile="logs/internal-nlog.txt">
|
||||
|
||||
<targets>
|
||||
<target name="login_counter-specific-file" xsi:type="AsyncWrapper" overflowAction="Grow" >
|
||||
<target xsi:type="File" archiveFileName="logs/${logger}/${logger}-lc.{##}.txt" fileName="logs/${logger}/${logger}-lc.txt"
|
||||
layout="${longdate} [${threadid}] ${level:uppercase=true} ${logger} - ${message} ${exception:format=ToString}"
|
||||
maxArchiveFiles="10" archiveNumbering="Rolling" archiveEvery="Day" />
|
||||
</target>
|
||||
<target name="common-file" xsi:type="AsyncWrapper" overflowAction="Grow" >
|
||||
<target xsi:type="File" archiveFileName="logs/login-counter.{##}.txt" fileName="logs/login-counter.txt"
|
||||
layout="${longdate} [${threadid}] ${level:uppercase=true} ${logger} - ${message} ${exception:format=ToString}"
|
||||
maxArchiveFiles="10" archiveNumbering="Rolling" archiveEvery="Day" />
|
||||
</target>
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="LC-*" minlevel="Warn" writeTo="common-file" />
|
||||
<logger name="LC-*" minlevel="Info" writeTo="gateway-specific-file" final="true"/>
|
||||
<logger name="*" minLevel="Trace" writeTo="common-file"/>
|
||||
</rules>
|
||||
</nlog>
|
26
gswi/nlog-production.config
Normal file
26
gswi/nlog-production.config
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true"
|
||||
internalLogLevel="Warn"
|
||||
internalLogFile="logs/internal-nlog.txt">
|
||||
|
||||
<targets>
|
||||
<target name="login_counter-specific-file" xsi:type="AsyncWrapper" overflowAction="Grow" >
|
||||
<target xsi:type="File" archiveFileName="logs/${logger}/${logger}-lc.{##}.txt" fileName="logs/${logger}/${logger}-lc.txt"
|
||||
layout="${longdate} [${threadid}] ${level:uppercase=true} ${logger} - ${message} ${exception:format=ToString}"
|
||||
maxArchiveFiles="10" archiveNumbering="Rolling" archiveEvery="Day" />
|
||||
</target>
|
||||
<target name="common-file" xsi:type="AsyncWrapper" overflowAction="Grow" >
|
||||
<target xsi:type="File" archiveFileName="logs/login-counter.{##}.txt" fileName="logs/login-counter.txt"
|
||||
layout="${longdate} [${threadid}] ${level:uppercase=true} ${logger} - ${message} ${exception:format=ToString}"
|
||||
maxArchiveFiles="10" archiveNumbering="Rolling" archiveEvery="Day" />
|
||||
</target>
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="LC-*" minlevel="Warn" writeTo="common-file" />
|
||||
<logger name="LC-*" minlevel="Trace" writeTo="gateway-specific-file" final="true"/>
|
||||
<logger name="*" minLevel="Trace" writeTo="common-file"/>
|
||||
</rules>
|
||||
</nlog>
|
26
gswi/nlog-staging.config
Normal file
26
gswi/nlog-staging.config
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true"
|
||||
internalLogLevel="Warn"
|
||||
internalLogFile="logs/internal-nlog.txt">
|
||||
|
||||
<targets>
|
||||
<target name="login_counter-specific-file" xsi:type="AsyncWrapper" overflowAction="Grow" >
|
||||
<target xsi:type="File" archiveFileName="logs/${logger}/${logger}-lc.{##}.txt" fileName="logs/${logger}/${logger}-lc.txt"
|
||||
layout="${longdate} [${threadid}] ${level:uppercase=true} ${logger} - ${message} ${exception:format=ToString}"
|
||||
maxArchiveFiles="10" archiveNumbering="Rolling" archiveEvery="Day" />
|
||||
</target>
|
||||
<target name="common-file" xsi:type="AsyncWrapper" overflowAction="Grow" >
|
||||
<target xsi:type="File" archiveFileName="logs/login-counter.{##}.txt" fileName="logs/login-counter.txt"
|
||||
layout="${longdate} [${threadid}] ${level:uppercase=true} ${logger} - ${message} ${exception:format=ToString}"
|
||||
maxArchiveFiles="10" archiveNumbering="Rolling" archiveEvery="Day" />
|
||||
</target>
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="LC-*" minlevel="Warn" writeTo="common-file" />
|
||||
<logger name="LC-*" minlevel="Trace" writeTo="gateway-specific-file" final="true"/>
|
||||
<logger name="*" minLevel="Trace" writeTo="common-file"/>
|
||||
</rules>
|
||||
</nlog>
|
52
gswi/update-version.ps1
Normal file
52
gswi/update-version.ps1
Normal file
@@ -0,0 +1,52 @@
|
||||
#! /snap/bin/pwsh
|
||||
|
||||
function Get-VersionFromBranch {
|
||||
$branch = git rev-parse --abbrev-ref HEAD
|
||||
$versions = $branch.Split('.')
|
||||
$major = "0"
|
||||
$minor = "0"
|
||||
$micro = "0"
|
||||
|
||||
if ($versions.Count -gt 0) {
|
||||
$major = $versions[0]
|
||||
}
|
||||
|
||||
if ($versions.Count -gt 1) {
|
||||
$minor = $versions[1]
|
||||
}
|
||||
|
||||
if ($versions.Count -gt 2) {
|
||||
$micro = $versions[2]
|
||||
}
|
||||
|
||||
return $major, $minor, $micro
|
||||
}
|
||||
|
||||
function Get-VersionAsJSON([string]$major, [string]$minor, [string]$micro) {
|
||||
return @{
|
||||
"Major" = "$major"
|
||||
"Minor" = "$minor"
|
||||
"Micro" = "$micro"
|
||||
} | ConvertTo-Json
|
||||
}
|
||||
|
||||
function Get-AppsettingsAsJSON() {
|
||||
return Get-Content -Raw -Path "./appsettings.json" | ConvertFrom-Json
|
||||
}
|
||||
|
||||
function Set-AppsettingsAsJSON($settings) {
|
||||
$settings | ConvertTo-Json | Out-File "./appsettings.json"
|
||||
}
|
||||
|
||||
function Set-VersionFromBranch([string]$major, [string]$minor, [string]$micro) {
|
||||
$versionJSON = Get-VersionAsJSON $major $minor $micro
|
||||
$appsettings = Get-AppsettingsAsJSON
|
||||
|
||||
$appsettings.API.ApiVersion.Major = $major
|
||||
$appsettings.API.ApiVersion.Minor = $minor
|
||||
$appsettings.API.ApiVersion.Micro = $micro
|
||||
Set-AppsettingsAsJSON $appsettings
|
||||
}
|
||||
|
||||
$res = Get-VersionFromBranch
|
||||
Set-VersionFromBranch $res[0] $res[1] $res[2]
|
Reference in New Issue
Block a user