Source/NuGetGallery.Operations/Tasks/Database/CreateSqlUserTask.cs (74 lines of code) (raw):
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using NuGetGallery.Operations.Common;
namespace NuGetGallery.Operations.Tasks
{
[Command("createsqluser", "Creates a new DB Owner for the gallery database", AltName="csu")]
public class CreateSqlUserTask : DatabaseTask
{
[Option("The user name to create, leave the blank for the default", AltName="u")]
public string UserName { get; set; }
[Option("Set this switch to put the new Connection String in the clipboard", AltName="c")]
public bool Clip { get; set; }
public override void ValidateArguments()
{
base.ValidateArguments();
if (String.IsNullOrEmpty(UserName) && CurrentEnvironment != null)
{
UserName = String.Format("{0}-site-{1}", CurrentEnvironment.Name, DateTime.UtcNow.ToString("MMMdd-yyyy"));
}
ArgCheck.RequiredOrConfig(UserName, "UserName");
}
public override void ExecuteCommand()
{
// Generate password
var rng = new RNGCryptoServiceProvider();
byte[] data = new byte[20];
rng.GetBytes(data);
string password = Convert.ToBase64String(data);
WithMasterConnection((c, db) =>
{
if (!WhatIf)
{
db.Execute(String.Format("CREATE LOGIN [{0}] WITH PASSWORD='{1}';", UserName, password));
}
Log.Info("Created Login: {0}", UserName);
});
WithConnection((c, db) =>
{
if (!WhatIf)
{
db.Execute(String.Format("CREATE USER [{0}] FROM LOGIN [{0}];", UserName));
}
Log.Info("Created User: {0}", UserName);
if (!WhatIf)
{
db.Execute(String.Format("EXEC sp_addrolemember 'db_owner', '{0}';", UserName));
}
Log.Info("Added User to db_owner role: {0}", UserName);
});
// Generate the new connection string
var newstr = new SqlConnectionStringBuilder(ConnectionString.ConnectionString);
newstr.UserID = String.Format("{0}@{1}", UserName, Util.GetDatabaseServerName(ConnectionString));
newstr.Password = password;
if (Clip)
{
var t = new Thread(() => Clipboard.SetText(newstr.ConnectionString));
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
Log.Info("Connection String for the new user is in the clipboard");
}
else
{
Log.Info("Connection String for the new user: ");
Log.Info(newstr.ConnectionString);
}
}
}
}