コード例 #1
0
        public void TestAnnotationFilenameSelection(string filename, bool expectedResult)
        {
            var piiProcessor = new PIIProcessing(_key);

            var target = new Entity("annotation")
            {
                Id               = Guid.NewGuid(),
                ["name"]         = "The name",
                ["deb_idnumber"] = "The id",
                ["documentbody"] = "The document body can be very very long",
                // ["birthdate"] = new DateTime(2019,1,25),
                ["name_encrypted"]         = "The name encrypted",
                ["deb_idnumber_encrypted"] = "The ID encrypted",
                ["documentbody_encrypted"] = "The docbody encrypted",
                ["date_encrypted"]         = "",
                ["filename"] = filename
            };

            var    original  = target.Clone();
            Entity preImage  = null;
            var    encrypted = piiProcessor.EncryptEntity(target, preImage, s => Debug.WriteLine(s));

            Assert.IsTrue(original.Id.Equals(encrypted.Id));

            if (expectedResult)
            {
                // Documentbody should encrypted
                Assert.IsTrue(original["documentbody"] != encrypted["documentbody"]);
            }
            else
            {
                // Documentbody should be un-encrypted
                Assert.IsFalse(original["documentbody"] == encrypted["documentbody"]);
            }
        }
コード例 #2
0
        public void TestNotEncryptedEntities()
        {
            var piiProcessor = new PIIProcessing(_key);

            var target = new Entity("nonencrypted")
            {
                Id                         = Guid.NewGuid(),
                ["name"]                   = "The name",
                ["deb_idnumber"]           = "The id",
                ["documentbody"]           = "The document body",
                ["date"]                   = new DateTime(2019, 1, 25),
                ["name_encrypted"]         = "The name encrypted",
                ["deb_idnumber_encrypted"] = "The ID encrypted",
                ["documentbody_encrypted"] = "The docbody encrypted",
                ["date_encrypted"]         = new DateTime(1900, 1, 1),
            };

            var    original  = target.Clone();
            Entity preImage  = null;
            var    encrypted = piiProcessor.EncryptEntity(target, preImage, s => Debug.WriteLine(s));

            Assert.IsTrue(original.Id.Equals(encrypted.Id));

            foreach (var attr in original.Attributes)
            {
                Assert.IsTrue(encrypted.Attributes.ContainsKey(attr.Key), $"Missing {attr.Key}");
                Assert.IsTrue(attr.Value.Equals(encrypted.Attributes[attr.Key]));
            }
        }
コード例 #3
0
        public void TestSetupColumnSet()
        {
            var piiProcessor = new PIIProcessing(_key);

            var target = new Entity("contact")
            {
                Id                         = Guid.NewGuid(),
                ["name"]                   = "The name",
                ["deb_idnumber"]           = "The id",
                ["documentbody"]           = "The document body",
                ["birthdate"]              = new DateTime(2019, 1, 25),
                ["name_encrypted"]         = "The name encrypted",
                ["deb_idnumber_encrypted"] = "The ID encrypted",
                ["documentbody_encrypted"] = "The docbody encrypted",
                ["date_encrypted"]         = "",
            };
            var target2 = new Entity("annotation")
            {
                Id               = Guid.NewGuid(),
                ["name"]         = "Note",
                ["documentbody"] = "The document body"
            };

            ColumnSetTest(piiProcessor, target.ToEntityReference(), new[] { "deb_idnumber" }, new[] { "deb_idnumber_encrypted" });
            ColumnSetTest(piiProcessor, target2.ToEntityReference(), new[] { "documentbody" });
            ColumnSetTest(piiProcessor, target.ToEntityReference(), new[] { "deb_idnumber", "birthdate" }, new[] { "deb_idnumber_encrypted", "deb_birthdate_encrypted" });
            ColumnSetTest(piiProcessor, target2.ToEntityReference(), new [] { "name" }, null);
        }
