using Bootstrap.Security; using Longbow.Security.Cryptography; using MongoDB.Driver; using System; using System.Collections.Generic; using System.Linq; namespace Bootstrap.DataAccess.MongoDB { /// /// /// public class User : DataAccess.User { /// /// /// public IEnumerable Roles { get; set; } /// /// /// public IEnumerable Groups { get; set; } /// /// /// /// /// public override BootstrapUser RetrieveUserByUserName(string userName) { var project = Builders.Projection.Include(u => u.Id) .Include(u => u.UserName) .Include(u => u.DisplayName) .Include(u => u.Icon) .Include(u => u.Css) .Include(u => u.App); var ret = DbManager.Users.Find(user => user.UserName.ToLowerInvariant() == userName.ToLowerInvariant()).Project(project).FirstOrDefault(); if (ret != null) { if (string.IsNullOrEmpty(ret.Icon)) ret.Icon = "default.jpg"; if (string.IsNullOrEmpty(ret.App)) ret.App = "0"; } return ret; } /// /// /// /// /// /// public override bool Authenticate(string userName, string password) { if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(password)) return false; var u = DbManager.Users.Find(user => user.UserName.ToLowerInvariant() == userName.ToLowerInvariant()).FirstOrDefault(); return u != null && !string.IsNullOrEmpty(u.PassSalt) && u.Password == LgbCryptography.ComputeHash(password, u.PassSalt); } public override bool SaveApp(string userName, string app) { var update = Builders.Update.Set(u => u.App, app); DbManager.Users.FindOneAndUpdate(u => u.UserName.ToLowerInvariant() == UserName.ToLowerInvariant(), update); return true; } /// /// /// /// public override IEnumerable RetrieveNewUsers() => DbManager.Users.Find(user => !user.ApprovedTime.HasValue).SortByDescending(user => user.RegisterTime).ToList(); /// /// /// /// public override IEnumerable Retrieves() { var project = Builders.Projection.Include(u => u.Id) .Include(u => u.UserName) .Include(u => u.DisplayName) .Include(u => u.RegisterTime) .Include(u => u.ApprovedTime) .Include(u => u.ApprovedBy) .Include(u => u.Description) .Include(u => u.Groups) .Include(u => u.Roles) .Include(u => u.IsReset); return DbManager.Users.Find(user => user.ApprovedTime != DateTime.MinValue).Project(project).ToList(); } /// /// /// /// /// public override bool Save(DataAccess.User user) { // 已经存在或者已经在新用户中了 if (UserHelper.RetrieveUserByUserName(user.UserName) != null || UserHelper.RetrieveNewUsers().Any(u => u.UserName == user.UserName)) return false; DbManager.Users.InsertOne(new User() { UserName = user.UserName, DisplayName = user.DisplayName, PassSalt = LgbCryptography.GenerateSalt(), Password = LgbCryptography.ComputeHash(user.Password, user.PassSalt), RegisterTime = DateTime.Now, ApprovedTime = user.ApprovedTime, ApprovedBy = user.ApprovedBy, Roles = new List(), Groups = new List(), Icon = user.Icon, Description = user.Description, IsReset = 0 }); return true; } /// /// /// /// /// /// /// public override bool Update(string id, string password, string displayName) { var passSalt = LgbCryptography.GenerateSalt(); var newPassword = LgbCryptography.ComputeHash(password, passSalt); var update = Builders.Update.Set(u => u.Password, newPassword).Set(u => u.PassSalt, passSalt).Set(u => u.DisplayName, displayName); DbManager.Users.FindOneAndUpdate(u => u.Id == id, update); return true; } /// /// /// /// /// /// /// public override bool ChangePassword(string userName, string password, string newPass) { bool ret = false; if (Authenticate(userName, password)) { var passSalt = LgbCryptography.GenerateSalt(); var newPassword = LgbCryptography.ComputeHash(password, passSalt); var update = Builders.Update.Set(u => u.Password, newPassword).Set(u => u.PassSalt, passSalt); DbManager.Users.FindOneAndUpdate(u => u.UserName == UserName, update); ret = true; } return ret; } /// /// /// /// /// public override bool Delete(IEnumerable value) { var list = new List>(); foreach (var id in value) { list.Add(new DeleteOneModel(Builders.Filter.Eq(u => u.Id, id))); } DbManager.Users.BulkWrite(list); return true; } /// /// /// /// /// public override IEnumerable RetrievesByRoleId(string roleId) { var users = UserHelper.Retrieves().Cast().ToList(); users.ForEach(p => p.Checked = (p.Roles != null && p.Roles.Contains(roleId)) ? "checked" : ""); return users; } /// /// /// /// /// /// public override bool SaveByRoleId(string roleId, IEnumerable userIds) { var users = DbManager.Users.Find(md => md.Roles != null && md.Roles.Contains(roleId)).ToList(); // Remove roles users.ForEach(p => { var roles = p.Roles == null ? new List() : p.Roles.ToList(); roles.Remove(roleId); DbManager.Users.UpdateOne(md => md.Id == p.Id, Builders.Update.Set(md => md.Roles, roles)); }); users = DbManager.Users.Find(md => userIds.Contains(md.Id)).ToList(); // Add roles users.ForEach(p => { var roles = p.Roles == null ? new List() : p.Roles.ToList(); roles.Add(roleId); DbManager.Users.UpdateOne(md => md.Id == p.Id, Builders.Update.Set(md => md.Roles, roles)); }); return true; } /// /// /// /// /// public override IEnumerable RetrievesByGroupId(string groupId) { var users = UserHelper.Retrieves().Cast().ToList(); users.ForEach(p => p.Checked = (p.Groups != null && p.Groups.Contains(groupId)) ? "checked" : ""); return users; } /// /// /// /// /// /// public override bool SaveByGroupId(string groupId, IEnumerable userIds) { var users = DbManager.Users.Find(md => md.Groups != null && md.Groups.Contains(groupId)).ToList(); // Remove roles users.ForEach(p => { var groups = p.Groups == null ? new List() : p.Groups.ToList(); groups.Remove(groupId); DbManager.Users.UpdateOne(md => md.Id == p.Id, Builders.Update.Set(md => md.Groups, groups)); }); users = DbManager.Users.Find(md => userIds.Contains(md.Id)).ToList(); // Add roles users.ForEach(p => { var groups = p.Groups == null ? new List() : p.Groups.ToList(); groups.Add(groupId); DbManager.Users.UpdateOne(md => md.Id == p.Id, Builders.Update.Set(md => md.Groups, groups)); }); return true; } /// /// /// /// /// public override bool ForgotPassword(DataAccess.ResetUser user) { DbManager.Users.UpdateOne(md => md.UserName.ToLowerInvariant() == user.UserName.ToLowerInvariant(), Builders.Update.Set(md => md.IsReset, 1)); user.ResetTime = DateTime.Now; DbManager.ResetUsers.InsertOne(user); return true; } /// /// /// /// /// /// public override bool ResetPassword(string userName, string password) { var ret = false; var resetUser = UserHelper.RetrieveResetUserByUserName(userName); if (resetUser == null) return ret; var passSalt = LgbCryptography.GenerateSalt(); var newPassword = LgbCryptography.ComputeHash(password, passSalt); DbManager.Users.UpdateOne(User => User.UserName.ToLowerInvariant() == userName.ToLowerInvariant(), Builders.Update.Set(md => md.Password, newPassword).Set(md => md.PassSalt, passSalt).Set(md => md.IsReset, 0)); DbManager.ResetUsers.DeleteMany(user => user.UserName.ToLowerInvariant() == userName.ToLowerInvariant()); return true; } /// /// /// /// /// /// public override bool Approve(string id, string approvedBy) { DbManager.Users.UpdateOne(User => User.Id == id, Builders.Update.Set(md => md.ApprovedTime, DateTime.Now).Set(md => md.ApprovedBy, approvedBy)); return true; } /// /// /// /// /// /// public override bool SaveDisplayName(string userName, string displayName) { DbManager.Users.UpdateOne(User => User.UserName == userName, Builders.Update.Set(md => md.DisplayName, displayName)); return true; } /// /// /// /// /// /// public override bool SaveUserCssByName(string userName, string cssName) { DbManager.Users.UpdateOne(User => User.UserName == userName, Builders.Update.Set(md => md.Css, cssName)); return true; } /// /// /// /// /// /// public override bool SaveUserIconByName(string userName, string iconName) { DbManager.Users.UpdateOne(User => User.UserName == userName, Builders.Update.Set(md => md.Icon, iconName)); return true; } /// /// /// /// /// /// public override bool Reject(string id, string rejectBy) { var user = UserHelper.RetrieveNewUsers().FirstOrDefault(u => u.Id == id); DbManager.RejectUsers.InsertOne(new RejectUser() { DisplayName = user.DisplayName, RegisterTime = user.RegisterTime, RejectedBy = rejectBy, RejectedReason = "", RejectedTime = DateTime.Now, UserName = user.UserName }); DbManager.Users.DeleteOne(User => User.Id == id); return true; } } }