From e40876aeb2f1b1797d50ed0264d86273fee99a52 Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 24 Apr 2024 17:16:49 +0100 Subject: [PATCH] v1.2.11.3 deployed --- Saxonite.sln | 12 +- SaxoniteCoreWeb/Base/App/SaxAppConfig.cs | 182 +++++++++--------- .../Base/App/SaxApplication_Web.cs | 17 ++ .../Base/Helpers/SaxResourceHelper_Web.cs | 56 ++++++ SaxoniteCoreWeb/SaxoniteCoreWeb.csproj | 37 ++-- .../Admin/App/SaxApplication_Admin.cs | 27 +-- .../Consoles/SaxActivityConsole_Admin.cs | 4 +- .../OrganisationController-Ajax-Activation.cs | 2 +- .../Controllers/SecurityController-Ajax.cs | 2 +- .../Online/App/SaxApplication_Online.cs | 26 +-- .../OrganisationController-Ajax-Members.cs | 2 +- .../Controllers/SecurityController-Ajax.cs | 2 +- SaxoniteStandardBase/Base/App/Sax-Config.cs | 14 ++ SaxoniteStandardBase/Base/App/Sax-Version.cs | 1 + SaxoniteStandardBase/Base/App/Sax.cs | 1 + .../Base/Consoles/SaxEmailConsole.cs | 6 +- .../Base/Helpers/SaxResourceHelper.cs | 39 +++- .../Base/Procs/SaxProcess_Base.cs | 29 +++ .../Config/appsettings.Development.json | 26 +++ .../Config/appsettings.Machine.Sarand110.json | 71 +++++++ .../Config/appsettings.Machine.Sarand602.json | 72 +++++++ .../Resources/Config/appsettings.Machine.json | 2 + .../Config/appsettings.Production.json | 19 ++ .../Resources/Config/appsettings.json | 10 + SaxoniteWebApi/.config/dotnet-tools.json | 13 ++ SaxoniteWebApi/Api/App/SaxApplication_Api.cs | 141 ++++++++++++++ .../Api/Consoles/SaxActivityConsole_Api.cs | 27 +++ .../Api/Consoles/SaxConsoleHelper_Api.cs | 84 ++++++++ .../Api/Consoles/SaxProcessConsole_Api.cs | 102 ++++++++++ .../Api/Controllers/SecurityController.cs | 39 ++++ .../Api/Controllers/SwapiControllerBase.cs | 140 ++++++++++++++ .../Api/Controllers/SystemController.cs | 39 ++++ SaxoniteWebApi/Api/Procs/SaxProcess_Api.cs | 32 +++ SaxoniteWebApi/Program.cs | 37 ++++ SaxoniteWebApi/Properties/launchSettings.json | 31 +++ SaxoniteWebApi/SaxoniteWebApi.csproj | 29 +++ SaxoniteWebApi/appsettings.Development.json | 8 + SaxoniteWebApi/appsettings.json | 9 + 38 files changed, 1222 insertions(+), 168 deletions(-) create mode 100644 SaxoniteCoreWeb/Base/Helpers/SaxResourceHelper_Web.cs create mode 100644 SaxoniteStandardBase/Resources/Config/appsettings.Development.json create mode 100644 SaxoniteStandardBase/Resources/Config/appsettings.Machine.Sarand110.json create mode 100644 SaxoniteStandardBase/Resources/Config/appsettings.Machine.Sarand602.json create mode 100644 SaxoniteStandardBase/Resources/Config/appsettings.Machine.json create mode 100644 SaxoniteStandardBase/Resources/Config/appsettings.Production.json create mode 100644 SaxoniteStandardBase/Resources/Config/appsettings.json create mode 100644 SaxoniteWebApi/.config/dotnet-tools.json create mode 100644 SaxoniteWebApi/Api/App/SaxApplication_Api.cs create mode 100644 SaxoniteWebApi/Api/Consoles/SaxActivityConsole_Api.cs create mode 100644 SaxoniteWebApi/Api/Consoles/SaxConsoleHelper_Api.cs create mode 100644 SaxoniteWebApi/Api/Consoles/SaxProcessConsole_Api.cs create mode 100644 SaxoniteWebApi/Api/Controllers/SecurityController.cs create mode 100644 SaxoniteWebApi/Api/Controllers/SwapiControllerBase.cs create mode 100644 SaxoniteWebApi/Api/Controllers/SystemController.cs create mode 100644 SaxoniteWebApi/Api/Procs/SaxProcess_Api.cs create mode 100644 SaxoniteWebApi/Program.cs create mode 100644 SaxoniteWebApi/Properties/launchSettings.json create mode 100644 SaxoniteWebApi/SaxoniteWebApi.csproj create mode 100644 SaxoniteWebApi/appsettings.Development.json create mode 100644 SaxoniteWebApi/appsettings.json diff --git a/Saxonite.sln b/Saxonite.sln index 997f4ec..3a38ba2 100644 --- a/Saxonite.sln +++ b/Saxonite.sln @@ -13,8 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardBase", "..\..\C EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardDbas", "..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj", "{E211FE36-108E-4D07-BD30-799A156DDDBB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardMob", "..\..\Common-VS\Workspace\SacsStandardMob\SacsStandardMob.csproj", "{53A962E2-F26B-4DAD-B0F0-EA0B24B520A1}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SaxoniteStandardMob", "SaxoniteStandardMob\SaxoniteStandardMob.csproj", "{89CFDAA1-15C9-45CF-8FBF-88E36E0E32CF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SaxoniteCoreWeb", "SaxoniteCoreWeb\SaxoniteCoreWeb.csproj", "{CFF91B48-04B7-4075-A5B2-FF3FC0B22BC1}" @@ -34,6 +32,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SaxoniteCoreUnitTestsOnline EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardProc", "..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj", "{E012B3D3-CF4D-4C2E-ABC6-9E3A3DAE03C5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SaxoniteWebApi", "SaxoniteWebApi\SaxoniteWebApi.csproj", "{3E1C2BE2-46C8-4D1D-A1C2-806BB1AD8A7E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -60,10 +60,6 @@ Global {E211FE36-108E-4D07-BD30-799A156DDDBB}.Debug|Any CPU.Build.0 = Debug|Any CPU {E211FE36-108E-4D07-BD30-799A156DDDBB}.Release|Any CPU.ActiveCfg = Release|Any CPU {E211FE36-108E-4D07-BD30-799A156DDDBB}.Release|Any CPU.Build.0 = Release|Any CPU - {53A962E2-F26B-4DAD-B0F0-EA0B24B520A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {53A962E2-F26B-4DAD-B0F0-EA0B24B520A1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {53A962E2-F26B-4DAD-B0F0-EA0B24B520A1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {53A962E2-F26B-4DAD-B0F0-EA0B24B520A1}.Release|Any CPU.Build.0 = Release|Any CPU {89CFDAA1-15C9-45CF-8FBF-88E36E0E32CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {89CFDAA1-15C9-45CF-8FBF-88E36E0E32CF}.Debug|Any CPU.Build.0 = Debug|Any CPU {89CFDAA1-15C9-45CF-8FBF-88E36E0E32CF}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -92,6 +88,10 @@ Global {E012B3D3-CF4D-4C2E-ABC6-9E3A3DAE03C5}.Debug|Any CPU.Build.0 = Debug|Any CPU {E012B3D3-CF4D-4C2E-ABC6-9E3A3DAE03C5}.Release|Any CPU.ActiveCfg = Release|Any CPU {E012B3D3-CF4D-4C2E-ABC6-9E3A3DAE03C5}.Release|Any CPU.Build.0 = Release|Any CPU + {3E1C2BE2-46C8-4D1D-A1C2-806BB1AD8A7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E1C2BE2-46C8-4D1D-A1C2-806BB1AD8A7E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E1C2BE2-46C8-4D1D-A1C2-806BB1AD8A7E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E1C2BE2-46C8-4D1D-A1C2-806BB1AD8A7E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SaxoniteCoreWeb/Base/App/SaxAppConfig.cs b/SaxoniteCoreWeb/Base/App/SaxAppConfig.cs index 10c5d47..a0d3d2b 100644 --- a/SaxoniteCoreWeb/Base/App/SaxAppConfig.cs +++ b/SaxoniteCoreWeb/Base/App/SaxAppConfig.cs @@ -25,6 +25,97 @@ namespace Saxonite.Net.Core.Web.Base.App PopulateConfig(configSection); } + //--------------------------------------------------------------- + // Properties. + public String Context { get; } + public List Environments { get { return new List(environments); } } + public String Instance { get; set; } = ""; + // URLs. + public class URLConfig + { + public class OnlineConfig + { + public String Root { get; set; } + } + public OnlineConfig Online { get; } = new OnlineConfig(); + } + public URLConfig URL { get; } = new URLConfig(); + // Security. + public class SecurityConfig + { + public class PasswordConfig + { + public int MinLength { get; set; } + } + public PasswordConfig Password { get; } = new PasswordConfig(); + public class SignUpConfig + { + public class ActivationConfig + { + public int EmailLinkExpiresMins = Sax.Config.Security.Activation.EmailLinkExpiresMins_Default; + } + public ActivationConfig Activation { get; } = new ActivationConfig(); + } + public SignUpConfig SignUp { get; } = new SignUpConfig(); + public class SignInConfig + { + public class PasswordRequestConfig + { + public int EmailLinkExpiresMins = Sax.Config.Security.Activation.EmailLinkExpiresMins_Default; + } + public PasswordRequestConfig PasswordRequest { get; } = new PasswordRequestConfig(); + public class KeepLoggedInConfig + { + public bool Allowed { get; set; } = Sax.Config.Security.SignIn.KeepLoggedIn.Allowed_Default; + public int CookieExpiresDays { get; set; } = Sax.Config.Security.SignIn.KeepLoggedIn.CookieExpiresDays_Default; + } + public KeepLoggedInConfig KeepLoggedIn { get; } = new KeepLoggedInConfig(); + } + public SignInConfig SignIn { get; } = new SignInConfig(); + } + public SecurityConfig Security { get; } = new SecurityConfig(); + // Email. + public class EmailConfig + { + public class SpecificEmailConfig + { + public List AddressesTo { get; } = new List(); + public List AddressesCc { get; } = new List(); + public List AddressesBcc { get; } = new List(); + } + public SpecificEmailConfig ContactUs { get; } = new SpecificEmailConfig(); + public SpecificEmailConfig Signup_Activate { get; } = new SpecificEmailConfig(); + public SpecificEmailConfig Signup_Welcome { get; } = new SpecificEmailConfig(); + public String Context { get; internal set; } + } + public EmailConfig Email { get; } = new EmailConfig(); + // Databases. + public class DatabaseConfig + { + public String Location { get; internal set; } + public String User { get; internal set; } + public String Password { get; internal set; } + } + public class DatabasesConfig + { + public Dictionary Databases { get; } = new Dictionary(); + public DatabaseConfig Core { get { return Databases.GetValue(Sax.Database.Core, new DatabaseConfig()); } } + public DatabaseConfig Support { get { return Databases.GetValue(Sax.Database.Support, new DatabaseConfig()); } } + } + public DatabasesConfig Databases { get; } = new DatabasesConfig(); + // Documents. + public class DocumentsConfig + { + public String RootFolder { get; internal set; } + } + public DocumentsConfig Documents { get; } = new DocumentsConfig(); + // Logging. + public class LoggingConfig + { + public String RootFolder { get; internal set; } + } + public LoggingConfig Logging { get; } = new LoggingConfig(); + //--------------------------------------------------------------- private void populateDefaults(SaxAppConfig defaultConfig) { @@ -146,97 +237,6 @@ namespace Saxonite.Net.Core.Web.Base.App databases.Databases.Add(databaseType, database); } - //--------------------------------------------------------------- - // Properties. - public String Context { get; } - public List Environments { get { return new List(environments); } } - public String Instance { get; set; } = ""; - // URLs. - public class URLConfig - { - public class OnlineConfig - { - public String Root { get; set; } - } - public OnlineConfig Online { get; } = new OnlineConfig(); - } - public URLConfig URL { get; } = new URLConfig(); - // Security. - public class SecurityConfig - { - public class PasswordConfig - { - public int MinLength { get; set; } - } - public PasswordConfig Password { get; } = new PasswordConfig(); - public class SignUpConfig - { - public class ActivationConfig - { - public int EmailLinkExpiresMins = Sax.Config.Security.Activation.EmailLinkExpiresMins_Default; - } - public ActivationConfig Activation { get; } = new ActivationConfig(); - } - public SignUpConfig SignUp { get; } = new SignUpConfig(); - public class SignInConfig - { - public class PasswordRequestConfig - { - public int EmailLinkExpiresMins = Sax.Config.Security.Activation.EmailLinkExpiresMins_Default; - } - public PasswordRequestConfig PasswordRequest { get; } = new PasswordRequestConfig(); - public class KeepLoggedInConfig - { - public bool Allowed { get; set; } = Sax.Config.Security.SignIn.KeepLoggedIn.Allowed_Default; - public int CookieExpiresDays { get; set; } = Sax.Config.Security.SignIn.KeepLoggedIn.CookieExpiresDays_Default; - } - public KeepLoggedInConfig KeepLoggedIn { get; } = new KeepLoggedInConfig(); - } - public SignInConfig SignIn { get; } = new SignInConfig(); - } - public SecurityConfig Security { get; } = new SecurityConfig(); - // Email. - public class EmailConfig - { - public class SpecificEmailConfig - { - public List AddressesTo { get; } = new List(); - public List AddressesCc { get; } = new List(); - public List AddressesBcc { get; } = new List(); - } - public SpecificEmailConfig ContactUs { get; } = new SpecificEmailConfig(); - public SpecificEmailConfig Signup_Activate { get; } = new SpecificEmailConfig(); - public SpecificEmailConfig Signup_Welcome { get; } = new SpecificEmailConfig(); - public String Context { get; internal set; } - } - public EmailConfig Email { get; } = new EmailConfig(); - // Databases. - public class DatabaseConfig - { - public String Location { get; internal set; } - public String User { get; internal set; } - public String Password { get; internal set; } - } - public class DatabasesConfig - { - public Dictionary Databases { get; } = new Dictionary(); - public DatabaseConfig Core { get { return Databases.GetValue(Sax.Database.Core, new DatabaseConfig()); } } - public DatabaseConfig Support { get { return Databases.GetValue(Sax.Database.Support, new DatabaseConfig()); } } - } - public DatabasesConfig Databases { get; } = new DatabasesConfig(); - // Documents. - public class DocumentsConfig - { - public String RootFolder { get; internal set; } - } - public DocumentsConfig Documents { get; } = new DocumentsConfig(); - // Logging. - public class LoggingConfig - { - public String RootFolder { get; internal set; } - } - public LoggingConfig Logging { get; } = new LoggingConfig(); - //--------------------------------------------------------------- } //======================================================================= diff --git a/SaxoniteCoreWeb/Base/App/SaxApplication_Web.cs b/SaxoniteCoreWeb/Base/App/SaxApplication_Web.cs index aab65c1..8c4d160 100644 --- a/SaxoniteCoreWeb/Base/App/SaxApplication_Web.cs +++ b/SaxoniteCoreWeb/Base/App/SaxApplication_Web.cs @@ -5,6 +5,7 @@ using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Email; using Sarand.Net.Standard.Base.IO; using Sarand.Net.Standard.Base.Utils; +using Sarand.Net.Standard.Dbas.Base; using Sarand.Net.Standard.Dbas.Data; using Saxonite.Net.Core.Web.Base.Consoles; using Saxonite.Net.Standard.Base.App; @@ -73,6 +74,22 @@ namespace Saxonite.Net.Core.Web.Base.App public IConfiguration Configuration { get; protected set; } public IConfiguration SaxConfiguration { get; protected set; } + //------------------------------------------------------------------- + // Database configuration. + protected void ConfigureDatabaseConnection(SessionContextData_Web sessionContextData, Sax.Database databaseInstance) + { + // Configure database connection. + SaxAppConfig.DatabaseConfig databaseConfig = AppConfig.Databases.Databases.GetValue(databaseInstance, new SaxAppConfig.DatabaseConfig()); + SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); + config.location = databaseConfig.Location; + config.user = databaseConfig.User; + config.pword = databaseConfig.Password; + SacsDatabase database = SacsDatabaseConsole.OpenOdbcDatabase(config); + if (database.HasErrorState()) + SaLogger.Warn(SysUtil.Fn + " " + databaseInstance.ToString() + " Database initialisation error: " + database.ErrorStateMessage); + sessionContextData.Databases.Add(databaseInstance, database); + } + //------------------------------------------------------------------- // Logging. protected void LogApplicationStart(String fn) diff --git a/SaxoniteCoreWeb/Base/Helpers/SaxResourceHelper_Web.cs b/SaxoniteCoreWeb/Base/Helpers/SaxResourceHelper_Web.cs new file mode 100644 index 0000000..731e6ac --- /dev/null +++ b/SaxoniteCoreWeb/Base/Helpers/SaxResourceHelper_Web.cs @@ -0,0 +1,56 @@ +using Sarand.Net.Standard.Base.Helpers; +using Sarand.Net.Standard.Base.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Saxonite.Net.Core.Web.Base.Helpers +{ + //======================================================================= + public static class SaxResourceHelper_Web + { + //------------------------------------------------------------------- + // Definitions. + + //------------------------------------------------------------------- + // Properties. + public static Assembly MyAssembly { get; } = typeof(SaxResourceHelper_Web).GetTypeInfo().Assembly; + + //------------------------------------------------------------------- + // Text resources. + + /// Retrieve contents of text resource in this assembly by name. + public static String GetResourceText(String resourceFilename, String partialPath = "") + { + if (!StringUtil.IsBlank(resourceFilename)) + { + String resourceText = SacsResourceHelper.GetManifestResourceAsText(MyAssembly, partialPath, resourceFilename); + if (!StringUtil.IsBlank(resourceText)) + return resourceText; + } + return ""; + } + + //------------------------------------------------------------------- + // Resource stream. + + /// + /// Retrieve stream to resource in this assembly. + /// + public static Stream GetResourceStream(String resourceFilename, String partialPath = "") + { + if (!StringUtil.IsBlank(resourceFilename)) + { + return SacsResourceHelper.GetManifestResourceStream(MyAssembly, partialPath, resourceFilename); + } + return null; + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteCoreWeb/SaxoniteCoreWeb.csproj b/SaxoniteCoreWeb/SaxoniteCoreWeb.csproj index 5254883..692d92f 100644 --- a/SaxoniteCoreWeb/SaxoniteCoreWeb.csproj +++ b/SaxoniteCoreWeb/SaxoniteCoreWeb.csproj @@ -1,28 +1,33 @@ - - net6.0 - Saxonite.Net.Core.Web - + + net6.0 + Saxonite.Net.Core.Web + - - - - - - - + + + + + + + - - - + + + + - + - + + + + + diff --git a/SaxoniteCoreWebAdmin/Admin/App/SaxApplication_Admin.cs b/SaxoniteCoreWebAdmin/Admin/App/SaxApplication_Admin.cs index 6b3f16b..efad334 100644 --- a/SaxoniteCoreWebAdmin/Admin/App/SaxApplication_Admin.cs +++ b/SaxoniteCoreWebAdmin/Admin/App/SaxApplication_Admin.cs @@ -21,6 +21,7 @@ using Saxonite.Net.Standard.Dbas.App; using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Saxonite.Net.Core.Web.Admin.App @@ -99,7 +100,6 @@ namespace Saxonite.Net.Core.Web.Admin.App /// Initialise environment - from internal (above) or unit tests. protected void InitEnvironment(IWebHostEnvironment env) { - String fn = GetType().Name + ".InitEnvironment"; Development = env.IsDevelopment(); environmentName = env.EnvironmentName; SaLogger.LogFilenamePrefix = "Sax-Web-Adm"; @@ -124,6 +124,9 @@ namespace Saxonite.Net.Core.Web.Admin.App appConfigs = SaxAppConfigHelper.ExtractAppConfigs(SaxConfiguration.GetSection("AppConfigs")); emailConfigs = SaxEmailConfigHelper.ExtractEmailConfigs(SaxConfiguration.GetSection("EmailConfigs")); LoggingRootFolder = AppConfig.Logging.RootFolder; + // Ensure root log folder ends with Admin folder. + if (!StringUtil.IsBlank(LoggingRootFolder) && !Regex.IsMatch(LoggingRootFolder, "[\\\\/]Admin$", RegexOptions.IgnoreCase)) + LoggingRootFolder = StringUtil.CombineFilePath(LoggingRootFolder, "Admin"); // Application instance. if (AppConfig.Instance.EqualsCI("Dev")) instanceType = Sax.InstanceType.Dev; @@ -139,7 +142,7 @@ namespace Saxonite.Net.Core.Web.Admin.App } if (DirectoryUtil.DirectoryExists(LoggingRootFolder)) SaLogger.LogFolder = LoggingRootFolder; - LogApplicationStart(fn); + LogApplicationStart(SysUtil.Fn); //Messages.Add($"Database location: {AppConfig.CoreDatabase.Location}"); //Messages.Add($"LoggingRootFolder: {SaLogger.LogFolder}"); @@ -155,7 +158,7 @@ namespace Saxonite.Net.Core.Web.Admin.App } catch (Exception exc) { - SaLogger.Error(fn + " " + ExceptionUtil.GetLogMessage(exc)); + SaLogger.Error(SysUtil.Fn + " " + ExceptionUtil.GetLogMessage(exc)); } // Occasional startup processing. @@ -165,22 +168,6 @@ namespace Saxonite.Net.Core.Web.Admin.App populateRegionsFromDataFile(SessionContext); } - private void ConfigureDatabaseConnection(SessionContextData_Admin sessionContextData, Sax.Database databaseInstance) - { - String fn = GetType().Name + ".ConfigureDatabaseConnection"; - - // Configure database connection. - SaxAppConfig.DatabaseConfig databaseConfig = AppConfig.Databases.Databases.GetValue(databaseInstance, new SaxAppConfig.DatabaseConfig()); - SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); - config.location = databaseConfig.Location; - config.user = databaseConfig.User; - config.pword = databaseConfig.Password; - SacsDatabase database = SacsDatabaseConsole.OpenOdbcDatabase(config); - if (database.HasErrorState()) - SaLogger.Warn(fn + " " + databaseInstance.ToString() + " Database initialisation error: " + database.ErrorStateMessage); - sessionContextData.Databases.Add(databaseInstance, database); - } - //------------------------------------------------------------------- private void GenerateDatabaseDefinitions(SaxSessionContext sessionContext) { @@ -208,7 +195,7 @@ namespace Saxonite.Net.Core.Web.Admin.App using (SaxInternals internals = new SaxInternals(sessionContext)) { SaxReferenceMgr referenceMgr = internals.ReferenceMgr; - String regionsData = SaxResourceHelper.GetTextResource(SaxResourceHelper.TextResource.Data_CountriesWithRegions_Txt); + String regionsData = SaxResourceHelper.GetResourceText(SaxResourceHelper.TextResource.Data_CountriesWithRegions_Txt); String[] regionDataValues = regionsData.Split("\n"); SysId parentRegionId = null; for (int idx = 0; idx < regionDataValues.Length; idx++) diff --git a/SaxoniteCoreWebAdmin/Admin/Consoles/SaxActivityConsole_Admin.cs b/SaxoniteCoreWebAdmin/Admin/Consoles/SaxActivityConsole_Admin.cs index 2c4d37f..1af04b8 100644 --- a/SaxoniteCoreWebAdmin/Admin/Consoles/SaxActivityConsole_Admin.cs +++ b/SaxoniteCoreWebAdmin/Admin/Consoles/SaxActivityConsole_Admin.cs @@ -1,4 +1,5 @@ using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Utils; using Saxonite.Net.Core.Web.Base.Consoles; using Saxonite.Net.Standard.Base.App; using Saxonite.Net.Standard.Base.Consoles; @@ -18,8 +19,7 @@ namespace Saxonite.Net.Core.Web.Admin.Consoles public SaxActivityConsole_Admin(SaxSessionContext sessionContext) : base(sessionContext) { - String fn = GetType().Name + ".CTR"; - SaLogger.Info(fn + ""); + SaLogger.Info(SysUtil.Fn + ""); } //------------------------------------------------------------------- diff --git a/SaxoniteCoreWebAdmin/Admin/Controllers/OrganisationController-Ajax-Activation.cs b/SaxoniteCoreWebAdmin/Admin/Controllers/OrganisationController-Ajax-Activation.cs index 8048a63..56b36b0 100644 --- a/SaxoniteCoreWebAdmin/Admin/Controllers/OrganisationController-Ajax-Activation.cs +++ b/SaxoniteCoreWebAdmin/Admin/Controllers/OrganisationController-Ajax-Activation.cs @@ -240,7 +240,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers private static void PopulateAccountActivatedEmailBody(SaxController_Admin controller, SaEmailData emailData, SaxUserAccount userAccount) { // Will need to handle culture (language/country) as and when introduced. - emailData.MessageBody = SaxResourceHelper.GetTextResource(SaxResourceHelper.TextResource.Email_Security_AccountActivated_Html); + emailData.MessageBody = SaxResourceHelper.GetResourceText(SaxResourceHelper.TextResource.Email_Security_AccountActivated_Html); emailData.HtmlBody = true; // Replace dynamic tags. diff --git a/SaxoniteCoreWebAdmin/Admin/Controllers/SecurityController-Ajax.cs b/SaxoniteCoreWebAdmin/Admin/Controllers/SecurityController-Ajax.cs index e671fed..7f9a218 100644 --- a/SaxoniteCoreWebAdmin/Admin/Controllers/SecurityController-Ajax.cs +++ b/SaxoniteCoreWebAdmin/Admin/Controllers/SecurityController-Ajax.cs @@ -394,7 +394,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers private static void PopulateRequestPasswordEmailBody(SaxController_Admin controller, SaEmailData emailData, SaxUserAccount userAccount, bool onlineContext) { // Will need to handle culture (language/country) as and when introduced. - emailData.MessageBody = SaxResourceHelper.GetTextResource(SaxResourceHelper.TextResource.Email_Security_RequestPassword_Html); + emailData.MessageBody = SaxResourceHelper.GetResourceText(SaxResourceHelper.TextResource.Email_Security_RequestPassword_Html); emailData.HtmlBody = true; // Replace dynamic tags. diff --git a/SaxoniteCoreWebOnline/Online/App/SaxApplication_Online.cs b/SaxoniteCoreWebOnline/Online/App/SaxApplication_Online.cs index a0d49f7..d56d743 100644 --- a/SaxoniteCoreWebOnline/Online/App/SaxApplication_Online.cs +++ b/SaxoniteCoreWebOnline/Online/App/SaxApplication_Online.cs @@ -19,6 +19,7 @@ using Saxonite.Net.Standard.Dbas.App; using Microsoft.Extensions.Hosting; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Utils; +using System.Text.RegularExpressions; namespace Saxonite.Net.Core.Web.Online.App { @@ -92,7 +93,6 @@ namespace Saxonite.Net.Core.Web.Online.App /// Initialise environment - from internal (above) or unit tests. protected void InitEnvironment(IWebHostEnvironment env) { - String fn = GetType().Name + ".InitEnvironment"; Development = env.IsDevelopment(); environmentName = env.EnvironmentName; SaLogger.LogFilenamePrefix = "Sax-Web-Onl"; @@ -114,6 +114,9 @@ namespace Saxonite.Net.Core.Web.Online.App appConfigs = SaxAppConfigHelper.ExtractAppConfigs(SaxConfiguration.GetSection("AppConfigs")); emailConfigs = SaxEmailConfigHelper.ExtractEmailConfigs(SaxConfiguration.GetSection("EmailConfigs")); LoggingRootFolder = AppConfig.Logging.RootFolder; + // Ensure root log folder ends with Admin folder. + if (!StringUtil.IsBlank(LoggingRootFolder) && !Regex.IsMatch(LoggingRootFolder, "[\\\\/]Online$", RegexOptions.IgnoreCase)) + LoggingRootFolder = StringUtil.CombineFilePath(LoggingRootFolder, "Online"); // Application instance. if (AppConfig.Instance.EqualsCI("Dev")) instanceType = Sax.InstanceType.Dev; @@ -129,7 +132,7 @@ namespace Saxonite.Net.Core.Web.Online.App } if (DirectoryUtil.DirectoryExists(LoggingRootFolder)) SaLogger.LogFolder = LoggingRootFolder; - LogApplicationStart(fn); + LogApplicationStart(SysUtil.Fn); // Session context - only one context available/necessary (for now). SessionContextData_Online sessionContextData = new SessionContextData_Online(new SaxSessionContext_Web(100, Sax.Application.Online)); @@ -143,27 +146,10 @@ namespace Saxonite.Net.Core.Web.Online.App } catch (Exception exc) { - SaLogger.Error(fn + " " + ExceptionUtil.GetLogMessage(exc)); + SaLogger.Error(SysUtil.Fn + " " + ExceptionUtil.GetLogMessage(exc)); } } - //------------------------------------------------------------------- - private void ConfigureDatabaseConnection(SessionContextData_Online sessionContextData, Sax.Database databaseInstance) - { - String fn = GetType().Name + ".ConfigureDatabaseConnection"; - - // Configure database connection. - SaxAppConfig.DatabaseConfig databaseConfig = AppConfig.Databases.Databases.GetValue(databaseInstance, new SaxAppConfig.DatabaseConfig()); - SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); - config.location = databaseConfig.Location; - config.user = databaseConfig.User; - config.pword = databaseConfig.Password; - SacsDatabase database = SacsDatabaseConsole.OpenOdbcDatabase(config); - if (database.HasErrorState()) - SaLogger.Warn(fn + " " + databaseInstance.ToString() + " Database initialisation error: " + database.ErrorStateMessage); - sessionContextData.Databases.Add(databaseInstance, database); - } - //------------------------------------------------------------------- } //======================================================================= diff --git a/SaxoniteCoreWebOnline/Online/Controllers/OrganisationController-Ajax-Members.cs b/SaxoniteCoreWebOnline/Online/Controllers/OrganisationController-Ajax-Members.cs index 910b8a2..abd5e04 100644 --- a/SaxoniteCoreWebOnline/Online/Controllers/OrganisationController-Ajax-Members.cs +++ b/SaxoniteCoreWebOnline/Online/Controllers/OrganisationController-Ajax-Members.cs @@ -619,7 +619,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers private void PopulateAccountActivatedEmailBody(SaEmailData emailData, SaxUserAccount userAccount) { // Will need to handle culture (language/country) as and when introduced. - emailData.MessageBody = SaxResourceHelper.GetTextResource(SaxResourceHelper.TextResource.Email_Security_AccountActivated_Html); + emailData.MessageBody = SaxResourceHelper.GetResourceText(SaxResourceHelper.TextResource.Email_Security_AccountActivated_Html); emailData.HtmlBody = true; // Replace dynamic tags. diff --git a/SaxoniteCoreWebOnline/Online/Controllers/SecurityController-Ajax.cs b/SaxoniteCoreWebOnline/Online/Controllers/SecurityController-Ajax.cs index 72c1d04..eebdec0 100644 --- a/SaxoniteCoreWebOnline/Online/Controllers/SecurityController-Ajax.cs +++ b/SaxoniteCoreWebOnline/Online/Controllers/SecurityController-Ajax.cs @@ -362,7 +362,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers private void PopulateRequestPasswordEmailBody(SaEmailData emailData, SaxUserAccount userAccount) { // Will need to handle culture (language/country) as and when introduced. - emailData.MessageBody = SaxResourceHelper.GetTextResource(SaxResourceHelper.TextResource.Email_Security_RequestPassword_Html); + emailData.MessageBody = SaxResourceHelper.GetResourceText(SaxResourceHelper.TextResource.Email_Security_RequestPassword_Html); emailData.HtmlBody = true; // Replace dynamic tags. diff --git a/SaxoniteStandardBase/Base/App/Sax-Config.cs b/SaxoniteStandardBase/Base/App/Sax-Config.cs index 2f0a3a8..65c5448 100644 --- a/SaxoniteStandardBase/Base/App/Sax-Config.cs +++ b/SaxoniteStandardBase/Base/App/Sax-Config.cs @@ -142,6 +142,20 @@ namespace Saxonite.Net.Standard.Base.App } } } + public class Api + { + public static class Session + { + public static class Cookie + { + /// Default cookie name: '.AspNetCore.Session' + public static String Name { get; } = "Saxonite.Api.Session"; + public static bool HttpOnly { get; } = true; + public static TimeSpan IdleTimeout { get; } = SacsSystem.DebugMode ? TimeSpan.FromMinutes(5) : TimeSpan.FromMinutes(15); + public static long KeepLoggedInTimeoutMillis { get; } = (long)(SacsSystem.DebugMode ? TimeSpan.FromMinutes(1) : TimeSpan.FromMinutes(5)).TotalMilliseconds; + } + } + } public class Admin { public static class Session diff --git a/SaxoniteStandardBase/Base/App/Sax-Version.cs b/SaxoniteStandardBase/Base/App/Sax-Version.cs index 7d4a0d0..8db1fea 100644 --- a/SaxoniteStandardBase/Base/App/Sax-Version.cs +++ b/SaxoniteStandardBase/Base/App/Sax-Version.cs @@ -42,6 +42,7 @@ namespace Saxonite.Net.Standard.Base.App //------------------------------------------------------------------- // 1.2.11 6-Jul-2023 // - Organisation associations, admin download [Feb24]. + // - Basic Api app [Apr24]. // 1.2.10 11-Oct-2022 // - Online organisations display issue fixed. // - User Sport 'Preparing' options. diff --git a/SaxoniteStandardBase/Base/App/Sax.cs b/SaxoniteStandardBase/Base/App/Sax.cs index 0367e86..1088433 100644 --- a/SaxoniteStandardBase/Base/App/Sax.cs +++ b/SaxoniteStandardBase/Base/App/Sax.cs @@ -46,6 +46,7 @@ namespace Saxonite.Net.Standard.Base.App public enum Application { Online = 100, + Api = 400, Admin = 900, } diff --git a/SaxoniteStandardBase/Base/Consoles/SaxEmailConsole.cs b/SaxoniteStandardBase/Base/Consoles/SaxEmailConsole.cs index 9458268..1542a99 100644 --- a/SaxoniteStandardBase/Base/Consoles/SaxEmailConsole.cs +++ b/SaxoniteStandardBase/Base/Consoles/SaxEmailConsole.cs @@ -53,21 +53,21 @@ namespace Saxonite.Net.Standard.Base.Consoles if (EmailContainsTag(emailData, EmailTag_MainStylesheet)) { // Tag replacement is expanded to avoid reading main stylesheet resource unless required. - ReplaceDynamicEmailTag(emailData, EmailTag_MainStylesheet, ""); + ReplaceDynamicEmailTag(emailData, EmailTag_MainStylesheet, ""); } // Partial content - Header. if (EmailContainsTag(emailData, EmailTag_Header)) { // Tag replacement is expanded to avoid reading Header resource unless required. - ReplaceDynamicEmailTag(emailData, EmailTag_Header, SaxResourceHelper.GetTextResource(SaxResourceHelper.TextResource.Email_Header_Html)); + ReplaceDynamicEmailTag(emailData, EmailTag_Header, SaxResourceHelper.GetResourceText(SaxResourceHelper.TextResource.Email_Header_Html)); } // Partial content - Footer. if (EmailContainsTag(emailData, EmailTag_Footer)) { // Tag replacement is expanded to avoid reading Footer resource unless required. - ReplaceDynamicEmailTag(emailData, EmailTag_Footer, SaxResourceHelper.GetTextResource(SaxResourceHelper.TextResource.Email_Footer_Html)); + ReplaceDynamicEmailTag(emailData, EmailTag_Footer, SaxResourceHelper.GetResourceText(SaxResourceHelper.TextResource.Email_Footer_Html)); } } diff --git a/SaxoniteStandardBase/Base/Helpers/SaxResourceHelper.cs b/SaxoniteStandardBase/Base/Helpers/SaxResourceHelper.cs index ae7d536..8fa1392 100644 --- a/SaxoniteStandardBase/Base/Helpers/SaxResourceHelper.cs +++ b/SaxoniteStandardBase/Base/Helpers/SaxResourceHelper.cs @@ -3,6 +3,7 @@ using Sarand.Net.Standard.Base.Helpers; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; +using System.IO; using System.Reflection; using System.Text; @@ -31,9 +32,15 @@ namespace Saxonite.Net.Standard.Base.Helpers Saxonite_logo_h75_png, } + //------------------------------------------------------------------- + // Properties. + public static Assembly MyAssembly { get; } = typeof(SaxResourceHelper).GetTypeInfo().Assembly; + //------------------------------------------------------------------- // Text resources. - public static String GetTextResource(TextResource textResource) + + /// Retrieve contents of text resource in this assembly by type. + public static String GetResourceText(TextResource textResource) { String partialPath = ""; String resourceFilename = ""; @@ -62,11 +69,16 @@ namespace Saxonite.Net.Standard.Base.Helpers resourceFilename = "CountriesWithRegions.txt"; break; } - if (!StringUtil.IsEmpty(resourceFilename)) + return GetResourceText(resourceFilename, partialPath); + } + + /// Retrieve contents of text resource in this assembly by name. + public static String GetResourceText(String resourceFilename, String partialPath = "") + { + if (!StringUtil.IsBlank(resourceFilename)) { - var assembly = typeof(SaxResourceHelper).GetTypeInfo().Assembly; - String resourceText = SacsResourceHelper.GetManifestResourceAsText(assembly, partialPath, resourceFilename); - if (!StringUtil.IsEmpty(resourceText)) + String resourceText = SacsResourceHelper.GetManifestResourceAsText(MyAssembly, partialPath, resourceFilename); + if (!StringUtil.IsBlank(resourceText)) return resourceText; } return ""; @@ -74,7 +86,7 @@ namespace Saxonite.Net.Standard.Base.Helpers //------------------------------------------------------------------- // Image resources. - public static byte[] GetImageResource(ImageResource imageResource) + public static byte[] GetResourceImage(ImageResource imageResource) { String partialPath = ""; String resourceFilename = ""; @@ -94,6 +106,21 @@ namespace Saxonite.Net.Standard.Base.Helpers return new byte[0]; } + //------------------------------------------------------------------- + // Resource stream. + + /// + /// Retrieve stream to resource in this assembly. + /// + public static Stream GetResourceStream(String resourceFilename, String partialPath = "") + { + if (!StringUtil.IsBlank(resourceFilename)) + { + return SacsResourceHelper.GetManifestResourceStream(MyAssembly, partialPath, resourceFilename); + } + return null; + } + //------------------------------------------------------------------- } //======================================================================= diff --git a/SaxoniteStandardBase/Base/Procs/SaxProcess_Base.cs b/SaxoniteStandardBase/Base/Procs/SaxProcess_Base.cs index 832f267..987f6b8 100644 --- a/SaxoniteStandardBase/Base/Procs/SaxProcess_Base.cs +++ b/SaxoniteStandardBase/Base/Procs/SaxProcess_Base.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Text; using Saxonite.Net.Standard.Base.App; +using Sarand.Net.Standard.Proc.Excel; namespace Saxonite.Net.Standard.Base.Procs { @@ -53,6 +54,34 @@ namespace Saxonite.Net.Standard.Base.Procs public SaxItemDataMgr ItemDataMgr { get { return Internals.ItemDataMgr; } } public SaxSupportMgr SupportMgr { get { return Internals.SupportMgr; } } + //------------------------------------------------------------------- + // Excel Spreadsheet utilities. + //------------------------------------------------------------------- + protected virtual SaMsExcelColumnHeading_Config GetExcelColumnHeadingConfig() + { + SaMsExcelColumnHeading_Config configHeading = new SaMsExcelColumnHeading_Config(); + configHeading.FontAttr.Name = "Arial"; + configHeading.FontAttr.HeightInPoints = 10; + configHeading.FontAttr.ColourIndex = SaXlColourIndex.DarkBlue; + configHeading.FontAttr.Bold = true; + configHeading.HeadingTextWrap = true; + configHeading.ForegroundColourIndex = SaXlColourIndex.LightYellow; + configHeading.BorderWeight = SaXlBorderWeight.Medium; + return configHeading; + } + + protected virtual SaMsExcelStyleAttr GetExcelDefaultWorkbookStyle() + { + SaMsExcelStyleAttr styleAttr = new SaMsExcelStyleAttr(); + styleAttr.FontAttr.Name = "Arial"; + styleAttr.FontAttr.HeightInPoints = 9; + styleAttr.FontAttr.ColourIndex = SaXlColourIndex.Black; + styleAttr.HorizontalAlignment = (short)XlHAlign.xlHAlignLeft; + styleAttr.VerticalAlignment = (short)XlVAlign.xlVAlignTop; + styleAttr.WrapText = true; + return styleAttr; + } + //------------------------------------------------------------------- } //======================================================================= diff --git a/SaxoniteStandardBase/Resources/Config/appsettings.Development.json b/SaxoniteStandardBase/Resources/Config/appsettings.Development.json new file mode 100644 index 0000000..89afa5c --- /dev/null +++ b/SaxoniteStandardBase/Resources/Config/appsettings.Development.json @@ -0,0 +1,26 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "EmailConfigs": { + "SAX-SF-Dev": { + "Message": { + "AddressFrom": "DoNotReply@sportierre.com" + }, + "SMTP": { + "Server": "smtp.ionos.co.uk", + "ServerPort": 587, + "UseSSL": true + }, + "Send": { + "Using": 2, + "UserName": "info@sportierre.com", + "Password": "5p0rTi3rre-info-2021!" + } + } + } +} diff --git a/SaxoniteStandardBase/Resources/Config/appsettings.Machine.Sarand110.json b/SaxoniteStandardBase/Resources/Config/appsettings.Machine.Sarand110.json new file mode 100644 index 0000000..397a235 --- /dev/null +++ b/SaxoniteStandardBase/Resources/Config/appsettings.Machine.Sarand110.json @@ -0,0 +1,71 @@ +{ + "AppConfigs": { + "Saxonite-Dev": { + "Environments": [ "Development" ], + "Instance": "Dev", + "URLs": { + "Online": { + "Root": "https://localhost:44364/" + } + }, + "Databases": { + "Core": { + "Location": "MsSql:Sarand110\\SQL2016.Saxonite_Core_Dev", + "User": "saxonite", + "Password": "sax-dev-2021" + }, + "Support": { + "Location": "MsSql:Sarand110\\SQL2016.Saxonite_Support_Dev", + "User": "saxonite", + "Password": "sax-dev-2021" + } + }, + "Email": { + "Context": "SAX-SF-Dev", + "ContactUs": { + "AddressesTo": [ "info@sportierre.com" ] + } + }, + "Documents": { + "RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\Saxonite\\Docs" + }, + "Logging": { + "RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\Saxonite\\Logs" + } + }, + "Saxonite-Test": { + "Environments": [ "Production" ], + "Instance": "QC", + "Databases": { + "Core": { + "Location": "MsSql:Sarand110\\SQL2016.Saxonite_Core_Dev", + "User": "saxonite", + "Password": "sax-dev-2021" + } + }, + "Email": { + "Context": "SAX-SF-Dev", + "ContactUs": { + "AddressesTo": [ "info@sportierre.com" ], + "AddressesBcc": [] + + } + }, + "Documents": { + "RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\Saxonite\\Docs" + }, + "Logging": { + "RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\Saxonite\\QC\\Logs" + }, + "Variants": [ + { + "ApplicationRootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\Saxonite\\QC2\\App", + "Instance": "QC", + "Logging": { + "RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\Saxonite\\QC2\\Logs" + } + } + ] + } + } +} diff --git a/SaxoniteStandardBase/Resources/Config/appsettings.Machine.Sarand602.json b/SaxoniteStandardBase/Resources/Config/appsettings.Machine.Sarand602.json new file mode 100644 index 0000000..f49bbdd --- /dev/null +++ b/SaxoniteStandardBase/Resources/Config/appsettings.Machine.Sarand602.json @@ -0,0 +1,72 @@ +{ + "AppConfigs": { + "SAX-Prod": { + "Environments": [ "Production" ], + "Instance": "", + "URLs": { + "Online": { + "Root": "https://sportierre.com/" + } + }, + "Databases": { + "Core": { + "Location": "MsSql:.\\SQL2016Exp.Saxonite_Core_Demo", + "User": "sax-demo-user", + "Password": "sax-demo-202105" + }, + "Support": { + "Location": "MsSql:.\\SQL2016Exp.Saxonite_Support_Demo", + "User": "sax-demo-user", + "Password": "sax-demo-202105" + } + }, + "Security": { + "Password": { + "MinLength": 9 + }, + "SignIn": { + "KeepLoggedIn": { + "Allowed": true, + "CookieExpiresDays": 5 + }, + "PasswordRequest": { + "LinkExpiresMins": 30 + } + } + }, + "Email": { + "Context": "SAX-SF-Prod", + "ContactUs": { + "AddressesTo": [], + "AddressesBcc": [ "info@sportierre.com" ] + }, + "Signup": { + "Activate": { + "AddressesBcc": [ "info@sportierre.com" ] + }, + "Welcome": { + "AddressesBcc": [ "info@sportierre.com" ] + } + } + }, + "Documents": { + "RootFolder": "C:\\Sarand\\Saxonite\\Demo\\Docs" + }, + "Logging": { + "RootFolder": "C:\\Sarand\\Saxonite\\Demo\\Logs" + }, + "Variants": [ + { + "ApplicationRootFolder": "C:\\Sarand\\Saxonite\\Demo", + "Instance": "Demo", + "Documents": { + "RootFolder": "C:\\Sarand\\Saxonite\\Demo\\Docs" + }, + "Logging": { + "RootFolder": "C:\\Sarand\\Saxonite\\Demo\\Logs" + } + } + ] + } + } +} diff --git a/SaxoniteStandardBase/Resources/Config/appsettings.Machine.json b/SaxoniteStandardBase/Resources/Config/appsettings.Machine.json new file mode 100644 index 0000000..2c63c08 --- /dev/null +++ b/SaxoniteStandardBase/Resources/Config/appsettings.Machine.json @@ -0,0 +1,2 @@ +{ +} diff --git a/SaxoniteStandardBase/Resources/Config/appsettings.Production.json b/SaxoniteStandardBase/Resources/Config/appsettings.Production.json new file mode 100644 index 0000000..269024f --- /dev/null +++ b/SaxoniteStandardBase/Resources/Config/appsettings.Production.json @@ -0,0 +1,19 @@ +{ + "EmailConfigs": { + "SAX-SF-Prod": { + "Message": { + "AddressFrom": "DoNotReply@sportierre.com" + }, + "SMTP": { + "Server": "smtp.ionos.co.uk", + "ServerPort": 587, + "UseSSL": true + }, + "Send": { + "Using": 2, + "UserName": "info@sportierre.com", + "Password": "5p0rTi3rre-info-2021!" + } + } + } +} diff --git a/SaxoniteStandardBase/Resources/Config/appsettings.json b/SaxoniteStandardBase/Resources/Config/appsettings.json new file mode 100644 index 0000000..d9d9a9b --- /dev/null +++ b/SaxoniteStandardBase/Resources/Config/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/SaxoniteWebApi/.config/dotnet-tools.json b/SaxoniteWebApi/.config/dotnet-tools.json new file mode 100644 index 0000000..cce5e14 --- /dev/null +++ b/SaxoniteWebApi/.config/dotnet-tools.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "8.0.4", + "commands": [ + "dotnet-ef" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/SaxoniteWebApi/Api/App/SaxApplication_Api.cs b/SaxoniteWebApi/Api/App/SaxApplication_Api.cs new file mode 100644 index 0000000..dd5e303 --- /dev/null +++ b/SaxoniteWebApi/Api/App/SaxApplication_Api.cs @@ -0,0 +1,141 @@ +using Microsoft.Identity.Client; +using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Dbas; +using Sarand.Net.Standard.Base.Helpers; +using Sarand.Net.Standard.Base.IO; +using Sarand.Net.Standard.Base.Utils; +using Saxonite.Net.Core.Web.Base.App; +using Saxonite.Net.Core.Web.Base.Helpers; +using Saxonite.Net.Standard.Base.App; +using Saxonite.Net.Standard.Base.Consoles; +using Saxonite.Net.Standard.Base.Helpers; +using Saxonite.Web.Api.Consoles; +using System.Text.RegularExpressions; +using static Saxonite.Net.Core.Web.Base.App.SaxAppConfig; + +namespace Saxonite.Web.Api.App +{ + //======================================================================= + public class SaxApplication_Api : SaxApplication_Web + { + //------------------------------------------------------------------- + // Data members. + private Dictionary appConfigs = new Dictionary(); + private Dictionary emailConfigs = new Dictionary(); + // Session contexts. + private class SessionContextData_Api : SessionContextData_Web + { + public SessionContextData_Api(SaxSessionContext_Web sessionContext) : base(sessionContext) { } + } + private readonly Dictionary sessionContexts = new Dictionary(); + + //------------------------------------------------------------------- + // Construction. + public SaxApplication_Api() + { + InitialiseTemporaryLoggingFolder(); + try + { + AppInstance = this; + ConsoleHelper_Api = new SaxConsoleHelper_Api(this); + + // Logging configuration. + SaLogger.LogFilenamePrefix = "Sax-Web-Api"; + SaLogger.IncludeHostInFileMessage = false; + SaLogger.IncludeUserInFileMessage = false; + + LoadConfiguration(); + } + catch (Exception exc) + { + SaLogger.Error(GetType().Name + ".CTR " + ExceptionUtil.GetErrorStateMessage(exc)); + throw; + } + } + + //------------------------------------------------------------------- + // Properties. + public static SaxApplication_Api? AppInstance { get; private set; } + public override SaxConsoleHelper ConsoleHelper { get { return ConsoleHelper_Api; } } + public SaxConsoleHelper_Api ConsoleHelper_Api { get; private set; } + // Database. + public override ISacsDatabase? GetDatabase(SaxSessionContext sessionContext, Sax.Database databaseType) + { + return sessionContexts.GetValue(sessionContext.Index, null)?.Databases.GetValue(databaseType, null); + } + // Configuration. + public override SaxAppConfig AppConfig { get { return appConfigs.Values.ToList().getConfigForApplication(); } } + public override SaxEmailConfig EmailConfig { get { return emailConfigs.Values.ToList().getConfigForSession(AppConfig); } } + public override String SessionCookieName { get { return Sax.Config.Api.Session.Cookie.Name; } } + // Startup messages - for debugging. See Admin.Views._Layout. + public List Messages { get; } = new List(); + + //------------------------------------------------------------------- + // Initialisation. + + private void LoadConfiguration() + { + try + { + // Environment. + environmentName = Environments.Development; + if (SaxSystem.ComputerName.EqualsCI("Sarand601")) + environmentName = Environments.Production; + + // Load server configuration. + var builder = + new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) + .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: false) + .AddJsonFile($"appsettings.machine.{SaxSystem.ComputerName}.json", optional: true, reloadOnChange: false) + .AddEnvironmentVariables(); + Stream configStream = SaxResourceHelper.GetResourceStream("appsettings.json", "Config"); + if (configStream != null) builder.AddJsonStream(configStream); + configStream = SaxResourceHelper.GetResourceStream($"appsettings.{environmentName}.json", "Config"); + if (configStream != null) builder.AddJsonStream(configStream); + configStream = SaxResourceHelper.GetResourceStream($"appsettings.machine.{SaxSystem.ComputerName}.json", "Config"); + if (configStream != null) builder.AddJsonStream(configStream); + SaxConfiguration = builder.Build(); + + // Application configuration. + appConfigs = SaxAppConfigHelper.ExtractAppConfigs(SaxConfiguration.GetSection("AppConfigs")); + emailConfigs = SaxEmailConfigHelper.ExtractEmailConfigs(SaxConfiguration.GetSection("EmailConfigs")); + LoggingRootFolder = AppConfig.Logging.RootFolder; + // Ensure root log folder ends with Api folder. + if (!StringUtil.IsBlank(LoggingRootFolder) && !Regex.IsMatch(LoggingRootFolder, "[\\\\/]Api$", RegexOptions.IgnoreCase)) + LoggingRootFolder = StringUtil.CombineFilePath(LoggingRootFolder, "Api"); + + // Application instance. + if (AppConfig.Instance.EqualsCI("Dev")) instanceType = Sax.InstanceType.Dev; + else if (AppConfig.Instance.ContainsCI("Q")) instanceType = Sax.InstanceType.QC; + else if (AppConfig.Instance.ContainsCI("UAT")) instanceType = Sax.InstanceType.UAT; + else if (AppConfig.Instance.EqualsCI("PreProd")) instanceType = Sax.InstanceType.UAT; + + // Initialise hard-coded logging path. + if (StringUtil.IsBlank(LoggingRootFolder)) + { + if (SaxSystem.ComputerName.EqualsCI("WIN-BPCLM1QUOMT")) + LoggingRootFolder = @"D:\Saxonite\Logs\" + (Development ? "Dev" : "Test"); + } + if (DirectoryUtil.DirectoryExists(LoggingRootFolder)) + SaLogger.LogFolder = LoggingRootFolder; + LogApplicationStart(SysUtil.Fn); + + // Session context - only one context available/necessary (for now). + SessionContextData_Api sessionContextData = new SessionContextData_Api(new SaxSessionContext_Web(100, Sax.Application.Api)); + ConfigureDatabaseConnection(sessionContextData, Sax.Database.Core); + ConfigureDatabaseConnection(sessionContextData, Sax.Database.Support); + sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData); + SessionContext = sessionContextData.SessionContext; + } + catch (Exception exc) + { + SaLogger.Warn(SysUtil.Fn + " " + ExceptionUtil.GetLogMessage(exc, "loading application configuration", 8)); + } + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteWebApi/Api/Consoles/SaxActivityConsole_Api.cs b/SaxoniteWebApi/Api/Consoles/SaxActivityConsole_Api.cs new file mode 100644 index 0000000..e667c03 --- /dev/null +++ b/SaxoniteWebApi/Api/Consoles/SaxActivityConsole_Api.cs @@ -0,0 +1,27 @@ +using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Utils; +using Saxonite.Net.Core.Web.Base.Consoles; +using Saxonite.Net.Standard.Base.App; + +namespace Saxonite.Web.Api.Consoles +{ + //======================================================================= + public class SaxActivityConsole_Api : SaxActivityConsole_Web + { + //------------------------------------------------------------------- + // Data members. + + //------------------------------------------------------------------- + public SaxActivityConsole_Api(SaxSessionContext sessionContext) : + base(sessionContext) + { + SaLogger.Info(SysUtil.Fn + ""); + } + + //------------------------------------------------------------------- + // Utilities. + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteWebApi/Api/Consoles/SaxConsoleHelper_Api.cs b/SaxoniteWebApi/Api/Consoles/SaxConsoleHelper_Api.cs new file mode 100644 index 0000000..e60a846 --- /dev/null +++ b/SaxoniteWebApi/Api/Consoles/SaxConsoleHelper_Api.cs @@ -0,0 +1,84 @@ +using Saxonite.Net.Core.Web.Base.Consoles; +using Saxonite.Net.Standard.Base.App; +using Saxonite.Net.Standard.Base.Consoles; +using Saxonite.Web.Api.App; + +namespace Saxonite.Web.Api.Consoles +{ + //======================================================================= + public class SaxConsoleHelper_Api : SaxConsoleHelper_Web + { + //------------------------------------------------------------------- + // Data members: + private readonly SaxApplication_Api app; + + //------------------------------------------------------------------- + // Construction. + public SaxConsoleHelper_Api(SaxApplication_Api app) + { + this.app = app; + } + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Clear process consoles. + foreach (SaxProcessConsole_Api processConsole in processConsoles.Values) + { + processConsole.Dispose(); + } + processConsoles.Clear(); + } + base.Dispose(disposing); + } + + //------------------------------------------------------------------- + // Data cache console. + public override SaxDataCacheConsole GetDataCacheConsole(SaxSessionContext sessionContext) + { + String fn = GetType().Name + ".GetDataCacheConsole"; + //throw new NotSupportedException(fn + " Data Cache Console not supported in Admin app."); + return null; + } + + //------------------------------------------------------------------- + // Session data console. + public override SaxSessionDataConsole? GetSessionDataConsole(SaxSessionContext sessionContext) + { + // Method is called by Base Controller on ValidUserSession and must return null for Admin app. + return null; + } + + //------------------------------------------------------------------- + // Process console. + private Dictionary processConsoles { get; } = new Dictionary(); + public SaxProcessConsole GetProcessConsole(SaxSessionContext sessionContext) + { + if (sessionContext == null) throw new NotSupportedException(GetType().Name + ".GetProcessConsole Session Context must be specified"); + SaxProcessConsole_Api processConsole = processConsoles.GetValueOrDefault(sessionContext.Index, null); + if (processConsole == null) + { + processConsole = processConsoles[sessionContext.Index] = new SaxProcessConsole_Api(sessionContext); + } + return processConsole; + } + + //------------------------------------------------------------------- + // Activity console. + public override SaxActivityConsole CreateActivityConsole(SaxSessionContext sessionContext) + { + return new SaxActivityConsole_Api(sessionContext); + } + + //------------------------------------------------------------------- + // Email console. + public override SaxEmailConsole CreateEmailConsole(SaxSessionContext sessionContext) + { + SaxEmailConsole emailConsole = new SaxEmailConsole_Web(app.EmailConfig); + return emailConsole; + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteWebApi/Api/Consoles/SaxProcessConsole_Api.cs b/SaxoniteWebApi/Api/Consoles/SaxProcessConsole_Api.cs new file mode 100644 index 0000000..9bb4b7b --- /dev/null +++ b/SaxoniteWebApi/Api/Consoles/SaxProcessConsole_Api.cs @@ -0,0 +1,102 @@ +using Sarand.Net.Standard.Base.Procs; +using Saxonite.Net.Standard.Base.App; +using Saxonite.Net.Standard.Base.Consoles; +using Saxonite.Web.Api.Procs; + +namespace Saxonite.Web.Api.Consoles +{ + //======================================================================= + public class SaxProcessConsole_Api : SaxProcessConsole + { + //------------------------------------------------------------------- + // Definitions. + public enum ProcessType + { + } + + //------------------------------------------------------------------- + // Process cache - to sustain processes outside of request/response timescales. + internal class ProcessData + { + public ProcessData(SaxProcess_Api process) + { + this.Process = process; + + } + public SaxProcess_Api Process { get; } + } + // Cache. + private Dictionary processes { get; } = new Dictionary(); + + //------------------------------------------------------------------- + // Data members. + private SaxInternals? internals = null; + + //------------------------------------------------------------------- + // Construction. + public SaxProcessConsole_Api(SaxSessionContext sessionContext) : base(sessionContext) + { + } + protected async override void Dispose(bool disposing) + { + if (disposing) + { + // Clear processes. + foreach (ProcessData processData in processes.Values) + { + await processData.Process.StopProcessAsync(); + processData.Process.Dispose(); + } + } + base.Dispose(disposing); + } + + //------------------------------------------------------------------- + // Processes. + //------------------------------------------------------------------- + + public SaxProcess_Api GetProcess(ProcessType processType) + { + return processes.GetValueOrDefault(processType, null)?.Process; + } + + public bool IsProcessing(ProcessType processType) + { + SaxProcess_Api process = GetProcess(processType); + if (process != null) + if (process.Processing) return true; + return false; + } + + /// + /// Remove the process from the cache. + /// + /// + /// + /// + public bool ClearProcess(ProcessType processType) + { + SaxProcess_Api process = GetProcess(processType); + if (process != null) + { + if (process.Processing) + throw new SaProcess_Base.InProgressException(); + process.Dispose(); + } + return processes.Remove(processType); + } + + public void SetProcess(ProcessType processType, SaxProcess_Api process) + { + ClearProcess(processType); + processes.Add(processType, new ProcessData(process)); + } + + //------------------------------------------------------------------- + // Specific processes. + //------------------------------------------------------------------- + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteWebApi/Api/Controllers/SecurityController.cs b/SaxoniteWebApi/Api/Controllers/SecurityController.cs new file mode 100644 index 0000000..dd75367 --- /dev/null +++ b/SaxoniteWebApi/Api/Controllers/SecurityController.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Saxonite.Web.Api.Controllers +{ + //======================================================================= + [ApiController] + //[Route("[controller]")] + public class SecurityController : SwapiControllerBase + { + //------------------------------------------------------------------- + // Construction. + public SecurityController() + { + } + + //------------------------------------------------------------------- + // Start session. + + public class RequestData_StartSession + { + public String userCode { get; set; } = ""; + } + public class ResponseData_StartSession : ApiResponse_Data + { + } + [HttpPost] + [Route("[controller]/StartSession")] + public ResponseData_StartSession StartSession_Get(RequestData_StartSession requestData) + { + ResponseData_StartSession responseData = new ResponseData_StartSession(); + responseData.SetMessage("Security",$"User: {requestData.userCode}."); + + return responseData; + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteWebApi/Api/Controllers/SwapiControllerBase.cs b/SaxoniteWebApi/Api/Controllers/SwapiControllerBase.cs new file mode 100644 index 0000000..50c86a5 --- /dev/null +++ b/SaxoniteWebApi/Api/Controllers/SwapiControllerBase.cs @@ -0,0 +1,140 @@ +using Microsoft.AspNetCore.Mvc; +using Sacs.Web.Components; +using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Utils; + +namespace Saxonite.Web.Api.Controllers +{ + //======================================================================= + public class SwapiControllerBase : ControllerBase + { + //------------------------------------------------------------------- + // Definitions. + + //------------------------------------------------------------------- + // Response data. + // Null values are ignored by JSON serialisation. + // - See Saxonite.Net.Core.Web.Base.App.SaxStartup.ConfigureServices() + // - Ref. config.services.AddMvc(...).AddJsonOptions(options => { options.JsonSerializerOptions.IgnoreNullValues = true; }); + //------------------------------------------------------------------- + // Base response data - for simple responses. + public class ApiResponse_Base + { + // Response status. + public bool? Success { get; set; } = null; + public bool? Error { get; set; } = null; + public bool? SessionExpired { get; protected set; } = null; + public ApiResponse_Base SetSessionExpired(String title, String text) + { + SessionExpired = true; + return SetMessage(title, text); + } + // Message - displays alert popup. + public class MessageData + { + public MessageData(String title, String text) + { + this.Title = title; + this.Text = text; + } + public String Title { get; } + public String Text { get; } + } + public MessageData? Message { get; private set; } + public ApiResponse_Base SetMessage(String title, String text) + { + if (!StringUtil.IsBlank(text)) + Message = new MessageData(title, text); + return this; + } + } + + //------------------------------------------------------------------- + public class ApiResponse_Data : ApiResponse_Base + { + //--------------------------------------------------------------- + // Construction. + protected ApiResponse_Data() + { + } + + //--------------------------------------------------------------- + /// Item data - Common properties for data items. + public class ItemData_Base + { + // Common item properties. + public String? Id { get; set; } + public String? Notes { get; set; } + public String? StatusCode { get; set; } + public String? StatusDesc { get; set; } + // Flags for common status values. + // Return true or null so that property is not serialised when false. + public bool? Awaiting { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Awaiting)) ? true : (bool?)null; } } + public bool? Active { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Active)) ? true : (bool?)null; } } + public bool? Inactive { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Inactive)) ? true : (bool?)null; } } + public bool? Deleted { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Deleted)) ? true : (bool?)null; } } + /// Created on date - YYYYMMDD + public String? CreatedOn { get; set; } + /// Created on date - formatted per locale + public String? CreatedOnFmt { get; set; } + /// Updated on date - YYYYMMDD + public String? UpdatedOn { get; set; } + /// Updated on date - formatted per locale + public String? UpdatedOnFmt { get; set; } + } + /// Contact Method properties. + public class ContactMethodData + { + public String? Method { get; set; } + public String? MethodCaption { get; set; } + public String? Value { get; set; } + } + /// Address properties. + public class AddressData : ItemData_Base + { + public String? Line1 { get; set; } + public String? Line2 { get; set; } + public String? Line3 { get; set; } + public String? Town { get; set; } + public String? RegionIdProvince { get; set; } + public String? RegionNameProvince { get; set; } + public String? RegionIdCountry { get; set; } + public String? RegionNameCountry { get; set; } + public String? PostalCode { get; set; } + } + /// + /// Item data with label and value. + /// + public class ItemLabelValue + { + public String? Label { get; set; } + public String? Value { get; set; } + } + /// + /// Item data with just Id and name. + /// - Id is String to allow for obfuscated values. + /// + public class ItemIdName + { + public String? Id { get; set; } + public String? Name { get; set; } + } + /// Item code and desc values. + public class ItemCodeDesc + { + public String? Code { get; set; } + public String? Desc { get; set; } + } + } + + //------------------------------------------------------------------- + // Construction. + protected SwapiControllerBase() + { + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteWebApi/Api/Controllers/SystemController.cs b/SaxoniteWebApi/Api/Controllers/SystemController.cs new file mode 100644 index 0000000..b29730e --- /dev/null +++ b/SaxoniteWebApi/Api/Controllers/SystemController.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Mvc; +using Saxonite.Net.Standard.Base.App; +using static Sarand.Net.Standard.Base.Helpers.SacsHttpClientHelper; + +namespace Saxonite.Web.Api.Controllers +{ + //======================================================================= + [ApiController] + public class SystemController : SwapiControllerBase + { + //------------------------------------------------------------------- + // Construction. + public SystemController() + { + } + + //------------------------------------------------------------------- + // Start session. + + public class RequestData_Version + { + } + public class ResponseData_Version : ApiResponse_Data + { + public String? Version { get; set; } + } + [HttpPost] + [Route("[controller]/Version")] + public ResponseData_Version GetVersion_Post(RequestData_Version requestData) + { + ResponseData_Version responseData = new ResponseData_Version(); + responseData.Version = Sax.Version.GetFullVersion(); + return responseData; + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteWebApi/Api/Procs/SaxProcess_Api.cs b/SaxoniteWebApi/Api/Procs/SaxProcess_Api.cs new file mode 100644 index 0000000..fdcbe52 --- /dev/null +++ b/SaxoniteWebApi/Api/Procs/SaxProcess_Api.cs @@ -0,0 +1,32 @@ +using Sarand.Net.Standard.Proc.Excel; +using Saxonite.Net.Standard.Base.App; +using Saxonite.Net.Standard.Base.Procs; + +namespace Saxonite.Web.Api.Procs +{ + //======================================================================= + public abstract class SaxProcess_Api : SaxProcess_Base + { + //------------------------------------------------------------------- + // Definitions. + public new class Config : SaxProcess_Base.Config + { + protected Config(SaxSessionContext sessionContext) : base(sessionContext) + { } + } + + //------------------------------------------------------------------- + // Data members. + private Config config; + + //------------------------------------------------------------------- + // Construction. + protected SaxProcess_Api(Config config) : base(config) + { + this.config = config; + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaxoniteWebApi/Program.cs b/SaxoniteWebApi/Program.cs new file mode 100644 index 0000000..d7da21d --- /dev/null +++ b/SaxoniteWebApi/Program.cs @@ -0,0 +1,37 @@ +using Saxonite.Web.Api.App; +using System.Text.Json.Serialization; + +{ + // Saxonite API application. + var application = new SaxApplication_Api(); + + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + + builder.Services.AddControllers(); + builder.Services.AddControllers().AddJsonOptions(options => + { + options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; + }); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + //app.UseHttpsRedirection(); + + app.UseAuthorization(); + + app.MapControllers(); + + app.Run(); +} diff --git a/SaxoniteWebApi/Properties/launchSettings.json b/SaxoniteWebApi/Properties/launchSettings.json new file mode 100644 index 0000000..f971d7c --- /dev/null +++ b/SaxoniteWebApi/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:52385", + "sslPort": 44304 + } + }, + "profiles": { + "SaxoniteWebApi": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7048;http://localhost:5193", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/SaxoniteWebApi/SaxoniteWebApi.csproj b/SaxoniteWebApi/SaxoniteWebApi.csproj new file mode 100644 index 0000000..50be495 --- /dev/null +++ b/SaxoniteWebApi/SaxoniteWebApi.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + enable + enable + Saxonite.Web + Saxonite.Web + + + + + + + + + + + + + + + + + + + + + diff --git a/SaxoniteWebApi/appsettings.Development.json b/SaxoniteWebApi/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/SaxoniteWebApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/SaxoniteWebApi/appsettings.json b/SaxoniteWebApi/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/SaxoniteWebApi/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}