Commit cccef077ba324775f8f780b28e430559c4850b5e

Authored by Schwirg László
1 parent 8d42e5c0

- add database user and sql server login

Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs
@@ -306,6 +306,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS @@ -306,6 +306,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS
306 public static class RelocatePhysicalFiles { public const string KEY = "COP"; } 306 public static class RelocatePhysicalFiles { public const string KEY = "COP"; }
307 public static class ShrinkDB { public const string KEY = "SHR"; } 307 public static class ShrinkDB { public const string KEY = "SHR"; }
308 public static class ExecuteScript{ public const string KEY = "EXE"; } 308 public static class ExecuteScript{ public const string KEY = "EXE"; }
  309 + public static class CreateLoginAndUser{ public const string KEY = "CRU"; }
  310 + public static class AddUserForLogin{ public const string KEY = "CRA"; }
309 } 311 }
310 } 312 }
311 313
Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs
@@ -25,6 +25,7 @@ using System.Text.RegularExpressions; @@ -25,6 +25,7 @@ using System.Text.RegularExpressions;
25 25
26 using Microsoft.SqlServer.Management.Common; 26 using Microsoft.SqlServer.Management.Common;
27 using Microsoft.SqlServer.Management.Smo; 27 using Microsoft.SqlServer.Management.Smo;
  28 +using System.Data.SqlClient;
28 29
29 namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS 30 namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
30 { 31 {
@@ -50,6 +51,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS @@ -50,6 +51,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
50 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.RelocatePhysicalFiles.KEY, "Copy database and or relocate its physical files", RelocatePhysicalFiles, ep)) 51 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.RelocatePhysicalFiles.KEY, "Copy database and or relocate its physical files", RelocatePhysicalFiles, ep))
51 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.ShrinkDB.KEY, "Shrink database", ShrinkDB, ep)) 52 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.ShrinkDB.KEY, "Shrink database", ShrinkDB, ep))
52 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.ExecuteScript.KEY, "Execute script", ExecuteScript, ep)) 53 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.ExecuteScript.KEY, "Execute script", ExecuteScript, ep))
  54 + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateLoginAndUser.KEY, "Create Server login and database user", CreteLoginAndAddToDB, ep))
  55 + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.AddUserForLogin.KEY, "Add database user to an existing Login", AddExistingLoginToDB, ep))
