From f6d7de15b1471b1c101362dbaf598de8031e6540 Mon Sep 17 00:00:00 2001 From: Alfred Schmid Date: Mon, 3 Feb 2014 10:01:04 +0100 Subject: [PATCH] Load empty groups as empty teams from ldap, when ldap user synchronization is enabled. --- src/main/distrib/data/gitblit.properties | 9 ++++++ .../com/gitblit/auth/LdapAuthProvider.java | 24 ++++++++++++++++ .../gitblit/tests/LdapAuthenticationTest.java | 28 +++++++++++++++++++ src/test/resources/ldap/addgroup.ldif | 5 ++++ 4 files changed, 66 insertions(+) create mode 100644 src/test/resources/ldap/addgroup.ldif diff --git a/src/main/distrib/data/gitblit.properties b/src/main/distrib/data/gitblit.properties index bd0efd9e..3297d254 100644 --- a/src/main/distrib/data/gitblit.properties +++ b/src/main/distrib/data/gitblit.properties @@ -1460,6 +1460,14 @@ realm.ldap.groupBase = OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain # SINCE 1.0.0 realm.ldap.groupMemberPattern = (&(objectClass=group)(member=${dn})) +# Filter criteria for empty LDAP groups +# +# Query pattern to use when searching for an empty team. This may be any valid +# LDAP query expression, including the standard (&) and (|) operators. +# +# SINCE 1.4.0 +realm.ldap.groupEmptyMemberPattern = (&(objectClass=group)(!(member=*))) + # LDAP users or groups that should be given administrator privileges. # # Teams are specified with a leading '@' character. Groups with spaces in the @@ -1516,6 +1524,7 @@ realm.ldap.synchronizeUsers.enable = false # default: 5 MINUTES # # RESTART REQUIRED +# SINCE 1.4.0 realm.ldap.synchronizeUsers.ldapSyncPeriod = 5 MINUTES # Defines whether to delete non-existent LDAP users from the backing user service diff --git a/src/main/java/com/gitblit/auth/LdapAuthProvider.java b/src/main/java/com/gitblit/auth/LdapAuthProvider.java index 1ec273a9..b2084595 100644 --- a/src/main/java/com/gitblit/auth/LdapAuthProvider.java +++ b/src/main/java/com/gitblit/auth/LdapAuthProvider.java @@ -152,6 +152,9 @@ public class LdapAuthProvider extends UsernamePasswordAuthenticationProvider { userManager.updateTeamModels(userTeams.values()); } } + if (!supportsTeamMembershipChanges()) { + getEmptyTeamsFromLdap(ldapConnection); + } lastLdapUserSync.set(System.currentTimeMillis()); } finally { ldapConnection.close(); @@ -435,6 +438,27 @@ public class LdapAuthProvider extends UsernamePasswordAuthenticationProvider { } } + private void getEmptyTeamsFromLdap(LDAPConnection ldapConnection) { + String groupBase = settings.getString(Keys.realm.ldap.groupBase, ""); + String groupMemberPattern = settings.getString(Keys.realm.ldap.groupEmptyMemberPattern, "(&(objectClass=group)(!(member=*)))"); + + SearchResult teamMembershipResult = doSearch(ldapConnection, groupBase, true, groupMemberPattern, null); + if (teamMembershipResult != null && teamMembershipResult.getEntryCount() > 0) { + for (int i = 0; i < teamMembershipResult.getEntryCount(); i++) { + SearchResultEntry teamEntry = teamMembershipResult.getSearchEntries().get(i); + if (!teamEntry.hasAttribute("member")) { + String teamName = teamEntry.getAttribute("cn").getValue(); + + TeamModel teamModel = userManager.getTeamModel(teamName); + if (teamModel == null) { + teamModel = createTeamFromLdap(teamEntry); + userManager.updateTeamModel(teamModel); + } + } + } + } + } + private TeamModel createTeamFromLdap(SearchResultEntry teamEntry) { TeamModel answer = new TeamModel(teamEntry.getAttributeValue("cn")); answer.accountType = getAccountType(); diff --git a/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java index ce3615e0..670dde00 100644 --- a/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java +++ b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java @@ -34,6 +34,7 @@ import com.gitblit.auth.LdapAuthProvider; import com.gitblit.manager.IUserManager; import com.gitblit.manager.RuntimeManager; import com.gitblit.manager.UserManager; +import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.tests.mock.MemorySettings; import com.unboundid.ldap.listener.InMemoryDirectoryServer; @@ -208,6 +209,23 @@ public class LdapAuthenticationTest extends GitblitUnitTest { assertEquals("Number of ldap users in gitblit user model", 6, countLdapUsersInUserManager()); } + @Test + public void addingGroupsInLdapShouldNotUpdateGitBlitUsersAndGroups() throws Exception { + settings.put("realm.ldap.ldapCachePeriod", "0 MINUTES"); + ds.addEntries(LDIFReader.readEntries(RESOURCE_DIR + "addgroup.ldif")); + ldap.synchronizeWithLdapService(); + assertEquals("Number of ldap groups in gitblit team model", 0, countLdapTeamsInUserManager()); + } + + @Test + public void addingGroupsInLdapShouldUpdateGitBlitUsersAndGroups() throws Exception { + settings.put("realm.ldap.synchronizeUsers.enable", "true"); + settings.put("realm.ldap.ldapCachePeriod", "0 MINUTES"); + ds.addEntries(LDIFReader.readEntries(RESOURCE_DIR + "addgroup.ldif")); + ldap.synchronizeWithLdapService(); + assertEquals("Number of ldap groups in gitblit team model", 1, countLdapTeamsInUserManager()); + } + private int countLdapUsersInUserManager() { int ldapAccountCount = 0; for (UserModel userModel : userManager.getAllUsers()) { @@ -218,4 +236,14 @@ public class LdapAuthenticationTest extends GitblitUnitTest { return ldapAccountCount; } + private int countLdapTeamsInUserManager() { + int ldapAccountCount = 0; + for (TeamModel teamModel : userManager.getAllTeams()) { + if (AccountType.LDAP.equals(teamModel.accountType)) { + ldapAccountCount++; + } + } + return ldapAccountCount; + } + } diff --git a/src/test/resources/ldap/addgroup.ldif b/src/test/resources/ldap/addgroup.ldif new file mode 100644 index 00000000..665df31b --- /dev/null +++ b/src/test/resources/ldap/addgroup.ldif @@ -0,0 +1,5 @@ +dn: CN=Git_Group_Without_Members,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain +objectClass: top +objectClass: group +cn: Git_Group_Without_Members +sAMAccountName: Git_Group_Without_Members -- 2.39.5