private IPromise <TokenCredentials> ValidCredentials(bool async)
 {
     if (_tokenCreds == null)
     {
         _tokenCreds = GetCredentials(async);
         return(_tokenCreds);
     }
     else
     {
         // Force synchronous in order to break the always extending promise chain
         try
         {
             // This will throw if the previous GetCredentials call failed
             // Can commonly happen when network connection is lost
             // This is not going to wait in practice since this location will be after the promise is already resolved
             var creds = _tokenCreds.Wait();
             if (creds.Expires <= DateTime.UtcNow)
             {
                 _tokenCreds = GetCredentials(async);
                 return(_tokenCreds);
             }
             else
             {
                 return(Promises.Resolved(creds));
             }
         }
         catch
         {
             // Catch the exception and try getting credentials again
             _tokenCreds = GetCredentials(async);
             return(_tokenCreds);
         }
     }
 }
        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));
            }
        }
        public override IPromise <Stream> Commit(bool async)
        {
            if (Status != UploadStatus.Pending)
            {
                return(_lastPromise);
            }

            Status       = UploadStatus.Committed;
            _lastPromise = Promises.All(Files
                                        .Where(f => f.UploadPromise != null)
                                        .Select(f => f.UploadPromise)
                                        .ToArray())
                           .Continue(l =>
            {
                var errorResult = l
                                  .Select(s => _conn.AmlContext.FromXml((Stream)s))
                                  .FirstOrDefault(r => r.Exception != null);
                if (errorResult == null)
                {
                    return(UploadAndApply(async));
                }
                else
                {
                    var memStream = new MemoryStream();
                    var xml       = XmlWriter.Create(memStream);
                    errorResult.ToAml(xml);
                    memStream.Position = 0;
                    return(Promises.Resolved((Stream)memStream));
                }
            });
            return(_lastPromise);
        }
 /// <summary>
 /// Get the result of executing the specified AML query
 /// </summary>
 /// <param name="conn">Connection to execute the query on</param>
 /// <param name="query">Query to be performed.  If parameters are specified, they will be substituted into the query</param>
 /// <param name="async">Whether to perform the query asynchronously</param>
 /// <param name="noItemsIsError">Whether a 'No items found' exception should be signaled to the <see cref="IPromise"/> as an exception</param>
 /// <param name="parameters">Parameters to be injected into the query</param>
 /// <returns>A read-only result</returns>
 public static IPromise <IReadOnlyResult> ApplyAsync(this IAsyncConnection conn, Command query, bool async, bool noItemsIsError, params object[] parameters)
 {
     if (async)
     {
         return(ApplyAsyncInt(conn, query, default(CancellationToken), parameters));
     }
     return(Promises.Resolved(Apply(conn, query, parameters)));
 }
示例#5
0
 /// <summary>
 /// Transforms the vault URL replacing any <c>$[]</c>-style parameters.
 /// </summary>
 /// <param name="conn">The connection.</param>
 /// <param name="async">Whether to perform this action asynchronously</param>
 /// <returns>A promise to return the transformed URL</returns>
 public IPromise <string> TransformUrl(IAsyncConnection conn, bool async)
 {
     return(Url.IndexOf("$[") < 0 ?
            Promises.Resolved(Url) :
            conn.Process(new Command("<url>@0</url>", Url)
                         .WithAction(CommandAction.TransformVaultServerURL), async)
            .Convert(s =>
     {
         Url = s.AsString();
         return Url;
     }));
 }
 public OAuthAuthenticator(HttpClient service, OAuthConfig config, ICredentials creds)
 {
     _config  = config;
     _service = service;
     if (creds is TokenCredentials token)
     {
         _tokenCreds = Promises.Resolved(token);
     }
     else
     {
         _hashCred = HashCredentials(creds);
     }
 }
        private IPromise <Stream> UploadFile(CommandFile file, bool async)
        {
            return(BeginTransaction(async)
                   .Continue(t =>
            {
                var chain = Promises.Resolved(default(IHttpResponse));

                foreach (var content in file.AsContent(this, _conn.AmlContext.LocalizationContext, false))
                {
                    chain = chain.Continue(_ => {
                        var req = new HttpRequest()
                        {
                            Content = content
                        };
                        req.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
                        _conn.SetDefaultHeaders(req.SetHeader);

                        foreach (var a in _conn.DefaultSettings)
                        {
                            a.Invoke(req);
                        }
                        Settings?.Invoke(req);
                        req.SetHeader("SOAPAction", "UploadFile");
                        req.SetHeader("VAULTID", Vault.Id);
                        req.SetHeader("transactionid", t);

                        var trace = new LogData(4
                                                , "Innovator: Upload File"
                                                , LogListener ?? Factory.LogListener)
                        {
                            { "aras_url", _conn.MapClientUrl("../../Server") },
                            { "database", _conn.Database },
                            { "soap_action", "UploadFile" },
                            { "url", Vault.Url },
                            { "user_id", _conn.UserId },
                            { "vault_id", Vault.Id },
                            { "version", _conn.Version }
                        };
                        var uri = new Uri(Vault.Url + "?fileId=" + file.Id);
                        return Vault.HttpClient
                        .PostPromise(uri, async, req, trace)
                        .Always(trace.Dispose)
                        .Always(req.Dispose);
                    });
                }

                return chain;
            })
                   .Convert(r => r.AsStream));
        }
