Esempio n. 1
0
        ///<summary>Every optional parameter provided should coincide with a commandline arguement.
        ///The values passed in will typically override any settings loaded in from the config file.
        ///Passing in a value for webServiceUri or databaseName will cause the config file to not even be considered.</summary>
        public static ChooseDatabaseModel GetChooseDatabaseModelFromConfig(string webServiceUri = "", YN webServiceIsEcw  = YN.Unknown, string odUser = ""
                                                                           , string serverName  = "", string databaseName = "", string mySqlUser      = "", string mySqlPassword = "", string mySqlPassHash = "", YN noShow = YN.Unknown)
        {
            ChooseDatabaseModel chooseDatabaseModel = new ChooseDatabaseModel();

            //Even if we are passed a URI as a command line argument we still need to check the FreeDentalConfig file for middle tier automatic log in.
            //The only time we do not need to do that is if a direct DB has been passed in.
            if (string.IsNullOrEmpty(databaseName))
            {
                #region Config File
                //command-line support for the upper portion of this window will be added later.
                //Improvement should be made here to avoid requiring admin priv.
                //Search path should be something like this:
                //1. /home/username/.opendental/config.xml (or corresponding user path in Windows)
                //2. /etc/opendental/config.xml (or corresponding machine path in Windows) (should be default for new installs)
                //3. Application Directory/FreeDentalConfig.xml (read-only if user is not admin)
                string xmlPath = ODFileUtils.CombinePaths(Application.StartupPath, "FreeDentalConfig.xml");
                if (!File.Exists(xmlPath))
                {
                    FileStream fs;
                    try {
                        fs = File.Create(xmlPath);
                    }
                    catch (Exception) {
                        //No translation right here because we typically do not have a database connection yet.
                        throw new ODException("The very first time that the program is run, it must be run as an Admin.  "
                                              + "If using Vista, right click, run as Admin.");
                    }
                    fs.Close();
                }
                XmlDocument document = new XmlDocument();
                try {
                    document.Load(xmlPath);
                    XPathNavigator Navigator = document.CreateNavigator();
                    XPathNavigator nav;
                    //Database type
                    nav = Navigator.SelectSingleNode("//DatabaseType");
                    DataConnection.DBtype = DatabaseType.MySql;
                    if (nav != null && nav.Value == "Oracle")
                    {
                        DataConnection.DBtype = DatabaseType.Oracle;
                    }
                    nav = Navigator.SelectSingleNode("//AdminCompNames");
                    if (nav != null)
                    {
                        chooseDatabaseModel.ListAdminCompNames.Clear();                         //this method gets called more than once
                        XPathNodeIterator navIterator = nav.SelectChildren(XPathNodeType.All);
                        for (int i = 0; i < navIterator.Count; i++)
                        {
                            navIterator.MoveNext();
                            chooseDatabaseModel.ListAdminCompNames.Add(navIterator.Current.Value);                            //Add this computer name to the list.
                        }
                    }
                    //See if there's a ConnectionString
                    nav = Navigator.SelectSingleNode("//ConnectionString");
                    if (nav != null)
                    {
                        //If there is a ConnectionString, then use it.
                        chooseDatabaseModel.ConnectionString = nav.Value;
                        return(chooseDatabaseModel);
                    }
                    //See if there's a UseXWebTestGateway
                    nav = Navigator.SelectSingleNode("//UseXWebTestGateway");
                    if (nav != null)
                    {
                        OpenDentBusiness.WebTypes.Shared.XWeb.XWebs.UseXWebTestGateway = nav.Value.ToLower() == "true";
                    }
                    //See if there's a DatabaseConnection
                    nav = Navigator.SelectSingleNode("//DatabaseConnection");
                    if (nav != null)
                    {
                        //If there is a DatabaseConnection, then use it.
                        chooseDatabaseModel.CentralConnectionCur.ServerName    = nav.SelectSingleNode("ComputerName").Value;
                        chooseDatabaseModel.CentralConnectionCur.DatabaseName  = nav.SelectSingleNode("Database").Value;
                        chooseDatabaseModel.CentralConnectionCur.MySqlUser     = nav.SelectSingleNode("User").Value;
                        chooseDatabaseModel.CentralConnectionCur.MySqlPassword = nav.SelectSingleNode("Password").Value;
                        XPathNavigator encryptedPwdNode = nav.SelectSingleNode("MySQLPassHash");
                        //If the Password node is empty, but there is a value in the MySQLPassHash node, decrypt the node value and use that instead
                        string _decryptedPwd;
                        if (chooseDatabaseModel.CentralConnectionCur.MySqlPassword == "" &&
                            encryptedPwdNode != null &&
                            encryptedPwdNode.Value != "" &&
                            CDT.Class1.Decrypt(encryptedPwdNode.Value, out _decryptedPwd))
                        {
                            //decrypted value could be an empty string, which means they don't have a password set, so textPassword will be an empty string
                            chooseDatabaseModel.CentralConnectionCur.MySqlPassword = _decryptedPwd;
                        }
                        XPathNavigator noshownav = nav.SelectSingleNode("NoShowOnStartup");
                        if (noshownav != null && noshownav.Value == "True")
                        {
                            chooseDatabaseModel.NoShow = YN.Yes;
                        }
                        return(chooseDatabaseModel);
                    }
                    nav = Navigator.SelectSingleNode("//ServerConnection");

                    /* example:
                     * <ServerConnection>
                     *      <URI>http://server/OpenDentalServer/ServiceMain.asmx</URI>
                     *      <UsingEcw>True</UsingEcw>
                     * </ServerConnection>
                     */
                    if (nav != null)
                    {
                        //If there is a ServerConnection, then use it.
                        chooseDatabaseModel.CentralConnectionCur.ServiceURI = nav.SelectSingleNode("URI").Value;
                        XPathNavigator ecwnav = nav.SelectSingleNode("UsingEcw");
                        if (ecwnav != null && ecwnav.Value == "True")
                        {
                            chooseDatabaseModel.NoShow = YN.Yes;
                            chooseDatabaseModel.CentralConnectionCur.WebServiceIsEcw = true;
                        }
                        XPathNavigator autoLoginNav = nav.SelectSingleNode("UsingAutoLogin");
                        //Auto login the user using their windows credentials
                        if (autoLoginNav != null && autoLoginNav.Value == "True")
                        {
                            chooseDatabaseModel.CentralConnectionCur.OdUser = nav.SelectSingleNode("User").Value;
                            //Get the user's password from Windows Credential Manager
                            try {
                                chooseDatabaseModel.CentralConnectionCur.OdPassword =
                                    PasswordVaultWrapper.RetrievePassword(chooseDatabaseModel.CentralConnectionCur.ServiceURI, chooseDatabaseModel.CentralConnectionCur.OdUser);
                                //Must set this so FormChooseDatabase() does not launch
                                chooseDatabaseModel.NoShow = YN.Yes;
                                chooseDatabaseModel.CentralConnectionCur.IsAutomaticLogin = true;
                            }
                            catch (Exception ex) {
                                ex.DoNothing();                                //We still want to display the server URI and the user name if getting the password fails.
                            }
                        }
                    }
                }
                catch (Exception) {
                    //Common error: root element is missing
                    chooseDatabaseModel.CentralConnectionCur.ServerName = "localhost";
        #if (TRIALONLY)
                    chooseDatabaseModel.CentralConnectionCur.ServerName = "demo";
        #else
                    chooseDatabaseModel.CentralConnectionCur.DatabaseName = "opendental";
        #endif
                    chooseDatabaseModel.CentralConnectionCur.MySqlUser = "******";
                }
                #endregion
            }
            //Command line args should always trump settings from the config file.
            #region Command Line Arguements
            if (webServiceUri != "")           //if a URI was passed in
            {
                chooseDatabaseModel.CentralConnectionCur.ServiceURI = webServiceUri;
            }
            if (webServiceIsEcw != YN.Unknown)
            {
                chooseDatabaseModel.CentralConnectionCur.WebServiceIsEcw = (webServiceIsEcw == YN.Yes ? true : false);
            }
            if (odUser != "")
            {
                chooseDatabaseModel.CentralConnectionCur.OdUser = odUser;
            }
            //OdPassHash;//not allowed to be used here.  Instead, only used directly in TryToConnect
            //OdPassword//not allowed to be used here.  Instead, only used directly in TryToConnect
            if (serverName != "")
            {
                chooseDatabaseModel.CentralConnectionCur.ServerName = serverName;
            }
            if (databaseName != "")
            {
                chooseDatabaseModel.CentralConnectionCur.DatabaseName = databaseName;
            }
            if (mySqlUser != "")
            {
                chooseDatabaseModel.CentralConnectionCur.MySqlUser = mySqlUser;
            }
            if (mySqlPassword != "")
            {
                chooseDatabaseModel.CentralConnectionCur.MySqlPassword = mySqlPassword;
            }
            if (mySqlPassHash != "")
            {
                string decryptedPwd;
                CDT.Class1.Decrypt(mySqlPassHash, out decryptedPwd);
                chooseDatabaseModel.CentralConnectionCur.MySqlPassword = decryptedPwd;
            }
            if (noShow != YN.Unknown)
            {
                chooseDatabaseModel.NoShow = noShow;
            }
            #endregion
            return(chooseDatabaseModel);
        }
