private static IPromise <IHttpResponse> SendSync(SyncHttpClient service, HttpRequest req, LogData trace)
        {
            try
            {
                return(Promises.Resolved((IHttpResponse)service.Send(req)));
            }
            catch (System.Net.WebException webex)
            {
                switch (webex.Status)
                {
                case System.Net.WebExceptionStatus.RequestCanceled:
                case System.Net.WebExceptionStatus.Timeout:
                    return(Promises.Rejected <IHttpResponse>(new HttpTimeoutException(string.Format("A response was not received after waiting for {0:m' minutes, 's' seconds'}", req.Timeout))));

                default:
                    foreach (var kvp in trace)
                    {
                        webex.Data[kvp.Key] = kvp.Value;
                    }
                    trace.Add("exception", webex);
                    return(Promises.Rejected <IHttpResponse>(webex));
                }
            }
            catch (Exception ex)
            {
                foreach (var kvp in trace)
                {
                    ex.Data[kvp.Key] = kvp.Value;
                }
                trace.Add("exception", ex);
                return(Promises.Rejected <IHttpResponse>(ex));
            }
        }
Ejemplo n.º 2
0
        private IPromise <ICredentials> DefaultAuthCallback(INetCredentials netCred, string endpoint, bool async)
        {
            var promise = new Promise <ICredentials>();

            if (string.IsNullOrEmpty(endpoint))
            {
                promise.Resolve(netCred);
            }
            else
            {
                var handler = new SyncClientHandler()
                {
                    Credentials     = netCred.Credentials,
                    PreAuthenticate = true
                };
                var http = new SyncHttpClient(handler);

                var endpointUri = new Uri(endpoint + "?db=" + netCred.Database);
                var trace       = new LogData(4, "Innovator: Authenticate user via mapping", Factory.LogListener)
                {
                    { "database", netCred.Database },
                    { "user_name", netCred.Credentials.GetCredential(endpointUri, null).UserName },
                    { "url", endpointUri },
                };
                http.GetPromise(endpointUri, async, trace)
                .Done(r =>
                {
                    var res  = r.AsXml().DescendantsAndSelf("Result").FirstOrDefault();
                    var user = res.Element("user").Value;
                    var pwd  = res.Element("password").Value;
                    if (pwd.IsNullOrWhiteSpace())
                    {
                        promise.Reject(new ArgumentException("Failed to authenticate with Innovator server '" + endpoint + "'. Original error: " + user, "credentials"));
                    }

                    var needHash = !string.Equals(res.Element("hash").Value, "false", StringComparison.OrdinalIgnoreCase);
                    if (needHash)
                    {
                        promise.Resolve(new ExplicitCredentials(netCred.Database, user, pwd));
                    }
                    else
                    {
                        promise.Resolve(new ExplicitHashCredentials(netCred.Database, user, pwd));
                    }
                }).Fail(ex =>
                {
                    // Only hard fail for problems which aren't time outs and not found issues.
                    var webEx = ex as HttpException;
                    if (webEx != null && webEx.Response.StatusCode == HttpStatusCode.NotFound)
                    {
                        promise.Resolve(netCred);
                    }
                    else if (webEx != null && webEx.Response.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        promise.Reject(ElementFactory.Local.ServerException("Invalid username or password"));
                    }
                    else if (webEx != null)
                    {
                        try
                        {
                            var result = ElementFactory.Local.FromXml(webEx.Response.AsStream);
                            if (result.Exception != null)
                            {
                                promise.Reject(result.Exception);
                            }
                            else
                            {
                                promise.Reject(ex);
                            }
                        }
                        catch (Exception)
                        {
                            promise.Reject(ex);
                        }
                    }
                    else if (ex is TaskCanceledException)
                    {
                        promise.Resolve(netCred);
                    }
                    else
                    {
                        promise.Reject(ex);
                    }
                }).Always(trace.Dispose);
            }

            return(promise);
        }
        /// <summary>
        /// Hashes the credentials for use with logging in or workflow voting
        /// </summary>
        /// <param name="credentials">The credentials.</param>
        /// <param name="async">Whether to perform this action asynchronously</param>
        /// <returns>
        /// A promise to return hashed credentials
        /// </returns>
        public IPromise <ExplicitHashCredentials> HashCredentials(ICredentials credentials, bool async)
        {
            var explicitCred = credentials as ExplicitCredentials;
            var hashCred     = credentials as ExplicitHashCredentials;
            var winCred      = credentials as WindowsCredentials;

            if (explicitCred != null)
            {
                return(Promises.Resolved(new ExplicitHashCredentials(explicitCred.Database, explicitCred.Username, _hashFunc(explicitCred.Password))));
            }
            else if (hashCred != null)
            {
                return(Promises.Resolved(hashCred));
            }
            else if (winCred != null)
            {
                var waLoginUrl = new Uri(this._innovatorClientBin, "../scripts/IOMLogin.aspx");
                var handler    = new SyncClientHandler()
                {
                    Credentials     = winCred.Credentials,
                    PreAuthenticate = true
                };
                var http = new SyncHttpClient(handler);
                var req  = new HttpRequest()
                {
                    Content = new SimpleContent("<?xml version=\"1.0\" encoding=\"utf-8\" ?><Item />", "text/xml")
                };

                var context = ElementFactory.Local.LocalizationContext;
                req.SetHeader("DATABASE", winCred.Database);
                req.SetHeader("LOCALE", context.Locale);
                req.SetHeader("TIMEZONE_NAME", context.TimeZone);

                return(http.PostPromise(waLoginUrl, async, req, new LogData(4
                                                                            , "Innovator: Execute query"
                                                                            , Factory.LogListener)
                {
                    { "database", winCred.Database },
                    { "url", waLoginUrl },
                }).Convert(r =>
                {
                    var res = r.AsXml().DescendantsAndSelf("Result").FirstOrDefault();
                    var username = res.Element("user").Value;
                    var pwd = res.Element("password").Value;
                    if (pwd.IsNullOrWhiteSpace())
                    {
                        throw new ArgumentException("Failed to authenticate with Innovator server '" + _innovatorClientBin, "credentials");
                    }

                    var needHash = res.Element("hash").Value;
                    var password = default(string);
                    if (string.Equals(needHash.Trim(), "false", StringComparison.OrdinalIgnoreCase))
                    {
                        password = pwd;
                    }
                    else
                    {
                        password = _hashFunc(pwd);
                    }

                    return new ExplicitHashCredentials(winCred.Database, username, password);
                }));
            }
            else
            {
                throw new NotSupportedException("This connection implementation does not support the specified credential type");
            }
        }