From 980257a2d0ad4c41e96e2abe68267a6be11e3c71 Mon Sep 17 00:00:00 2001 From: TLRZ Seyfferth Date: Wed, 8 Apr 2020 18:40:10 +0200 Subject: [PATCH] [TASK] update to latest dll --- ActiveDirectoryExtensions.cs | 163 +++++++++++++++++++++++------ Chrosey.Extensions.csproj | 7 +- CollectionExtensions.cs | 37 ++++--- Helper/PasswordGenerator.cs | 107 +++++++++++++++++++ Helper/SemiNumericComparer.cs | 19 ++++ Interfaces/ISearchResultWrapper.cs | 9 ++ RandomSecureVersion.cs | 27 +++++ StringExtensions.cs | 52 ++++++++- Wrapper/ASearchResultWrapper.cs | 18 ++++ 9 files changed, 394 insertions(+), 45 deletions(-) create mode 100644 Helper/PasswordGenerator.cs create mode 100644 Helper/SemiNumericComparer.cs create mode 100644 Interfaces/ISearchResultWrapper.cs create mode 100644 RandomSecureVersion.cs create mode 100644 Wrapper/ASearchResultWrapper.cs diff --git a/ActiveDirectoryExtensions.cs b/ActiveDirectoryExtensions.cs index ac3c460..54d3238 100644 --- a/ActiveDirectoryExtensions.cs +++ b/ActiveDirectoryExtensions.cs @@ -1,4 +1,6 @@ -using System; +using Chrosey.Extensions.Interfaces; +using Chrosey.Extensions.Wrapper; +using System; using System.Collections.Generic; using System.DirectoryServices; using System.Linq; @@ -11,62 +13,161 @@ namespace Chrosey.Extensions { public static T Get(this DirectoryEntry entry, string propertyName) where T : class { - if (string.IsNullOrWhiteSpace(propertyName)) throw new ArgumentNullException("propertyName darf nicht leer sein"); - if (!entry.Properties.PropertyNames.Cast().Contains(propertyName)) return null; - - return entry.Properties[propertyName].Value as T; + try + { + if (string.IsNullOrEmpty(propertyName)) + throw new ArgumentNullException("Der PropertyName[" + propertyName + "] kann nicht null oder leer sein"); + if (entry == null) + throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); + return !entry.Properties.Contains(propertyName) ? default(T) : entry.Properties[propertyName].Value as T; + } + catch (Exception ex) + { + throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", (object)entry.Name, (object)propertyName), ex); + } } public static string GetValue(this DirectoryEntry entry, string propertyName) { try { - if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException("Der PropertyName[" + propertyName + "] kann nicht null oder leer sein"); - if (null == entry) throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); - if (!entry.Properties.Contains(propertyName)) return string.Empty; - - return entry.Properties[propertyName].Value.ToString(); - + if (string.IsNullOrEmpty(propertyName)) + throw new ArgumentNullException("Der PropertyName[" + propertyName + "] kann nicht null oder leer sein"); + if (entry == null) + throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); + return !entry.Properties.Contains(propertyName) ? string.Empty : entry.Properties[propertyName].Value.ToString(); } - catch (Exception e) + catch (Exception ex) { - throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}",entry.Name,propertyName), e); + throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", (object)entry.Name, (object)propertyName), ex); } } + public static byte[] Photo(this DirectoryEntry entry) { try { - if (null == entry) throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); - if (!entry.Properties.Contains("thumbnailPhoto")) return null; - - return entry.Properties["thumbnailPhoto"].Value as byte[]; - + if (entry == null) + throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); + return !entry.Properties.Contains("thumbnailPhoto") ? (byte[])null : entry.Properties["thumbnailPhoto"].Value as byte[]; } - catch (Exception e) + catch (Exception ex) { - throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", entry.Name, "thumbnailPhoto"), e); + throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", (object)entry.Name, (object)"thumbnailPhoto"), ex); } } public static string GetValue(this SearchResult sr, string propertyName) { - if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException("Der PropertyName[" + propertyName + "] kann nicht null oder leer sein"); - if (null == sr) throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); - try { - var s = sr.Properties[propertyName.ToLower()]; - if (s.Count > 0) - { - return s[0].ToString(); - } - return string.Empty; + if (string.IsNullOrEmpty(propertyName)) + throw new ArgumentNullException("Der PropertyName[" + propertyName + "] kann nicht null oder leer sein"); + if (sr == null) + throw new NullReferenceException("Kann keine Eigenschaft von null abrufen"); + ResultPropertyValueCollection property = sr.Properties[propertyName.ToLower()]; + return property.Count > 0 ? property[0].ToString() : string.Empty; } - catch (Exception e) + catch (Exception ex) { - throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", sr.Path, propertyName), e); + throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", (object)sr.Path, (object)propertyName), ex); } } + + public static IEnumerable GetList( + this SearchResult source, + string propertyName) + where T : class + { + try + { + if (string.IsNullOrEmpty(propertyName)) + throw new ArgumentNullException("Der PropertyName[" + propertyName + "] kann nicht null oder leer sein"); + if (source == null) + throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); + if (!source.Properties.Contains(propertyName)) + return (IEnumerable)null; + ResultPropertyValueCollection property = source.Properties[propertyName.ToLower()]; + return property.Count > 0 ? (IEnumerable)property.Cast().ToList() : (IEnumerable)null; + } + catch (Exception ex) + { + throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", (object)source.Path, (object)propertyName), ex); + } + } + + public static IEnumerable GetList( + this DirectoryEntry source, + string propertyName) + where T : class + { + try + { + if (string.IsNullOrEmpty(propertyName)) + throw new ArgumentNullException("Der PropertyName[" + propertyName + "] kann nicht null oder leer sein"); + if (source == null) + throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); + if (!source.Properties.Contains(propertyName)) + return (IEnumerable)null; + PropertyValueCollection property = source.Properties[propertyName]; + return property.Count > 0 ? (IEnumerable)property.Cast().ToList() : (IEnumerable)null; + } + catch (Exception ex) + { + throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", (object)source.Path, (object)propertyName), ex); + } + } + + public static T Get(this SearchResult source, string propertyName) where T : class + { + try + { + if (string.IsNullOrEmpty(propertyName)) + throw new ArgumentNullException("Der PropertyName[" + propertyName + "] kann nicht null oder leer sein"); + if (source == null) + throw new ArgumentNullException("Kann keine Eigenschaft von null abrufen"); + if (!source.Properties.Contains(propertyName)) + return default(T); + ResultPropertyValueCollection property = source.Properties[propertyName.ToLower()]; + return property.Count > 0 ? property[0] as T : default(T); + } + catch (Exception ex) + { + throw new FieldAccessException(string.Format("Fehler beim Lesen von {0}.{1}", (object)source.Path, (object)propertyName), ex); + } + } + + public static T Make(this SearchResult source) where T : ISearchResultWrapper + { + T instance = Activator.CreateInstance(); + instance.Bind(source); + return instance; + } + + public static IEnumerable Make(this SearchResultCollection source) where T : ISearchResultWrapper + { + List objList = new List(); + foreach (SearchResult source1 in source) + objList.Add(source1.Make()); + return (IEnumerable)objList; + } + + public static T FindAs(this DirectorySearcher searcher, IEnumerable filter) where T : ASearchResultWrapper + { + string str = "(&(" + string.Join(")(", filter) + "))"; + IEnumerable source = searcher.PropertiesToLoad.Cast(); + string filter1 = searcher.Filter; + T instance = Activator.CreateInstance(); + searcher.PropertiesToLoad.Clear(); + searcher.PropertiesToLoad.AddRange(instance.propertiesToLoad); + searcher.Filter = str; + SearchResult one = searcher.FindOne(); + if (one == null) + throw new NotFoundException("Element wurde nicht gefunden"); + searcher.Filter = filter1; + searcher.PropertiesToLoad.Clear(); + searcher.PropertiesToLoad.AddRange(source.ToArray()); + return one.Make(); + } } } diff --git a/Chrosey.Extensions.csproj b/Chrosey.Extensions.csproj index d952b49..053f6c7 100644 --- a/Chrosey.Extensions.csproj +++ b/Chrosey.Extensions.csproj @@ -1,5 +1,5 @@  - + Debug @@ -48,14 +48,19 @@ + + + + + diff --git a/CollectionExtensions.cs b/CollectionExtensions.cs index 12a953a..229187b 100644 --- a/CollectionExtensions.cs +++ b/CollectionExtensions.cs @@ -1,4 +1,5 @@ -using System; +using Chrosey.Extensions.Helper; +using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; @@ -9,17 +10,13 @@ namespace Chrosey.Extensions { public static class CollectionExtensions { + private static readonly Lazy RandomSecure = new Lazy((Func)(() => new RandomSecureVersion())); public static T Get(this Dictionary dict, string key) where T : class { - T value; - if (!dict.TryGetValue(key,out value)) - { - return null; - } - return value; + T obj; + return !dict.TryGetValue(key, out obj) ? default(T) : obj; } - public static IEnumerable Filter(this IEnumerable collection, NameValueCollection query) where T : class { var props = typeof(T).GetProperties().Select(p => p.Name.ToLower()); @@ -75,15 +72,15 @@ namespace Chrosey.Extensions } catch (NotFoundException) { - + } - + } return collection; } public static IOrderedEnumerable Sort(this IEnumerable collection, NameValueCollection query, string defaultSortProperty = "") where T : class { - + if (string.IsNullOrEmpty(query["sort"])) { if (!string.IsNullOrEmpty(defaultSortProperty) && collection.First().HasProperty(defaultSortProperty)) @@ -122,7 +119,7 @@ namespace Chrosey.Extensions public static IEnumerable> GroupBy(this IEnumerable collection, NameValueCollection query) where T : class { var props = typeof(T).GetProperties().Select(p => p.Name.ToLower()); - var groupBy = string.IsNullOrEmpty(query["groupby"])? "" : query["groupby"].ToLower(); + var groupBy = string.IsNullOrEmpty(query["groupby"]) ? "" : query["groupby"].ToLower(); var entferneAb = string.IsNullOrEmpty(query["groupbynletters"]) ? 0 : int.Parse(query["groupbynletters"]); if (string.IsNullOrEmpty(groupBy) || !props.Contains(groupBy)) @@ -139,5 +136,21 @@ namespace Chrosey.Extensions { return collection.Filter(query).Sort(query, defaultSortProperty).GroupBy(query); } + + public static string ToQueryString(this IEnumerable> me) + { + return string.Join("&", me.Select, string>((Func, string>)(x => x.Key + "=" + x.Value))); + } + + public static IEnumerable ShuffleSecure(this IEnumerable source) + { + T[] sourceArray = source.ToArray(); + for (int counter = 0; counter < sourceArray.Length; ++counter) + { + int randomIndex = CollectionExtensions.RandomSecure.Value.Next(counter, sourceArray.Length); + yield return sourceArray[randomIndex]; + sourceArray[randomIndex] = sourceArray[counter]; + } + } } } diff --git a/Helper/PasswordGenerator.cs b/Helper/PasswordGenerator.cs new file mode 100644 index 0000000..5886e77 --- /dev/null +++ b/Helper/PasswordGenerator.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Chrosey.Extensions.Helper +{ + public class PasswordGenerator + { + private readonly RandomSecureVersion _randomSecure = new RandomSecureVersion(); + private readonly string _allAvailableChars; + private int _minimumNumberOfChars; + + public int MinimumLengthPassword { get; private set; } + + public int MaximumLengthPassword { get; private set; } + + public int MinimumLowerCaseChars { get; private set; } + + public int MinimumUpperCaseChars { get; private set; } + + public int MinimumNumericChars { get; private set; } + + public int MinimumSpecialChars { get; private set; } + + public static string AllLowerCaseChars { get; private set; } + + public static string AllUpperCaseChars { get; private set; } + + public static string AllNumericChars { get; private set; } + + public static string AllSpecialChars { get; private set; } + + static PasswordGenerator() + { + PasswordGenerator.AllLowerCaseChars = PasswordGenerator.GetCharRange('a', 'z', ""); + PasswordGenerator.AllUpperCaseChars = PasswordGenerator.GetCharRange('A', 'Z', ""); + PasswordGenerator.AllNumericChars = PasswordGenerator.GetCharRange('0', '9', ""); + PasswordGenerator.AllSpecialChars = "#?!@$%^&*-"; + } + + public PasswordGenerator( + int minimumLengthPassword = 8, + int maximumLengthPassword = 15, + int minimumLowerCaseChars = 2, + int minimumUpperCaseChars = 1, + int minimumNumericChars = 3, + int minimumSpecialChars = 1) + { + if (minimumLengthPassword < 1) + throw new ArgumentException("The minimumlength is smaller than 1.", nameof(minimumLengthPassword)); + if (minimumLengthPassword > maximumLengthPassword) + throw new ArgumentException("The minimumLength is bigger than the maximum length.", nameof(minimumLengthPassword)); + if (minimumLowerCaseChars < 0) + throw new ArgumentException("The minimumLowerCase is smaller than 0.", nameof(minimumLowerCaseChars)); + if (minimumUpperCaseChars < 0) + throw new ArgumentException("The minimumUpperCase is smaller than 0.", nameof(minimumUpperCaseChars)); + if (minimumNumericChars < 0) + throw new ArgumentException("The minimumNumeric is smaller than 0.", nameof(minimumNumericChars)); + if (minimumSpecialChars < 0) + throw new ArgumentException("The minimumSpecial is smaller than 0.", nameof(minimumSpecialChars)); + this._minimumNumberOfChars = minimumLowerCaseChars + minimumUpperCaseChars + minimumNumericChars + minimumSpecialChars; + if (minimumLengthPassword < this._minimumNumberOfChars) + throw new ArgumentException("The minimum length ot the password is smaller than the sum of the minimum characters of all catagories.", nameof(maximumLengthPassword)); + this.MinimumLengthPassword = minimumLengthPassword; + this.MaximumLengthPassword = maximumLengthPassword; + this.MinimumLowerCaseChars = minimumLowerCaseChars; + this.MinimumUpperCaseChars = minimumUpperCaseChars; + this.MinimumNumericChars = minimumNumericChars; + this.MinimumSpecialChars = minimumSpecialChars; + this._allAvailableChars = this.OnlyIfOneCharIsRequired(minimumLowerCaseChars, PasswordGenerator.AllLowerCaseChars) + this.OnlyIfOneCharIsRequired(minimumUpperCaseChars, PasswordGenerator.AllUpperCaseChars) + this.OnlyIfOneCharIsRequired(minimumNumericChars, PasswordGenerator.AllNumericChars) + this.OnlyIfOneCharIsRequired(minimumSpecialChars, PasswordGenerator.AllSpecialChars); + } + + private string OnlyIfOneCharIsRequired(int minimum, string allChars) + { + return minimum > 0 || this._minimumNumberOfChars == 0 ? allChars : string.Empty; + } + + public string Generate() + { + int num = this._randomSecure.Next(this.MinimumLengthPassword, this.MaximumLengthPassword); + string str = this.GetRandomString(PasswordGenerator.AllLowerCaseChars, this.MinimumLowerCaseChars) + this.GetRandomString(PasswordGenerator.AllUpperCaseChars, this.MinimumUpperCaseChars) + this.GetRandomString(PasswordGenerator.AllNumericChars, this.MinimumNumericChars) + this.GetRandomString(PasswordGenerator.AllSpecialChars, this.MinimumSpecialChars); + string randomString = this.GetRandomString(this._allAvailableChars, num - str.Length); + return (str + randomString).ShuffleTextSecure(); + } + + private string GetRandomString(string possibleChars, int lenght) + { + string empty = string.Empty; + for (int index1 = 0; index1 < lenght; ++index1) + { + int index2 = this._randomSecure.Next(possibleChars.Length); + empty += possibleChars[index2].ToString(); + } + return empty; + } + + private static string GetCharRange(char minimum, char maximum, string exclusiveChars = "") + { + string first = string.Empty; + for (char ch = minimum; (int)ch <= (int)maximum; ++ch) + first += ch.ToString(); + if (!string.IsNullOrEmpty(exclusiveChars)) + first = new string(first.Except((IEnumerable)exclusiveChars).ToArray()); + return first; + } + } +} \ No newline at end of file diff --git a/Helper/SemiNumericComparer.cs b/Helper/SemiNumericComparer.cs new file mode 100644 index 0000000..cbb27e5 --- /dev/null +++ b/Helper/SemiNumericComparer.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace Chrosey.Extensions.Helper +{ + public class SemiNumericComparer : IComparer + { + public int Compare(string x, string y) + { + if (x.IsDate() && y.IsDate()) + return DateTime.Parse(x).CompareTo(DateTime.Parse(y)); + if (x.IsNumeric() && y.IsNumeric()) + return x.CompareTo(y); + if (x.IsNumeric()) + return 1; + return y.IsNumeric() ? -1 : string.Compare(x, y, true); + } + } +} \ No newline at end of file diff --git a/Interfaces/ISearchResultWrapper.cs b/Interfaces/ISearchResultWrapper.cs new file mode 100644 index 0000000..d0d2fdc --- /dev/null +++ b/Interfaces/ISearchResultWrapper.cs @@ -0,0 +1,9 @@ +using System.DirectoryServices; + +namespace Chrosey.Extensions.Interfaces +{ + public interface ISearchResultWrapper + { + void Bind(SearchResult source); + } +} \ No newline at end of file diff --git a/RandomSecureVersion.cs b/RandomSecureVersion.cs new file mode 100644 index 0000000..a3b11e6 --- /dev/null +++ b/RandomSecureVersion.cs @@ -0,0 +1,27 @@ +using System; +using System.Security.Cryptography; + +namespace Chrosey.Extensions +{ + internal class RandomSecureVersion + { + private readonly RNGCryptoServiceProvider _rngProvider = new RNGCryptoServiceProvider(); + + public int Next() + { + byte[] data = new byte[4]; + this._rngProvider.GetBytes(data); + return BitConverter.ToInt32(data, 0); + } + + public int Next(int maximumValue) + { + return this.Next(0, maximumValue); + } + + public int Next(int minimumValue, int maximumValue) + { + return new Random(this.Next()).Next(minimumValue, maximumValue); + } + } +} \ No newline at end of file diff --git a/StringExtensions.cs b/StringExtensions.cs index a955236..94aa178 100644 --- a/StringExtensions.cs +++ b/StringExtensions.cs @@ -139,7 +139,7 @@ namespace Chrosey.Extensions /// der Wert der Eigenschaft /// Das Format in dem die Rückgabe erfolgen soll /// Normales Format "(propertyName=value) - public static string PropertyValueFormat(this string propertyName, object value, string format="({0}={1})") + public static string PropertyValueFormat(this string propertyName, object value, string format = "({0}={1})") { return string.Format(format, propertyName, value.ToString()); } @@ -157,5 +157,55 @@ namespace Chrosey.Extensions { return string.Format(format, args); } + public static string ReplaceUmlaute(this string input) + { + return input.ToLower().Replace("ä", "ae").Replace("ü", "ue").Replace("ö", "oe").Replace("ß", "ss").Replace("é", "e"); + } + + public static string PlaceUmlaute(this string input) + { + return input.Replace("ae", "ä").Replace("oe", "ö").Replace("ue", "ü").Replace("ss", "ß").Replace("aü", "aue").Replace("chäl", "chael").Replace("ßl", "ssl"); + } + + public static string ShuffleTextSecure(this string source) + { + return new string(source.ShuffleSecure().ToArray()); + } + + public static bool IsNumeric(this string value) + { + return int.TryParse(value, out int _); + } + + public static bool IsDate(this string value) + { + return DateTime.TryParse(value, out DateTime _); + } + + public static int LevenshteinDistance(this string a, string b) + { + int length1 = a.Length; + int length2 = b.Length; + if (length1 == 0) + return length2; + if (length2 == 0) + return length1; + int[,] numArray = new int[length1 + 1, length2 + 1]; + int index1 = 0; + while (index1 <= length1) + numArray[index1, 0] = index1++; + int index2 = 0; + while (index2 <= length2) + numArray[0, index2] = index2++; + for (int index3 = 1; index3 <= length1; ++index3) + { + for (int index4 = 1; index4 <= length2; ++index4) + { + int num = (int)b[index4 - 1] == (int)a[index3 - 1] ? 0 : 1; + numArray[index3, index4] = Math.Min(Math.Min(numArray[index3 - 1, index4] + 1, numArray[index3, index4 - 1] + 1), numArray[index3 - 1, index4 - 1] + num); + } + } + return numArray[length1, length2]; + } } } diff --git a/Wrapper/ASearchResultWrapper.cs b/Wrapper/ASearchResultWrapper.cs new file mode 100644 index 0000000..4fc2279 --- /dev/null +++ b/Wrapper/ASearchResultWrapper.cs @@ -0,0 +1,18 @@ +using Chrosey.Extensions.Interfaces; +using System.DirectoryServices; + +namespace Chrosey.Extensions.Wrapper +{ + public abstract class ASearchResultWrapper : ISearchResultWrapper + { + public readonly string[] propertiesToLoad = new string[2] + { + "SAMAccountName", + "sn" + }; + + public virtual void Bind(SearchResult source) + { + } + } +} \ No newline at end of file