diff --git a/BeWo/PasswortSecurity/PasswortSicherheit.cs b/BeWo/PasswortSecurity/PasswortSicherheit.cs index 4237566de..861660551 100644 --- a/BeWo/PasswortSecurity/PasswortSicherheit.cs +++ b/BeWo/PasswortSecurity/PasswortSicherheit.cs @@ -47,107 +47,107 @@ namespace BeWo.PasswortSecurity */ #region Passwort Stärke Ermitteln und Anzeigen - public static Label ShowPasswordStrengthLabel(string passwordToValidate, Label passwordStrengthLabel) - { - var passwordStrength = CalculatePasswordStrength(passwordToValidate); + //public static Label ShowPasswordStrengthLabel(string passwordToValidate, Label passwordStrengthLabel) + //{ + // var passwordStrength = CalculatePasswordStrength(passwordToValidate); - var visibility = Visibility.Visible; - var content = "Passwortstärke: "; - var foreground = new SolidColorBrush(Colors.Black); + // var visibility = Visibility.Visible; + // var content = "Passwortstärke: "; + // var foreground = new SolidColorBrush(Colors.Black); - switch(passwordStrength) - { - case 0: - content += "sehr schwach"; - foreground = new SolidColorBrush(Colors.Red); - break; - case 1: - content += "schwach"; - foreground = new SolidColorBrush(Colors.OrangeRed); - break; - case 2: - content += "mittel"; - foreground = new SolidColorBrush(Colors.Yellow); - break; - case 3: - content += "stark"; - foreground = new SolidColorBrush(Colors.Green); - break; - case 4: - content += "sehr stark"; - foreground = new SolidColorBrush(Colors.Green); - break; - default: - visibility = Visibility.Hidden; - content = string.Empty; - break; - } + // switch(passwordStrength) + // { + // case 0: + // content += "sehr schwach"; + // foreground = new SolidColorBrush(Colors.Red); + // break; + // case 1: + // content += "schwach"; + // foreground = new SolidColorBrush(Colors.OrangeRed); + // break; + // case 2: + // content += "mittel"; + // foreground = new SolidColorBrush(Colors.Yellow); + // break; + // case 3: + // content += "stark"; + // foreground = new SolidColorBrush(Colors.Green); + // break; + // case 4: + // content += "sehr stark"; + // foreground = new SolidColorBrush(Colors.Green); + // break; + // default: + // visibility = Visibility.Hidden; + // content = string.Empty; + // break; + // } - passwordStrengthLabel.Visibility = visibility; - passwordStrengthLabel.Foreground = foreground; - passwordStrengthLabel.Content = content; + // passwordStrengthLabel.Visibility = visibility; + // passwordStrengthLabel.Foreground = foreground; + // passwordStrengthLabel.Content = content; - return passwordStrengthLabel; - } + // return passwordStrengthLabel; + //} - private static int CalculatePasswordStrength(string passwordToValidate) - { - var length = passwordToValidate?.Length ?? 0; - if(string.IsNullOrEmpty(passwordToValidate) || length < 6) - { - return -1; - } + //private static int CalculatePasswordStrength(string passwordToValidate) + //{ + // var length = passwordToValidate?.Length ?? 0; + // if(string.IsNullOrEmpty(passwordToValidate) || length < 6) + // { + // return -1; + // } - var score = 0; + // var score = 0; - if(length < 9) - { - score += 1; - } - else if(length < 12) - { - score += 2; - } - else if(length < 18) - { - score += 3; - } - else - { - score += 4; - } + // if(length < 9) + // { + // score += 1; + // } + // else if(length < 12) + // { + // score += 2; + // } + // else if(length < 18) + // { + // score += 3; + // } + // else + // { + // score += 4; + // } - var numberCount = passwordToValidate.Count(c => Numbers.Contains(c)); - var lowercaseLetterCount = passwordToValidate.Count(c => LowercaseLetters.Contains(c)); - var uppercaseLetterCount = passwordToValidate.Count(c => UppercaseLetters.Contains(c)); - var lowercaseUmlautsCount = passwordToValidate.Count(c => LowercaseUmlauts.Contains(c)); - var uppercaseUmlautsCount = passwordToValidate.Count(c => UppercaseUmlauts.Contains(c)); - var specialCharacterCount = passwordToValidate.Count(c => SpecialCharacters.Contains(c)); + // var numberCount = passwordToValidate.Count(c => Numbers.Contains(c)); + // var lowercaseLetterCount = passwordToValidate.Count(c => LowercaseLetters.Contains(c)); + // var uppercaseLetterCount = passwordToValidate.Count(c => UppercaseLetters.Contains(c)); + // var lowercaseUmlautsCount = passwordToValidate.Count(c => LowercaseUmlauts.Contains(c)); + // var uppercaseUmlautsCount = passwordToValidate.Count(c => UppercaseUmlauts.Contains(c)); + // var specialCharacterCount = passwordToValidate.Count(c => SpecialCharacters.Contains(c)); - score += numberCount * 3; - score += lowercaseLetterCount * 2; - score += uppercaseLetterCount * 3; - score += lowercaseUmlautsCount * 2; - score += uppercaseUmlautsCount * 2; - score += specialCharacterCount * 4; + // score += numberCount * 3; + // score += lowercaseLetterCount * 2; + // score += uppercaseLetterCount * 3; + // score += lowercaseUmlautsCount * 2; + // score += uppercaseUmlautsCount * 2; + // score += specialCharacterCount * 4; - if(score < 16) - { - return 0; - } + // if(score < 16) + // { + // return 0; + // } - if(score < 56) - { - return 1; - } + // if(score < 56) + // { + // return 1; + // } - if(score < 116) - { - return 2; - } + // if(score < 116) + // { + // return 2; + // } - return score < 156 ? 3 : 4; - } + // return score < 156 ? 3 : 4; + //} // Score, PreivousValue, Schalter, und LetzteWerte werden im Objekt gepeichert. public Label ErmittleUndZeigePasswortStaerke(string passwordToValidate, Label passwordLabel) diff --git a/BeWoPlanerMobil/BeWoPlanerMobil.csproj b/BeWoPlanerMobil/BeWoPlanerMobil.csproj index f200008f4..ee4e2dc55 100644 --- a/BeWoPlanerMobil/BeWoPlanerMobil.csproj +++ b/BeWoPlanerMobil/BeWoPlanerMobil.csproj @@ -296,6 +296,7 @@ + diff --git a/BeWoPlanerMobil/BeWoPlanerMobil.csproj.user b/BeWoPlanerMobil/BeWoPlanerMobil.csproj.user index 19e97f07a..359c270c6 100644 --- a/BeWoPlanerMobil/BeWoPlanerMobil.csproj.user +++ b/BeWoPlanerMobil/BeWoPlanerMobil.csproj.user @@ -8,7 +8,7 @@ - Release|Any CPU + Debug|Any CPU ShowAllFiles 600 MvcControllerEmptyScaffolder diff --git a/BeWoPlanerMobil/Controllers/MainController.cs b/BeWoPlanerMobil/Controllers/MainController.cs index e0dcf7409..d3c2f6ce6 100644 --- a/BeWoPlanerMobil/Controllers/MainController.cs +++ b/BeWoPlanerMobil/Controllers/MainController.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Web.Mvc; using System.Windows.Forms; +using BeWo.Data.Entities; using BeWo.Service.Plugins; using BeWo.Service.ServiceImplementations; using BeWo.View.Navigation.Filter; @@ -26,6 +27,8 @@ using DevExpress.XtraScheduler.Compatibility; using Newtonsoft.Json; using static BS.Shared.ServiceRecordValidationResult; using FormCollection = System.Web.Mvc.FormCollection; +using GoalRating = BeWoPlanerMobil.Util.GoalRating; +using Image = System.Drawing.Image; using ServiceRecordDC = BS.Shared.DataContracts.ServiceRecordDC; namespace BeWoPlanerMobil.Controllers @@ -101,6 +104,28 @@ namespace BeWoPlanerMobil.Controllers var mokSessionTimeout = UserSettingsUtils.GetSettingValueAsInteger(Model.Mandator.Settings, SettingsKeys.MoKSessionTimeout, 20); Session.Timeout = mokSessionTimeout; + + Model.IsPasswordSecurityEnabled = UserSettingsUtils.GetSettingValueAsBool(Model.Mandator.Settings, SettingsKeys.IsPasswordSecurityActiv); + + if(Model.IsPasswordSecurityEnabled) + { + var tempDataValue = string.Empty; + + switch(MobileSessionFacade.PasswordStrength) + { + case 0: + tempDataValue = "Sie benutzen ein sehr schwaches Passwort.

