From cccef077ba324775f8f780b28e430559c4850b5e Mon Sep 17 00:00:00 2001 From: Schwirg László Date: Fri, 19 Jul 2024 17:40:41 +0200 Subject: [PATCH] - add database user and sql server login --- Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs | 2 ++ Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs | 4 ++-- 3 files changed, 144 insertions(+), 3 deletions(-) diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs index 338bd99..1160b8f 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs @@ -306,6 +306,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS public static class RelocatePhysicalFiles { public const string KEY = "COP"; } public static class ShrinkDB { public const string KEY = "SHR"; } public static class ExecuteScript{ public const string KEY = "EXE"; } + public static class CreateLoginAndUser{ public const string KEY = "CRU"; } + public static class AddUserForLogin{ public const string KEY = "CRA"; } } } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs index dedc975..af0eb56 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs @@ -25,6 +25,7 @@ using System.Text.RegularExpressions; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Smo; +using System.Data.SqlClient; namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS { @@ -50,6 +51,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.RelocatePhysicalFiles.KEY, "Copy database and or relocate its physical files", RelocatePhysicalFiles, ep)) .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.ShrinkDB.KEY, "Shrink database", ShrinkDB, ep)) .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.ExecuteScript.KEY, "Execute script", ExecuteScript, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateLoginAndUser.KEY, "Create Server login and database user", CreteLoginAndAddToDB, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.AddUserForLogin.KEY, "Add database user to an existing Login", AddExistingLoginToDB, ep)) .SetSelectionMode(Menu.SelectionMode.Single) .SetMenuHeaderDisplayer(DataBaseListDisplayer); menufunctions.ExecuteMenu(functionkey); @@ -220,6 +223,101 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS } return o; } + private static object CreteLoginAndAddToDB(object parameter, object o) { return _CreteLoginAndUser(parameter, o, true); } + private static object AddExistingLoginToDB(object parameter, object o) { return _CreteLoginAndUser(parameter, o, false); } + private static object _CreteLoginAndUser(object parameter, object o,bool createlogin) + { + const string COMMA = ","; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); + var functionname = createlogin ? nameof(CreteLoginAndAddToDB) : nameof(AddExistingLoginToDB); + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function '{functionname}'!", silent: true); + Menu.Selection sr = menufolders.Select(selectedtaskindexes); + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + string dbusername = null; + string password = null; + string rolenamecommalist = null; + int loopindex = 0; + bool effectivecreatelogin = createlogin; + foreach (var p in sr.SelectedParameterList) + { + effectivecreatelogin = createlogin && loopindex == 0; + SQLDataBase sqld = p.Parameters as SQLDataBase; + try + { + var enabledrolelist = new string[] { "db_datareader", "db_datawriter", "db_accessadmin", "db_securityadmin", "db_backupoperator" }; + if (effectivecreatelogin) + { + ColorConsole.WriteLine(prefix: $"Enter the parameters for creating user for database: {sqld.DBName}. Format:", bracket: "()", text: "DBUSERNAME,PASSWORD,ROLENAME,ROLENAME,ROLENAME...", f: ConsoleColor.Yellow); + } + else + { + ColorConsole.WriteLine(prefix: $"Enter the parameters for creating user for database: {sqld.DBName}. Format:", bracket: "()", text: "DBUSERNAME,ROLENAME,ROLENAME,ROLENAME...", f: ConsoleColor.Yellow); + if (createlogin) + { + ColorConsole.WriteLine(prefix: $"Press [Enter] to use parameters set in the previous loop.", bracket: "()", text: $"{dbusername},{rolenamecommalist}", f: ConsoleColor.Yellow); + } + } + ColorConsole.WriteLine(prefix: " ", text: "DBUSERNAME", bracket: "", suffix: $": dbusername (server login name; must exist when adding login to DB)"); + if (effectivecreatelogin) + { + ColorConsole.WriteLine(prefix: " ", text: "PASSWORD", bracket: "", suffix: $": password for login"); + } + ColorConsole.WriteLine(prefix: " ", text: "ROLENAME", bracket: "", suffix: $": One of these->" + string.Join(COMMA, enabledrolelist)); + + var createuseroptions = ColorConsole.ReadLine($"EX=exit.", ConsoleColor.Yellow, suffix: " --> "); + if (createuseroptions.ToUpper() == "EX") { continue; } + if (loopindex>0 && string.IsNullOrWhiteSpace(createuseroptions)) { createuseroptions = $"{dbusername},{rolenamecommalist}"; } + + dbusername = null; + password = null; + rolenamecommalist = null; + var optionList = createuseroptions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + if (effectivecreatelogin) + { + if (optionList.Length < 3) { ColorConsole.WriteLine("ERROR! USERNAME,PASSWORD and at least one ROLENAME are required", ConsoleColor.Red); continue; } + } + else + { + if (optionList.Length < 2) { ColorConsole.WriteLine("ERROR! USERNAME and at least one ROLENAME are required", ConsoleColor.Red); continue; } + } + //012345678 + //uuu,ppp,r1,r2,r3 + dbusername = optionList[0]; + password = effectivecreatelogin ? optionList[1]:null; + //rolenamecommalist = cretauseroptions.Substring(username.Length + password.Length + 2); + var rolenameList = optionList.Skip(effectivecreatelogin ? 2:1).ToArray(); + List badrolenames = new List(); + foreach (var rolename in rolenameList) + { + if (!enabledrolelist.Contains(rolename)) { badrolenames.Add(rolename); } + } + if (badrolenames.Count > 0) { ColorConsole.WriteLine($"ERROR! {string.Join(COMMA, badrolenames)} are not available!", ConsoleColor.Red); continue; } + rolenamecommalist = string.Join(",", rolenameList); + + if (effectivecreatelogin) + { + SQLDataBaseManagerCore.CreateLogin(sqld.SQLCS, dbusername, password, "master", null); + SQLDataBaseManagerCore.CreateUser(sqld.SQLCS, dbusername, rolenamecommalist); + ColorConsole.WriteLine($"Login and DB users created. DB name:{sqld.DBName}, login and DB username:{dbusername}, password:{password},rolelist={rolenamecommalist}.", ConsoleColor.Green); + } + else + { + SQLDataBaseManagerCore.CreateUser(sqld.SQLCS, dbusername, rolenamecommalist); + ColorConsole.WriteLine($"DB user created. DB name:{sqld.DBName}, DB username:{dbusername}, rolelist={rolenamecommalist}.", ConsoleColor.Green); + } + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red);continue; } + loopindex++; + } + return o; + } + private static object ExecuteScript(object parameter, object o) { var config = (parameter as Menu.ExecutorParameter).GetConfig(); @@ -627,6 +725,47 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS sqlserver.Logins["a"].Refresh(); return SQLServerConnect(cs).ConnectionContext.ConnectionString; } + public static void CreateUser(string sqldbconnectionString, string dbusername, string dbrolenamecommalist) + { + using (SqlConnection connection = new SqlConnection(sqldbconnectionString)) + { + connection.Open(); + // Create user + //USE [LearALM2] + //DROP USER[datareader] + + string createUserQuery = "CREATE USER [" + dbusername + "] FOR LOGIN [" + dbusername + "];"; + using (SqlCommand createUserCommand = new SqlCommand(createUserQuery, connection)) { createUserCommand.ExecuteNonQuery(); } + //--ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_BasicAccess] TO[dbo] + //--ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_FullAccess] TO[dbo] + // Grant permissions (optional) + var rolenameList = dbrolenamecommalist.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var rolename in rolenameList) + { + string grantPermissionsQuery = "EXEC sp_addrolemember N'"+ rolename + "', N'"+ dbusername + "'"; + using (SqlCommand grantPermissionsCommand = new SqlCommand(grantPermissionsQuery, connection)) { grantPermissionsCommand.ExecuteNonQuery(); } + } + } + } + public static void CreateLogin(string sqldbconnectionString, string name, string password, string defaultDatabase, string[] roles) + { + var _server = SQLServerConnect(sqldbconnectionString); + Login login = new Login(_server, name); + login.LoginType = LoginType.SqlLogin; + login.DefaultDatabase = defaultDatabase; + + login.PasswordExpirationEnabled = false; + login.PasswordPolicyEnforced = false; + + login.Create(password, LoginCreateOptions.None); + + for (int i = 0; i < (roles==null?-1:roles.Length); i++) { login.AddToRole(roles[i]); } + + login.Alter(); + login.Enable(); + login.Alter(); + } + public static void ConfigureWindowsUser(string cs, string sapassword, string databasename, string windowsfullusername,string windowsuserpassword,List rolenamelist) { var sqlserver = SQLServerConnect(cs); @@ -1180,7 +1319,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS #endregion BackupSqlData #endregion private methods } -#endregion class SQLDataBaseManager + #endregion class SQLDataBaseManager #region SQLDataBaseManager class public class SQLDataBaseManagerXmlProcessor : XmlParser diff --git a/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs b/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs index e73e9c3..57fbe46 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.23.0.0")] -[assembly: AssemblyFileVersion("1.23.0.0")] +[assembly: AssemblyVersion("1.24.0.0")] +[assembly: AssemblyFileVersion("1.24.0.0")] -- libgit2 0.21.2