53 .SetSelectionMode(Menu.SelectionMode.Single) 56 .SetSelectionMode(Menu.SelectionMode.Single)
54 .SetMenuHeaderDisplayer(DataBaseListDisplayer); 57 .SetMenuHeaderDisplayer(DataBaseListDisplayer);
55 menufunctions.ExecuteMenu(functionkey); 58 menufunctions.ExecuteMenu(functionkey);
@@ -220,6 +223,101 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS @@ -220,6 +223,101 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
220 } 223 }
221 return o; 224 return o;
222 } 225 }
  226 + private static object CreteLoginAndAddToDB(object parameter, object o) { return _CreteLoginAndUser(parameter, o, true); }
  227 + private static object AddExistingLoginToDB(object parameter, object o) { return _CreteLoginAndUser(parameter, o, false); }
  228 + private static object _CreteLoginAndUser(object parameter, object o,bool createlogin)
  229 + {
  230 + const string COMMA = ",";
  231 + var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
  232 + var args = (parameter as Menu.ExecutorParameter).Args;
  233 + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS);
  234 + var functionname = createlogin ? nameof(CreteLoginAndAddToDB) : nameof(AddExistingLoginToDB);
  235 + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function '{functionname}'!", silent: true);
  236 + Menu.Selection sr = menufolders.Select(selectedtaskindexes);
  237 + if (sr.Result == Menu.SelectionResult.Exit) { return o; }
  238 + else if (sr.Result == Menu.SelectionResult.None) { return o; }
  239 + else if (sr.Result == Menu.SelectionResult.Error) { return o; }
  240 + else if (sr.Result == Menu.SelectionResult.Ok) { }
  241 + else { }
  242 + string dbusername = null;
  243 + string password = null;
  244 + string rolenamecommalist = null;
  245 + int loopindex = 0;
  246 + bool effectivecreatelogin = createlogin;
  247 + foreach (var p in sr.SelectedParameterList)
  248 + {
  249 + effectivecreatelogin = createlogin && loopindex == 0;
  250 + SQLDataBase sqld = p.Parameters as SQLDataBase;
  251 + try
  252 + {
  253 + var enabledrolelist = new string[] { "db_datareader", "db_datawriter", "db_accessadmin", "db_securityadmin", "db_backupoperator" };
  254 + if (effectivecreatelogin)
  255 + {
  256 + ColorConsole.WriteLine(prefix: $"Enter the parameters for creating user for database: {sqld.DBName}. Format:", bracket: "()", text: "DBUSERNAME,PASSWORD,ROLENAME,ROLENAME,ROLENAME...", f: ConsoleColor.Yellow);
  257 + }
  258 + else
  259 + {
  260 + ColorConsole.WriteLine(prefix: $"Enter the parameters for creating user for database: {sqld.DBName}. Format:", bracket: "()", text: "DBUSERNAME,ROLENAME,ROLENAME,ROLENAME...", f: ConsoleColor.Yellow);
  261 + if (createlogin)
  262 + {
  263 + ColorConsole.WriteLine(prefix: $"Press [Enter] to use parameters set in the previous loop.", bracket: "()", text: $"{dbusername},{rolenamecommalist}", f: ConsoleColor.Yellow);
  264 + }
  265 + }
  266 + ColorConsole.WriteLine(prefix: " ", text: "DBUSERNAME", bracket: "", suffix: $": dbusername (server login name; must exist when adding login to DB)");
  267 + if (effectivecreatelogin)
  268 + {
  269 + ColorConsole.WriteLine(prefix: " ", text: "PASSWORD", bracket: "", suffix: $": password for login");
  270 + }
  271 + ColorConsole.WriteLine(prefix: " ", text: "ROLENAME", bracket: "", suffix: $": One of these->" + string.Join(COMMA, enabledrolelist));
  272 +
  273 + var createuseroptions = ColorConsole.ReadLine($"EX=exit.", ConsoleColor.Yellow, suffix: " --> ");
  274 + if (createuseroptions.ToUpper() == "EX") { continue; }
  275 + if (loopindex>0 && string.IsNullOrWhiteSpace(createuseroptions)) { createuseroptions = $"{dbusername},{rolenamecommalist}"; }
  276 +
  277 + dbusername = null;
  278 + password = null;
  279 + rolenamecommalist = null;
  280 + var optionList = createuseroptions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  281 + if (effectivecreatelogin)
  282 + {
  283 + if (optionList.Length < 3) { ColorConsole.WriteLine("ERROR! USERNAME,PASSWORD and at least one ROLENAME are required", ConsoleColor.Red); continue; }
  284 + }
  285 + else
  286 + {
  287 + if (optionList.Length < 2) { ColorConsole.WriteLine("ERROR! USERNAME and at least one ROLENAME are required", ConsoleColor.Red); continue; }
  288 + }
  289 + //012345678
  290 + //uuu,ppp,r1,r2,r3
  291 + dbusername = optionList[0];
  292 + password = effectivecreatelogin ? optionList[1]:null;
  293 + //rolenamecommalist = cretauseroptions.Substring(username.Length + password.Length + 2);
  294 + var rolenameList = optionList.Skip(effectivecreatelogin ? 2:1).ToArray();
  295 + List<string> badrolenames = new List<string>();
  296 + foreach (var rolename in rolenameList)
  297 + {
  298 + if (!enabledrolelist.Contains(rolename)) { badrolenames.Add(rolename); }
  299 + }
  300 + if (badrolenames.Count > 0) { ColorConsole.WriteLine($"ERROR! {string.Join(COMMA, badrolenames)} are not available!", ConsoleColor.Red); continue; }
  301 + rolenamecommalist = string.Join(",", rolenameList);
  302 +
  303 + if (effectivecreatelogin)
  304 + {
  305 + SQLDataBaseManagerCore.CreateLogin(sqld.SQLCS, dbusername, password, "master", null);
  306 + SQLDataBaseManagerCore.CreateUser(sqld.SQLCS, dbusername, rolenamecommalist);
  307 + ColorConsole.WriteLine($"Login and DB users created. DB name:{sqld.DBName}, login and DB username:{dbusername}, password:{password},rolelist={rolenamecommalist}.", ConsoleColor.Green);
  308 + }
  309 + else
  310 + {
  311 + SQLDataBaseManagerCore.CreateUser(sqld.SQLCS, dbusername, rolenamecommalist);
  312 + ColorConsole.WriteLine($"DB user created. DB name:{sqld.DBName}, DB username:{dbusername}, rolelist={rolenamecommalist}.", ConsoleColor.Green);
  313 + }
  314 + }
  315 + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red);continue; }
  316 + loopindex++;
  317 + }
  318 + return o;
  319 + }
  320 +