Bitte ändern Sie Ihr Passwort, indem Sie im Menü auf 'Password ändern' klicken."; + break; + case 1: + tempDataValue = "Sie benutzen ein schwaches Passwort.

Bitte ändern Sie Ihr Passwort, indem Sie im Menü auf 'Password ändern' klicken."; + break; + } + + if(!string.IsNullOrEmpty(tempDataValue)) + { + TempData["show_pw_change_popup"] = tempDataValue; + } + } } var mandatorSettings = Model.Mandator.Settings; @@ -3807,14 +3832,23 @@ namespace BeWoPlanerMobil.Controllers return RedirectToActionPermanent("Main"); } + var passwordUtils = new PasswordUtils(); + if(passwordUtils.EvaluatePasswordStrength(newPassword) < 2) + { + var checkResult = UserService.CheckPassword(MobileSessionFacade.LoggedInUser.Oid.Value, oldPassword, newPassword); + + if(!(checkResult is null)) + { + TempData["passwd-change-error"] = checkResult; + return RedirectToActionPermanent("Main"); + } + } + var userName = MobileSessionFacade.LoggedInUserDC.LoginName; var userVersion = MobileSessionFacade.LoggedInUserDC.UserVersion.Value; - // ToDo: Testen! falsches oldPassword, kein oldPassword, newPassword stimmt nicht mit confirmationPassword überein, kein confirmationPassword, kein newPassword UserService.ChangePassword(userName, userVersion, oldPassword, newPassword); - // ToDo: Regeln beachten, welche Passwortstärke mindestens erreicht werden muss. - return RedirectToActionPermanent("Main"); } } diff --git a/BeWoPlanerMobil/Models/MainModel.cs b/BeWoPlanerMobil/Models/MainModel.cs index dd8d812ce..163746097 100644 --- a/BeWoPlanerMobil/Models/MainModel.cs +++ b/BeWoPlanerMobil/Models/MainModel.cs @@ -671,7 +671,6 @@ namespace BeWoPlanerMobil.Models public bool IsOnlyYearMonthVisible { get; set; } - #region Mehrfachbuchung private bool _IsInMultiBookingMode; @@ -725,9 +724,11 @@ namespace BeWoPlanerMobil.Models } } + #endregion + public MandatorDC Mandator { get; set; } - #endregion + public bool IsPasswordSecurityEnabled { get; set; } } public class CustomSelectListItem diff --git a/BeWoPlanerMobil/Scripts/mobileUtils.js b/BeWoPlanerMobil/Scripts/mobileUtils.js index a9dc47602..4f8ab7cea 100644 --- a/BeWoPlanerMobil/Scripts/mobileUtils.js +++ b/BeWoPlanerMobil/Scripts/mobileUtils.js @@ -82,22 +82,22 @@ function submitForm(submitButton) { submitButton.form.submit(); } -function showMessagePopupWithHtml(title, html) { - $("#popupTitle").text(title); +//function showMessagePopupWithHtml(title, html) { +// $("#popupTitle").text(title); - if(html !== null) { - $("#modal-body").html("

