/// <summary>
        /// Constructor
        /// </summary>
        /// <param name="isUiSupported">Does this authentication manager support a UI?</param>
        /// <param name="applicationToken">An application token to be used as the file name to store data as (no extension needed). Each
        /// consuming application should use a unique name in order to ensure that the user credentials are not
        /// overwritten by other applications. An exception will be thrown elsewhere if this is not a valid file name.</param>
        /// <param name="encryptionKey">The encryption key, or salt, to be used for any encryption routines. This salt
        /// should be different for each user, and not the same for everyone consuming the same application. Only used
        /// for UI support.</param>
        /// <param name="encryptionRoutines">The encryption routines to use for encryption/decryption of data. Only used for UI support.</param>
        /// <param name="webServiceVersion">The version of the WSAPI API to use.</param>
        protected ApiAuthManager(bool isUiSupported, string applicationToken, string encryptionKey,
                                 IEncryptionRoutines encryptionRoutines, string webServiceVersion = RallyRestApi.DEFAULT_WSAPI_VERSION)
        {
            if (isUiSupported)
            {
                if (String.IsNullOrWhiteSpace(applicationToken))
                {
                    throw new ArgumentNullException("applicationToken",
                                                    "You must provide an application token.");
                }

                if (encryptionKey == null)
                {
                    throw new ArgumentNullException("encryptionKey",
                                                    "You must provide an encryption key that will be used to keep user data safe.");
                }

                if (encryptionRoutines == null)
                {
                    throw new ArgumentNullException("encryptionRoutines",
                                                    "You must provide encryption routines that will be used to keep user data safe.");
                }

                ApplicationToken   = applicationToken;
                EncryptionKey      = encryptionKey;
                EncryptionRoutines = encryptionRoutines;

                LoginDetails = new LoginDetails(this);
                LoginDetails.LoadFromDisk();
            }

            IsUiSupported = isUiSupported;
            Api           = new RallyRestApi(this, webServiceVersion: webServiceVersion);
        }
        private void UpdateAuthenticationState()
        {
            if (AuthenticationStateChange != null)
            {
                switch (Api.AuthenticationState)
                {
                case RallyRestApi.AuthenticationResult.Authenticated:
                    AuthenticationStateChange.Invoke(Api.AuthenticationState, Api);
                    break;

                case RallyRestApi.AuthenticationResult.PendingSSO:
                case RallyRestApi.AuthenticationResult.NotAuthorized:
                    AuthenticationStateChange.Invoke(Api.AuthenticationState, null);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            if (Api.AuthenticationState == RallyRestApi.AuthenticationResult.Authenticated)
            {
                LoginDetails.SaveToDisk();
            }
        }
        /// <summary>
        /// Reports the results of an SSO action.
        /// </summary>
        /// <param name="success">Was SSO authentication completed successfully?</param>
        /// <param name="rallyServer">The server that the ZSessionID is for.</param>
        /// <param name="zSessionID">The zSessionID that was returned from Rally.</param>
        protected void ReportSsoResults(bool success, string rallyServer, string zSessionID)
        {
            if (SsoAuthenticationComplete != null)
            {
                if (success)
                {
                    RallyRestApi.AuthenticationResult authResult =
                        Api.AuthenticateWithZSessionID(Api.ConnectionInfo.UserName, zSessionID, rallyServer: rallyServer);

                    if (authResult == RallyRestApi.AuthenticationResult.Authenticated)
                    {
                        LoginDetails.SaveToDisk();
                        NotifyLoginWindowSsoComplete(authResult, Api);
                        SsoAuthenticationComplete.Invoke(authResult, Api);
                        return;
                    }
                }

                LoginDetails.MarkUserAsLoggedOut();
                Api.Logout();
                NotifyLoginWindowSsoComplete(RallyRestApi.AuthenticationResult.NotAuthorized, null);
                SsoAuthenticationComplete.Invoke(RallyRestApi.AuthenticationResult.NotAuthorized, null);
            }
        }
 /// <summary>
 /// Performs an logout from Rally.
 /// </summary>
 /// <example>
 /// <code language="C#">
 /// authMgr.PerformLogoutFromRally();
 /// </code>
 /// </example>
 protected void PerformLogoutFromRally()
 {
     Api.Logout();
     LoginDetails.MarkUserAsLoggedOut();
     AuthenticationStateChange.Invoke(Api.AuthenticationState, null);
 }
        /// <summary>
        /// Creates the web proxy object.
        /// </summary>
        private WebProxy GetProxy(out string errorMessage)
        {
            errorMessage = String.Empty;
            WebProxy proxy = null;

            if (!String.IsNullOrWhiteSpace(LoginDetails.ProxyServer))
            {
                try
                {
                    proxy = new WebProxy(new Uri(LoginDetails.ProxyServer));
                }
                catch
                {
                    errorMessage = "Bad URI format for Proxy Server";
                    return(null);
                }

                if (!String.IsNullOrWhiteSpace(LoginDetails.ProxyUsername))
                {
                    proxy.Credentials = new NetworkCredential(LoginDetails.ProxyUsername, LoginDetails.GetProxyPassword());
                }
                else
                {
                    proxy.UseDefaultCredentials = true;
                }
            }

            return(proxy);
        }
        /// <summary>
        /// Performs an authentication check against Rally with the specified credentials
        /// </summary>
        private RallyRestApi.AuthenticationResult PerformAuthenticationCheckAgainstRally(out string errorMessage,
                                                                                         bool allowSso)
        {
            if (!IsUiSupported)
            {
                throw new InvalidProgramException("This method is only supported by UI enabled Authentication Managers.");
            }

            RallyRestApi.AuthenticationResult authResult = RallyRestApi.AuthenticationResult.NotAuthorized;
            errorMessage = String.Empty;
            WebProxy proxy = GetProxy(out errorMessage);

            if (!String.IsNullOrWhiteSpace(errorMessage))
            {
                return(RallyRestApi.AuthenticationResult.NotAuthorized);
            }

            if (String.IsNullOrWhiteSpace(LoginDetails.RallyServer))
            {
                errorMessage = LoginFailureServerEmpty;
            }
            else if (String.IsNullOrWhiteSpace(LoginDetails.Username))
            {
                errorMessage = LoginFailureLoginEmpty;
            }

            Uri serverUri = null;

            try
            {
                if (String.IsNullOrWhiteSpace(LoginDetails.RallyServer))
                {
                    errorMessage = "Bad URI format for Rally Server";
                }
                else
                {
                    serverUri = new Uri(LoginDetails.RallyServer);
                }
            }
            catch
            {
                errorMessage = "Bad URI format for Rally Server";
            }

            try
            {
                if (String.IsNullOrWhiteSpace(errorMessage))
                {
                    authResult = Api.Authenticate(LoginDetails.Username, LoginDetails.GetPassword(),
                                                  serverUri, proxy, allowSSO: allowSso);
                }
            }
            catch (RallyUnavailableException)
            {
                errorMessage = "Rally is currently unavailable.";
            }
            catch (WebException e)
            {
                if (e.Response is HttpWebResponse)
                {
                    if ((((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.BadGateway) ||
                        (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.BadRequest))
                    {
                        errorMessage = LoginFailureBadServer;
                    }
                    else if (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.ProxyAuthenticationRequired)
                    {
                        errorMessage = LoginFailureProxyCredentials;
                    }
                    else if (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.Unauthorized)
                    {
                        errorMessage = LoginFailureCredentials;
                    }
                    else
                    {
                        errorMessage = LoginFailureUnknown;
                    }
                }
                else if ((e is WebException) &&
                         (((WebException)e).Status == WebExceptionStatus.ConnectFailure))
                {
                    errorMessage = LoginFailureBadConnection;
                }
                else
                {
                    errorMessage = LoginFailureUnknown;
                }
            }

            UpdateAuthenticationState();
            return(Api.AuthenticationState);
        }
 /// <summary>
 /// Deletes any cached login credentials from disk.
 /// </summary>
 /// <returns>If the files were successfully deleted or not.</returns>
 /// <example>
 /// <code language="C#">
 /// bool success = authMgr.DeleteCachedLoginDetailsFromDisk();
 /// </code>
 /// </example>
 public bool DeleteCachedLoginDetailsFromDisk()
 {
     return(LoginDetails.DeleteCachedLoginDetailsFromDisk());
 }
		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");
		}
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="isUiSupported">Does this authentication manager support a UI?</param>
		/// <param name="applicationToken">An application token to be used as the file name to store data as (no extension needed). Each 
		/// consuming application should use a unique name in order to ensure that the user credentials are not 
		/// overwritten by other applications. An exception will be thrown elsewhere if this is not a valid file name.</param>
		/// <param name="encryptionKey">The encryption key, or salt, to be used for any encryption routines. This salt 
		/// should be different for each user, and not the same for everyone consuming the same application. Only used 
		/// for UI support.</param>
		/// <param name="encryptionRoutines">The encryption routines to use for encryption/decryption of data. Only used for UI support.</param>
		/// <param name="webServiceVersion">The version of the WSAPI API to use.</param>
		protected ApiAuthManager(bool isUiSupported, string applicationToken, string encryptionKey,
			IEncryptionRoutines encryptionRoutines, string webServiceVersion = RallyRestApi.DEFAULT_WSAPI_VERSION)
		{
			if (isUiSupported)
			{
				if (String.IsNullOrWhiteSpace(applicationToken))
				{
					throw new ArgumentNullException("applicationToken",
						"You must provide an application token.");
				}

				if (encryptionKey == null)
				{
					throw new ArgumentNullException("encryptionKey",
						"You must provide an encryption key that will be used to keep user data safe.");
				}

				if (encryptionRoutines == null)
				{
					throw new ArgumentNullException("encryptionRoutines",
						"You must provide encryption routines that will be used to keep user data safe.");
				}

				ApplicationToken = applicationToken;
				EncryptionKey = encryptionKey;
				EncryptionRoutines = encryptionRoutines;

				LoginDetails = new LoginDetails(this);
				LoginDetails.LoadFromDisk();
			}

			IsUiSupported = isUiSupported;
			Api = new RallyRestApi(this, webServiceVersion: webServiceVersion);
		}