/// <summary> /// Gets the instance of <see cref="IntelSession"/> to use when /// contacting the intel server. /// </summary> /// <param name="create"> /// <see langword="true"/> to create a new instance of /// <see cref="IntelSession"/> if there is currently not an active /// session; othwerise, return <see langword="null"/> if no session /// is currently active. /// </param> protected virtual IntelSession GetSession(bool create) { Contract.Requires(IsRunning); Contract.Ensures((Contract.Result<IntelSession>() != null) || !create); var session = this.session; if ((session != null) && session.IsConnected) { // Existing session is still valid return session; } else if (create && (String.IsNullOrEmpty(this.username) || String.IsNullOrEmpty(this.passwordHash))) { // Can't login without a username/password throw new AuthenticationException(); } else if (create && this.lastAuthFailure.HasValue && (this.lastAuthFailure + this.authRetryTimeout > DateTime.UtcNow)) { // Wait longer before trying to log in again throw new AuthenticationException(); } else if (create) { // Safe to create a new instance of IntelSession session = new IntelSession(this.username, this.passwordHash, this.serviceUri); this.session = session; this.timerSession.Change(this.keepAlivePeriod, this.keepAlivePeriod); this.lastIntel = DateTime.UtcNow; this.Status = IntelStatus.Active; this.OnPropertyChanged("Users"); return session; } else if (session != null) { // Session has expired this.session = null; timerSession.Change(Timeout.Infinite, Timeout.Infinite); return null; } else { // No session open return null; } }
/// <summary> /// Stops the <see cref="IntelReporter"/> from providing /// location data and events. <see cref="IntelReported"/> /// events will no longer be raised. /// </summary> public void Stop() { Contract.Ensures(!this.IsRunning); lock (this.syncRoot) { try { if (this.IsRunning) { this.Status = IntelStatus.Stopping; if (this.session != null) { this.session.Dispose(); this.session = null; } this.channels.Stop(); this.Status = IntelStatus.Stopped; } } catch { this.Status = IntelStatus.FatalError; throw; } } }
/// <inheritdoc/> protected override void Dispose(bool disposing) { try { if (disposing) { // Clean up lock (this.syncRoot) { if (this.Status != IntelStatus.Disposed) { this.Status = IntelStatus.Disposing; if (this.session != null) { this.session.Dispose(); this.session = null; } this.timerSession.Dispose(); this.channels.Dispose(); } } } else { // Cannot safely clean up } } finally { this.status = IntelStatus.Disposed; base.Dispose(disposing); } }
/// <summary> /// Updates the user's credentials and forces the service to /// reauthenticate with the reporting service. /// </summary> /// <param name="username"> /// The TEST auth username. /// </param> /// <param name="password"> /// The plaintext TEST services password. It will be hashed /// automatically. /// </param> /// <exception cref="AuthenticationException"> /// The credentials provided by the user are incorrect. /// </exception> public void Authenticate(string username, string password) { Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(username)); Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(password)); Contract.Requires<ObjectDisposedException>(this.Status != IntelStatus.Disposed); Contract.Requires<InvalidOperationException>(this.Status != IntelStatus.FatalError); // Verify the password is correct before saving anything var passwordHash = IntelSession.HashPassword(password); IntelSession testSession; try { testSession = new IntelSession(username, passwordHash, this.serviceUri); } catch (WebException) { lock (this.syncRoot) { this.Status = IntelStatus.NetworkError; throw; } } // Update the program state lock (this.syncRoot) { this.username = username; this.passwordHash = passwordHash; if (this.session != null) { this.session.Dispose(); } this.session = testSession; this.lastIntel = DateTime.UtcNow; this.lastAuthFailure = null; this.Status = IntelStatus.Active; this.timerSession.Change(this.keepAlivePeriod, this.keepAlivePeriod); this.OnPropertyChanged("Username"); this.OnPropertyChanged("PasswordHash"); this.OnPropertyChanged("Users"); } }