コード例 #4
0
        private void EncryptPII(IPluginExecutionContext context, int stage, Action <string> trace)
        {
            if (!context.InputParameters.ContainsKey("Target"))
            {
                trace("PluginExecutionContext does not contain Target");
            }
            else
            {
                var    target   = (Entity)context.InputParameters["Target"];
                Entity preImage = null;
                if (context.PreEntityImages.ContainsKey("PreImage"))
                {
                    preImage = context.PreEntityImages["PreImage"];
                }
                var PIIProcessing = new PIIProcessing(encryptionKey);

                trace($"Message: {context.MessageName} Entity: {context.PrimaryEntityName}");
                if ((context.MessageName == "Create" || context.MessageName == "Update") &&
                    stage == PreOperation)
                {
                    PIIProcessing.EncryptEntity(target, preImage, trace);
                }
                else
                {
                    trace($"Ignore this message: {context.MessageName} stage: {stage}");
                }
            }
        }
コード例 #5
0
        public void TestLiveMayDecrypt()
        {
            // Assumes that the test user has "View Confidential Information" privilege, and that the "CRM Service" user does not have this privilege.
            var service      = TestUtilities.TestUserService;
            var piiProcessor = new PIIProcessing(_key);
            var myUserId     = Guid.Empty;

            FluentSystemUser.CurrentUser(service)
            .WeakExtract((Guid id) => myUserId = id, "systemuserid").Execute();
            Assert.IsFalse(Guid.Empty.Equals(myUserId));

            var otherUserId = Guid.Empty;

            FluentSystemUser.SystemUser(service)
            .Trace(s => Debug.WriteLine(s))
            .Where("fullname").Equals("CRM Service").WeakExtract((Guid id) => otherUserId = id, "systemuserid")
            .Execute();
            Assert.IsFalse(Guid.Empty.Equals(otherUserId));

            var result = piiProcessor.MayDecrypt(myUserId, service);

            Assert.IsTrue(result);

            result = piiProcessor.MayDecrypt(otherUserId, service);
            Assert.IsFalse(result);
        }
コード例 #6
0
        public void TestDateEncryption()
        {
            var piiProcessor = new PIIProcessing(_key);

            var target = new Entity("contact")
            {
                Id                         = Guid.NewGuid(),
                ["name"]                   = "The name",
                ["deb_idnumber"]           = "The id",
                ["documentbody"]           = "The document body",
                ["birthdate"]              = new DateTime(2019, 1, 25),
                ["name_encrypted"]         = "The name encrypted",
                ["deb_idnumber_encrypted"] = "The ID encrypted",
                ["documentbody_encrypted"] = "The docbody encrypted",
                ["date_encrypted"]         = "",
            };

            var original  = target.Clone();
            var encrypted = piiProcessor.EncryptEntity(target, null, s => Debug.WriteLine(s));

            Assert.IsTrue(original.Id.Equals(encrypted.Id));

            foreach (var attr in new[] { "name", "documentbody", "name_encrypted", "documentbody_encrypted" })
            {
                Debug.WriteLine($"Attribute: {attr}");
                Assert.IsTrue(encrypted.Attributes.ContainsKey(attr), $"Missing {attr}");
                Assert.IsTrue(original.Attributes[attr].Equals(encrypted.Attributes[attr]));
            }

            Assert.AreEqual("******", encrypted.Attributes["deb_idnumber"]);
            Assert.AreNotEqual("The ID Encrypted", encrypted.Attributes["deb_idnumber_encrypted"]);
            Assert.AreEqual(new DateTime(1900, 1, 1), encrypted.Attributes["birthdate"]);
            Assert.AreNotEqual("The ID Encrypted", encrypted.Attributes["deb_birthdate_encrypted"]);
            Debug.WriteLine(encrypted.GetAttributeValue <string>("deb_birthdate_encrypted"));

            // Now decrypt the encrypted entity.
            var decrypted = piiProcessor.DecryptEntity(target, s => Debug.WriteLine(s));

            // Assert that deb_idnumber (and other fields) should be as they were.
            foreach (var attr in new[] { "name", "documentbody", "name_encrypted", "documentbody_encrypted", "deb_idnumber", "birthdate" })
            {
                Debug.WriteLine($"Attribute: {attr}");
                Assert.IsTrue(decrypted.Attributes.ContainsKey(attr), $"Missing {attr}");
                if (!original.Attributes[attr].Equals(decrypted.Attributes[attr]))
                {
                    Assert.IsTrue(original.Attributes[attr].Equals(decrypted.Attributes[attr]));
                }
            }
            Assert.AreNotEqual("The ID Encrypted", encrypted.Attributes["deb_birthdate_encrypted"]);
            Assert.AreEqual(decrypted.Attributes["deb_birthdate_encrypted"], encrypted.Attributes["deb_birthdate_encrypted"]);
        }