示例#8
0
        /// <summary>
        /// Fetches the version from the database if it is not already known.
        /// </summary>
        /// <param name="conn">The connection to fetch the version for</param>
        /// <param name="async">Whether to fetch the version asynchronously</param>
        /// <returns>A promise to return the version of the Aras installation.</returns>
        public static IPromise <Version> FetchVersion(this IAsyncConnection conn, bool async)
        {
            var version = (conn as Connection.IArasConnection)?.Version;

            if (version != default(Version) && version.Major > 0)
            {
                return(Promises.Resolved(version));
            }

            return(conn.ApplyAsync(@"<Item type='Variable' action='get' select='name,value'>
        <name condition='like'>Version*</name>
      </Item>", async, false)
                   .Convert(res =>
            {
                var dict = res.Items()
                           .GroupBy(i => i.Property("name").AsString(""))
                           .ToDictionary(g => g.Key, g => g.First().Property("value").Value);

                string majorStr;
                int major;
                string minorStr;
                int minor;
                string servicePackStr;
                int servicePack;
                string buildStr;
                int build;
                if (dict.TryGetValue("VersionMajor", out majorStr) && int.TryParse(majorStr, out major) &&
                    dict.TryGetValue("VersionMinor", out minorStr) && int.TryParse(minorStr, out minor) &&
                    dict.TryGetValue("VersionServicePack", out servicePackStr))
                {
                    if (!dict.TryGetValue("VersionBuild", out buildStr) || !int.TryParse(buildStr, out build))
                    {
                        build = 0;
                    }

                    if (!int.TryParse(servicePackStr.TrimStart('S', 'P'), out servicePack))
                    {
                        servicePack = 0;
                    }

                    return new Version(major, minor, servicePack, build);
                }
                return default(Version);
            }));
        }
        /// <summary>
        /// Fetches the version from the database if it is not already known.
        /// </summary>
        /// <param name="conn">The connection to fetch the version for</param>
        /// <param name="async">Whether to fetch the version asynchronously</param>
        /// <returns>A promise to return the version of the Aras installation.</returns>
        public static IPromise <Version> FetchVersion(this IAsyncConnection conn, bool async)
        {
            if (!(conn is Connection.IArasConnection arasConn))
            {
                return(Promises.Resolved(default(Version)));
            }
            var version = arasConn.Version;

            if (version != default(Version))
            {
                return(Promises.Resolved(version));
            }

            return(conn.ApplyAsync(@"<Item type='Variable' action='get' select='name,value'>
        <name condition='like'>Version*</name>
      </Item>", async, false)
                   .Convert(res =>
            {
                var dict = res.Items()
                           .GroupBy(i => i.Property("name").AsString(""))
                           .ToDictionary(g => g.Key, g => g.First().Property("value").Value);

                var major = 0;
                var minor = 0;
                var servicePack = 0;
                var build = 0;
                // int.TryParse will default to 0 on a failure
                // Always set a version with the pieces even if the version doesn't make sense so that we don't repeat retrieval
                var _ = dict.TryGetValue("VersionMajor", out string majorStr) && int.TryParse(majorStr, out major);
                _ = dict.TryGetValue("VersionMinor", out string minorStr) && int.TryParse(minorStr, out minor);
                _ = dict.TryGetValue("VersionServicePack", out string servicePackStr) &&
                    int.TryParse(servicePackStr.TrimStart('S', 'P'), out servicePack);
                _ = dict.TryGetValue("VersionBuild", out string buildStr) && int.TryParse(buildStr, out build);

                version = new Version(major, minor, servicePack, build);
                arasConn.Version = version;
                return version;
            }));
        }
        public override IPromise <Stream> Rollback(bool async)
        {
            if (Status == UploadStatus.RolledBack)
            {
                return(_lastPromise);
            }

            Status       = UploadStatus.RolledBack;
            _lastPromise = Promises.All(Files
                                        .Where(f => f.UploadPromise != null)
                                        .Select(f => f.UploadPromise.Continue(s =>
            {
                var result = _conn.AmlContext.FromXml(s);
                if (result.Exception != null)
                {
                    return(Promises.Resolved((Stream) new MemoryStream()));
                }

                return(_conn.Process(new Command("<Item type='File' action='delete' id='@0' />", f.Id), async));
            })).ToArray())
                           .Convert(l => l.OfType <Stream>().FirstOrDefault() ?? new MemoryStream());
            return(_lastPromise);
        }
示例#11
0
 private IPromise <TokenCredentials> ValidCredentials(bool async)
 {
     if (_tokenCreds == null)
     {
         _tokenCreds = GetCredentials(async);
         return(_tokenCreds);
     }
     else
     {
         return(_tokenCreds.Continue(c =>
         {
             if (c.Expires <= DateTime.UtcNow)
             {
                 _tokenCreds = GetCredentials(async);
                 return _tokenCreds;
             }
             else
             {
                 return Promises.Resolved(c);
             }
         }));
     }
 }
示例#12
0
 public IPromise <ExplicitHashCredentials> HashCredentials(ICredentials credentials, bool async)
 {
     return(Promises.Resolved(HashCredentials(credentials)));
 }
        /// <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");
            }
        }