BO4E-dotnet.Encryption/Anonymizer.cs
/// <summary>
///     Apply the configuration set in the constructor to the JObject set in the constructor.
/// </summary>
/// <see cref="Anonymizer(AnonymizerConfiguration)" />
/// <returns>A modified JObject with the configuration applied.</returns>
Apply the configuration set in the constructor to the JObject set in the constructor.
Apply the configuration set in the constructor to the JObject set in the constructor .
public T ApplyOperations<T>(BusinessObject bo)
        {
            if (bo == null) throw new ArgumentNullException(nameof(bo));
            var mapping = _configuration.Operations;
            var result = bo.DeepClone();
            foreach (var dataCategory in mapping.Keys)
            {
                var approach = mapping[dataCategory];
                var affectedProps = bo.GetType().GetProperties()
                    .Where(p => p.GetCustomAttributes(typeof(DataCategoryAttribute), false).Length > 0)
                    .OrderBy(ap => ap.GetCustomAttribute<JsonPropertyAttribute>()?.Order)
                    .ToArray();
                foreach (var affectedProp in affectedProps)
                {
                    if (!affectedProp.IsAnonymizerRelevant(approach, dataCategory)) continue;
                    switch (approach)
                    {
                        case AnonymizerApproach.HASH:
                            try
                            {
                                var affectedFieldValue = affectedProp.GetValue(result);
                                HashObject(ref affectedFieldValue, dataCategory);
                                affectedProp.SetValue(result, affectedFieldValue);
                            }
                            catch (RuntimeBinderException e)
                            {
                                _logger.LogWarning(
                                    $"Catched RuntimeBinderException in Object {bo.GetBoTyp()}. Probably due to trying to get the type of a null object BO: {e.Message}");
                            }
                            break;
                        case AnonymizerApproach.DELETE:
                            var isRequired = false;
                            Attribute defaultValueAttribute = null;
                            var jsonPropertyAttribute = affectedProp.GetCustomAttributes()
                                .FirstOrDefault(a => a is JsonPropertyAttribute);
                            if (jsonPropertyAttribute != null)
                            {
                                var jpa = (JsonPropertyAttribute)jsonPropertyAttribute;
                                if (jpa.Required == Required.Always)
                                {
                                    isRequired = true;
                                    defaultValueAttribute = affectedProp.GetCustomAttributes()
                                        .FirstOrDefault(a => a.GetType() == typeof(DefaultValueAttribute));
                                }
                            }
                            if (isRequired && defaultValueAttribute != null)
                            {
                                var dva = (DefaultValueAttribute)defaultValueAttribute;
                                affectedProp.SetValue(result, dva.Value);
                            }
                            else if (bo.GetType().IsSubclassOf(typeof(BusinessObject)))
                            {
                                var boSubObject = affectedProp.GetValue(bo);
                                if (boSubObject != null)
                                {
                                    try
                                    {
                                        if (boSubObject.GetType().IsGenericType &&
                                            boSubObject.GetType().GetGenericTypeDefinition() == typeof(List<>))
                                        {
                                            var listElementType = boSubObject.GetType().GetGenericArguments()[0];
                                            var listType = typeof(List<>).MakeGenericType(listElementType);
                                            var newEmptyList = Activator.CreateInstance(listType);
                                            boSubObject = newEmptyList;
                                        }
                                        else
                                        {
                                            boSubObject = null;
                                        }
                                    }
                                    catch (RuntimeBinderException e)
                                    {
                                        _logger.LogError($"Couldn't null BO field!: {e.Message}");
                                    }
                                    affectedProp.SetValue(result, boSubObject);
                                }
                            }
                            else
                            {
                                affectedProp.SetValue(result, null);
                            }
                            break;
                        case AnonymizerApproach.ENCRYPT:
                            if (PublicKeyX509 == null)
                                throw new ArgumentNullException(nameof(PublicKeyX509),
                                    "To use the encryption feature you have to provide a public X509 certificate using the SetPublicKey method.");
                            using (var xasyncenc = new X509AsymmetricEncrypter(PublicKeyX509))
                            {
                                if (affectedProp.GetValue(bo) is string)
                                {
                                    if (affectedProp.GetValue(bo) != null)
                                        affectedProp.SetValue(result,
                                            xasyncenc.Encrypt(affectedProp.GetValue(bo).ToString()));
                                }
                                else if (affectedProp.GetValue(bo).GetType().IsSubclassOf(typeof(COM.COM)))
                                {
                                    var comObject = affectedProp.GetValue(bo);
                                    dynamic comFields = comObject.GetType().GetProperties();
                                    foreach (var comField in comFields)
                                        try
                                        {
                                            comField.SetValue(comObject,
                                                xasyncenc.Encrypt(comField.GetValue(comObject)).ToString());
                                        }
                                        catch (ArgumentException e)
                                        {
                                            _logger.LogError($"Couldn't encrypt COM field!: {e.Message}");
                                        }
                                        catch (Exception f)
                                        {
                                            _logger.LogError($"Couldn't encrypt COM field!: {f.Message}");
                                        }
                                    affectedProp.SetValue(result, comObject);
                                }
                                else if (affectedProp.PropertyType.IsSubclassOf(typeof(BusinessObject)))
                                {
                                    affectedProp.SetValue(result,
                                        xasyncenc.Encrypt((BusinessObject)affectedProp.GetValue(bo)));
                                }
                                else if (affectedProp.PropertyType.ToString()
                                    .StartsWith(
                                        "BO4E.ENUM")) 
                                {
                                    _logger.LogWarning(
                                        $"Encrypting {affectedProp.PropertyType} is not supported, since the result would not be a valid ENUM value.");
                                }
                                else
                                {
                                    throw new NotImplementedException(
                                        $"Encrypting {affectedProp.PropertyType} is not implemented yet.");
                                }
                            }
                            break;
                        case AnonymizerApproach.DECRYPT:
                            if (_privateKey == null)
                                throw new ArgumentNullException(nameof(PrivateKeyFactory),
                                    "To use the decryption feature you have to provide a private key using the SetPrivateKey method.");
                            using (var xasydec = new X509AsymmetricEncrypter(_privateKey))
                            {
                                affectedProp.SetValue(result, xasydec.Decrypt(affectedProp.GetValue(bo).ToString()));
                            }
                            continue;
                        case AnonymizerApproach.KEEP:
                            continue;
                        default:
                            continue;
                    }
                }
            }
            if (typeof(T) == typeof(JObject)) return (T)(object)JObject.FromObject(result);
            return (T)(object)result;
        }
public T ApplyOperations < T > ( BusinessObject bo ) { if ( bo == null ) throw new ArgumentNullException ( nameof ( bo ) ) ; var mapping = _configuration . Operations ; var result = bo . DeepClone ( ) ; foreach ( var dataCategory in mapping . Keys ) { var approach = mapping [ dataCategory ] ; var affectedProps = bo . GetType ( ) . GetProperties ( ) . Where ( p => p . GetCustomAttributes ( typeof ( DataCategoryAttribute ) , false ) . Length > 0 ) . OrderBy ( ap => ap . GetCustomAttribute < JsonPropertyAttribute > ( ) ? . Order ) . ToArray ( ) ; foreach ( var affectedProp in affectedProps ) { if ( ! affectedProp . IsAnonymizerRelevant ( approach , dataCategory ) ) continue ; switch ( approach ) { case AnonymizerApproach . HASH : try { var affectedFieldValue = affectedProp . GetValue ( result ) ; HashObject ( ref affectedFieldValue , dataCategory ) ; affectedProp . SetValue ( result , affectedFieldValue ) ; } catch ( RuntimeBinderException e ) { _logger . LogWarning ( $" Catched RuntimeBinderException in Object  { bo . GetBoTyp ( ) } . Probably due to trying to get the type of a null object BO:  { e . Message } " ) ; } break ; case AnonymizerApproach . DELETE : var isRequired = false ; Attribute defaultValueAttribute = null ; var jsonPropertyAttribute = affectedProp . GetCustomAttributes ( ) . FirstOrDefault ( a => a is JsonPropertyAttribute ) ; if ( jsonPropertyAttribute != null ) { var jpa = ( JsonPropertyAttribute ) jsonPropertyAttribute ; if ( jpa . Required == Required . Always ) { isRequired = true ; defaultValueAttribute = affectedProp . GetCustomAttributes ( ) . FirstOrDefault ( a => a . GetType ( ) == typeof ( DefaultValueAttribute ) ) ; } } if ( isRequired && defaultValueAttribute != null ) { var dva = ( DefaultValueAttribute ) defaultValueAttribute ; affectedProp . SetValue ( result , dva . Value ) ; } else if ( bo . GetType ( ) . IsSubclassOf ( typeof ( BusinessObject ) ) ) { var boSubObject = affectedProp . GetValue ( bo ) ; if ( boSubObject != null ) { try { if ( boSubObject . GetType ( ) . IsGenericType && boSubObject . GetType ( ) . GetGenericTypeDefinition ( ) == typeof ( List < > ) ) { var listElementType = boSubObject . GetType ( ) . GetGenericArguments ( ) [ 0 ] ; var listType = typeof ( List < > ) . MakeGenericType ( listElementType ) ; var newEmptyList = Activator . CreateInstance ( listType ) ; boSubObject = newEmptyList ; } else { boSubObject = null ; } } catch ( RuntimeBinderException e ) { _logger . LogError ( $" Couldn't null BO field!:  { e . Message } " ) ; } affectedProp . SetValue ( result , boSubObject ) ; } } else { affectedProp . SetValue ( result , null ) ; } break ; case AnonymizerApproach . ENCRYPT : if ( PublicKeyX509 == null ) throw new ArgumentNullException ( nameof ( PublicKeyX509 ) , " " ) ; using ( var xasyncenc = new X509AsymmetricEncrypter ( PublicKeyX509 ) ) { if ( affectedProp . GetValue ( bo ) is string ) { if ( affectedProp . GetValue ( bo ) != null ) affectedProp . SetValue ( result , xasyncenc . Encrypt ( affectedProp . GetValue ( bo ) . ToString ( ) ) ) ; } else if ( affectedProp . GetValue ( bo ) . GetType ( ) . IsSubclassOf ( typeof ( COM . COM ) ) ) { var comObject = affectedProp . GetValue ( bo ) ; dynamic comFields = comObject . GetType ( ) . GetProperties ( ) ; foreach ( var comField in comFields ) try { comField . SetValue ( comObject , xasyncenc . Encrypt ( comField . GetValue ( comObject ) ) . ToString ( ) ) ; } catch ( ArgumentException e ) { _logger . LogError ( $" Couldn't encrypt COM field!:  { e . Message } " ) ; } catch ( Exception f ) { _logger . LogError ( $" Couldn't encrypt COM field!:  { f . Message } " ) ; } affectedProp . SetValue ( result , comObject ) ; } else if ( affectedProp . PropertyType . IsSubclassOf ( typeof ( BusinessObject ) ) ) { affectedProp . SetValue ( result , xasyncenc . Encrypt ( ( BusinessObject ) affectedProp . GetValue ( bo ) ) ) ; } else if ( affectedProp . PropertyType . ToString ( ) . StartsWith ( " " ) ) { _logger . LogWarning ( $" Encrypting  { affectedProp . PropertyType }  is not supported, since the result would not be a valid ENUM value. " ) ; } else { throw new NotImplementedException ( $" Encrypting  { affectedProp . PropertyType }  is not implemented yet. " ) ; } } break ; case AnonymizerApproach . DECRYPT : if ( _privateKey == null ) throw new ArgumentNullException ( nameof ( PrivateKeyFactory ) , " " ) ; using ( var xasydec = new X509AsymmetricEncrypter ( _privateKey ) ) { affectedProp . SetValue ( result , xasydec . Decrypt ( affectedProp . GetValue ( bo ) . ToString ( ) ) ) ; } continue ; case AnonymizerApproach . KEEP : continue ; default : continue ; } } } if ( typeof ( T ) == typeof ( JObject ) ) return ( T ) ( object ) JObject . FromObject ( result ) ; return ( T ) ( object ) result ; }
Apply the configuration set in the constructor to the JObject set in the constructor.
Apply the configuration set in the constructor to the JObject set in the constructor .
/* We'd like to set the value to null, but the business object might not allow
                             * it resulting in a JsonSerializationException. That's why we first check, 
                             * whether the field is actually required. If it has to be non-null we set the
                             * annotated default value, otherwise we can safely set null. */ // e.g. 1*Energiemenge (mappedObject)---> n*Verbrauch (boSubObject) // strings, integers, elementary // das sollte passieren, wenn das Argument kein String is und deswegen das encrypten kein sinn macht // das sollte passieren, wenn das Argument ein enum // todo: check for namespace instead of strinyfied comparison //affectedField.SetValue(mappedObject, Sha256HashEnum(affectedField.GetValue(mappedObject).ToString())); //throw new NotSupportedException($"Hashing {affectedField.FieldType} is not supported, since the result would not be a valid ENUM value."); // do nothing
A modified JObject with the configuration applied.
A modified JObject with the configuration applied .
bo
BusinessObject
see
None