using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL; using Tango.BL.Builders; using Tango.BL.DTO; using Tango.BL.Entities; using Tango.BL.Enumerations; using Tango.FSE.Web.Messages; using Z.EntityFramework.Extensions; using Z.EntityFramework.Plus; namespace Tango.FSE.BL.Services { public class OrganizationsService : FSEServiceBase { private static Random rnd = new Random(); public Task> GetCurrentUserOrganizations() { return DataResolver>.Builder.New() .ConfigureCascade(DataResolverNode.Online) .Online((context) => { using (ObservablesContext db = ObservablesContext.CreateDefault()) { bool allowAll = CurrentUser.HasPermission(Tango.BL.Enumerations.Permissions.FSE_ManageAllOrganizationsUsersAndRoles); return db.Organizations.Where(x => allowAll || x.Guid == CurrentUser.OrganizationGuid).ToList(); } }) .BuildExecuteAsync(); } public Task> GetOrganizationUsers(String organizationGuid, bool withDeleted = false) { return DataResolver>.Builder.New() .ConfigureCascade(DataResolverNode.Online) .Online((context) => { using (ObservablesContext db = ObservablesContext.CreateDefault()) { return db.Users .Where(x => x.OrganizationGuid == organizationGuid && (!x.Deleted || withDeleted)) .Include(x => x.Contact) .Include(x => x.UsersRoles) .Include(x => x.UsersRoles.Select(y => y.Role)) .ToList(); } }) .BuildExecuteAsync(); } public Task GetUserDetails(String userGuid) { return DataResolver.Builder.New() .ConfigureCascade(DataResolverNode.Online) .Online((context) => { using (ObservablesContext db = ObservablesContext.CreateDefault()) { return new UserBuilder(db).Set(userGuid).WithDeleted().WithRolesAndPermissions().WithOrganization().Build(); } }) .BuildExecuteAsync(); } public Task> GetAllRoles() { return DataResolver>.Builder.New() .ConfigureCascade(DataResolverNode.Online) .Online((context) => { using (ObservablesContext db = ObservablesContext.CreateDefault()) { return db.Roles .Where(x => x.Code >= 1000 && x.Code < 3000) //Only FSE & Twine RSM .Include(x => x.RolesPermissions) .Include(x => x.RolesPermissions.Select(y => y.Permission)) .ToList(); } }) .BuildExecuteAsync(); } public Task UpdateUser(User user, bool resetPassword = false, String temporaryResetPassword = null) { return Task.Factory.StartNew(() => { Authentication.ThrowIfNoPermission(Permissions.FSE_ManageOrganizationUsersAndRoles); ConnectivityProvider.ThrowIfNoInternet(); UserDTO userBeforeDTO = null; using (var db = ObservablesContext.CreateDefault()) { var currentUser = GetUserDetails(user.Guid).Result; userBeforeDTO = UserDTO.FromObservable(currentUser); var rolesToAdd = user.FSERoles.ToList().Where(x => !currentUser.FSERoles.Exists(y => y.Guid == x.Guid)).ToList(); var rolesToRemove = currentUser.FSERoles.ToList().Where(x => !user.FSERoles.ToList().Exists(y => y.Guid == x.Guid)).ToList(); foreach (var role in rolesToAdd) { db.UsersRoles.Add(new UsersRole() { UserGuid = user.Guid, RoleGuid = role.Guid, }); } foreach (var role in rolesToRemove) { var userRole = currentUser.UsersRoles.SingleOrDefault(x => x.RoleGuid == role.Guid); if (userRole != null) { db.UsersRoles.Attach(userRole, EntityState.Deleted); } } if (resetPassword) { user.Password = User.GetPasswordHash(temporaryResetPassword); user.PasswordChangeRequired = true; } db.SaveChanges(); } using (ObservablesContext db2 = ObservablesContext.CreateDefault()) { user.LastUpdated = DateTime.UtcNow; var oldList = user.UsersRoles; user.UsersRoles = new Core.SynchronizedObservableCollection(); db2.Users.Attach(user, EntityState.Modified); db2.Contacts.Attach(user.Contact, EntityState.Modified); db2.Addresses.Attach(user.Address, EntityState.Modified); db2.SaveChanges(); user.UsersRoles = oldList; } var updatedUser = GetUserDetails(user.Guid).Result; var userAfterDTO = UserDTO.FromObservable(updatedUser); if (!userBeforeDTO.Deleted && userAfterDTO.Deleted) { ActionLogManager.InsertLog(ActionLogType.UserDeleted, CurrentUser, user.Email, user, "User suspended using Tango FSE."); } else if (userBeforeDTO.Deleted && !userAfterDTO.Deleted) { ActionLogManager.InsertLog(ActionLogType.UserRestored, CurrentUser, user.Email, user, "User activated using Tango FSE."); } ActionLogManager.InsertLog(ActionLogType.UserSaved, CurrentUser, user.Email, userBeforeDTO, userAfterDTO, "User saved using Tango FSE."); return updatedUser; }); } public Task InsertUser(User user) { return Task.Factory.StartNew(() => { Authentication.ThrowIfNoPermission(Permissions.FSE_ManageOrganizationUsersAndRoles); ConnectivityProvider.ThrowIfNoInternet(); using (ObservablesContext db = ObservablesContext.CreateDefault()) { var usersRolesToAdd = user.UsersRoles.ToList(); user.UsersRoles.Clear(); foreach (var userRole in usersRolesToAdd) { db.UsersRoles.Add(new UsersRole() { UserGuid = userRole.UserGuid, RoleGuid = userRole.RoleGuid }); } user.Email = user.Email.Trim(); user.Contact.FullName = user.Contact.FirstName + " " + user.Contact.LastName; user.Contact.Email = user.Email; user.Password = User.GetPasswordHash(user.Password); user.PasswordChangeRequired = true; db.Users.Add(user); db.SaveChanges(); ActionLogManager.InsertLog(ActionLogType.UserCreated, CurrentUser, user.Email, user, "User created using Tango FSE."); } var u = GetUserDetails(user.Guid).Result; return u; }); } public Task SuspendUser(User user) { return Task.Factory.StartNew(() => { Authentication.ThrowIfNoPermission(Permissions.FSE_ManageOrganizationUsersAndRoles); ConnectivityProvider.ThrowIfNoInternet(); using (ObservablesContext db = ObservablesContext.CreateDefault()) { try { user.LastUpdated = DateTime.UtcNow; user.Deleted = true; db.Users.Attach(user, EntityState.Modified); db.UsersRoles.DetachRange(user.UsersRoles.ToList()); db.SaveChanges(); ActionLogManager.InsertLog(ActionLogType.UserDeleted, CurrentUser, user.Email, user, "User suspended using Tango FSE."); return GetUserDetails(user.Guid).Result; } catch (Exception ex) { user.Deleted = false; throw ex; } } }); } public Task SendNewUserInvitationEmail(String userGuid, String password) { return Task.Factory.StartNew(() => { Authentication.ThrowIfNoPermission(Permissions.FSE_ManageOrganizationUsersAndRoles); ConnectivityProvider.ThrowIfNoInternet(); var response = WebClient.SendUserInvitationEmail(new UserInvitationEmailRequest() { UserGuid = userGuid, Password = password, MachineServiceAddress = Authentication.CurrentEnvironment.MachineServiceAddress, Build = BuildProvider.Build }).Result; }); } public String GenerateRandomPassword() { String pass = String.Empty; for (int i = 0; i < 4; i++) { pass += rnd.Next(0, 9).ToString(); } return pass; } public async Task CheckEmailAvailable(String email) { using (ObservablesContext db = ObservablesContext.CreateDefault()) { return !await db.Users.AnyAsync(x => x.Email.ToLower() == email.ToLower()); } } } }