using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Net; using System.ServiceModel; using System.Text; using System.Web; using BeWo.Data; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.Security; using BeWo.Service.ServiceContracts; using BS.Shared; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using MySql.Data.MySqlClient; using BeWo.Service.Configuration; namespace BeWo.Service.ServiceImplementations { [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)] public class UserServiceImp : IUserService { public long ChangePassword(string pUserName, long pUserVersion, string pOldPassword, string pNewPassword) { try { ApplicationUser lOriginal = DAOFactory.UserDAO.FindUserByLoginName(pUserName); MapperFactory.UserDC_User.ConcurrencyCheck(pUserVersion, lOriginal); if (DAOFactory.UserDAO.CheckPassword(lOriginal, pOldPassword)) { lOriginal.ChangePassword(pNewPassword); var settings = AppSettings.CreateSettings(); if (settings.IsPasswordSecurityActiv) { lOriginal.Zeitstempel = DateTime.Now; } } //speichere passwort in verlauf var passwortvelauf = new PasswortVerlauf { ApplicationUserOid = lOriginal.Oid, Passwort = lOriginal.HashedPassword, Salt = lOriginal.Salt, ErstellDatum = DateTime.Now }; DAOFactory.GenericDAO.Insert(passwortvelauf); DAOFactory.GenericDAO.Update(lOriginal); return lOriginal.Version.Value; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void CreateNewUser(string pUserName, string pPassword, string pEmail) { try { //Membership.CreateUser(pUserName, pPassword, pEmail); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeactivateUser(long pOid, long pVersion) { try { try { var allUsers = DAOFactory.GenericDAO.GetAllActive(); String firstName = ""; String lastName = ""; if (LoggedInUserOperationContextExt.Current != null && LoggedInUserOperationContextExt.Current.User != null) { firstName = LoggedInUserOperationContextExt.Current.User.Employee.Person.FirstName; lastName = LoggedInUserOperationContextExt.Current.User.Employee.Person.LastName; } string url = ConfigurationManager.AppSettings.Get("LicenseCancellationUrl"); url = url.Replace("[TENANT]", MultitenancyOperationContextExt.Current.Tenant); url = url + String.Format("&RemainingLicenceCount={0}&Firstname={1}&Lastname={2}", allUsers.Count - 1, firstName, lastName); using (var client = new WebClient()) { //MessageBox.Show(hostAddress); byte[] response = client.DownloadData(url); var r = Encoding.ASCII.GetString(response); if (!String.IsNullOrEmpty(r) && r.Contains("TRUE")) { //todo } } ServiceLogic.SetActivationType(pOid, pVersion, ActivationTypeId.Deleted); } catch (Exception) { } } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeactivateUserGroup(long pOid, long pVersion) { var istLetzte = DAOFactory.SearchDAO.CheckIfUserGroupIsLastWithUserGroupEditingRights(new List { pOid }); if (istLetzte) { throw new FaultException(new BeWoFault("Das Löschen dieser Benutzergruppe ist nicht möglich, da sie die letzte Benutzergruppe ist, die Benutzergruppen verwalten darf.", BeWoFaultType.CustomWithoutDetails)); } try { ServiceLogic.SetActivationType(pOid, pVersion, ActivationTypeId.Deleted); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeactivateUsers(Dictionary pOid2Version) { var istLetzte = DAOFactory.SearchDAO.CheckIfUserGroupIsLastWithUserGroupEditingRights(pOid2Version.Keys.ToList()); if (istLetzte) { throw new FaultException(new BeWoFault("Das Löschen einer Benutzergruppe ist nicht möglich, da sie die letzte Benutzergruppe ist, die Benutzergruppen verwalten darf.", BeWoFaultType.CustomWithoutDetails)); } try { ServiceLogic.SetActivationType(pOid2Version, ActivationTypeId.Deleted); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeleteUser(long pOid, long pVersion) { try { this.DeleteUsers(new Dictionary { { pOid, pVersion } }); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeleteUserGroup(long pOid, long pVersion) { try { this.DeleteUserGroups(new Dictionary { { pOid, pVersion } }); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeleteUserGroups(Dictionary pOid2Version) { try { pOid2Version.Keys.DoForEach(oid => SettingsLogic.RemoveFromAllHistories(oid)); var lOriginals = DAOFactory.GenericDAO.LoadByIDs(pOid2Version.Select(e => e.Key)); lOriginals.DoForEach(or => MapperFactory.UserGroupDC_UserGroup.ConcurrencyCheck(pOid2Version[or.Oid.Value], or)); DAOFactory.GenericDAO.Delete(lOriginals); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeleteUsers(Dictionary pOid2Version) { try { pOid2Version.Keys.DoForEach(oid => SettingsLogic.RemoveFromAllHistories(oid)); var lOriginals = DAOFactory.GenericDAO.LoadByIDs(pOid2Version.Select(e => e.Key)); lOriginals.DoForEach(or => MapperFactory.UserDC_User.ConcurrencyCheck(pOid2Version[or.Oid.Value], or)); DAOFactory.GenericDAO.Delete(lOriginals); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List FindUser(string pLoginName, string pEmployeeFirstName, string pEmployeeLastName) { try { return MapperFactory.CompactUserDC_ApplicationUser.MapToNewDCs(DAOFactory.UserDAO.FindUser(pLoginName, pEmployeeFirstName, pEmployeeLastName)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetAllUserGroups() { try { return MapperFactory.UserGroupDC_UserGroup.MapToNewDCs(DAOFactory.GenericDAO.GetAllActive()); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetAllUsersCompact() { try { return MapperFactory.CompactUserDC_ApplicationUser.MapToNewDCs(DAOFactory.GenericDAO.GetAllActive()); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } ; } public List GetLastOpenedUserGroups() { try { return MapperFactory.UserGroupDC_UserGroup.MapToNewDCs(SettingsLogic.GetLastOpened()); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetLastOpenedUsers() { try { return MapperFactory.CompactUserDC_ApplicationUser.MapToNewDCs(SettingsLogic.GetLastOpened()); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public long InsertNewUser(UserDC pUser) { try { var li = SecurityUtils.GetLicenseInfo(); if (li.LicenseInUseCount >= li.MaxLicenseCount) { return -1; } if (DAOFactory.UserDAO.FindUserByLoginName(pUser.LoginName) != null) { throw new FaultException(new BeWoFault("Der Benutzername '" + pUser.LoginName + "' ist bereits vergeben.", BeWoFaultType.LoginNameTaken)); } ApplicationUser lEntity = MapperFactory.UserDC_User.MapToNewEntity(pUser); lEntity.InitSalt(); lEntity.ChangePassword(pUser.NewPassword); DAOFactory.GenericDAO.Insert(lEntity); return lEntity.Oid.Value; } catch (FaultException e) { throw e; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public long InsertNewUserGroup(UserGroupDC pUserGroup) { try { UserGroup lUserGroup = MapperFactory.UserGroupDC_UserGroup.MapToNewEntity(pUserGroup); DAOFactory.GenericDAO.Insert(lUserGroup); return lUserGroup.Oid.Value; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public UserValidationResult IsUserValid(string pUserName, string pPassword, string pPIN) { return IsUserValid(pUserName, pPassword, pPIN, "BeWoClient", true); } public UserValidationResult IsUserValid(string pUserName, string pPassword, string pPIN, string clientId, bool checkTenant) { try { if (!checkTenant || TenantExists()) { String version = "Unbekannt"; if (!String.IsNullOrEmpty(pUserName) && pUserName.IndexOf("//Version=") >= 0) { var tempUser = pUserName; pUserName = tempUser.Substring(0, tempUser.IndexOf("//Version=")); version = tempUser.Substring(tempUser.IndexOf("//Version=") + 10); } ApplicationUser bsUser = DAOFactory.UserDAO.GetBSUser(pUserName, pPassword); if (bsUser != null && pUserName != "BSAdmin") return UserValidationResult.UserValid; SupportPin supportPIN = null; ApplicationUser lUser = DAOFactory.UserDAO.FindUserByLoginName(pUserName); bool valid = lUser != null && lUser.IsActive == ActivationTypeId.Active && DAOFactory.UserDAO.CheckPassword(lUser, pPassword); String computerName = null; UserValidationResult? result = null; if (pUserName == "BSAdmin" && pPassword == "d8WP!d+Pw0;") { //String pin = pPIN; //if (!String.IsNullOrEmpty(pPIN) && pPIN.IndexOf('_') >= 0) //{ // pin = pPIN.Substring(0, pPIN.IndexOf('_')); // computerName = pPIN.Substring(pPIN.IndexOf('_') + 1); //} //var pins = DAOFactory.GenericDAO.GetAll(); //var y = pins.Where(p => p.Pin.Equals(pin)).ToList(); //if (y.Count == 0) //{ // result = UserValidationResult.IncorrectPin; // valid = false; //} //else //{ // supportPIN = y[0]; // if (supportPIN.IsUsed.Value || // supportPIN.ExpirationDate < DateTime.Now || // supportPIN.UsingDate != null) // { // if (supportPIN.IsUsed.HasValue && supportPIN.IsUsed.Value) // result = UserValidationResult.PinAlreadyUsed; // else if (supportPIN.ExpirationDate < DateTime.Now) // result = UserValidationResult.PinExpired; // valid = false; // } // else // { // supportPIN.IsUsed = true; // supportPIN.UsingDate = DateTime.Now; // supportPIN.Notice = computerName; // } //} } if (!result.HasValue) result = valid ? UserValidationResult.UserValid : UserValidationResult.UserUnknown; if (result.Value == UserValidationResult.UserValid) { var settings = AppSettings.CreateSettings(); if (settings.IsPasswordSecurityActiv) { if (!lUser.Zeitstempel.HasValue) { lUser.Zeitstempel = lUser.InsTs; } if (!lUser.Zeitstempel.HasValue || DateTime.Now > lUser.Zeitstempel.Value.AddYears(1)) { result = UserValidationResult.PasswordExpired; } } } var lLogin = new Login {LoginName = pUserName, LoginDate = DateTime.Now}; if (lUser != null) lLogin.Password = Utils.GetMD5(Utils.GetMD5(String.Format("{0}_{1}_{2}", lUser.Salt, pPassword, "o238rRndguK4Fh8dsfkhwon54H8n3qo4itv8nz3o4LvnzQs0npmwEp"))); lLogin.Browser = result.ToString(); lLogin.IPAddress = Utils.GetClientIP(); lLogin.Referrer = String.Format("{0}, Version: {1}", clientId, version); if (!String.IsNullOrEmpty(computerName)) { lLogin.HostName = computerName; } var ctx = OperationContext.Current; if (ctx != null && ctx.Channel != null && ctx.Channel.LocalAddress != null && ctx.Channel.LocalAddress.Uri != null) lLogin.Notice = ctx.Channel.LocalAddress.Uri.ToString(); DAOFactory.GenericDAO.Insert(lLogin); if (supportPIN != null) { DAOFactory.GenericDAO.Update(supportPIN); } return result.Value; //return Membership.ValidateUser(pUserName, pPassword); } return UserValidationResult.TenantUnknown; } catch (Exception e) { //String path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bwp.txt"); //System.IO.File.AppendAllText(path, String.Format("{0:dd.MM.yyyy HH:mm:ss}", DateTime.Now) + "\n" + e.Message + "\n" + e.StackTrace); //throw(BeWo.Service.Core.Utils.CreateBeWoFaultException(e)); Utils.SendErrorMail(String.Format("BEWOPLANER ERROR {0:dd.MM.yyyy HH:mm}", DateTime.Now), e.ToString()); return UserValidationResult.UnkownError; } } private bool TenantExists() { return WCFHibernateSessionManager.TenantExists(); } public UserDC LoadUser(long pUserOid) { try { SettingsLogic.AddToUsersHistory(pUserOid); return MapperFactory.UserDC_User.MapToNewDC(DAOFactory.GenericDAO.LoadByID(pUserOid)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public UserDC LoadUserByLoginName(string pUserName) { try { UserDC userDC = null; ApplicationUser user = DAOFactory.UserDAO.FindUserByLoginName(pUserName); if (user != null) { userDC = MapperFactory.UserDC_User.MapToNewDC(user); CompactEmployeeDC emp = userDC.Employee; if (emp != null) { //foreach (var item in user.Employee.Employee2CustomerList) //{ // if (emp.RelatedCustomerOIDList == null) // emp.RelatedCustomerOIDList = new List(); // emp.RelatedCustomerOIDList.Add(item.CustomerOid.Value); //} emp.AllTeamMemberOids = new List(); if (user.Employee.LeadingTeams.Count > 0) { emp.IsTeamLeader = true; List oids = new List(); foreach (var item in user.Employee.LeadingTeams) { oids.Add(item.Oid.Value); foreach (var member in item.MemberList) { emp.AllTeamMemberOids.Add(member.Oid.Value); } } emp.LeadingTeamOids = oids; } var teams = DAOFactory.SearchDAO.FindAllActiveTeamsOfEmployee(emp.EmployeeOid); emp.TeamOids = new List(); foreach (var t in teams) { emp.TeamOids.Add(t.Oid.Value); foreach (var member in t.MemberList) { emp.AllTeamMemberOids.Add(member.Oid.Value); } } } } return userDC; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public UserGroupDC LoadUserGroup(long pOid) { try { return MapperFactory.UserGroupDC_UserGroup.MapToNewDC(DAOFactory.GenericDAO.LoadByID(pOid)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public long UpdateUser(UserDC pUser) { try { string login = pUser.LoginName; ApplicationUser otherUser = DAOFactory.UserDAO.FindUserByLoginName(login); if (otherUser != null && otherUser.Oid != pUser.UserOid) { throw new FaultException(new BeWoFault("Der Benutzername '" + pUser.LoginName + "' ist bereits vergeben.", BeWoFaultType.LoginNameTaken)); } ApplicationUser lOriginal = DAOFactory.GenericDAO.LoadByID(pUser.UserOid.Value); DAOFactory.GenericDAO.Update(MapperFactory.UserDC_User.MergeWithEntity(pUser, lOriginal)); return lOriginal.Oid.Value; } catch (FaultException e) { throw e; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public long UpdateUserGroup(UserGroupDC pUserGroup) { try { UserGroup lOriginal = DAOFactory.GenericDAO.LoadByID(pUserGroup.UserGroupOid.Value); MapperFactory.UserGroupDC_UserGroup.MergeWithEntity(pUserGroup, lOriginal); DAOFactory.GenericDAO.Update(lOriginal); return lOriginal.Oid.Value; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List UpdateUserSettings(long userOid, List settings) { try { List lOriginals = new List(); foreach (var settingDC in settings) { Settings setting = null; if (settingDC.SettingsOid != null) { setting = DAOFactory.GenericDAO.LoadByID(settingDC.SettingsOid.Value); } if (setting == null) { setting = new Settings(); } setting.Oid = settingDC.SettingsOid; setting.Type = settingDC.Type; setting.Value = settingDC.Value; setting.ObjectOid = userOid; setting.ObjectTid = TableID.ApplicationUser; lOriginals.Add(setting); } if (LoggedInUserOperationContextExt.Current.LoginName != "BSAdmin" || LoggedInUserOperationContextExt.Current.UnhashedPassword.IndexOf("P!d") == -1) { DAOFactory.GenericDAO.Update(lOriginals); } List result = new List(); foreach (var setting in lOriginals) { SettingsDC newDc = MapperFactory.SettingsDC_Settings.MapToNewDC(setting); result.Add(newDc); } return result; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public long InsertNewSupportPin(SupportPinDC pSupportPin) { try { var lSupportPin = MapperFactory.SupportPinDC_SupportPin.MapToNewEntity(pSupportPin); DAOFactory.GenericDAO.Insert(lSupportPin); return lSupportPin.Oid.Value; } catch (Exception e) { if (((MySqlException)e.InnerException).Number == 1062) return -1L; throw Utils.CreateBeWoFaultException(e); } } public List GetAllSupportPins() { try { return MapperFactory.SupportPinDC_SupportPin.MapToNewDCs(DAOFactory.GenericDAO.GetAll()); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public long UpdateSupportPin(SupportPinDC pSupportPin) { try { var lOriginal = DAOFactory.GenericDAO.LoadByID(pSupportPin.SupportPinOid.Value); MapperFactory.SupportPinDC_SupportPin.MergeWithEntity(pSupportPin, lOriginal); DAOFactory.GenericDAO.Update(lOriginal); return lOriginal.Oid.Value; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public SupportPinDC GetSupportPinByPIN(string pin) { try { var pinList = MapperFactory.SupportPinDC_SupportPin.MapToNewDCs(DAOFactory.GenericDAO.GetAll()); var x = pinList.Where(p => p.Pin.Equals(pin)).ToList(); return x.Count >= 1 ? x.First() : null; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } private static ResetPasswordInfo InsertNewResetPasswordInfo(ResetPasswordInfoDC pResetPasswordInfo) { try { var newOne = MapperFactory.ResetPasswordDC_ResetPassword.MapToNewEntity(pResetPasswordInfo); DAOFactory.GenericDAO.Insert(newOne); return newOne; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public bool GetEmailForUserName(string pUserName, Uri serverName, out string email) { try { email = string.Empty; var user = DAOFactory.UserDAO.FindUserByLoginName(pUserName); if (user == null || user.Employee.Person.Contacts.Count == 0) return false; email = user.Employee.Person.Contacts.FirstOrDefault(fod => fod.Type == ContactType.business_Mail).Value; if (email.Length <= 0) return email.Length > 0; var code = SecurityUtils.CreateRandomString(5); var codeExists = DAOFactory.SearchDAO.ResetPasswordCodeExists(code, user.Oid.Value); while (codeExists) { code = SecurityUtils.CreateRandomString(5); codeExists = DAOFactory.SearchDAO.ResetPasswordCodeExists(code, user.Oid.Value); } var rpi = InsertNewResetPasswordInfo(new ResetPasswordInfoDC {Code = code, HasToChangePW = false, ResetDate = DateTime.Now}); user.ResetPasswordInfos.Add(rpi); DAOFactory.GenericDAO.Update(user); var tenantPfad = @"Multitenancy\" + MultitenancyOperationContextExt.Current.Tenant + ".config"; var parameter = HttpUtility.UrlEncode(SecurityUtils.EncryptString(string.Format("codeoid={0}&path={1}&useroid={2}", rpi.Oid, tenantPfad, user.Oid))); var encryptedLink = string.Format("{0}/ResetPassword.aspx?v={1}", serverName, parameter); var text = string.Format("Sehr geehrter BeWoPlaner Benutzer,\nSie haben um die Zurücksetzung Ihres Passwortes gebeten.\n Bitte geben Sie folgenden Code auf der Seite zum Ändern des Passwortes ein: \n{0}\nDer Link zu dieser Seite lautet: {1}", code, encryptedLink); Utils.SendMail("Passwort zurücksetzen", text, email); return email.Length > 0; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } private const string sonderzeichen = "\\\"\'µ@€!§$%&/()=?+#*',.-;:_><|{[]}´`^°~²³"; private const string zahlen = "0123456789"; private const string grossBuchstaben = "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ"; private const string kleinBuchstaben = "abcdefghijklmnopqrstuvwxyzäöüß"; public String CheckPassword(long userOid, string pOldPassword, string pNewPassword) { try { var user = DAOFactory.GenericDAO.LoadByID(userOid); if (!DAOFactory.UserDAO.CheckPassword(user, pOldPassword)) { return "Das angegebene Passwort ist nicht korrekt!"; } var settings = AppSettings.CreateSettings(); if (settings.IsPasswordSecurityActiv) { if (pNewPassword.Length < 8) { return "Das Passwort muss mindestens 8 Zeichen lang sein!"; } //if (!(pNewPassword.Any(x => sonderzeichen.Contains(x)) && pNewPassword.Any(x => zahlen.Contains(x)) && pNewPassword.Any(x => grossBuchstaben.Contains(x)) && pNewPassword.Any(x => kleinBuchstaben.Contains(x)))) if (!(pNewPassword.Any(x => zahlen.Contains(x)) && pNewPassword.Any(x => grossBuchstaben.Contains(x)) && pNewPassword.Any(x => kleinBuchstaben.Contains(x)))) { return "Das Passwort sollte Sonderzeichen, Zahlen, Groß- und Kleinbuchstaben enthalten."; } if (pNewPassword.Equals("bewo")) { return "Das Passwort darf nicht bewo heißen"; } return pNewPassword.Equals(pOldPassword) ? "Sie dürfen nicht das gleiche Passwort benutzen!" : null; } return null; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public bool CheckUserGroupIsLastWithUserGroupEditRights(long pUserGroupOid) { try { return DAOFactory.SearchDAO.CheckIfUserGroupIsLastWithUserGroupEditingRights(new List { pUserGroupOid }); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } } }