Skip to content

Instantly share code, notes, and snippets.

@scionwest
Created December 6, 2014 20:38
Show Gist options
  • Save scionwest/88c0401d30a51a32bb48 to your computer and use it in GitHub Desktop.
Save scionwest/88c0401d30a51a32bb48 to your computer and use it in GitHub Desktop.
UserService
public class UserService : IUserService
{
/// <summary>
/// The cached user for re-use once fetched.
/// </summary>
private static User _cachedUser;
/// <summary>
/// The filename used when saving the users session token.
/// </summary>
private const string tokenFilename = "session";
/// <summary>
/// The key name used to save the key/value pair associated with the session token.
/// </summary>
private const string tokenKey = "token";
/// <summary>
/// The user repository
/// </summary>
private IUserRepository userRepository;
/// <summary>
/// The storage service
/// </summary>
private IStorageService storageService;
/// <summary>
/// Initializes a new instance of the <see cref="UserService"/> class.
/// </summary>
/// <param name="repository">The repository.</param>
/// <param name="storageService">The storage service.</param>
public UserService(IUserRepository repository, IStorageService storageService)
{
this.userRepository = repository;
this.storageService = storageService;
}
/// <summary>
/// Asks the data store to create a new user with the given data..
/// </summary>
/// <param name="user"></param>
/// <param name="password">The password.</param>
/// <returns>
/// Returns true if the user was created.
/// </returns>
public async Task<bool> CreateUser(User user, string password)
{
// Convert the user object to a dictionary for the repository.
var data = new Dictionary<string, string>
{
{ user.GetPropertyName(p => p.Username), user.Username },
{ user.GetPropertyName(p => p.Email), user.Email },
{ "password", password},
};
string sessionToken = await this.userRepository.CreateUser(data, password);
// Save the encrypted token and return.
await this.storageService.SaveValueByKey(tokenFilename, new KeyValuePair<string, string>(tokenKey, sessionToken));
_cachedUser = user;
return true;
}
/// <summary>
/// Retrieves user data for a user who has a matching username and password.
/// </summary>
/// <param name="username">The username.</param>
/// <param name="password">The password.</param>
/// <returns>
/// Returns a restored user.
/// </returns>
public async Task<User> RetrieveUser(string username, string password)
{
Dictionary<string, string> data = await this.userRepository.RetrieveUser(username, password);
User user = this.RestoreUserFromData(data);
_cachedUser = user;
return user;
}
/// <summary>
/// Retrieves the user associated with the provided session token.
/// </summary>
/// <returns>
/// Returns a restored user.
/// </returns>
/// <exception cref="Entities.Exceptions.UserNotAuthenticatedException">Session Token does not exist. Use must re-authenticate with a username and password.</exception>
public async Task<User> RetrieveUser()
{
// Check if our cache is valid and return it.
if (_cachedUser != null)
{
return _cachedUser;
}
// Load the session token.
string sessionToken = await this.storageService.LoadValueFromKey(tokenFilename, tokenKey);
if (string.IsNullOrWhiteSpace(sessionToken))
{
throw new UserNotAuthenticatedException("Session Token does not exist. Use must re-authenticate with a username and password.");
}
Dictionary<string, string> data = await this.userRepository.RetrieveUser(sessionToken);
User user = this.RestoreUserFromData(data);
_cachedUser = user;
return user;
}
/// <summary>
/// Logs the current user out, closing their session.
/// </summary>
public void Logout()
{
_cachedUser = null;
}
/// <summary>
/// Restores the user from data provided by the repository.
/// </summary>
/// <param name="data">The data retrieved from the repository.</param>
/// <returns>Returns a user instance.</returns>
private User RestoreUserFromData(Dictionary<string, string> data)
{
var user = new User();
user.UserId = data[user.GetPropertyName(p => p.UserId)];
user.Email = data[user.GetPropertyName(p => p.Email)];
user.Username = data[user.GetPropertyName(p => p.Username)];
user.CreatedDate = Convert.ToDateTime(data[user.GetPropertyName(p => p.CreatedDate)]);
user.UpdatedDate = Convert.ToDateTime(data[user.GetPropertyName(p => p.UpdatedDate)]);
return user;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment