Beispiel #1
0
        /// <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>
        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:
                        /* 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. */
                        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)))
                        {
                            // e.g. 1*Energiemenge (mappedObject)---> n*Verbrauch (boSubObject)
                            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
                        {
                            // strings, integers, elementary
                            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)
                                    {
                                        // das sollte passieren, wenn das Argument kein String is und deswegen das encrypten kein sinn macht
                                        _logger.LogError($"Couldn't encrypt COM field!: {e.Message}");
                                    }
                                }
                                catch (Exception f)
                                {
                                    // das sollte passieren, wenn das Argument ein enum
                                    _logger.LogError($"Couldn't encrypt COM field!: {f.Message}");
                                }

                                affectedProp.SetValue(result, comObject);
                            }
Beispiel #2
0
        /// <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>
        public T ApplyOperations <T>(BusinessObject bo)
        {
            if (bo == null)
            {
                throw new ArgumentNullException(nameof(bo));
            }
            Dictionary <DataCategory, AnonymizerApproach> mapping = configuration.operations;
            BusinessObject result = bo.DeepClone <BusinessObject>();

            foreach (DataCategory dataCategory in mapping.Keys)
            {
                AnonymizerApproach approach      = mapping[dataCategory];
                PropertyInfo[]     affectedProps = bo.GetType().GetProperties()
                                                   .Where(p => p.GetCustomAttributes(typeof(DataCategoryAttribute), false).Length > 0)
                                                   .OrderBy(ap => ap.GetCustomAttribute <JsonPropertyAttribute>()?.Order)
                                                   .ToArray <PropertyInfo>();
                foreach (PropertyInfo affectedProp in affectedProps)
                {
                    if (!affectedProp.IsAnonymizerRelevant(approach, dataCategory))
                    {
                        continue;
                    }
                    switch (approach)
                    {
                    case AnonymizerApproach.HASH:
                        try
                        {
                            object 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:
                        /* 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. */
                        bool      isRequired            = false;
                        Attribute defaultValueAttribute = null;
                        Attribute jsonPropertyAttribute = affectedProp.GetCustomAttributes().Where(a => a.GetType() == typeof(JsonPropertyAttribute)).FirstOrDefault();
                        if (jsonPropertyAttribute != null)
                        {
                            JsonPropertyAttribute jpa = (JsonPropertyAttribute)jsonPropertyAttribute;
                            if (jpa.Required == Required.Always)
                            {
                                isRequired            = true;
                                defaultValueAttribute = affectedProp.GetCustomAttributes().Where(a => a.GetType() == typeof(DefaultValueAttribute)).FirstOrDefault();
                            }
                        }

                        if (isRequired && defaultValueAttribute != null)
                        {
                            DefaultValueAttribute dva = (DefaultValueAttribute)defaultValueAttribute;
                            affectedProp.SetValue(result, dva.Value);
                        }
                        else if (bo.GetType().IsSubclassOf(typeof(BO4E.BO.BusinessObject)))
                        {
                            // e.g. 1*Energiemenge (mappedObject)---> n*Verbrauch (boSubObject)
                            var boSubObject = affectedProp.GetValue(bo);
                            if (boSubObject != null)
                            {
                                try
                                {
                                    if (boSubObject.GetType().IsGenericType&& boSubObject.GetType().GetGenericTypeDefinition() == typeof(List <>))
                                    {
                                        Type   listElementType = boSubObject.GetType().GetGenericArguments()[0];
                                        Type   listType        = typeof(List <>).MakeGenericType(listElementType);
                                        object 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
                        {
                            // strings, integers, elementary
                            affectedProp.SetValue(result, null);
                        }
                        break;

                    case AnonymizerApproach.ENCRYPT:
                        if (this.publicKeyX509 == null)
                        {
                            throw new ArgumentNullException("To use the encryption feature you have to provide a public X509 certificate using the SetPublicKey method.");
                        }
                        using (X509AsymmetricEncrypter xasyncenc = new X509AsymmetricEncrypter(this.publicKeyX509))
                        {
                            if (affectedProp.GetValue(bo).GetType() == typeof(string))
                            {
                                if (affectedProp.GetValue(bo) != null)
                                {
                                    affectedProp.SetValue(result, xasyncenc.Encrypt(affectedProp.GetValue(bo).ToString()));
                                }
                            }
                            else if (affectedProp.GetValue(bo).GetType().IsSubclassOf(typeof(BO4E.COM.COM)))
                            {
                                var     comObject = affectedProp.GetValue(bo);
                                dynamic comFields = comObject.GetType().GetProperties();
                                foreach (dynamic comField in comFields)
                                {
                                    try
                                    {
                                        comField.SetValue(comObject, xasyncenc.Encrypt(comField.GetValue(comObject)).ToString());
                                    }
                                    catch (ArgumentException e)
                                    {
                                        // das sollte passieren, wenn das Argument kein String is und deswegen das encrypten kein sinn macht
                                        _logger.LogError($"Couldn't encrypt COM field!: {e.Message}");
                                    }
                                    catch (Exception f)
                                    {
                                        // das sollte passieren, wenn das Argument ein enum
                                        _logger.LogError($"Couldn't encrypt COM field!: {f.Message}");
                                    }
                                }
                                affectedProp.SetValue(result, comObject);
                            }
                            else if (affectedProp.PropertyType.IsSubclassOf(typeof(BO4E.BO.BusinessObject)))
                            {
                                affectedProp.SetValue(result, xasyncenc.Encrypt((BusinessObject)affectedProp.GetValue(bo)));
                            }
                            else if (affectedProp.PropertyType.ToString().StartsWith("BO4E.ENUM"))     // todo: check for namespace instead of strinyfied comparison
                            {
                                //affectedField.SetValue(mappedObject, Sha256HashEnum(affectedField.GetValue(mappedObject).ToString()));
                                _logger.LogWarning($"Encrypting {affectedProp.PropertyType} is not supported, since the result would not be a valid ENUM value.");
                                //throw new NotSupportedException($"Hashing {affectedField.FieldType} 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 (this.privateKey == null)
                        {
                            throw new ArgumentNullException("To use the decryption feature you have to provide a private key using the SetPrivateKey method.");
                        }
                        using (X509AsymmetricEncrypter xasydec = new X509AsymmetricEncrypter(this.privateKey))
                        {
                            affectedProp.SetValue(result, xasydec.Decrypt(affectedProp.GetValue(bo).ToString()));
                        }
                        continue;

                    case AnonymizerApproach.KEEP:
                        // do nothing
                        continue;

                    default:
                        continue;
                    }
                }
            }
            if (typeof(T) == typeof(JObject))
            {
                return((T)(object)JObject.FromObject(result));
            }
            return((T)(object)result);
        }