From 00580cd53377102403e48fde7aa4cf1c1a32cac1 Mon Sep 17 00:00:00 2001 From: Morten Holt Date: Tue, 10 Mar 2026 09:39:33 +0100 Subject: [PATCH 1/2] Throw better exception when security role isn't found on create --- src/XrmMockup365/Security.cs | 13 +++++++++---- tests/XrmMockup365Test/TestSecurityRoles.cs | 11 +++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/XrmMockup365/Security.cs b/src/XrmMockup365/Security.cs index 1f6b9796..32955b15 100644 --- a/src/XrmMockup365/Security.cs +++ b/src/XrmMockup365/Security.cs @@ -341,7 +341,7 @@ internal void AddPrinciplePrivileges(Guid principleId, Privileges privileges) PrinciplePrivilages.Add(principleId, currentPrivileges); } - private void AddPrinciplePrivlieges(Guid principleId, Guid[] roles) + private void AddPrinciplePrivileges(Guid principleId, Guid[] roles) { if (!roles.Any()) { @@ -358,9 +358,14 @@ private void AddPrinciplePrivlieges(Guid principleId, Guid[] roles) // Combine users current privilege with the securityRoles foreach (var roleId in roles) { - var securityRolePrivilages = SecurityRoles[roleId].Privileges; + if (!SecurityRoles.TryGetValue(roleId, out var securityRole)) + { + throw new MockupException( + $"Security role with id '{roleId}' was not found. " + + $"Ensure the security role exists in the metadata or has been added via AddSecurityRole."); + } - currentPrivileges = JoinPrivileges(currentPrivileges, securityRolePrivilages); + currentPrivileges = JoinPrivileges(currentPrivileges, securityRole.Privileges); } // Update the principles privileges; @@ -378,7 +383,7 @@ internal void SetSecurityRole(EntityReference entRef, Guid[] secRoles) return; } - AddPrinciplePrivlieges(entRef.Id, secRoles); + AddPrinciplePrivileges(entRef.Id, secRoles); if (secRoles.Any(s => !SecurityRoles.ContainsKey(s))) { throw new MockupException($"Unknown security role"); diff --git a/tests/XrmMockup365Test/TestSecurityRoles.cs b/tests/XrmMockup365Test/TestSecurityRoles.cs index 1b8bf98e..f99e4db9 100644 --- a/tests/XrmMockup365Test/TestSecurityRoles.cs +++ b/tests/XrmMockup365Test/TestSecurityRoles.cs @@ -255,6 +255,17 @@ public void TestParentChangeCascading() } } + [Fact] + public void TestCreateUserWithNonExistentSecurityRoleThrowsMockupException() + { + var nonExistentRoleId = Guid.NewGuid(); + + var ex = Assert.Throws(() => + crm.CreateUser(orgAdminUIService, crm.RootBusinessUnit, nonExistentRoleId)); + + Assert.Contains(nonExistentRoleId.ToString(), ex.Message); + Assert.Contains("was not found", ex.Message); + } } } From a9670589bcfc27d0469a5fd6977a6fde63667548 Mon Sep 17 00:00:00 2001 From: Morten Holt Date: Tue, 10 Mar 2026 09:50:52 +0100 Subject: [PATCH 2/2] Remove unreachable code after review --- src/XrmMockup365/Security.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/XrmMockup365/Security.cs b/src/XrmMockup365/Security.cs index 32955b15..519e0835 100644 --- a/src/XrmMockup365/Security.cs +++ b/src/XrmMockup365/Security.cs @@ -384,10 +384,6 @@ internal void SetSecurityRole(EntityReference entRef, Guid[] secRoles) } AddPrinciplePrivileges(entRef.Id, secRoles); - if (secRoles.Any(s => !SecurityRoles.ContainsKey(s))) - { - throw new MockupException($"Unknown security role"); - } var user = Core.GetDbRow(entRef).ToEntity(); var relationship = entRef.LogicalName == LogicalNames.SystemUser ? new Relationship("systemuserroles_association") : new Relationship("teamroles_association"); var roles = secRoles