private IPromise <string> LoginAmlCall(bool async)
        {
            var result = new Promise <string>();

            result.CancelTarget(
                Process(new Command("<Item/>").WithAction(CommandAction.ValidateUser), async)
                .Progress(result.Notify)
                .Done(r =>
            {
                string xml;
                using (var reader = new StreamReader(r))
                {
                    xml = reader.ReadToEnd();
                }

                var root     = XElement.Parse(xml);
                var data     = root.DescendantsAndSelf("Result").FirstOrDefault();
                var afNs     = (XNamespace)"http://www.aras.com/InnovatorFault";
                var authNode = root.DescendantsAndSelf(afNs + "supported_authentication_schema").FirstOrDefault();
                if (authNode != null &&
                    authNode.Element(afNs + "schema")?.Attribute("mode")?.Value == "SHA256" &&
                    _authenticator is LegacyAuthenticator legacy)
                {
                    legacy.HashFunction = ElementFactory.Local.CalcSha256;
                    // Switch from MD5 hashing to SHA256
                    LoginAmlCall(async)
                    .Done(result.Resolve)
                    .Fail(result.Reject);
                }
                else if (data == null)
                {
                    var res = ElementFactory.Local.FromXml(xml);
                    var ex  = res.Exception ?? ElementFactory.Local.ServerException("Failed to login");
                    ex.SetDetails(Database, "<Item/>");

                    Database      = null;
                    _httpUsername = null;
                    result.Reject(ex);
                }
                else
                {
                    foreach (var elem in data.Elements())
                    {
                        switch (elem.Name.LocalName)
                        {
                        case "id":
                            UserId = elem.Value;
                            break;

                        case "login_name":
                            _httpUsername = elem.Value;
                            break;

                        case "database":
                            Database = elem.Value;
                            break;

                        case "i18nsessioncontext":
                            _context.DefaultLanguageCode   = elem.Element("default_language_code").Value;
                            _context.DefaultLanguageSuffix = elem.Element("default_language_suffix").Value;
                            _context.LanguageCode          = elem.Element("language_code").Value;
                            _context.LanguageSuffix        = elem.Element("language_suffix").Value;
                            _context.Locale   = elem.Element("locale").Value;
                            _context.TimeZone = elem.Element("time_zone").Value;
                            break;

                        case "ServerInfo":
                            foreach (var info in elem.Elements())
                            {
                                if (info.Name.LocalName == "Version")
                                {
                                    Version = new Version(info.Value);
                                }

                                if (!string.IsNullOrEmpty(elem.Value))
                                {
                                    _serverInfo.Add(new KeyValuePair <string, string>("ServerInfo/" + elem.Name.LocalName, elem.Value));
                                }
                            }
                            break;

                        default:
                            if (!string.IsNullOrEmpty(elem.Value))
                            {
                                _serverInfo.Add(new KeyValuePair <string, string>(elem.Name.LocalName, elem.Value));
                            }
                            break;
                        }
                    }

                    _vaultConn.InitializeStrategy();
                    result.Resolve(UserId);
                }
            }).Fail(ex =>
            {
                Database      = null;
                _httpUsername = null;
                result.Reject(ex);
            }));
            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Log in to the database asynchronosuly
        /// </summary>
        /// <param name="credentials">Credentials used for authenticating to the instance</param>
        /// <param name="async">Whether to perform this action asynchronously</param>
        /// <returns>
        /// A promise to return the user ID as a string
        /// </returns>
        /// <exception cref="NotSupportedException">This connection implementation does not support the specified credential type</exception>
        public IPromise <string> Login(ICredentials credentials, bool async)
        {
            var authProcess = HashCreds(credentials, async);

            _lastCredentials = credentials;
            var unHashedPassword = default(SecureToken);

            var result = new Promise <string>();

            result.CancelTarget(
                authProcess.Continue(h =>
            {
                unHashedPassword = h.UnhashedPassword;
                _httpDatabase    = h.Cred.Database;
                _httpPassword    = h.Cred.PasswordHash;
                _httpUsername    = h.Cred.Username;
                return(Process(new Command("<Item/>").WithAction(CommandAction.ValidateUser), async));
            })
                .Progress(result.Notify)
                .Done(r =>
            {
                string xml;
                using (var reader = new StreamReader(r))
                {
                    xml = reader.ReadToEnd();
                }

                var root     = XElement.Parse(xml);
                var data     = root.DescendantsAndSelf("Result").FirstOrDefault();
                var afNs     = (XNamespace)"http://www.aras.com/InnovatorFault";
                var authNode = root.DescendantsAndSelf(afNs + "supported_authentication_schema").FirstOrDefault();
                if (authNode != null && unHashedPassword != null &&
                    authNode.Element(afNs + "schema")?.Attribute("mode")?.Value == "SHA256" &&
                    _httpPassword?.Length == 32)
                {
                    _hashFunc = ElementFactory.Local.CalcSha256;
                    // Switch from MD5 hashing to SHA256
                    Login(new ExplicitHashCredentials(_httpDatabase, _httpUsername, _hashFunc(unHashedPassword)), true)
                    .Done(result.Resolve)
                    .Fail(result.Reject);
                }
                else if (data == null)
                {
                    var res = ElementFactory.Local.FromXml(xml);
                    var ex  = res.Exception ?? ElementFactory.Local.ServerException("Failed to login");
                    ex.SetDetails(_httpDatabase, "<Item/>");

                    _httpDatabase = null;
                    _httpUsername = null;
                    _httpPassword = null;
                    result.Reject(ex);
                }
                else
                {
                    foreach (var elem in data.Elements())
                    {
                        switch (elem.Name.LocalName)
                        {
                        case "id":
                            _userId = elem.Value;
                            break;

                        case "i18nsessioncontext":
                            _context.DefaultLanguageCode   = elem.Element("default_language_code").Value;
                            _context.DefaultLanguageSuffix = elem.Element("default_language_suffix").Value;
                            _context.LanguageCode          = elem.Element("language_code").Value;
                            _context.LanguageSuffix        = elem.Element("language_suffix").Value;
                            _context.Locale   = elem.Element("locale").Value;
                            _context.TimeZone = elem.Element("time_zone").Value;
                            break;

                        case "ServerInfo":
                            foreach (var info in elem.Elements())
                            {
                                if (info.Name.LocalName == "Version")
                                {
                                    _arasVersion = new Version(info.Value);
                                }

                                if (!string.IsNullOrEmpty(elem.Value))
                                {
                                    _serverInfo.Add(new KeyValuePair <string, string>("ServerInfo/" + elem.Name.LocalName, elem.Value));
                                }
                            }
                            break;

                        default:
                            if (!string.IsNullOrEmpty(elem.Value))
                            {
                                _serverInfo.Add(new KeyValuePair <string, string>(elem.Name.LocalName, elem.Value));
                            }
                            break;
                        }
                    }

                    _vaultConn.InitializeStrategy();
                    result.Resolve(_userId);
                }
            }).Fail(ex =>
            {
                _httpDatabase = null;
                _httpUsername = null;
                _httpPassword = null;
                result.Reject(ex);
            }));
            return(result);
        }