namespace IssueVision.Data.Web
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.Server;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server.ApplicationServices;
using System.Web;
using System.Web.Security;
[EnableClientAccess()]
public class AuthenticationService : LinqToEntitiesDomainService<IssueVisionEntities>, IAuthentication<LoginUser>
{
#region "Private Data"
private static LoginUser DefaultUser = new LoginUser()
{
Name = String.Empty,
Password = String.Empty,
Roles = new List<string>()
};
#endregion "Private Data"
#region "IAuthentication<LoginUser> Interface implementation"
/// <summary>
/// Get the user information for the currently login user
/// </summary>
/// <returns></returns>
[Query(IsComposable = false)]
public LoginUser GetUser()
{
if ((this.ServiceContext != null) &&
(this.ServiceContext.User != null) &&
this.ServiceContext.User.Identity.IsAuthenticated)
{
return this.GetUserByName(this.ServiceContext.User.Identity.Name);
}
return AuthenticationService.DefaultUser;
}
/// <summary>
/// Not implemented.
/// </summary>
/// <param name="user"></param>
[Update]
public void UpdateUser(LoginUser user)
{
throw new NotImplementedException();
}
/// <summary>
/// Validate and login
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <param name="isPersistent"></param>
/// <param name="customData"></param>
/// <returns></returns>
public LoginUser Login(string userName, string password, bool isPersistent, string customData)
{
try
{
string userData;
if (this.ValidateUser(userName, password, customData, out userData))
{
// if IsPersistent is true, will keep logged in for up to a week (or until you logout)
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
/* version */ 1,
userName,
DateTime.Now, DateTime.Now.AddDays(7),
isPersistent,
userData,
FormsAuthentication.FormsCookiePath);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
if (ticket.IsPersistent)
{
authCookie.Expires = ticket.Expiration;
}
HttpContextBase httpContext = (HttpContextBase)ServiceContext.GetService(typeof(HttpContextBase));
httpContext.Response.Cookies.Add(authCookie);
return this.GetUserByName(userName);
}
return AuthenticationService.DefaultUser;
}
catch (Exception ex)
{
Exception actualException = ex;
while (actualException.InnerException != null)
{
actualException = actualException.InnerException;
}
throw actualException;
}
}
/// <summary>
/// Logout
/// </summary>
/// <returns></returns>
public LoginUser Logout()
{
FormsAuthentication.SignOut();
return AuthenticationService.DefaultUser;
}
#endregion "IAuthentication<LoginUser> Interface implementation"
#region "Private Methods"
/// <summary>
/// Get user by user name
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
private LoginUser GetUserByName(string userName)
{
User foundUser = this.ObjectContext.Users.FirstOrDefault(u => u.Name == userName);
if (foundUser != null)
{
return new LoginUser()
{
Name = foundUser.Name,
PasswordHash = foundUser.PasswordHash,
PasswordSalt = foundUser.PasswordSalt,
UserType = foundUser.UserType,
ProfileReset = foundUser.ProfileReset
};
}
else
return null;
}
/// <summary>
/// Validate user with password
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
private bool ValidateUser(string username, string password, string customData, out string userData)
{
userData = null;
LoginUser foundUser = this.GetUserByName(username);
if (foundUser != null)
{
// generate password hash
string passwordHash = HashHelper.ComputeSaltedHash(password, foundUser.PasswordSalt);
if (string.Equals(passwordHash, foundUser.PasswordHash, StringComparison.Ordinal))
{
userData = foundUser.UserType;
return true;
}
else
return false;
}
else
return false;
}
#endregion "Private Methods"
}
}