From ab4c68acb19fb84eb7b847a31b23cf72ead4e10a Mon Sep 17 00:00:00 2001 From: Martin Noreke Date: Mon, 30 Mar 2015 14:25:35 -0600 Subject: [PATCH 01/13] Adding try/catch around headers to ignore errors. --- Rally.RestApi/RallyRestApi.cs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Rally.RestApi/RallyRestApi.cs b/Rally.RestApi/RallyRestApi.cs index c511def..881551b 100644 --- a/Rally.RestApi/RallyRestApi.cs +++ b/Rally.RestApi/RallyRestApi.cs @@ -1230,17 +1230,25 @@ private string GetSecurityToken() internal Dictionary GetProcessedHeaders() { var result = new Dictionary(); - foreach (HeaderType headerType in Headers.Keys) + try { - string output = null; - string value = Headers[headerType]; - FieldInfo fieldInfo = headerType.GetType().GetField(headerType.ToString()); - StringValue[] attrs = fieldInfo.GetCustomAttributes(typeof(StringValue), false) as StringValue[]; - if (attrs.Length > 0) - output = attrs[0].Value; - - result.Add(output, value); + foreach (HeaderType headerType in Headers.Keys) + { + string output = null; + string value = Headers[headerType]; + FieldInfo fieldInfo = headerType.GetType().GetField(headerType.ToString()); + StringValue[] attrs = fieldInfo.GetCustomAttributes(typeof(StringValue), false) as StringValue[]; + if (attrs.Length > 0) + output = attrs[0].Value; + + result.Add(output, value); + } } + catch + { + // Swallow exception for headers. + } + return result; } #endregion From 46c0ede8f59579bf2d70ebff74cacf4657b8b2fd Mon Sep 17 00:00:00 2001 From: Josh Stupplebeen Date: Thu, 16 Apr 2015 15:22:26 -0600 Subject: [PATCH 02/13] Added error suppression to SSO Window and DateTime handling to dynamicjsonobj --- Rally.RestApi.UiForWpf/SsoWindow.xaml.cs | 18 +++++++++++++++++- Rally.RestApi/Json/DynamicJsonObject.cs | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs b/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs index e4bc37e..bed825b 100644 --- a/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs +++ b/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs @@ -1,4 +1,5 @@ -using mshtml; +using System.Reflection; +using mshtml; using Rally.RestApi.Auth; using System; using System.Collections.Generic; @@ -38,6 +39,21 @@ public SsoWindow() { InitializeComponent(); browser.LoadCompleted += browser_LoadCompleted; + //browser.Navigated += (a, b) => HideScriptErrors(browser, true); + } + + private void HideScriptErrors(WebBrowser browser, bool hide) + { + var fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic); + if (fiComWebBrowser == null) return; + var objComWebBrowser = fiComWebBrowser.GetValue(browser); + if (objComWebBrowser == null) + { + browser.Navigated += (o, s) => HideScriptErrors(browser, hide); + return; + } + objComWebBrowser.GetType() + .InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { hide }); } #endregion diff --git a/Rally.RestApi/Json/DynamicJsonObject.cs b/Rally.RestApi/Json/DynamicJsonObject.cs index 35f8ade..73a7bd3 100644 --- a/Rally.RestApi/Json/DynamicJsonObject.cs +++ b/Rally.RestApi/Json/DynamicJsonObject.cs @@ -120,6 +120,10 @@ private object FormatSetValue(object value) { return value; } + if (value is DateTime) + { + return ((DateTime)value).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"); + } throw new ArgumentException("Attempt to set property to an unsupported type."); } From a37556dda10bef73557df93f357145729741fd2b Mon Sep 17 00:00:00 2001 From: Josh Stupplebeen Date: Fri, 17 Apr 2015 09:19:09 -0600 Subject: [PATCH 03/13] Changed DTM passed to GMT --- Rally.RestApi/Json/DynamicJsonObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rally.RestApi/Json/DynamicJsonObject.cs b/Rally.RestApi/Json/DynamicJsonObject.cs index 73a7bd3..debf39e 100644 --- a/Rally.RestApi/Json/DynamicJsonObject.cs +++ b/Rally.RestApi/Json/DynamicJsonObject.cs @@ -122,7 +122,7 @@ private object FormatSetValue(object value) } if (value is DateTime) { - return ((DateTime)value).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"); + return ((DateTime)value).ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"); } throw new ArgumentException("Attempt to set property to an unsupported type."); } From 6a12947ed967d8067d581c308a9ae334c8079e98 Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Wed, 24 Jun 2015 12:25:36 -0600 Subject: [PATCH 04/13] Enabled AllowIDPBasedSSO toggle" --- Rally.RestApi.UiForWpf/LoginWindow.xaml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs b/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs index 36be34e..f5c8bf2 100644 --- a/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs +++ b/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs @@ -72,6 +72,7 @@ public LoginWindow() { InitializeComponent(); + RestApiAuthMgrWpf.AllowIdpBasedSso = true; headerLabel.Content = ApiAuthManager.LoginWindowHeaderLabelText; controls = new Dictionary(); controlReadOnlyLabels = new Dictionary(); From 0e7cf5aaf97db0552889c8363c40ff88f0e7501f Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Wed, 24 Jun 2015 15:52:10 -0600 Subject: [PATCH 05/13] Refactored wsapi2x test --- Rally.RestApi.Test/RallyRestApiTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rally.RestApi.Test/RallyRestApiTest.cs b/Rally.RestApi.Test/RallyRestApiTest.cs index 806dbfe..6fdf89e 100644 --- a/Rally.RestApi.Test/RallyRestApiTest.cs +++ b/Rally.RestApi.Test/RallyRestApiTest.cs @@ -404,7 +404,7 @@ private static void VerifyAttributes(QueryResult result, bool forWsapi2) select i["Name"] as string; string[] expectedNames; if (forWsapi2) - expectedNames = new string[] { "App Id", "Creation Date", "VersionId", "Object ID", "Name", "Project", "User", "Value", "Workspace" }; + expectedNames = new string[] { "App Id", "Creation Date", "VersionId", "Object ID", "Name", "Project", "User", "Value", "Workspace", "ObjectUUID", "Type" }; else expectedNames = new string[] { "App Id", "Creation Date", "Object ID", "Name", "Project", "User", "Value", "Workspace" }; From 2cb499a39c1549adcb4de8f202ad5a29fb0e7d73 Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Wed, 1 Jul 2015 12:00:10 -0600 Subject: [PATCH 06/13] DE22791 Redirect to /slm/empty.sp for idp sso if logging into /login/sso --- Rally.RestApi.UiForWpf/LoginWindow.xaml.cs | 33 ++++++++----------- Rally.RestApi/Auth/LoginDetails.cs | 23 ++++++++++++- .../Web/CookieAwareCacheableWebClient.cs | 2 +- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs b/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs index f5c8bf2..70250db 100644 --- a/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs +++ b/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs @@ -1,20 +1,13 @@ -using Rally.RestApi.Auth; -using System; +using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; -using System.Net; -using System.Text; using System.Threading; -using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; +using Rally.RestApi.Auth; using Rally.RestApi.Connection; namespace Rally.RestApi.UiForWpf @@ -30,7 +23,7 @@ private enum TabType { Credentials, Rally, - Proxy, + Proxy } #endregion @@ -45,7 +38,7 @@ private enum EditorControlType TrustAllCertificates, ProxyServer, ProxyUsername, - ProxyPassword, + ProxyPassword } #endregion @@ -72,7 +65,7 @@ public LoginWindow() { InitializeComponent(); - RestApiAuthMgrWpf.AllowIdpBasedSso = true; + RestApiAuthMgrWpf.AllowIdpBasedSso = true; headerLabel.Content = ApiAuthManager.LoginWindowHeaderLabelText; controls = new Dictionary(); controlReadOnlyLabels = new Dictionary(); @@ -149,9 +142,9 @@ internal void BuildLayout(RestApiAuthMgrWpf authMgr) inputRow.Height = new GridLength(tabControl.Height + 20, GridUnitType.Pixel); inputRow.MinHeight = inputRow.Height.Value; - this.Height = inputRow.Height.Value + (28 * 2) + 100; - this.MinHeight = this.Height; - this.MaxHeight = this.Height; + Height = inputRow.Height.Value + (28 * 2) + 100; + MinHeight = Height; + MaxHeight = Height; SetDefaultValues(); ConnectionTypeChanged(GetEditor(EditorControlType.ConnectionType), null); @@ -544,13 +537,15 @@ private string GetEditorValue(EditorControlType controlType) return null; TextBox textBox = control as TextBox; + if (textBox != null && controlType == EditorControlType.IdpServer) + return AuthMgr.LoginDetails.RedirectIfIdpPointsAtLoginSso(textBox.Text); + if (textBox != null) return textBox.Text; PasswordBox passwordBox = control as PasswordBox; if (passwordBox != null) return passwordBox.Password; - return null; } #endregion @@ -587,8 +582,6 @@ private void AddButtons() AddColumnDefinition(buttonGrid, 70); AddColumnDefinition(buttonGrid); - - loginButton = GetButton(); loginButton.IsDefault = true; loginButton.Content = ApiAuthManager.LoginWindowLoginText; @@ -738,7 +731,7 @@ private void ShowMessage(string message = "") #endregion #region OnClosing - protected override void OnClosing(System.ComponentModel.CancelEventArgs e) + protected override void OnClosing(CancelEventArgs e) { AuthMgr.LoginWindowSsoAuthenticationComplete = null; base.OnClosing(e); diff --git a/Rally.RestApi/Auth/LoginDetails.cs b/Rally.RestApi/Auth/LoginDetails.cs index c6b45d1..5cca202 100644 --- a/Rally.RestApi/Auth/LoginDetails.cs +++ b/Rally.RestApi/Auth/LoginDetails.cs @@ -247,7 +247,7 @@ private string GetChildNodeValue(XmlNodeList childNodes, string childNodeName) foreach (XmlElement node in childNodes) { if (node.Name.Equals(childNodeName, StringComparison.InvariantCultureIgnoreCase)) - return node.InnerXml; + return node.InnerText; } return null; @@ -277,5 +277,26 @@ internal void MarkUserAsLoggedOut() SaveToDisk(); } #endregion + + #region RedirectIfIDPPointsAtLoginSSO + /// + /// HACK: Redirect to custom SSO page if attempting to connect to /login/sso + /// This workaround is for internet explorer 7 compatability due to excel and VSP + /// relying on IE7 as its embedded browser + /// + /// + public string RedirectIfIdpPointsAtLoginSso(string idpServer) + { + String[] parseIdpServer = idpServer.Split('&'); + for (int i = 0; i < parseIdpServer.Length; i++) + { + if (parseIdpServer[i].Contains("TargetResource") && parseIdpServer[i].Contains("/login/sso")) + { + parseIdpServer[i] = parseIdpServer[i].Replace("/login/sso", "/slm/empty.sp"); + } + } + return String.Join("&", parseIdpServer); + } + #endregion } } diff --git a/Rally.RestApi/Web/CookieAwareCacheableWebClient.cs b/Rally.RestApi/Web/CookieAwareCacheableWebClient.cs index 24e7ffb..f1ff8ec 100644 --- a/Rally.RestApi/Web/CookieAwareCacheableWebClient.cs +++ b/Rally.RestApi/Web/CookieAwareCacheableWebClient.cs @@ -347,7 +347,7 @@ private static CachedResult DeserializeData(byte[] serializedData) if (obj is CachedResult) typedObj = (CachedResult)obj; else - throw new InvalidDataException("Data sent to deserialization is not of type DynamicJsonObject."); + throw new InvalidDataException(String.Format("Data sent to deserialization is not of type DynamicJsonObject: {0}", obj.GetType())); } return typedObj; } From 8490afe0d651588c9f9268a575f6592dec946f3f Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Wed, 1 Jul 2015 16:37:24 -0600 Subject: [PATCH 07/13] DE22791 refactored to only target targetResource in idp url --- Rally.RestApi/Auth/LoginDetails.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rally.RestApi/Auth/LoginDetails.cs b/Rally.RestApi/Auth/LoginDetails.cs index 5cca202..bc2c38e 100644 --- a/Rally.RestApi/Auth/LoginDetails.cs +++ b/Rally.RestApi/Auth/LoginDetails.cs @@ -287,10 +287,10 @@ internal void MarkUserAsLoggedOut() /// public string RedirectIfIdpPointsAtLoginSso(string idpServer) { - String[] parseIdpServer = idpServer.Split('&'); + String[] parseIdpServer = idpServer.Split('&', '?'); for (int i = 0; i < parseIdpServer.Length; i++) { - if (parseIdpServer[i].Contains("TargetResource") && parseIdpServer[i].Contains("/login/sso")) + if (parseIdpServer[i].StartsWith("TargetResource") && parseIdpServer[i].Contains("/login/sso")) { parseIdpServer[i] = parseIdpServer[i].Replace("/login/sso", "/slm/empty.sp"); } From ca1c9506c1da960c8d112d83c5d85e41660b2948 Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Thu, 2 Jul 2015 09:38:18 -0600 Subject: [PATCH 08/13] Change redirect method to internal scope --- Rally.RestApi/Auth/LoginDetails.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rally.RestApi/Auth/LoginDetails.cs b/Rally.RestApi/Auth/LoginDetails.cs index bc2c38e..fb780d0 100644 --- a/Rally.RestApi/Auth/LoginDetails.cs +++ b/Rally.RestApi/Auth/LoginDetails.cs @@ -285,7 +285,7 @@ internal void MarkUserAsLoggedOut() /// relying on IE7 as its embedded browser /// /// - public string RedirectIfIdpPointsAtLoginSso(string idpServer) + internal string RedirectIfIdpPointsAtLoginSso(string idpServer) { String[] parseIdpServer = idpServer.Split('&', '?'); for (int i = 0; i < parseIdpServer.Length; i++) From 25095abd532108dc6c00252476c372b94f9febe0 Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Tue, 7 Jul 2015 13:09:29 -0600 Subject: [PATCH 09/13] Removed script error suppression --- Rally.RestApi.UiForWpf/SsoWindow.xaml.cs | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs b/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs index 36b4938..3685f8c 100644 --- a/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs +++ b/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using mshtml; +using mshtml; using Rally.RestApi.Auth; using System; using System.Collections.Generic; @@ -40,21 +39,6 @@ public SsoWindow() { InitializeComponent(); browser.LoadCompleted += browser_LoadCompleted; - //browser.Navigated += (a, b) => HideScriptErrors(browser, true); - } - - private void HideScriptErrors(WebBrowser browser, bool hide) - { - var fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic); - if (fiComWebBrowser == null) return; - var objComWebBrowser = fiComWebBrowser.GetValue(browser); - if (objComWebBrowser == null) - { - browser.Navigated += (o, s) => HideScriptErrors(browser, hide); - return; - } - objComWebBrowser.GetType() - .InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { hide }); } #endregion From 17d52fd751f16e4b32c85b288f7133796e87f532 Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Tue, 7 Jul 2015 15:18:55 -0600 Subject: [PATCH 10/13] DE22791 Added unit test and fixed a bug --- Rally.RestApi.Test/RallyRestApiTest.cs | 10 ++++++++++ Rally.RestApi/Auth/LoginDetails.cs | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Rally.RestApi.Test/RallyRestApiTest.cs b/Rally.RestApi.Test/RallyRestApiTest.cs index 6fdf89e..0b7cdd3 100644 --- a/Rally.RestApi.Test/RallyRestApiTest.cs +++ b/Rally.RestApi.Test/RallyRestApiTest.cs @@ -2,7 +2,9 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Net; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Rally.RestApi.Auth; using Rally.RestApi.Response; using Rally.RestApi.Test.Properties; using Rally.RestApi.Connection; @@ -397,6 +399,14 @@ public void TestIsNotWsapi2() Assert.IsFalse(restApi.IsWsapi2); } + [TestMethod] + public void TestIdpLoginEndpointRedirect() + { + LoginDetails login = new LoginDetails(new ApiConsoleAuthManager()); + string redirectUrl = login.RedirectIfIdpPointsAtLoginSso("your-idp-url&TargetResource=https://rally1.rallydev.com/login/sso"); + Assert.AreEqual(redirectUrl, "your-idp-url&TargetResource=https://rally1.rallydev.com/slm/empty.sp"); + } + private static void VerifyAttributes(QueryResult result, bool forWsapi2) { var list = (IEnumerable)result.Results; diff --git a/Rally.RestApi/Auth/LoginDetails.cs b/Rally.RestApi/Auth/LoginDetails.cs index fb780d0..935a8b8 100644 --- a/Rally.RestApi/Auth/LoginDetails.cs +++ b/Rally.RestApi/Auth/LoginDetails.cs @@ -287,7 +287,7 @@ internal void MarkUserAsLoggedOut() /// internal string RedirectIfIdpPointsAtLoginSso(string idpServer) { - String[] parseIdpServer = idpServer.Split('&', '?'); + String[] parseIdpServer = idpServer.Split('&'); for (int i = 0; i < parseIdpServer.Length; i++) { if (parseIdpServer[i].StartsWith("TargetResource") && parseIdpServer[i].Contains("/login/sso")) From 9d1613503fd3efdda6620d7c8817052724675a98 Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Mon, 19 Oct 2015 10:11:55 -0600 Subject: [PATCH 11/13] S100891 rebrading to CA Agile Central --- Rally.RestApi.UiForWpf/LoginWindow.xaml.cs | 6 ++-- Rally.RestApi.UiForWpf/SsoWindow.xaml | 2 +- Rally.RestApi/Auth/ApiAuthManager.cs | 20 ++++++------- .../Exceptions/RallyUnavailableException.cs | 2 +- Rally.RestApi/Properties/AssemblyInfo.cs | 8 ++--- Rally.RestApi/RallyRestApi.cs | 30 +++++++++++-------- 6 files changed, 36 insertions(+), 32 deletions(-) diff --git a/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs b/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs index 70250db..9175d37 100644 --- a/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs +++ b/Rally.RestApi.UiForWpf/LoginWindow.xaml.cs @@ -73,8 +73,8 @@ public LoginWindow() controlRowElements = new Dictionary(); connectionTypes = new Dictionary(); - connectionTypes.Add(ConnectionType.BasicAuth, "Basic Authentication (will try Rally SSO if it fails)"); - connectionTypes.Add(ConnectionType.SpBasedSso, "Rally based SSO Authentication"); + connectionTypes.Add(ConnectionType.BasicAuth, "Basic Authentication (will try CA Agile Central SSO if it fails)"); + connectionTypes.Add(ConnectionType.SpBasedSso, "CA Agile Central based SSO Authentication"); connectionTypes.Add(ConnectionType.IdpBasedSso, "IDP Based SSO Authentication"); } #endregion @@ -673,7 +673,7 @@ private void AddColumnDefinition(Grid grid, int pixels = Int32.MaxValue) void loginButton_Click(object sender, RoutedEventArgs e) { string errorMessage; - ShowMessage("Logging into Rally"); + ShowMessage("Logging into CA Agile Central"); AuthMgr.LoginDetails.Username = GetEditorValue(EditorControlType.Username); AuthMgr.LoginDetails.SetPassword(GetEditorValue(EditorControlType.Password)); diff --git a/Rally.RestApi.UiForWpf/SsoWindow.xaml b/Rally.RestApi.UiForWpf/SsoWindow.xaml index 00e9b2c..e7d5745 100644 --- a/Rally.RestApi.UiForWpf/SsoWindow.xaml +++ b/Rally.RestApi.UiForWpf/SsoWindow.xaml @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x:ClassModifier="internal" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Topmost="True" - Title="Single Sign On for Rally" Height="700" Width="800"> + Title="Single Sign On for CA Agile Central" Height="700" Width="800"> diff --git a/Rally.RestApi/Auth/ApiAuthManager.cs b/Rally.RestApi/Auth/ApiAuthManager.cs index 94ed0a5..4fdf365 100644 --- a/Rally.RestApi/Auth/ApiAuthManager.cs +++ b/Rally.RestApi/Auth/ApiAuthManager.cs @@ -293,11 +293,11 @@ public static void Configure(string loginWindowTitle = null, { LoginWindowTitle = loginWindowTitle; if (String.IsNullOrWhiteSpace(LoginWindowTitle)) - LoginWindowTitle = "Login to Rally"; + LoginWindowTitle = "Login to CA Agile Central"; LoginWindowHeaderLabelText = loginWindowHeaderLabelText; if (String.IsNullOrWhiteSpace(LoginWindowHeaderLabelText)) - LoginWindowHeaderLabelText = "Login to Rally"; + LoginWindowHeaderLabelText = "Login to CA Agile Central"; LoginWindowDefaultServer = loginWindowDefaultServer; if (LoginWindowDefaultServer == null) @@ -325,7 +325,7 @@ public static void Configure(string loginWindowTitle = null, LoginWindowRallyServerTabText = loginWindowServerTabText; if (String.IsNullOrWhiteSpace(LoginWindowRallyServerTabText)) - LoginWindowRallyServerTabText = "Rally"; + LoginWindowRallyServerTabText = "CA Agile Central"; LoginWindowServerLabelText = loginWindowServerLabelText; if (String.IsNullOrWhiteSpace(LoginWindowServerLabelText)) @@ -391,11 +391,11 @@ public static void Configure(string loginWindowTitle = null, LoginFailureServerEmpty = loginFailureServerEmpty; if (String.IsNullOrWhiteSpace(LoginFailureServerEmpty)) - LoginFailureServerEmpty = "Rally Server is a required field."; + LoginFailureServerEmpty = "CA Agile Central Server is a required field."; LoginFailureBadConnection = loginFailureBadConnection; if (String.IsNullOrWhiteSpace(LoginFailureBadConnection)) - LoginFailureBadConnection = "Failed to connect to the Rally server or proxy."; + LoginFailureBadConnection = "Failed to connect to the CA Agile Central server or proxy."; LoginFailureUnknown = loginFailureUnknown; if (String.IsNullOrWhiteSpace(LoginFailureUnknown)) @@ -566,13 +566,13 @@ private RallyRestApi.AuthenticationResult PerformAuthenticationCheckAgainstRally try { if (String.IsNullOrWhiteSpace(LoginDetails.RallyServer)) - errorMessage = "Bad URI format for Rally Server"; + errorMessage = "Bad URI format for CA Agile Central Server"; else serverUri = new Uri(LoginDetails.RallyServer); } catch { - errorMessage = "Bad URI format for Rally Server"; + errorMessage = "Bad URI format for CA Agile Central Server"; } try @@ -585,7 +585,7 @@ private RallyRestApi.AuthenticationResult PerformAuthenticationCheckAgainstRally } catch (RallyUnavailableException) { - errorMessage = "Rally is currently unavailable."; + errorMessage = "CA Agile Central is currently unavailable."; } catch (WebException e) { @@ -645,7 +645,7 @@ private RallyRestApi.AuthenticationResult PerformAuthenticationCheckAgainstIdp(o } catch { - errorMessage = "Bad URI format for Rally Server"; + errorMessage = "Bad URI format for CA Agile Central Server"; } try @@ -658,7 +658,7 @@ private RallyRestApi.AuthenticationResult PerformAuthenticationCheckAgainstIdp(o } catch (RallyUnavailableException) { - errorMessage = "Rally is currently unavailable."; + errorMessage = "CA Agile Central is currently unavailable."; } catch (WebException e) { diff --git a/Rally.RestApi/Exceptions/RallyUnavailableException.cs b/Rally.RestApi/Exceptions/RallyUnavailableException.cs index 51bbbb9..a05023d 100644 --- a/Rally.RestApi/Exceptions/RallyUnavailableException.cs +++ b/Rally.RestApi/Exceptions/RallyUnavailableException.cs @@ -21,7 +21,7 @@ public class RallyUnavailableException : Exception /// The exception that is the cause of the current exception. /// The HTML error message that was returned from Rally. internal RallyUnavailableException(Exception innerException, string errorMessage) - : base("Rally Unavailable", innerException) + : base("CA Agile Central Unavailable", innerException) { ErrorMessage = errorMessage; } diff --git a/Rally.RestApi/Properties/AssemblyInfo.cs b/Rally.RestApi/Properties/AssemblyInfo.cs index 760a56a..d3283ce 100644 --- a/Rally.RestApi/Properties/AssemblyInfo.cs +++ b/Rally.RestApi/Properties/AssemblyInfo.cs @@ -4,12 +4,12 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Rally Rest API for .NET")] +[assembly: AssemblyTitle("CA Agile Central Rest API for .NET")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Rally Software, Inc.")] -[assembly: AssemblyProduct("Rally Rest API for .NET")] -[assembly: AssemblyCopyright("Copyright © Rally Software 2013")] +[assembly: AssemblyCompany("CA Technologies")] +[assembly: AssemblyProduct("CA Agile Central Rest API for .NET")] +[assembly: AssemblyCopyright("Copyright © CA Technologie 2013")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/Rally.RestApi/RallyRestApi.cs b/Rally.RestApi/RallyRestApi.cs index 881551b..e97cc07 100644 --- a/Rally.RestApi/RallyRestApi.cs +++ b/Rally.RestApi/RallyRestApi.cs @@ -116,6 +116,10 @@ internal class StringValue : Attribute /// The default server to use: (https://rally1.rallydev.com) /// public const string DEFAULT_SERVER = "https://rally1.rallydev.com"; + /// + /// /// The default auth arror + /// + public const string AUTH_ERROR = "You must authenticate against CA Agile Central prior to performing any data operations."; #endregion #region Properties and Fields @@ -485,7 +489,7 @@ public static void SetDefaultConnectionLimit(ushort maxConnections) public DynamicJsonObject Post(String relativeUri, DynamicJsonObject data) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); Uri uri = new Uri(String.Format("{0}slm/webservice/{1}/{2}", httpService.Server.AbsoluteUri, WsapiVersion, relativeUri)); string postData = serializer.Serialize(data); @@ -502,7 +506,7 @@ public DynamicJsonObject Post(String relativeUri, DynamicJsonObject data) private DynamicJsonObject DoDelete(Uri uri, bool retry = true) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); var response = serializer.Deserialize(httpService.Delete(GetSecuredUri(uri), GetProcessedHeaders())); if (retry && ConnectionInfo.SecurityToken != null && response[response.Fields.First()].Errors.Count > 0) @@ -542,7 +546,7 @@ private DynamicJsonObject DoDelete(Uri uri, bool retry = true) public QueryResult Query(Request request) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); DynamicJsonObject response; if (IsWsapi2) @@ -635,7 +639,7 @@ public dynamic GetCurrentUser(params string[] fetchedFields) public dynamic GetSubscription(params string[] fetchedFields) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); return GetByReference("/subscription.js", fetchedFields); } @@ -684,10 +688,10 @@ public dynamic GetByReference(string typePath, long oid, params string[] fetched public dynamic GetByReference(string aRef, params string[] fetchedFields) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); if (aRef == null) - throw new ArgumentNullException("aRef", "You must provide a reference to retrieve data from Rally."); + throw new ArgumentNullException("aRef", "You must provide a reference to retrieve data from CA Agile Central."); if (fetchedFields.Length == 0) { @@ -725,7 +729,7 @@ public dynamic GetByReference(string aRef, params string[] fetchedFields) public dynamic GetByReferenceAndWorkspace(string aRef, string workspaceRef, params string[] fetchedFields) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); if (fetchedFields.Length == 0) { @@ -823,7 +827,7 @@ public OperationResult Delete(string aRef) public OperationResult Delete(string workspaceRef, string aRef) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); var result = new OperationResult(); if (!aRef.Contains(".js")) @@ -879,7 +883,7 @@ public CreateResult Create(string typePath, DynamicJsonObject obj) public CreateResult Create(string workspaceRef, string typePath, DynamicJsonObject obj) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); var data = new DynamicJsonObject(); data[typePath] = obj; @@ -940,7 +944,7 @@ public OperationResult Update(string reference, DynamicJsonObject obj) public OperationResult Update(string typePath, string oid, DynamicJsonObject obj) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); var result = new OperationResult(); var data = new DynamicJsonObject(); @@ -972,7 +976,7 @@ public OperationResult Update(string typePath, string oid, DynamicJsonObject obj public QueryResult GetAllowedAttributeValues(string typePath, string attributeName) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); QueryResult attributes = GetAttributesByType(typePath); var attribute = attributes.Results.SingleOrDefault(a => a.ElementName.ToLower() == attributeName.ToLower().Replace(" ", "")); @@ -1017,7 +1021,7 @@ public QueryResult GetAllowedAttributeValues(string typePath, string attributeNa public CacheableQueryResult GetTypes(string queryString) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); if (!IsWsapi2) throw new InvalidOperationException("This method requires WSAPI 2.0"); @@ -1046,7 +1050,7 @@ public CacheableQueryResult GetTypes(string queryString) public QueryResult GetAttributesByType(string type) { if (ConnectionInfo == null) - throw new InvalidOperationException("You must authenticate against Rally prior to performing any data operations."); + throw new InvalidOperationException(AUTH_ERROR); var typeDefRequest = new Request("TypeDefinition"); typeDefRequest.Fetch = new List() { "Attributes" }; From b77db15f2f719988bb03f7ee00801ec68e8c969f Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Tue, 3 Nov 2015 16:13:06 -0700 Subject: [PATCH 12/13] Readding sso window error suppression --- Rally.RestApi.UiForWpf/SsoWindow.xaml.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs b/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs index 3685f8c..2535f5b 100644 --- a/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs +++ b/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs @@ -39,6 +39,7 @@ public SsoWindow() { InitializeComponent(); browser.LoadCompleted += browser_LoadCompleted; + //browser.Navigated += (a, b) => HideScriptErrors(browser, true); } #endregion @@ -181,5 +182,19 @@ protected override void OnClosed(EventArgs e) base.OnClosed(e); } #endregion + + private void HideScriptErrors(WebBrowser browser, bool hide) + { + var fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic); + if (fiComWebBrowser == null) return; + var objComWebBrowser = fiComWebBrowser.GetValue(browser); + if (objComWebBrowser == null) + { + browser.Navigated += (o, s) => HideScriptErrors(browser, hide); + return; + } + objComWebBrowser.GetType() + .InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { hide }); + } } } From ebb3bf13ee6fe332dc489077e7ce1cd2b5c97a71 Mon Sep 17 00:00:00 2001 From: Joshua Stupplebeen Date: Thu, 5 Nov 2015 10:16:21 -0700 Subject: [PATCH 13/13] DE22791 Adding removed js alert error suppression --- Rally.RestApi.UiForWpf/SsoWindow.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs b/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs index 2535f5b..fe0172a 100644 --- a/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs +++ b/Rally.RestApi.UiForWpf/SsoWindow.xaml.cs @@ -39,7 +39,7 @@ public SsoWindow() { InitializeComponent(); browser.LoadCompleted += browser_LoadCompleted; - //browser.Navigated += (a, b) => HideScriptErrors(browser, true); + browser.Navigated += (a, b) => HideScriptErrors(browser, true); } #endregion