bin/projects/dbatools/dbatools/Parameter/DbaCredentialParameter.cs
using System; using System.Collections.Generic; using System.Linq; using System.Management.Automation; using System.Net; using System.Security; using System.Text; using System.Threading.Tasks; namespace Sqlcollaborative.Dbatools.Parameter { /// <summary> /// Parameter class that handles the various kinds of credential input /// </summary> [System.ComponentModel.TypeConverter(typeof(TypeConversion.DbaCredentialParameterConverter))] public class DbaCredentialParameter : IConvertible { #region Fields of contract /// <summary> /// The credential object received /// </summary> [ParameterContract(ParameterContractType.Field, ParameterContractBehavior.Mandatory)] public PSCredential Credential; /// <summary> /// The name of the credential object /// </summary> [ParameterContract(ParameterContractType.Field, ParameterContractBehavior.Mandatory)] public string UserName { get { return Credential.UserName; } } /// <summary> /// The password of the credential object /// </summary> [ParameterContract(ParameterContractType.Field, ParameterContractBehavior.Mandatory)] public SecureString Password { get { return Credential.Password; } } #endregion Fields of contract #region Constructors /// <summary> /// Creates a credential parameter from a PSCredential object /// </summary> /// <param name="Credential">A PSCredential object</param> public DbaCredentialParameter(PSCredential Credential) { this.Credential = Credential; } /// <summary> /// Creates a credential parameter from a NetworkCredential object /// </summary> /// <param name="Credential">The credentials to use</param> public DbaCredentialParameter(NetworkCredential Credential) { this.Credential = new PSCredential(String.Format("{0}\\{1}", Credential.Domain, Credential.UserName).Trim('\\'), Credential.SecurePassword); } /// <summary> /// Creates a credential parameter from a string only. Will prompt the user for the rest of the input. Will provide an option to remember the credential under the name provided /// </summary> /// <param name="UserName">The username (and domain name as may be the case) to put a credential around</param> public DbaCredentialParameter(string UserName) { if (CredentialStore.ContainsKey(UserName.ToLower())) { Credential = CredentialStore[UserName.ToLower()]; } else if (dbaSystem.SystemHost.UnattendedMode) throw new InvalidOperationException("Cannot prompt for credentials in unattended mode!"); else Credential = PromptForCredential(UserName); } /// <summary> /// Creates a credential parameter from anything it nows how to handle /// </summary> /// <param name="Credential">The object to convert</param> public DbaCredentialParameter(object Credential) { if (Credential is NetworkCredential) this.Credential = (new DbaCredentialParameter((NetworkCredential)Credential)).Credential; else if (Credential is PSCredential) this.Credential = (PSCredential)Credential; else throw new PSArgumentException("Invalid input type"); } #endregion Constructors #region Conversion /// <summary> /// Implicitly converts from DbaCredentialParameter to PSCredential /// </summary> /// <param name="Input">The DbaCredentialParameter to convert</param> [ParameterContract(ParameterContractType.Operator, ParameterContractBehavior.Conversion)] public static implicit operator PSCredential(DbaCredentialParameter Input) { return Input.Credential; } /// <summary> /// Implicitly converts a PSCredential object to DbaCredenitalParameter /// </summary> /// <param name="Input">The PSCredential to convert</param> public static implicit operator DbaCredentialParameter(PSCredential Input) { return new DbaCredentialParameter(Input); } /// <summary> /// Implicitly converts from DbaCredentialParameter to NetworkCredential /// </summary> /// <param name="Input">The DbaCredentialParameter to convert</param> [ParameterContract(ParameterContractType.Operator, ParameterContractBehavior.Conversion)] public static implicit operator NetworkCredential(DbaCredentialParameter Input) { return Input.Credential.GetNetworkCredential(); } /// <summary> /// Implicitly converts a NetworkCredential object to DbaCredenitalParameter /// </summary> /// <param name="Input">The NetworkCredential to convert</param> public static implicit operator DbaCredentialParameter(NetworkCredential Input) { return new DbaCredentialParameter(Input); } #endregion Conversion #region Utility /// <summary> /// Legacy wrapper. While there exists implicit conversion, this allows using the object as before, avoiding errors for unknown method. /// </summary> /// <returns>A network credential object with the same credentials as the original object</returns> [ParameterContract(ParameterContractType.Method, ParameterContractBehavior.Conversion)] public NetworkCredential GetNetworkCredential() { return Credential.GetNetworkCredential(); } /// <summary> /// Prompts the user for a password to complete a credentials object /// </summary> /// <param name="Name">The name of the user. If specified, this will be added to the prompt.</param> /// <returns>The finished PSCredential object</returns> public static PSCredential PromptForCredential(string Name = "") { Utility.CredentialPrompt prompt = Utility.CredentialPrompt.GetCredential(Name); if (prompt.Cancelled) throw new ArgumentException("No credentials specified!"); PSCredential cred = new PSCredential(prompt.Username, prompt.Password); if (prompt.Remember) CredentialStore[cred.UserName.ToLower()] = cred; return cred; } /// <summary> /// Cached credentials, if the user stors them under a name. /// </summary> internal static Dictionary<string, PSCredential> CredentialStore = new Dictionary<string, PSCredential>(); #endregion Utility #region Interface Implementation /// <summary> /// /// </summary> /// <returns></returns> public TypeCode GetTypeCode() { return TypeCode.Object; } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public bool ToBoolean(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public char ToChar(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public sbyte ToSByte(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public byte ToByte(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public short ToInt16(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public ushort ToUInt16(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public int ToInt32(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public uint ToUInt32(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public long ToInt64(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public ulong ToUInt64(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public Single ToSingle(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public double ToDouble(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public decimal ToDecimal(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public DateTime ToDateTime(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// /// </summary> /// <param name="Format"></param> /// <returns></returns> public string ToString(IFormatProvider Format) { throw new NotSupportedException(); } /// <summary> /// Tries to convert the credential parameter to one of its supported types /// </summary> /// <param name="TargetType">The type to convert to</param> /// <param name="Format">Irrelevant</param> /// <returns></returns> public object ToType(Type TargetType, IFormatProvider Format) { if (TargetType.FullName == "System.Management.Automation.PSCredential") return Credential; if (TargetType.FullName == "System.Net.NetworkCredential") return GetNetworkCredential(); throw new NotSupportedException(String.Format("Converting from {0} to {1} is not supported!", GetType().FullName, TargetType.FullName)); } #endregion Interface Implementation } } |