223 private static object ExecuteScript(object parameter, object o) 321 private static object ExecuteScript(object parameter, object o)
224 { 322 {
225 var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>(); 323 var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
@@ -627,6 +725,47 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS @@ -627,6 +725,47 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
627 sqlserver.Logins["a"].Refresh(); 725 sqlserver.Logins["a"].Refresh();
628 return SQLServerConnect(cs).ConnectionContext.ConnectionString; 726 return SQLServerConnect(cs).ConnectionContext.ConnectionString;
629 } 727 }
  728 + public static void CreateUser(string sqldbconnectionString, string dbusername, string dbrolenamecommalist)
  729 + {
  730 + using (SqlConnection connection = new SqlConnection(sqldbconnectionString))
  731 + {
  732 + connection.Open();
  733 + // Create user
  734 + //USE [LearALM2]
  735 + //DROP USER[datareader]
  736 +
  737 + string createUserQuery = "CREATE USER [" + dbusername + "] FOR LOGIN [" + dbusername + "];";
  738 + using (SqlCommand createUserCommand = new SqlCommand(createUserQuery, connection)) { createUserCommand.ExecuteNonQuery(); }
  739 + //--ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_BasicAccess] TO[dbo]
  740 + //--ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_FullAccess] TO[dbo]
  741 + // Grant permissions (optional)
  742 + var rolenameList = dbrolenamecommalist.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
  743 + foreach (var rolename in rolenameList)
  744 + {
  745 + string grantPermissionsQuery = "EXEC sp_addrolemember N'"+ rolename + "', N'"+ dbusername + "'";
  746 + using (SqlCommand grantPermissionsCommand = new SqlCommand(grantPermissionsQuery, connection)) { grantPermissionsCommand.ExecuteNonQuery(); }
  747 + }
  748 + }
  749 + }
  750 + public static void CreateLogin(string sqldbconnectionString, string name, string password, string defaultDatabase, string[] roles)
  751 + {
  752 + var _server = SQLServerConnect(sqldbconnectionString);
  753 + Login login = new Login(_server, name);
  754 + login.LoginType = LoginType.SqlLogin;
  755 + login.DefaultDatabase = defaultDatabase;
  756 +
  757 + login.PasswordExpirationEnabled = false;
  758 + login.PasswordPolicyEnforced = false;
  759 +
  760 + login.Create(password, LoginCreateOptions.None);
  761 +
  762 + for (int i = 0; i < (roles==null?-1:roles.Length); i++) { login.AddToRole(roles[i]); }
  763 +
  764 + login.Alter();
  765 + login.Enable();
  766 + login.Alter();
  767 + }
  768 +
630 public static void ConfigureWindowsUser(string cs, string sapassword, string databasename, string windowsfullusername,string windowsuserpassword,List<string> rolenamelist) 769 public static void ConfigureWindowsUser(string cs, string sapassword, string databasename, string windowsfullusername,string windowsuserpassword,List<string> rolenamelist)
631 { 770 {
632 var sqlserver = SQLServerConnect(cs); 771 var sqlserver = SQLServerConnect(cs);
@@ -1180,7 +1319,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS @@ -1180,7 +1319,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
1180 #endregion BackupSqlData 1319 #endregion BackupSqlData
1181 #endregion private methods 1320 #endregion private methods
1182 } 1321 }
1183 -#endregion class SQLDataBaseManager 1322 + #endregion class SQLDataBaseManager
1184 1323
1185 #region SQLDataBaseManager class 1324 #region SQLDataBaseManager class
1186 public class SQLDataBaseManagerXmlProcessor : XmlParser 1325 public class SQLDataBaseManagerXmlProcessor : XmlParser
Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices; @@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
32 // You can specify all the values or you can default the Build and Revision Numbers 32 // You can specify all the values or you can default the Build and Revision Numbers
33 // by using the '*' as shown below: 33 // by using the '*' as shown below:
34 // [assembly: AssemblyVersion("1.0.*")] 34 // [assembly: AssemblyVersion("1.0.*")]
35 -[assembly: AssemblyVersion("1.23.0.0")]  
36 -[assembly: AssemblyFileVersion("1.23.0.0")] 35 +[assembly: AssemblyVersion("1.24.0.0")]
  36 +[assembly: AssemblyFileVersion("1.24.0.0")]