Skip to content

Commit c23750d

Browse files
YvandCopilotCopilot
authored
Update admin page (#342)
* update page * Update EntraIDProviderConfiguration.cs * Update CHANGELOG.md * Update Yvand.EntraCP/TEMPLATE/ADMIN/EntraCP/GlobalSettings.ascx.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * apply suggestions * Update Yvand.EntraCP/TEMPLATE/ADMIN/EntraCP/GlobalSettings.ascx.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Simplify InvalidGroupIdentifier test using UpdateGroupIdentifier API (#343) * Initial plan * Add unit test for invalid GroupIdentifierConfig.EntityProperty validation Co-authored-by: Yvand <8788631+Yvand@users.noreply.github.com> * Refactor: Move InvalidGroupIdentifier test to CustomizeConfigTests Co-authored-by: Yvand <8788631+Yvand@users.noreply.github.com> * Shorten assertion message in InvalidGroupIdentifier test Co-authored-by: Yvand <8788631+Yvand@users.noreply.github.com> * Simplify InvalidGroupIdentifier test using UpdateGroupIdentifier method Co-authored-by: Yvand <8788631+Yvand@users.noreply.github.com> * Update CustomizeConfigTests.cs --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Yvand <8788631+Yvand@users.noreply.github.com> Co-authored-by: Yvan Duhamel <yvandev@outlook.fr> * Update CustomizeConfigTests.cs --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Yvand <8788631+Yvand@users.noreply.github.com>
1 parent 73faee6 commit c23750d

File tree

4 files changed

+71
-14
lines changed

4 files changed

+71
-14
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* Rename both methods UpdateTenantCredentials in class EntraIDProviderConfiguration, to SetTenantSecret and SetTenantCertificate, to prevent using the unexpected overload, due to the last, optional newClientId parameter - https://github.com/Yvand/EntraCP/pull/334
1616
* Improve performance and make some optimizations in the code - https://github.com/Yvand/EntraCP/pull/327
1717
* Add proxy information in the logging
18+
* Restrict the list of properties that can be set as user identifiers in the global config page - https://github.com/Yvand/EntraCP/pull/342
19+
* Ensure the group identifier property is valid before committing the changes - https://github.com/Yvand/EntraCP/pull/342
1820

1921
## EntraCP v29.0.20250721.38 - enhancements & bug-fixes - Published in July 21, 2025
2022

Yvand.EntraCP.Tests/CustomizeConfigTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,5 +173,21 @@ public void ModifyUserIdentifier()
173173
configUpdated = Settings.ClaimTypes.UpdateIdentifierForGuestUsers(backupIdentityCTConfig.DirectoryObjectPropertyForGuestUsers);
174174
Assert.That(configUpdated, Is.False, $"Update user identifier of Guest UserType with the same DirectoryObjectProperty should not change anything and return false");
175175
}
176+
177+
[Test]
178+
public void InvalidGroupIdentifier()
179+
{
180+
if (Settings.ClaimTypes.GroupIdentifierConfig != null)
181+
{
182+
DirectoryObjectProperty backupGroupIdentifier = Settings.ClaimTypes.GroupIdentifierConfig.EntityProperty;
183+
184+
// Update GroupIdentifierConfig to use UserPrincipalName, which exists for User but not Group
185+
Settings.ClaimTypes.UpdateGroupIdentifier(DirectoryObjectProperty.UserPrincipalName);
186+
// ValidateConfiguration should throw InvalidOperationException because the group identifier property is invalid
187+
Assert.Throws<InvalidOperationException>(() => UnitTestsHelper.PersistedConfiguration.ApplySettings(Settings, true), "ValidateConfiguration should throw when GroupIdentifierConfig.EntityProperty doesn't exist for Group");
188+
189+
Settings.ClaimTypes.UpdateGroupIdentifier(backupGroupIdentifier);
190+
}
191+
}
176192
}
177193
}