コード例 #7
0
 /// <summary>
 ///  Update the column set parameter directly.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="trace"></param>
 private void UpdateColumnSet(IPluginExecutionContext context, PIIProcessing PIIProcessing, Action <string> trace)
 {
     if (!context.InputParameters.ContainsKey("ColumnSet") ||
         !context.InputParameters.ContainsKey("Target"))
     {
         trace("Input parameters for Retrieve does not contain ColumnSet or Target");
     }
     else
     {
         var colSet = (ColumnSet)context.InputParameters["ColumnSet"];
         var target = (EntityReference)context.InputParameters["Target"];
         trace("Adding encrypted columns to columnSet");
         PIIProcessing.AddAdditionalColumns(target, colSet, trace);
     }
 }
コード例 #8
0
        // Update the column set in the associated query.
        private void UpdateColumnSetInQuery(IPluginExecutionContext context, PIIProcessing PIIProcessing, Action <string> trace)
        {
            if (!(context.InputParameters.ContainsKey("Query") && context.InputParameters["Query"] is QueryExpression))
            {
                trace("Input parameters for RetrieveMultiple does not contain Query or is not QueryExpression");
            }
            else
            {
                var query  = (QueryExpression)context.InputParameters["Query"];
                var colSet = query.ColumnSet;
                var target = new EntityReference(query.EntityName, Guid.Empty);

                trace("Adding encrypted columns to query columnSet");
                PIIProcessing.AddAdditionalColumns(target, colSet, trace);
            }
        }
コード例 #9
0
        public void TestAnnotationEncryption()
        {
            var piiProcessor = new PIIProcessing(_key);

            var target = new Entity("annotation")
            {
                Id               = Guid.NewGuid(),
                ["name"]         = "The name",
                ["deb_idnumber"] = "The id",
                ["documentbody"] = "The document body can be very very long",
                // ["birthdate"] = new DateTime(2019,1,25),
                ["name_encrypted"]         = "The name encrypted",
                ["deb_idnumber_encrypted"] = "The ID encrypted",
                ["documentbody_encrypted"] = "The docbody encrypted",
                ["date_encrypted"]         = "",
            };

            var original = target.Clone();
            var preImage = new Entity("annotation")
            {
                ["filename"] = "PersonalID.jpg"
            };
            var encrypted = piiProcessor.EncryptEntity(target, preImage, s => Debug.WriteLine(s));

            Assert.IsTrue(original.Id.Equals(encrypted.Id));

            foreach (var attr in new[] { "name", "deb_idnumber", "name_encrypted", "documentbody_encrypted", "deb_idnumber_encrypted" })
            {
                Debug.WriteLine($"Attribute: {attr}");
                Assert.IsTrue(encrypted.Attributes.ContainsKey(attr), $"Missing {attr}");
                Assert.IsTrue(original.Attributes[attr].Equals(encrypted.Attributes[attr]));
            }

            Assert.AreNotEqual(original.Attributes["documentbody"], encrypted.Attributes["documentbody"]);

            // Now decrypt the encrypted entity.
            var decrypted = piiProcessor.DecryptEntity(target, s => Debug.WriteLine(s));

            // Assert that deb_idnumber (and other fields) should be as they were.
            foreach (var attr in original.Attributes.Keys)
            {
                Debug.WriteLine($"Attribute: {attr}");
                Assert.IsTrue(encrypted.Attributes.ContainsKey(attr), $"Missing {attr}");
                Assert.IsTrue(original.Attributes[attr].Equals(encrypted.Attributes[attr]));
            }
        }