Esempio n. 2
0
        ///<summary>Gets all of the connection setting information from the FreeDentalConfig.xml
        ///Throws exceptions.</summary>
        public static void GetChooseDatabaseConnectionSettings(out CentralConnection centralConnection, out string connectionString, out YN noShow
                                                               , out DatabaseType dbType, out List <string> listAdminCompNames)
        {
            //No remoting role check; out parameters are used.
            centralConnection  = new CentralConnection();
            connectionString   = "";
            noShow             = YN.Unknown;
            dbType             = DatabaseType.MySql;
            listAdminCompNames = new List <string>();
            string xmlPath = ODFileUtils.CombinePaths(Application.StartupPath, "FreeDentalConfig.xml");

            #region Permission Check
            //Improvement should be made here to avoid requiring admin priv.
            //Search path should be something like this:
            //1. /home/username/.opendental/config.xml (or corresponding user path in Windows)
            //2. /etc/opendental/config.xml (or corresponding machine path in Windows) (should be default for new installs)
            //3. Application Directory/FreeDentalConfig.xml (read-only if user is not admin)
            if (!File.Exists(xmlPath))
            {
                FileStream fs;
                try {
                    fs = File.Create(xmlPath);
                }
                catch (Exception) {
                    //No translation right here because we typically do not have a database connection yet.
                    throw new ODException("The very first time that the program is run, it must be run as an Admin.  "
                                          + "If using Vista, right click, run as Admin.");
                }
                fs.Close();
            }
            #endregion
            XmlDocument document = new XmlDocument();
            try {
                document.Load(xmlPath);
                XPathNavigator Navigator = document.CreateNavigator();
                XPathNavigator nav;
                #region Nodes with No UI
                //Always look for these settings first in order to always preserve them correctly.
                nav = Navigator.SelectSingleNode("//AdminCompNames");
                if (nav != null)
                {
                    listAdminCompNames.Clear();                     //this method gets called more than once
                    XPathNodeIterator navIterator = nav.SelectChildren(XPathNodeType.All);
                    for (int i = 0; i < navIterator.Count; i++)
                    {
                        navIterator.MoveNext();
                        listAdminCompNames.Add(navIterator.Current.Value);                        //Add this computer name to the list.
                    }
                }
                //See if there's a UseXWebTestGateway
                nav = Navigator.SelectSingleNode("//UseXWebTestGateway");
                if (nav != null)
                {
                    OpenDentBusiness.WebTypes.Shared.XWeb.XWebs.UseXWebTestGateway = nav.Value.ToLower() == "true";
                }
                #endregion
                #region Nodes from Choose Database Window
                #region Nodes with No Group Box
                //Database Type
                nav    = Navigator.SelectSingleNode("//DatabaseType");
                dbType = DatabaseType.MySql;
                if (nav != null && nav.Value == "Oracle")
                {
                    dbType = DatabaseType.Oracle;
                }
                //ConnectionString
                nav = Navigator.SelectSingleNode("//ConnectionString");
                if (nav != null)
                {
                    //If there is a ConnectionString, then use it.
                    connectionString = nav.Value;
                }
                #endregion
                #region Connection Settings Group Box
                //See if there's a DatabaseConnection
                nav = Navigator.SelectSingleNode("//DatabaseConnection");
                if (nav != null)
                {
                    //If there is a DatabaseConnection, then use it.
                    centralConnection.ServerName    = nav.SelectSingleNode("ComputerName").Value;
                    centralConnection.DatabaseName  = nav.SelectSingleNode("Database").Value;
                    centralConnection.MySqlUser     = nav.SelectSingleNode("User").Value;
                    centralConnection.MySqlPassword = nav.SelectSingleNode("Password").Value;
                    XPathNavigator encryptedPwdNode = nav.SelectSingleNode("MySQLPassHash");
                    //If the Password node is empty, but there is a value in the MySQLPassHash node, decrypt the node value and use that instead
                    string _decryptedPwd;
                    if (centralConnection.MySqlPassword == "" &&
                        encryptedPwdNode != null &&
                        encryptedPwdNode.Value != "" &&
                        CDT.Class1.Decrypt(encryptedPwdNode.Value, out _decryptedPwd))
                    {
                        //decrypted value could be an empty string, which means they don't have a password set, so textPassword will be an empty string
                        centralConnection.MySqlPassword = _decryptedPwd;
                    }
                    XPathNavigator noshownav = nav.SelectSingleNode("NoShowOnStartup");
                    if (noshownav != null)
                    {
                        if (noshownav.Value == "True")
                        {
                            noShow = YN.Yes;
                        }
                        else
                        {
                            noShow = YN.No;
                        }
                    }
                }
                #endregion
                #region Connect to Middle Tier Group Box
                nav = Navigator.SelectSingleNode("//ServerConnection");

                /* example:
                 * <ServerConnection>
                 *      <URI>http://server/OpenDentalServer/ServiceMain.asmx</URI>
                 *      <UsingEcw>True</UsingEcw>
                 * </ServerConnection>
                 */
                if (nav != null)
                {
                    //If there is a ServerConnection, then use it.
                    centralConnection.ServiceURI = nav.SelectSingleNode("URI").Value;
                    XPathNavigator ecwnav = nav.SelectSingleNode("UsingEcw");
                    if (ecwnav != null && ecwnav.Value == "True")
                    {
                        noShow = YN.Yes;
                        centralConnection.WebServiceIsEcw = true;
                    }
                    XPathNavigator autoLoginNav = nav.SelectSingleNode("UsingAutoLogin");
                    //Auto login the user using their windows credentials
                    if (autoLoginNav != null && autoLoginNav.Value == "True")
                    {
                        centralConnection.OdUser = nav.SelectSingleNode("User").Value;
                        //Get the user's password from Windows Credential Manager
                        try {
                            centralConnection.OdPassword =
                                PasswordVaultWrapper.RetrievePassword(centralConnection.ServiceURI, centralConnection.OdUser);
                            //Must set this so FormChooseDatabase() does not launch
                            noShow = YN.Yes;
                            centralConnection.IsAutomaticLogin = true;
                        }
                        catch (Exception ex) {
                            ex.DoNothing();                            //We still want to display the server URI and the user name if getting the password fails.
                        }
                    }
                }
                #endregion
                #endregion
            }
            catch (Exception) {
                //Common error: root element is missing
                centralConnection.ServerName = "localhost";
#if (TRIALONLY)
                centralConnection.ServerName = "demo";
#else
                centralConnection.DatabaseName = "opendental";
#endif
                centralConnection.MySqlUser = "******";
            }
        }
        ///<summary>Returns true if the connection settings were successfully saved to the FreeDentalConfig file and/or Windows PasswordVault.
        ///Otherwise, false.
        ///Set isCommandLineArgs to true in order to preserve settings within FreeDentalConfig.xml that are not command line args.
        ///E.g. the current value within the FreeDentalConfig.xml for NoShowOnStartup will be preserved instead of the value passed in.</summary>
        public static bool TrySaveConnectionSettings(CentralConnection centralConnection, DatabaseType dbType, string connectionString = ""
                                                     , bool noShowOnStartup = false, List <string> listAdminCompNames = null, bool isCommandLineArgs = false, bool useDynamicMode = false, bool allowAutoLogin = true)
        {
            try {
                //The parameters passed in might have misleading information (like noShowOnStartup) if they were comprised from command line arguments.
                //Non-command line settings within the FreeDentalConfig.xml need to be preserved when command line arguments are used.
                if (isCommandLineArgs)
                {
                    //Updating the freedentalconfig.xml file when connecting via command line arguments causes issues for users
                    //who prefer to have a desktop icon pointing to their main database and additional icons for other databases (popular amongst CEMT users).
                    return(false);

                    /**** The following code will be reintroduced in the near future.  Leaving as a comment on purpose. ****
                     * //Override all variables that are NOT valid command line arguments with their current values within the FreeDentalConfig.xml
                     * //This will preserve the values that should stay the same (e.g. noShowOnStartup is NOT a command line arg and will always be true).
                     * CentralConnection centralConnectionFile;
                     * string connectionStringFile;
                     * YN noShowFile;
                     * DatabaseType dbTypeFile;
                     * List<string> listAdminCompNamesFile;
                     * GetChooseDatabaseConnectionSettings(out centralConnectionFile,out connectionStringFile,out noShowFile,out dbTypeFile
                     *      ,out listAdminCompNamesFile,out useDynamicMode);
                     * //Since command line args are being used, override any variables that are NOT allowed to be passed in via the command line.
                     #region FreeDentalConfig Nodes That Do Not Have a Corresponding Command Line Arg
                     * switch(noShowFile) {//config node: <NoShowOnStartup>
                     *      case YN.Yes:
                     *              noShowOnStartup=true;
                     *              break;
                     *      case YN.No:
                     *      case YN.Unknown:
                     *              //Either NoShowOnStartup was not found or was explicitly set to no.
                     *              noShowOnStartup=false;
                     *              break;
                     * }
                     * listAdminCompNames=listAdminCompNamesFile;//config node: <AdminCompNames>
                     * connectionString=connectionStringFile;//config node: <ConnectionString>
                     * centralConnection.IsAutomaticLogin=centralConnectionFile.IsAutomaticLogin;//config node: <UsingAutoLogin>
                     #endregion
                     ********************************************************************************************************/
                }
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent      = true;
                settings.IndentChars = ("    ");
                using (XmlWriter writer = XmlWriter.Create(ODFileUtils.CombinePaths(Application.StartupPath, "FreeDentalConfig.xml"), settings)) {
                    writer.WriteStartElement("ConnectionSettings");
                    if (!allowAutoLogin)
                    {
                        //Only add if it was added before.
                        writer.WriteElementString("AllowAutoLogin", "False");
                    }
                    if (connectionString != "")
                    {
                        writer.WriteStartElement("ConnectionString");
                        writer.WriteString(connectionString);
                        writer.WriteEndElement();
                    }
                    else if (RemotingClient.RemotingRole == RemotingRole.ClientDirect)
                    {
                        writer.WriteStartElement("DatabaseConnection");
                        writer.WriteStartElement("ComputerName");
                        writer.WriteString(centralConnection.ServerName);
                        writer.WriteEndElement();
                        writer.WriteStartElement("Database");
                        writer.WriteString(centralConnection.DatabaseName);
                        writer.WriteEndElement();
                        writer.WriteStartElement("User");
                        writer.WriteString(centralConnection.MySqlUser);
                        writer.WriteEndElement();
                        string encryptedPwd;
                        CDT.Class1.Encrypt(centralConnection.MySqlPassword, out encryptedPwd);                       //sets encryptedPwd ot value or null
                        writer.WriteStartElement("Password");
                        //If encryption fails, write plain text password to xml file; maintains old behavior.
                        writer.WriteString(string.IsNullOrEmpty(encryptedPwd) ? centralConnection.MySqlPassword : "");
                        writer.WriteEndElement();
                        writer.WriteStartElement("MySQLPassHash");
                        writer.WriteString(encryptedPwd ?? "");
                        writer.WriteEndElement();
                        writer.WriteStartElement("NoShowOnStartup");
                        if (noShowOnStartup)
                        {
                            writer.WriteString("True");
                        }
                        else
                        {
                            writer.WriteString("False");
                        }
                        writer.WriteEndElement();
                        writer.WriteEndElement();
                    }
                    else if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
                    {
                        writer.WriteStartElement("ServerConnection");
                        writer.WriteStartElement("URI");
                        writer.WriteString(centralConnection.ServiceURI);
                        writer.WriteEndElement();                        //end URI
                        if (centralConnection.IsAutomaticLogin)
                        {
                            writer.WriteStartElement("User");
                            writer.WriteString(centralConnection.OdUser);
                            writer.WriteEndElement();                            //end Username
                            writer.WriteStartElement("UsingAutoLogin");
                            writer.WriteString("True");
                            writer.WriteEndElement();                            //end UsingAutoLogin
                        }
                        writer.WriteStartElement("UsingEcw");
                        if (centralConnection.WebServiceIsEcw)
                        {
                            writer.WriteString("True");
                        }
                        else
                        {
                            writer.WriteString("False");
                        }
                        writer.WriteEndElement();                        //end UsingEcw
                        writer.WriteEndElement();                        //end ServerConnection
                    }
                    writer.WriteStartElement("DatabaseType");
                    if (dbType == DatabaseType.MySql)
                    {
                        writer.WriteString("MySql");
                    }
                    else
                    {
                        writer.WriteString("Oracle");
                    }
                    writer.WriteEndElement();
                    writer.WriteStartElement("UseDynamicMode");
                    writer.WriteString(useDynamicMode.ToString());
                    writer.WriteEndElement();
                    if (OpenDentBusiness.WebTypes.Shared.XWeb.XWebs.UseXWebTestGateway)
                    {
                        writer.WriteStartElement("UseXWebTestGateway");
                        writer.WriteString("True");
                        writer.WriteEndElement();
                    }
                    if (listAdminCompNames != null && listAdminCompNames.Count > 0)
                    {
                        writer.WriteStartElement("AdminCompNames");
                        foreach (string compName in listAdminCompNames)
                        {
                            writer.WriteStartElement("CompName");
                            writer.WriteString(compName);
                            writer.WriteEndElement();
                        }
                        writer.WriteEndElement();
                    }
                    writer.WriteEndElement();
                    writer.Flush();
                }                //using writer
                //Input the user's credentials to WCM (Windows Credential Manager) if necessary.
                if (RemotingClient.RemotingRole == RemotingRole.ClientWeb &&
                    !string.IsNullOrWhiteSpace(centralConnection.ServiceURI) &&
                    centralConnection.IsAutomaticLogin)
                {
                    bool isCredentialSaveRequired = true;                                                            //Assume credentials are not saved yet.
                    if (PasswordVaultWrapper.TryRetrieveUserName(centralConnection.ServiceURI, out string userName)) //Found a saved OD MT UserName
                    //Update the credentials if the user or password is different.
                    {
                        if (centralConnection.OdUser != userName ||
                            PasswordVaultWrapper.RetrievePassword(centralConnection.ServiceURI, userName) != centralConnection.OdPassword)
                        {
                            //UserName or Password in the saved credentials does not match current password.  Delete the saved credentials and save the new
                            //credentials.  This will clear all the saved credentials from the PasswordVault for the currently logged in Windows User, which is
                            //desired behavior as each Windows User should only have one set of OpenDental Middle Tier credentials.
                            PasswordVaultWrapper.ClearCredentials(centralConnection.ServiceURI);
                        }
                        else
                        {
                            isCredentialSaveRequired = false;                          //Username and Password already saved and match current credentials.
                        }
                    }
                    if (isCredentialSaveRequired)
                    {
                        if (!string.IsNullOrWhiteSpace(centralConnection.OdUser) && !string.IsNullOrWhiteSpace(centralConnection.OdPassword))
                        {
                            //Save the new credentials.
                            PasswordVaultWrapper.WritePassword(centralConnection.ServiceURI, centralConnection.OdUser, centralConnection.OdPassword);
                        }
                        else
                        {
                            return(false);                           //Invalid username/password.
                        }
                    }
                }
            }
            catch (Exception ex) {
                ex.DoNothing();
                return(false);
            }
            return(true);
        }