using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Security.Authentication;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.Builders;
using Tango.BL.DTO;
using Tango.BL.Entities;
using Tango.FSE.BL.CacheEntities;
using Tango.FSE.Web.Messages;
namespace Tango.FSE.BL.Services
{
///
/// Represents a users service used for retrieving/updating users.
///
///
public class UsersService : FSEServiceBase
{
private const string FULL_USERS_COLLECTION = "Users_Full";
///
/// Gets a user by the specified email along with all its organization, roles and permissions.
/// Once a user is retrieved, it will be cached on disk.
///
/// The email.
///
public Task GetUserFull(String email)
{
return DataResolver.Builder.New()
.ConfigureCascade(DataResolverNode.Web, DataResolverNode.Online, DataResolverNode.DiskCache)
.Web((context) =>
{
var response = WebClient.GetUser(new GetUserRequest() { Email = email }).GetAwaiter().GetResult();
var user = response.User.ToObservable();
LogManager.Log($"User '{email}' successfully retrieved. Caching user on disk...");
try
{
using (var cache = DiskCache.CreateContext())
{
var cachedUser = CachedUser.FromObservable(user);
cache.Database.GetCollection(FULL_USERS_COLLECTION).Upsert(cachedUser);
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error caching user on disk.");
}
return user;
})
.Online((context) =>
{
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
var user = new UserBuilder(db).Set(x => !x.Deleted && x.Email.ToLower() == email.ToLower())
.WithOrganization()
.WithRolesAndPermissions()
.Build();
LogManager.Log($"User '{email}' successfully retrieved. Caching user on disk...");
try
{
using (var cache = DiskCache.CreateContext())
{
var cachedUser = CachedUser.FromObservable(user);
cache.Database.GetCollection(FULL_USERS_COLLECTION).Upsert(cachedUser);
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error caching user on disk.");
}
return user;
}
})
.DiskCache((context) =>
{
using (var cache = DiskCache.CreateContext())
{
var cachedUser = cache.Database.GetCollection(FULL_USERS_COLLECTION).FindOne(x => x.Email.ToLower() == email.ToLower());
if (cachedUser != null)
{
return cachedUser.ToObservable();
}
throw new AuthenticationException("User not found online or in disk cache.");
}
}).BuildExecuteAsync();
}
}
}