"); - } +// if(html !== null) { +// $("#modal-body").html("

"); +// } - $("#popupMessage").html(html); +// $("#popupMessage").html(html); - $("#messagePopup").modal( - { - backdrop: "static", - keyboard: false - } - ); -} +// $("#messagePopup").modal( +// { +// backdrop: "static", +// keyboard: false +// } +// ); +//} function hasEmptyRequiredFields(form) { var count = 0; diff --git a/BeWoPlanerMobil/Service/ASPHibernateSessionManager.cs b/BeWoPlanerMobil/Service/ASPHibernateSessionManager.cs index b4bfc9491..0f758cf75 100644 --- a/BeWoPlanerMobil/Service/ASPHibernateSessionManager.cs +++ b/BeWoPlanerMobil/Service/ASPHibernateSessionManager.cs @@ -10,7 +10,7 @@ using System.Web; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Service.ServiceImplementations; - +using BeWoPlanerMobil.Util; using BS.Shared; using BS.Shared.Core; using log4net; @@ -184,6 +184,7 @@ namespace BeWoPlanerMobil.Service return false; } + MobileSessionFacade.PasswordStrength = new PasswordUtils().EvaluatePasswordStrength(password); MobileSessionFacade.LoggedInUser = user; } diff --git a/BeWoPlanerMobil/Service/MobileSessionFacade.cs b/BeWoPlanerMobil/Service/MobileSessionFacade.cs index 7fafcc657..f424316cf 100644 --- a/BeWoPlanerMobil/Service/MobileSessionFacade.cs +++ b/BeWoPlanerMobil/Service/MobileSessionFacade.cs @@ -84,5 +84,7 @@ namespace BeWoPlanerMobil.Service } public static string CookieName => "tenantKeks"; + + public static int PasswordStrength; } } \ No newline at end of file diff --git a/BeWoPlanerMobil/Util/PasswordUtils.cs b/BeWoPlanerMobil/Util/PasswordUtils.cs new file mode 100644 index 000000000..f38ff5b3f --- /dev/null +++ b/BeWoPlanerMobil/Util/PasswordUtils.cs @@ -0,0 +1,231 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using BeWo.Data.Access; +using BS.Shared.DataContracts; + +namespace BeWoPlanerMobil.Util +{ + internal class PasswordUtils + { + private const string Numbers = "0123456789"; + private const string LowercaseLetters = "abcdefghijklmnopqrstuvwxyz"; + private const string UppercaseLetters = "ABDEFGHIJKLMNOPQRSTUVWXYZ"; + private const string LowercaseUmlauts = "äöüß"; + private const string UppercaseUmlauts = "ÄÖÜ"; + private const string SpecialCharacters1 = "\\\"\'µ@€!"; + private const string SpecialCharacters2 = "&/()=?+#*"; + private const string SpecialCharacters3 = ",.-;:_><|"; + private const string SpecialCharacters4 = "§$%'{[]}´"; + private const string SpecialCharacters5 = "`^°~²³"; + + private string _PartialPassword = string.Empty; + private bool _IsPartial; + private int _PasswordLengthDifference; + + private int _Score; + private int _PreviousValue; + private bool _Schalter; + private List _PreviousValues = new List(); + + public int EvaluatePasswordStrength(string passwordToEvaluate) + { + var passwordStrength = 0; + _PreviousValue = 0; + + if(string.IsNullOrWhiteSpace(passwordToEvaluate)) + { + return 0; + } + + if(_IsPartial) + { + if(_PasswordLengthDifference == 1) + { + _Score -= _PreviousValues.Last(); + _PreviousValues.RemoveAt(_PreviousValues.Count - 1); + } + else + { + for(var i = 0; i < _PasswordLengthDifference; i++) + { + _Score += _PreviousValues.Last(); + _PreviousValues.RemoveAt(_PreviousValues.Count - 1); + } + } + + _IsPartial = false; + } + else + { + var passwordLength = passwordToEvaluate.Length; + + if(passwordLength > 5 && passwordLength < 9) + { + AddLengthScore(1); + } + + if(passwordLength > 8 && passwordLength < 12) + { + AddLengthScore(2); + } + + if(passwordLength > 11 && passwordLength < 18) + { + AddLengthScore(3); + } + + if(passwordLength > 17) + { + AddLengthScore(4); + } + + // Ziffern + if(passwordToEvaluate.Any(character => Numbers.Contains(character))) + { + AddTokenScore(3); + } + + // Großbuchstaben + if(passwordToEvaluate.Any(character => UppercaseLetters.Contains(character))) + { + AddTokenScore(3); + } + + // Großumlaute + if(passwordToEvaluate.Any(character => UppercaseUmlauts.Contains(character))) + { + AddTokenScore(2); + } + + // Kleinbuchstaben + if(passwordToEvaluate.Any(character => LowercaseLetters.Contains(character))) + { + AddTokenScore(2); + } + + // Kleinumlaute + if(passwordToEvaluate.Any(character => LowercaseUmlauts.Contains(character))) + { + AddTokenScore(2); + } + + // Sonderzeichen + if(passwordToEvaluate.Any(character => SpecialCharacters1.Contains(character))) + { + AddTokenScore(4); + } + + if(passwordToEvaluate.Any(character => SpecialCharacters2.Contains(character))) + { + AddTokenScore(4); + } + + if(passwordToEvaluate.Any(character => SpecialCharacters3.Contains(character))) + { + AddTokenScore(4); + } + + if(passwordToEvaluate.Any(character => SpecialCharacters4.Contains(character))) + { + AddTokenScore(4); + } + + if(passwordToEvaluate.Any(character => SpecialCharacters5.Contains(character))) + { + AddTokenScore(4); + } + + _PreviousValues.Add(_PreviousValue); + } + + if(_Score < 16) + { + passwordStrength = 0; + } + + if(_Score > 15 && _Score < 56) + { + passwordStrength = 1; + } + + if(_Score > 55 && _Score < 116) + { + passwordStrength = 2; + } + + if(_Score > 115 && _Score < 156) + { + passwordStrength = 3; + } + + if(_Score > 155) + { + passwordStrength = 4; + } + + return passwordStrength; + } + + private void AddLengthScore(int valueToAdd) + { + _Score += valueToAdd; + _PreviousValue = valueToAdd; + _Schalter = true; + } + + private void AddTokenScore(int valueToAdd) + { + _Score += valueToAdd; + + if(_Schalter) + { + _PreviousValue += valueToAdd; + } + else + { + _PreviousValue = valueToAdd; + } + } + + public string CheckPassword(string newPassword) + { + if(string.IsNullOrEmpty(newPassword)) + { + return "Das Passwort muss mindestens 8 Zeichen lang sein!"; + } + + var passwordLength = newPassword.Length; + + if(passwordLength < 8) + { + return "Das Passwort muss mindestens 8 Zeichen lang sein!"; + } + + var richtliniencount = 0; + + if(newPassword.Any(character => Numbers.Contains(character))) + { + richtliniencount++; + } + + if(newPassword.Any(character => LowercaseLetters.Contains(character) || LowercaseUmlauts.Contains(character))) + { + richtliniencount++; + } + + if(newPassword.Any(character => UppercaseLetters.Contains(character) || UppercaseUmlauts.Contains(character))) + { + richtliniencount++; + } + + if(newPassword.Any(character => SpecialCharacters1.Contains(character) || SpecialCharacters2.Contains(character) || SpecialCharacters3.Contains(character) || SpecialCharacters4.Contains(character) || SpecialCharacters5.Contains(character))) + { + richtliniencount++; + } + + return richtliniencount < 3 ? "Das Passwort muss mindestens drei Zeichen aus der Gruppe Sonderzeichen, Zahlen, Groß- und Kleinbuchstaben enthalten." : null; + } + } +} \ No newline at end of file diff --git a/BeWoPlanerMobil/Views/Main/Main.cshtml b/BeWoPlanerMobil/Views/Main/Main.cshtml index 06c2d7e20..b670f79f7 100644 --- a/BeWoPlanerMobil/Views/Main/Main.cshtml +++ b/BeWoPlanerMobil/Views/Main/Main.cshtml @@ -29,7 +29,34 @@ function submitChangePasswordForm() { try { showSpinner(); - $('#change-password-form').submit(); + var form = $('#change-password-form'); + + var isValid = true; + // ToDo: Hier weitermachen + //$.each($(".pw-chng-inv-fdb"), + $.each($(".pw-ch-in-container"), + function (index, item) { + var input = $(item).find("input"); + var feedback = $(item).find(".pw-chng-inv-fdb"); + + + logInfo3(input.val()); + if (isEmptyOrSpaces(input.val())) { + feedback.addClass("d-block"); + isValid = false; + } else { + feedback.removeClass("was-validated"); + feedback.removeClass("d-block"); + } + + feedback.addClass("was-validated"); + }); + + if (true === isValid) { + form.submit(); + } else { + hideSpinner(); + } } catch (error) { showErrorPopup(error); } @@ -245,6 +272,13 @@ initializeSignatureImagePopup(); + @if(TempData["show_pw_change_popup"] is string passwordWarning && !string.IsNullOrEmpty(passwordWarning)) + { + + showMessagePopupWithHtml("Achtung!", "@Html.Raw(passwordWarning)"); + + } + @if (Model != null && Model.IsInEditingMode) { @@ -826,31 +860,40 @@
-
+
Altes Passwort
+
+ Dieses Feld darf nicht leer sein. +
-
+
Neues Passwort
+
+ Dieses Feld darf nicht leer sein. +
-
+
Passwort bestätigen
+
+ Dieses Feld darf nicht leer sein. +
diff --git a/Host/Host.csproj.user b/Host/Host.csproj.user index 769cd8b25..a0002e9f5 100644 --- a/Host/Host.csproj.user +++ b/Host/Host.csproj.user @@ -3,7 +3,7 @@ BeWo2.0 true - Release|Any CPU + Debug|Any CPU false