diff --git a/Database/Core/DCL/SetupApplicationUser.cs b/Database/Core/DCL/SetupApplicationUser.cs new file mode 100644 index 0000000..5420617 --- /dev/null +++ b/Database/Core/DCL/SetupApplicationUser.cs @@ -0,0 +1,86 @@ +using System.Data; +using Database.Common; +using Insight.Database; + +namespace Database.Core.DataControlLanguage +{ + + /// + /// Only a superadmin or similar can create Application Users + /// + public class SetupApplicationUser + { + + IDbConnection _db; + string _schema; + string _user; + string _password; + + public SetupApplicationUser(IDbConnection db) + { + _db = db; + } + + public void CreateUserWithSchemaInDatabase(string schema, string user, string password) + { + _schema = schema; + _password = password; + _user = user; + + if (!Validations.IsValidSchemaName(_schema)) + throw new ArgumentException("Invalid schema name", _schema); + + using (var transaction = _db.BeginTransaction()) + { + try + { + CreateSchema(); + CreateRole(); + GrantSchemaRights(); + + transaction.Commit(); + } + catch (Exception ex) + { + transaction.Rollback(); + throw new InvalidOperationException("Failed to SetupApplicationUser in Database", ex); + } + } + + } + private void ExecuteSql(string sql) + { + _db.ExecuteSql(sql); + } + + private void CreateSchema() + { + var sql = $"CREATE SCHEMA IF NOT EXISTS {_schema}"; + ExecuteSql(sql); + } + + private void CreateRole() + { + var sql = $"CREATE ROLE {_user} WITH CREATEDB CREATEROLE LOGIN PASSWORD '{_password}';"; + ExecuteSql(sql); + + var sql1 = $"ALTER ROLE {_user} SET search_path='{_schema}';"; + ExecuteSql(sql1); + + } + + private void GrantSchemaRights() + { + var sql = $"GRANT USAGE ON SCHEMA {_schema} TO {_user};"; + ExecuteSql(sql); + + var sql1 = $"ALTER DEFAULT PRIVILEGES IN SCHEMA {_schema} " + + $"GRANT INSERT, SELECT, UPDATE PRIVILEGES ON TABLES TO {_user};"; + ExecuteSql(sql1); + + var sql2 = $"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA {_schema} TO {_user};"; + ExecuteSql(sql2); + + } + } +} diff --git a/Database/Core/DCL/SetupOrganizationUser.cs b/Database/Core/DCL/SetupOrganizationUser.cs new file mode 100644 index 0000000..b58b98b --- /dev/null +++ b/Database/Core/DCL/SetupOrganizationUser.cs @@ -0,0 +1,86 @@ +using System.Data; +using Database.Common; +using Insight.Database; + +namespace Database.Core.DataControlLanguage +{ + public class SetupOrganization + { + + IDbConnection _db; + string _schema; + string _user; + string _password; + + public SetupOrganization(IDbConnection db) + { + _db = db; + } + + public void CreateUserWithSchemaInDatabase(string schema, string user, string password) + { + + _schema = schema; + _password = password; + _user = user; + + if (!Validations.IsValidSchemaName(_schema)) + throw new ArgumentException("Invalid schema name", _schema); + + using (var transaction = _db.BeginTransaction()) + { + try + { + CreateSchema(); + CreateRole(); + GrantSchemaRights(); + + transaction.Commit(); + } + catch (Exception ex) + { + transaction.Rollback(); + throw new InvalidOperationException("Failed to SetupOrganization in Database", ex); + } + } + + + + + } + private void ExecuteSql(string sql) + { + _db.ExecuteSql(sql); + } + + private void CreateSchema() + { + var sql = $"CREATE SCHEMA IF NOT EXISTS {_schema}"; + ExecuteSql(sql); + } + + private void CreateRole() + { + var sql = $"CREATE ROLE {_user} LOGIN PASSWORD '{_password}';"; + ExecuteSql(sql); + + var sql1 = $"ALTER ROLE {_user} SET search_path='{_schema}';"; + ExecuteSql(sql1); + + } + + private void GrantSchemaRights() + { + var sql = $"GRANT USAGE ON SCHEMA {_schema} TO {_user};"; + ExecuteSql(sql); + + var sql1 = $"ALTER DEFAULT PRIVILEGES IN SCHEMA {_schema} " + + $"GRANT INSERT, SELECT, UPDATE PRIVILEGES ON TABLES TO {_user};"; + ExecuteSql(sql1); + + var sql2 = $"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA {_schema} TO {_user};"; + ExecuteSql(sql2); + + } + } +} diff --git a/Database/Core/SetupIdentitySystem.cs b/Database/Core/DDL/SetupIdentitySystem.cs similarity index 99% rename from Database/Core/SetupIdentitySystem.cs rename to Database/Core/DDL/SetupIdentitySystem.cs index 6400ce1..072106e 100644 --- a/Database/Core/SetupIdentitySystem.cs +++ b/Database/Core/DDL/SetupIdentitySystem.cs @@ -1,7 +1,7 @@ using Insight.Database; using System.Data; -namespace Database.Core +namespace Database.Core.DataDefinitionLanguage { public interface IDbSetup { diff --git a/Database/Tenants/Setup.cs b/Database/Tenants/Setup.cs deleted file mode 100644 index 61dcd62..0000000 --- a/Database/Tenants/Setup.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Data; -using System.Text.RegularExpressions; -using Database.Common; -using Insight.Database; - -namespace Database.Tenants -{ - public class Setup - { - - IDbConnection _db; - string _schema; - string _user; - string _password; - - public Setup(IDbConnection db) - { - _db = db; - } - - public void CreateUserWithSchemaInDatabase(string schema, string user, string password) - { - - _schema = schema; - _password = password; - _user = user; - - if (!Validations.IsValidSchemaName(_schema)) - throw new ArgumentException("Invalid schema name", _schema); - - using (var transaction = _db.BeginTransaction()) - { - try - { - CreateSchema(); - CreateRole(); - GrantSchemaRights(); - - transaction.Commit(); - } - catch (Exception ex) - { - transaction.Rollback(); - throw new InvalidOperationException("Failed to CreateUserWithSchemaInDatabase", ex); - } - } - - - - - } - private void ExecuteSql(string sql) - { - _db.ExecuteSql(sql); - } - - private void CreateSchema() - { - var sql = $"CREATE SCHEMA IF NOT EXISTS {_schema}"; - ExecuteSql(sql); - } - - private void CreateRole() - { - var sql = $"CREATE ROLE {_user} LOGIN PASSWORD '{_password}';"; - ExecuteSql(sql); - - var sql1 = $"ALTER ROLE {_user} SET search_path='{_schema}';"; - ExecuteSql(sql1); - - } - - private void GrantSchemaRights() - { - var sql = $"GRANT USAGE ON SCHEMA {_schema} TO {_user};"; - ExecuteSql(sql); - - var sql1 = $"ALTER DEFAULT PRIVILEGES IN SCHEMA {_schema} " + - $"GRANT INSERT, SELECT, UPDATE PRIVILEGES ON TABLES TO {_user};"; - ExecuteSql(sql1); - - var sql2 = $"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA {_schema} TO {_user};"; - ExecuteSql(sql2); - - } - } -} diff --git a/SetupInfrastructure/Program.cs b/SetupInfrastructure/Program.cs index fcc0471..7b6da29 100644 --- a/SetupInfrastructure/Program.cs +++ b/SetupInfrastructure/Program.cs @@ -1,48 +1,136 @@ using Autofac; +using Insight.Database; +using System.Data; namespace SetupInfrastructure { - /// - /// SETUP APPLICATION USER NAMED sathumper - /// - /// This should be handled on the Postgresql db server with a superadmin or similar. - /// - /// Execute SQL CreateRole.txt - /// - /// After that is executed it is time for running this main program - /// Remember to use the newly created sathumper - /// "ConnectionStrings": { - /// "DefaultConnection": "Host=192.168.1.57;Port=5432;Database=ptdb01;User Id=sathumper;Password=;" - /// - internal class Program - { - static async Task Main(string[] args) - { - string userPass; - do - { - Console.WriteLine("Input username:password"); - userPass = Console.ReadLine() ?? string.Empty; - } while (!userPass.Contains(":") || userPass.Split(":").Length != 2 || - string.IsNullOrEmpty(userPass.Split(":")[0]) || - string.IsNullOrEmpty(userPass.Split(":")[1])); + /// + /// SETUP APPLICATION USER NAMED sathumper + /// + /// This should be handled on the Postgresql db server with a superadmin or similar. + /// + /// Execute SQL CreateRole.txt + /// + /// After that is executed it is time for running this main program + /// Remember to use the newly created sathumper + /// "ConnectionStrings": { + /// "DefaultConnection": "Host=192.168.1.57;Port=5432;Database=ptdb01;User Id=;Password=;" + /// + internal class Program + { + static IContainer _container; - var ctp = new Startup.ConnectionStringTemplateParameters( - user: userPass.Split(":")[0], - pwd: userPass.Split(":")[1] - ); - var container = new Startup().ConfigureContainer(ctp); + static async Task Main(string[] args) + { + string userPass; - // SetupIdentitySystem - // ConfigurationDatabaseSetup - // input configurations!!! TODO:Missing + try + { + do + { + Console.WriteLine("Input :"); + userPass = Console.ReadLine() ?? string.Empty; + } while (!userPass.Contains(":") || userPass.Split(":").Length != 2 || + string.IsNullOrEmpty(userPass.Split(":")[0]) || + string.IsNullOrEmpty(userPass.Split(":")[1])); + + var ctp = new Startup.ConnectionStringTemplateParameters( + user: userPass.Split(":")[0], + pwd: userPass.Split(":")[1] + ); + _container = new Startup().ConfigureContainer(ctp); + + if (TestDbRole()) + { + + // SetupApplicationUser + // SetupIdentitySystem + // SetupConfiguration + //and a lot of other tables that we haven't defined yet + + // input configurations!!! TODO:Missing - } - } + } + + } + + catch (Exception e) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(e); + + } + + + } + + static bool TestDbRole() + { + var backgroundColor = Console.BackgroundColor; + var foregroundColor = Console.ForegroundColor; + + //test db access + Console.WriteLine("Testing db access..."); + + string query = @"SELECT usename, usesuper FROM pg_user WHERE usename = CURRENT_USER;"; + + var conn = _container.Resolve(); + var result = (dynamic)conn.QuerySql(query).Single(); + + string username = result.usename; + bool isSuperuser = (bool)result.usesuper; + + if ((bool)result.usesuper) + { + Console.ForegroundColor = ConsoleColor.Green; + Console.BackgroundColor = ConsoleColor.Yellow; + Console.WriteLine(); + Console.WriteLine("TEST SUCCESSFULLY"); + Console.WriteLine(); + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = backgroundColor; + Console.WriteLine("-------------------------------"); + Console.WriteLine(); + Console.WriteLine($"Username: {username}"); + Console.WriteLine($"Super admin: true"); + Console.WriteLine(); + Console.WriteLine("-------------------------------"); + + + Console.WriteLine("Press any key to start database setup"); + Console.Read(); + + return true; + } + + + Console.ForegroundColor = ConsoleColor.Green; + Console.BackgroundColor = ConsoleColor.Red; + Console.WriteLine(); + Console.WriteLine("TEST WAS NOT SUCCESSFULLY"); + Console.WriteLine(); + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = backgroundColor; + Console.WriteLine("-------------------------------"); + Console.WriteLine(); + Console.WriteLine($"Username: {username}"); + Console.WriteLine($"Super admin: false"); + Console.WriteLine(); + Console.WriteLine("-------------------------------"); + + + Console.WriteLine("User is required to be super admin"); + Console.Read(); + + return false; + + + } + } } diff --git a/SetupInfrastructure/SetupInfrastructure.csproj b/SetupInfrastructure/SetupInfrastructure.csproj index ac3a41d..9f1d266 100644 --- a/SetupInfrastructure/SetupInfrastructure.csproj +++ b/SetupInfrastructure/SetupInfrastructure.csproj @@ -1,20 +1,19 @@  - - Exe - net8.0 - enable - enable - + + Exe + net8.0 + enable + - - - + + + - - - Always - - + + + Always + + diff --git a/SetupInfrastructure/Startup.cs b/SetupInfrastructure/Startup.cs index aac2e6f..c047aea 100644 --- a/SetupInfrastructure/Startup.cs +++ b/SetupInfrastructure/Startup.cs @@ -10,7 +10,7 @@ namespace SetupInfrastructure public virtual IConfigurationRoot Configuration() { var configuration = new ConfigurationBuilder() - .AddJsonFile("appconfiguration.dev.json") + .AddJsonFile("appconfiguration.json") .Build(); return configuration; diff --git a/SetupInfrastructure/appconfiguration.json b/SetupInfrastructure/appconfiguration.json index 684dac2..7607c57 100644 --- a/SetupInfrastructure/appconfiguration.json +++ b/SetupInfrastructure/appconfiguration.json @@ -1,7 +1,7 @@ { "AllowedHosts": "*", "ConnectionStrings": { - "DefaultConnection": "Host=192.168.1.57;Port=5432;Database=ptdb01;User Id={usr};Password={pwd};" + "DefaultConnection": "Host=192.168.1.57;Port=5432;Database=ptmain;User Id={usr};Password={pwd};" }, "ApplicationInsights": { "ConnectionString": "InstrumentationKey=6d2e76ee-5343-4691-a5e3-81add43cb584;IngestionEndpoint=https://northeurope-0.in.applicationinsights.azure.com/" diff --git a/SqlManagement/.dbeaver/.credentials-config.json.bak b/SqlManagement/.dbeaver/.credentials-config.json.bak index 0568d24..95f3cea 100644 Binary files a/SqlManagement/.dbeaver/.credentials-config.json.bak and b/SqlManagement/.dbeaver/.credentials-config.json.bak differ diff --git a/SqlManagement/.dbeaver/.data-sources.json.bak b/SqlManagement/.dbeaver/.data-sources.json.bak index 253676f..ba364e4 100644 --- a/SqlManagement/.dbeaver/.data-sources.json.bak +++ b/SqlManagement/.dbeaver/.data-sources.json.bak @@ -9,8 +9,7 @@ "configuration": { "host": "192.168.1.57", "port": "5432", - "database": "postgres", - "url": "jdbc:postgresql://192.168.1.57:5432/postgres", + "url": "jdbc:postgresql://192.168.1.57:5432/", "configurationType": "MANUAL", "home": "postgresql_client", "type": "dev", diff --git a/SqlManagement/.dbeaver/.project-metadata.json.bak b/SqlManagement/.dbeaver/.project-metadata.json.bak index cf4d1a0..a675f9d 100644 --- a/SqlManagement/.dbeaver/.project-metadata.json.bak +++ b/SqlManagement/.dbeaver/.project-metadata.json.bak @@ -1 +1 @@ -{"resources":{"Scripts/Script-2.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01"},"Scripts/SmartConfigSystem.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01","default-schema":"ptmain"},"Scripts/grant-privileges.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01"}}} \ No newline at end of file +{"resources":{"Scripts/Script-1.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"postgres"},"Scripts/Script-2.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01"},"Scripts/Script-3.sql":{"default-datasource":"postgres-jdbc-19484872d85-cd2a4a40116e706","default-catalog":"ptdb01","default-schema":"ptmain"},"Scripts/Script-4.sql":{"default-datasource":"postgres-jdbc-19484872d85-cd2a4a40116e706","default-catalog":"ptdb01","default-schema":"ptmain"},"Scripts/Script-5.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"sandbox"},"Scripts/Script.sql":{"default-datasource":"postgres-jdbc-19484872d85-cd2a4a40116e706","default-catalog":"sandbox","default-schema":"public"},"Scripts/SmartConfigSystem.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"sandbox"},"Scripts/grant-privileges.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01"}}} \ No newline at end of file diff --git a/SqlManagement/.dbeaver/credentials-config.json b/SqlManagement/.dbeaver/credentials-config.json index 804772a..d6c80af 100644 Binary files a/SqlManagement/.dbeaver/credentials-config.json and b/SqlManagement/.dbeaver/credentials-config.json differ diff --git a/SqlManagement/.dbeaver/data-sources.json b/SqlManagement/.dbeaver/data-sources.json index 253676f..6bd4c37 100644 --- a/SqlManagement/.dbeaver/data-sources.json +++ b/SqlManagement/.dbeaver/data-sources.json @@ -9,8 +9,8 @@ "configuration": { "host": "192.168.1.57", "port": "5432", - "database": "postgres", - "url": "jdbc:postgresql://192.168.1.57:5432/postgres", + "database": "ptmain", + "url": "jdbc:postgresql://192.168.1.57:5432/ptmain", "configurationType": "MANUAL", "home": "postgresql_client", "type": "dev", @@ -34,34 +34,6 @@ }, "auth-model": "native" } - }, - "postgres-jdbc-19484872d85-cd2a4a40116e706": { - "provider": "postgresql", - "driver": "postgres-jdbc", - "name": "UB-KK01-sathumper", - "configuration": { - "host": "192.168.1.57", - "port": "5432", - "database": "postgres", - "url": "jdbc:postgresql://192.168.1.57:5432/postgres", - "configurationType": "MANUAL", - "home": "postgresql_client", - "type": "dev", - "closeIdleConnection": true, - "provider-properties": { - "@dbeaver-show-non-default-db@": "true", - "@dbeaver-chosen-role@": "", - "@dbeaver-show-template-db@": "false", - "@dbeaver-show-unavailable-db@": "false", - "show-database-statistics": "false", - "@dbeaver-read-all-data-types-db@": "false", - "read-keys-with-columns": "false", - "@dbeaver-use-prepared-statements-db@": "false", - "postgresql.dd.plain.string": "false", - "postgresql.dd.tag.string": "false" - }, - "auth-model": "native" - } } }, "connection-types": { diff --git a/SqlManagement/.dbeaver/project-metadata.json b/SqlManagement/.dbeaver/project-metadata.json index 877db95..ff0a6f6 100644 --- a/SqlManagement/.dbeaver/project-metadata.json +++ b/SqlManagement/.dbeaver/project-metadata.json @@ -1 +1 @@ -{"resources":{"Scripts/Script-1.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01","default-schema":"ptmain"},"Scripts/Script-2.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01"},"Scripts/SmartConfigSystem.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01"},"Scripts/grant-privileges.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01"}}} \ No newline at end of file +{"resources":{"Scripts/SmartConfigSystem.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"sandbox"},"Scripts/grant-privileges.sql":{"default-datasource":"postgres-jdbc-1948450a8b4-5fc9eec404e65c44","default-catalog":"ptdb01"}}} \ No newline at end of file diff --git a/SqlManagement/Scripts/Script-1.sql b/SqlManagement/Scripts/Script-1.sql deleted file mode 100644 index e69de29..0000000 diff --git a/SqlManagement/Scripts/Script-2.sql b/SqlManagement/Scripts/Script-2.sql deleted file mode 100644 index 2d5b856..0000000 --- a/SqlManagement/Scripts/Script-2.sql +++ /dev/null @@ -1,99 +0,0 @@ - - - - -GRANT USAGE, CREATE ON SCHEMA swp TO sathumper; - -ALTER DEFAULT PRIVILEGES IN SCHEMA swp -GRANT ALL PRIVILEGES ON TABLES TO sathumper; - -GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA swp TO sathumper; - -GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA swp TO sathumper; - - -select * from dev.app_configuration - -CREATE OR REPLACE FUNCTION dev.notify_config_change() -RETURNS TRIGGER AS $$ -BEGIN - IF TG_OP = 'DELETE' THEN - PERFORM pg_notify( - 'config_changes', - json_build_object('operation', TG_OP, 'data', row_to_json(OLD))::text - ); - RETURN OLD; -- Return OLD for DELETE operations - ELSE - PERFORM pg_notify( - 'config_changes', - json_build_object('operation', TG_OP, 'data', row_to_json(NEW))::text - ); - RETURN NEW; -- Return NEW for INSERT/UPDATE operations - END IF; -END; -$$ LANGUAGE plpgsql; - - - --- Trigger på configuration tabellen -CREATE TRIGGER config_change_trigger -AFTER INSERT OR UPDATE OR DELETE ON dev.app_configuration -FOR EACH ROW EXECUTE FUNCTION dev.notify_config_change(); - - -update dev.app_configuration -set "label" = "label" where id = 3 - -SELECT row_to_json(t) -FROM (SELECT 1 as id, 'test' as key) t; - -SET myapp.tenant_id = '1'; - -SHOW myapp.tenant_id; - -create TABLE dev.app_configuration1 ( - tenant_id varchar(25), - config_key VARCHAR(255), - config_value TEXT, - PRIMARY KEY (tenant_id, config_key) -); - -ALTER TABLE dev.app_configuration1 ENABLE ROW LEVEL SECURITY; - -CREATE drop POLICY tenant_policy -ON dev.app_configuration1 -FOR SELECT -USING ( - current_setting('myapp.tenant_id', true) IS NOT NULL AND - tenant_id = current_setting('myapp.tenant_id')::INT -); - -CREATE POLICY tenant_policy -ON dev.app_configuration1 -FOR SELECT -USING ( - tenant_id::text = current_user -); - -insert into dev.app_configuration1 -(tenant_id, config_key, config_value) values('dev', 't2', 'best dat') - -SET myapp.tenant_id = 0 - -ALTER USER din_bruger NOBYPASS RLS; -select * from dev.app_configuration1 - -SHOW row_security; - - - - -GRANT USAGE, CREATE ON SCHEMA dev TO sathumper; - -ALTER DEFAULT PRIVILEGES IN SCHEMA dev -GRANT ALL PRIVILEGES ON TABLES TO sathumper; - -GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA dev TO sathumper; - -GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA dev TO sathumper; -