Yvand.EntraCP/TEMPLATE/ADMIN/EntraCP/GlobalSettings.ascx.cs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,6 @@ private void PopulateFields()
8282
{
8383
// User identifier settings
8484
this.lblUserIdClaimType.Text = Settings.ClaimTypes.UserIdentifierConfig.ClaimType;
85-
if (IdentityCTConfig.EntityPropertyToUseAsDisplayText == DirectoryObjectProperty.NotSet)
86-
{
87-
this.DdlUserGraphPropertyToDisplay.Items.FindByValue("NotSet").Selected = true;
88-
}
89-
else
90-
{
91-
this.DdlUserGraphPropertyToDisplay.Items.FindByValue(((int)IdentityCTConfig.EntityPropertyToUseAsDisplayText).ToString()).Selected = true;
92-
}
93-
this.DdlUserIdDirectoryPropertyMembers.Items.FindByValue(((int)IdentityCTConfig.EntityProperty).ToString()).Selected = true;
94-
this.DdlUserIdDirectoryPropertyGuests.Items.FindByValue(((int)IdentityCTConfig.DirectoryObjectPropertyForGuestUsers).ToString()).Selected = true;
9585
this.ChkFilterUserAccountsEnabledOnly.Checked = Settings.FilterUserAccountsEnabledOnly;
9686

9787
// Group identifier settings
@@ -138,6 +128,16 @@ private void PopulateFields()
138128

139129
private void PopulateGraphPropertiesLists()
140130
{
131+
List<DirectoryObjectProperty> preferredUserIdentifiers = new List<DirectoryObjectProperty>() { DirectoryObjectProperty.Id, DirectoryObjectProperty.Mail, DirectoryObjectProperty.UserPrincipalName, DirectoryObjectProperty.OnPremisesDistinguishedName, DirectoryObjectProperty.OnPremisesSamAccountName, DirectoryObjectProperty.OnPremisesSecurityIdentifier, DirectoryObjectProperty.OnPremisesUserPrincipalName };
132+
if (!preferredUserIdentifiers.Contains(IdentityCTConfig.EntityProperty))
133+
{
134+
preferredUserIdentifiers.Add(IdentityCTConfig.EntityProperty);
135+
}
136+
if (!preferredUserIdentifiers.Contains(IdentityCTConfig.DirectoryObjectPropertyForGuestUsers))
137+
{
138+
preferredUserIdentifiers.Add(IdentityCTConfig.DirectoryObjectPropertyForGuestUsers);
139+
}
140+
141141
this.DdlUserGraphPropertyToDisplay.Items.Add(new ListItem("(Same as the identifier property)", "NotSet"));
142142
this.DdlGroupGraphPropertyToDisplay.Items.Add(new ListItem("(Same as the identifier property)", "NotSet"));
143143

@@ -152,8 +152,11 @@ private void PopulateGraphPropertiesLists()
152152
PropertyInfo pi = typeof(User).GetProperty(prop.ToString());
153153
if (pi != null && pi.PropertyType == typeof(String))
154154
{
155-
this.DdlUserIdDirectoryPropertyMembers.Items.Add(new ListItem(prop.ToString(), ((int)prop).ToString()));
156-
this.DdlUserIdDirectoryPropertyGuests.Items.Add(new ListItem(prop.ToString(), ((int)prop).ToString()));
155+
if (preferredUserIdentifiers.Contains(prop))
156+
{
157+
this.DdlUserIdDirectoryPropertyMembers.Items.Add(new ListItem(prop.ToString(), ((int)prop).ToString()));
158+
this.DdlUserIdDirectoryPropertyGuests.Items.Add(new ListItem(prop.ToString(), ((int)prop).ToString()));
159+
}
157160
this.DdlUserGraphPropertyToDisplay.Items.Add(new ListItem(prop.ToString(), ((int)prop).ToString()));
158161
}
159162
}
@@ -170,6 +173,35 @@ private void PopulateGraphPropertiesLists()
170173
}
171174
}
172175
}
176+
177+
ListItem userIdMembersItem = this.DdlUserIdDirectoryPropertyMembers.Items.FindByValue(((int)IdentityCTConfig.EntityProperty).ToString());
178+
if (userIdMembersItem != null)
179+
{
180+
userIdMembersItem.Selected = true;
181+
}
182+
183+
ListItem userIdGuestsItem = this.DdlUserIdDirectoryPropertyGuests.Items.FindByValue(((int)IdentityCTConfig.DirectoryObjectPropertyForGuestUsers).ToString());
184+
if (userIdGuestsItem != null)
185+
{
186+
userIdGuestsItem.Selected = true;
187+
}
188+
189+
if (IdentityCTConfig.EntityPropertyToUseAsDisplayText == DirectoryObjectProperty.NotSet)
190+
{
191+
ListItem notSetItem = this.DdlUserGraphPropertyToDisplay.Items.FindByValue("NotSet");
192+
if (notSetItem != null)
193+
{
194+
notSetItem.Selected = true;
195+
}
196+
}
197+
else
198+
{
199+
ListItem displayTextItem = this.DdlUserGraphPropertyToDisplay.Items.FindByValue(((int)IdentityCTConfig.EntityPropertyToUseAsDisplayText).ToString());
200+
if (displayTextItem != null)
201+
{
202+
displayTextItem.Selected = true;
203+
}
204+
}
173205
}
174206

175207
protected void grdAzureTenants_RowDeleting(object sender, GridViewDeleteEventArgs e)

Yvand.EntraCP/Yvand.EntraClaimsProvider/Configuration/EntraIDProviderConfiguration.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Microsoft.SharePoint.Administration;
1+
using Microsoft.Graph.Models;
2+
using Microsoft.SharePoint.Administration;
23
using Microsoft.SharePoint.Administration.Claims;
34
using Microsoft.SharePoint.WebControls;
45
using System;
@@ -84,7 +85,7 @@ public interface IEntraIDProviderSettings
8485
/// Gets if only enabled user accounts should be returned
8586
/// </summary>
8687
bool FilterUserAccountsEnabledOnly { get; }
87-
88+
8889
/// <summary>
8990
/// Gets the count of group members returned per page in a request. Its value must be between 1 and 999 inclusive. Default value is 100.
9091
/// </summary>
@@ -616,6 +617,12 @@ public virtual void ValidateConfiguration()
616617
{
617618
throw new InvalidOperationException($"{configInvalidStartText} because property {nameof(ProxyAddress)} must be either empty, or start with \"http://\".");
618619
}
620+
621+
// Ensure the group identifier is valid
622+
if (this.ClaimTypes.GroupIdentifierConfig != null && Utils.GetDirectoryObjectPropertyValue(new Group(), this.ClaimTypes.GroupIdentifierConfig.EntityProperty.ToString()) == null)
623+
{
624+
throw new InvalidOperationException($"{configInvalidStartText} because the selected group identifier property \"{this.ClaimTypes.GroupIdentifierConfig.EntityProperty}\" does not exist for a Group.");
625+
}
619626
}
620627

621628
/// <summary>

0 commit comments

Comments
 (0)