コード例 #10
0
        private void DecryptPIIForSingleEntity(LocalPluginContext localContext, int stage, Action <string> trace,
                                               IPluginExecutionContext context)
        {
            if (!context.OutputParameters.ContainsKey("BusinessEntity"))
            {
                trace("PluginExecutionContext does not contain BusinessEntity in OutputParameters");
            }
            else
            {
                var target        = (Entity)context.OutputParameters["BusinessEntity"];
                var PIIProcessing = new PIIProcessing(encryptionKey);

                if (stage == PostOperation)
                {
                    PIIProcessing.DecryptEntity(target, trace);
                }
            }
        }
コード例 #11
0
        private void ColumnSetTest(PIIProcessing processor, EntityReference target, string[] initial, string[] added = null)
        {
            var columnSet         = new ColumnSet(initial);
            var expectedColumnSet = new HashSet <string>(initial);

            if (added != null)
            {
                added.ForEach((a, i) => expectedColumnSet.Add((string)a.GetValue(i)));
            }
            processor.AddAdditionalColumns(target, columnSet, s => Debug.WriteLine(s));
            Assert.AreEqual(expectedColumnSet.Count, columnSet.Columns.Count);

            foreach (var s in expectedColumnSet)
            {
                Assert.IsTrue(columnSet.Columns.Contains(s), $"Columnset did not contain expected value {s}");
            }
            foreach (var s in columnSet.Columns)
            {
                Assert.IsTrue(expectedColumnSet.Contains(s), $"Columnset contained unexpected value {s}");
            }
        }
コード例 #12
0
        /// <summary>
        /// Ensure that we are also retrieving the encrypted columns (for decryption during post-operation phase)
        /// Note that Retrieve and RetrieveMultiple have different approaches to specifying the columnset.
        /// Retrieve has a "ColumnSet" parameter in the InputParameters collection.
        /// RetrieveMultiple has a "Query" parameter in the Input Parameters collection - this is a QueryExpression and the column set is elsewhere.
        /// Also avoid adding the extra columns if the user does not have privilege to decrypt - and store MayDecrypt setting in a shared Variable.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="trace"></param>
        private void AddEncryptedColsToRetreivedCols(LocalPluginContext context, Action <string> trace)
        {
            var PIIProcessing = new PIIProcessing(encryptionKey);
            var pluginContext = context.PluginExecutionContext;

            if (PIIProcessing.MayDecrypt(pluginContext.UserId, context.OrganizationService, trace))
            {
                pluginContext.SharedVariables.Add(MayDecrypt, true);
                if (pluginContext.MessageName == "Retrieve")
                {
                    UpdateColumnSet(pluginContext, PIIProcessing, trace);
                }
                else
                {
                    UpdateColumnSetInQuery(pluginContext, PIIProcessing, trace);
                }
            }
            else
            {
                pluginContext.SharedVariables.Add(MayDecrypt, false);
            }
        }
コード例 #13
0
        public void TestMayDecrypt()
        {
            var piiProcessor = new PIIProcessing(_key);
            var userId       = Guid.NewGuid();

            #region "Setup fake"
            var user = new Entity("systemuser")
            {
                Id = userId
            };

            var securityRole = new Entity("role")
            {
                Id       = Guid.NewGuid(),
                ["name"] = "View Confidential Information"
            };

            var systemUserRole = new Entity("systemuserroles")
            {
                Id               = Guid.NewGuid(),
                ["roleid"]       = securityRole.Id,
                ["systemuserid"] = userId
            };

            var context = new XrmFakedContext();
            context.Initialize(new List <Entity>()
            {
                user, securityRole, systemUserRole
            });
            #endregion

            var result = piiProcessor.MayDecrypt(userId, context.GetOrganizationService());
            Assert.IsTrue(result);

            result = piiProcessor.MayDecrypt(Guid.NewGuid(), context.GetOrganizationService());
            Assert.IsFalse(result);
        }