using System;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Security.Principal;
using System.ServiceModel.DomainServices.Client;
using System.ServiceModel.DomainServices.Client.ApplicationServices;
using IssueVision.Data.Web;
using IssueVision.Common;
namespace IssueVision.Model
{
[Export(typeof(IAuthenticationModel))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class AuthenticationModel : IAuthenticationModel
{
#region "Private Data"
private AuthenticationService _service;
#endregion "Private Data"
#region "Protected Propertes"
protected AuthenticationService AuthService
{
get
{
if (_service == null)
{
// This will enable WebContext to dsicover Authenticaion Context's from a CLass Library
((WebAuthenticationService)WebContext.Current.Authentication).DomainContext = new AuthenticationContext();
_service = WebContext.Current.Authentication;
((INotifyPropertyChanged)_service).PropertyChanged += new PropertyChangedEventHandler(_service_PropertyChanged);
_service.LoggedIn += new EventHandler<AuthenticationEventArgs>(_service_LoggedIn);
_service.LoggedOut += new EventHandler<AuthenticationEventArgs>(_service_LoggedOut);
}
return _service;
}
}
#endregion "Protected Propertes"
#region "IAuthenticationModel Interface implementation"
/// <summary>
/// This will automatically authenticate a user when
/// the user chose "Keep me signed in" on a previous login attempt
/// </summary>
public void LoadUserAsync()
{
this.AuthService.LoadUser(this.LoadUserOperation_Completed, null);
}
/// <summary>
/// Authenticate a user with user name and password
/// </summary>
/// <param name="loginParameters"></param>
public void LoginAsync(LoginParameters loginParameters)
{
this.AuthService.Login(loginParameters, this.LoginOperation_Completed, null);
}
/// <summary>
/// Logout
/// </summary>
public void LogoutAsync()
{
this.AuthService.Logout(this.LogoutOperation_Completed, null);
}
/// <summary>
/// A principal object represents the security context of the user
/// on whose behalf the code is running, including that user's
/// identity (IIdentity) and any roles to which they belong.
/// </summary>
public IPrincipal User
{
get { return this.AuthService.User; }
}
/// <summary>
/// True if there is an operation (LoadUserAsync,
/// LoginAsync, or LogoutAsync) in progress; otherwise, false
/// </summary>
public Boolean IsBusy
{
get { return this.AuthService.IsBusy; }
}
/// <summary>
/// true if there is an operation in progress; otherwise, false
/// </summary>
public bool IsLoadingUser
{
get { return this.AuthService.IsLoadingUser; }
}
/// <summary>
/// true if there is an operation in progress; otherwise, false
/// </summary>
public bool IsLoggingIn
{
get { return this.AuthService.IsLoggingIn; }
}
/// <summary>
/// true if there is an operation in progress; otherwise, false
/// </summary>
public bool IsLoggingOut
{
get { return this.AuthService.IsLoggingOut; }
}
/// <summary>
/// true if there is an operation in progress; otherwise, false
/// </summary>
public bool IsSavingUser
{
get { return this.AuthService.IsSavingUser; }
}
public event EventHandler<LoadUserOperationEventArgs> LoadUserComplete;
public event EventHandler<LoginOperationEventArgs> LoginComplete;
public event EventHandler<LogoutOperationEventArgs> LogoutComplete;
public event EventHandler<AuthenticationEventArgs> AuthenticationChanged;
#endregion "IAuthenticationModel Interface implementation"
#region "INotifyPropertyChanged Interface implementation"
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion "INotifyPropertyChanged Interface implementation"
#region "Private Methods"
private void _service_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "IsBusy":
this.OnPropertyChanged("IsBusy");
break;
case "IsLoadingUser":
this.OnPropertyChanged("IsLoadingUser");
break;
case "IsLoggingIn":
this.OnPropertyChanged("IsLoggingIn");
break;
case "IsLoggingOut":
this.OnPropertyChanged("IsLoggingOut");
break;
case "IsSavingUser":
this.OnPropertyChanged("IsSavingUser");
break;
case "User":
this.OnPropertyChanged("User");
break;
}
}
private void _service_LoggedIn(object sender, AuthenticationEventArgs e)
{
if (this.AuthenticationChanged != null)
this.AuthenticationChanged(this, e);
}
private void _service_LoggedOut(object sender, AuthenticationEventArgs e)
{
if (this.AuthenticationChanged != null)
this.AuthenticationChanged(this, e);
}
private void LoadUserOperation_Completed(LoadUserOperation loadUserOperation)
{
if (loadUserOperation.HasError)
{
if (this.LoadUserComplete != null)
this.LoadUserComplete(this, new LoadUserOperationEventArgs(loadUserOperation, loadUserOperation.Error));
loadUserOperation.MarkErrorAsHandled();
}
else
{
if (this.LoadUserComplete != null)
this.LoadUserComplete(this, new LoadUserOperationEventArgs(loadUserOperation));
}
}
private void LoginOperation_Completed(LoginOperation loginOperation)
{
if (loginOperation.LoginSuccess)
{
if (this.LoginComplete != null)
this.LoginComplete(this, new LoginOperationEventArgs(loginOperation));
}
else
{
if (loginOperation.HasError)
{
if (this.LoginComplete != null)
this.LoginComplete(this, new LoginOperationEventArgs(loginOperation, loginOperation.Error));
loginOperation.MarkErrorAsHandled();
}
else if (!loginOperation.IsCanceled)
{
if (this.LoginComplete != null)
{
Exception ex = new Exception(CommonResources.BadUserOrPassword);
this.LoginComplete(this, new LoginOperationEventArgs(ex));
}
}
else
{
if (this.LoginComplete != null)
this.LoginComplete(this, new LoginOperationEventArgs(loginOperation));
}
}
}
private void LogoutOperation_Completed(LogoutOperation logoutOperation)
{
if (logoutOperation.HasError)
{
if (this.LogoutComplete != null)
this.LogoutComplete(this, new LogoutOperationEventArgs(logoutOperation, logoutOperation.Error));
logoutOperation.MarkErrorAsHandled();
}
else
{
if (this.LogoutComplete != null)
this.LogoutComplete(this, new LogoutOperationEventArgs(logoutOperation));
}
}
#endregion "Private Methods"
}
}