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))); }
/// <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)); }
/// <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); }
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); } })); } }
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"); } }