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(); } } }