src/main/distrib/data/gitblit.properties | ●●●●● patch | view | raw | blame | history | |
src/main/java/com/gitblit/auth/LdapAuthProvider.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/com/gitblit/service/LdapSyncService.java | ●●●●● patch | view | raw | blame | history | |
src/test/config/test-users.conf | ●●●●● patch | view | raw | blame | history | |
src/test/java/com/gitblit/tests/LdapAuthenticationTest.java | ●●●●● patch | view | raw | blame | history | |
src/test/resources/ldap/adduser.ldif | ●●●●● patch | view | raw | blame | history | |
src/test/resources/ldap/users.conf | ●●●●● patch | view | raw | blame | history |
src/main/distrib/data/gitblit.properties
@@ -1508,6 +1508,16 @@ # If left blank, false is assumed realm.ldap.synchronizeUsers.enable = false # Defines the period to be used when synchronizing users from ldap. This is currently # only used for LDAP user synchronization. # # Must be of the form '<long> <TimeUnit>' where <TimeUnit> is one of 'MILLISECONDS', 'SECONDS', 'MINUTES', 'HOURS', 'DAYS' # <long> is at least 5 Minutes if lower values are given the default is used. # default: 5 MINUTES # # RESTART REQUIRED realm.ldap.synchronizeUsers.ldapSyncPeriod = 5 MINUTES # Defines whether to delete non-existent LDAP users from the backing user service # during synchronization. depends on realm.ldap.synchronizeUsers.enable = true # src/main/java/com/gitblit/auth/LdapAuthProvider.java
@@ -23,6 +23,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; @@ -32,8 +34,10 @@ import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.service.LdapSyncService; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; import com.unboundid.ldap.sdk.Attribute; import com.unboundid.ldap.sdk.DereferencePolicy; import com.unboundid.ldap.sdk.ExtendedResult; @@ -57,7 +61,7 @@ */ public class LdapAuthProvider extends UsernamePasswordAuthenticationProvider { private AtomicLong lastLdapUserSync = new AtomicLong(0L); private final AtomicLong lastLdapUserSync = new AtomicLong(0L); public LdapAuthProvider() { super("ldap"); @@ -77,6 +81,11 @@ @Override public void setup() { synchronizeLdapUsers(); configureLdapSyncService(); } public void synchronizeWithLdapService() { synchronizeLdapUsers(); } @@ -519,4 +528,24 @@ } return sb.toString(); } private void configureLdapSyncService() { logger.info("Start configuring ldap sync service"); LdapSyncService ldapSyncService = new LdapSyncService(settings, this); if (ldapSyncService.isReady()) { int mins = TimeUtils.convertFrequencyToMinutes(settings.getString(Keys.realm.ldap.synchronizeUsers.ldapSyncPeriod, "5 mins")); if (mins < 5) { mins = 5; } int delay = 1; ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); scheduledExecutorService.scheduleAtFixedRate(ldapSyncService, delay, mins, TimeUnit.MINUTES); logger.info("Ldap sync service will update user and groups every {} minutes.", mins); logger.info("Next scheduled ldap sync is in {} minutes", delay); } else { logger.info("Ldap sync service is disabled."); } logger.info("Finished configuring ldap sync service"); } } src/main/java/com/gitblit/service/LdapSyncService.java
New file @@ -0,0 +1,64 @@ /* * Copyright 2013 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.service; import java.util.concurrent.atomic.AtomicBoolean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.auth.LdapAuthProvider; /** * @author Alfred Schmid * */ public final class LdapSyncService implements Runnable { private final Logger logger = LoggerFactory.getLogger(LdapSyncService.class); private final IStoredSettings settings; private final LdapAuthProvider ldapAuthProvider; private final AtomicBoolean running = new AtomicBoolean(false); public LdapSyncService(IStoredSettings settings, LdapAuthProvider ldapAuthProvider) { this.settings = settings; this.ldapAuthProvider = ldapAuthProvider; } /** * * @see java.lang.Runnable#run() */ @Override public void run() { logger.info("Starting user and group sync with ldap service"); if (!running.getAndSet(true)) { ldapAuthProvider.synchronizeWithLdapService(); running.getAndSet(false); } logger.info("Finished user and group sync with ldap service"); } public boolean isReady() { return settings.getBoolean(Keys.realm.ldap.synchronizeUsers.enable, false); } } src/test/config/test-users.conf
@@ -4,6 +4,11 @@ accountType = LOCAL role = "#admin" role = "#notfederated" [user "sampleuser"] password = sampleuser cookie = 6e07ed42149fc166206319faffdfba2e2ec82e43 accountType = LOCAL role = "#none" [team "admins"] role = "#none" accountType = LOCAL src/test/java/com/gitblit/tests/LdapAuthenticationTest.java
@@ -24,8 +24,10 @@ import org.junit.BeforeClass; import org.junit.Test; import com.gitblit.Constants.AccountType; import com.gitblit.IStoredSettings; import com.gitblit.auth.LdapAuthProvider; import com.gitblit.manager.IUserManager; import com.gitblit.manager.RuntimeManager; import com.gitblit.manager.UserManager; import com.gitblit.models.UserModel; @@ -33,6 +35,8 @@ import com.unboundid.ldap.listener.InMemoryDirectoryServer; import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; import com.unboundid.ldap.listener.InMemoryListenerConfig; import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchScope; import com.unboundid.ldif.LDIFReader; /** @@ -50,6 +54,10 @@ static int ldapPort = 1389; private static InMemoryDirectoryServer ds; private IUserManager userManager; @BeforeClass public static void createInMemoryLdapServer() throws Exception { InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=MyDomain"); @@ -57,7 +65,7 @@ config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", ldapPort)); config.setSchema(null); InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); ds = new InMemoryDirectoryServer(config); ds.importFromLDIF(true, new LDIFReader(new FileInputStream(RESOURCE_DIR + "sampledata.ldif"))); ds.startListening(); } @@ -69,9 +77,9 @@ public LdapAuthProvider newLdapAuthentication(IStoredSettings settings) { RuntimeManager runtime = new RuntimeManager(settings, GitBlitSuite.BASEFOLDER).start(); UserManager users = new UserManager(runtime).start(); userManager = new UserManager(runtime).start(); LdapAuthProvider ldap = new LdapAuthProvider(); ldap.setup(runtime, users); ldap.setup(runtime, userManager); return ldap; } @@ -91,6 +99,9 @@ backingMap.put("realm.ldap.admins", "UserThree @Git_Admins \"@Git Admins\""); backingMap.put("realm.ldap.displayName", "displayName"); backingMap.put("realm.ldap.email", "email"); backingMap.put("realm.ldap.synchronizeUsers.enable", "true"); backingMap.put("realm.ldap.uid", "sAMAccountName"); backingMap.put("realm.ldap.ldapCachePeriod", "0 MINUTES"); MemorySettings ms = new MemorySettings(backingMap); return ms; @@ -162,4 +173,30 @@ assertNull(userOneModel); } @Test public void checkIfSevenUsersLoadedFromLdap() throws Exception { SearchResult searchResult = ds.search("OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain", SearchScope.SUB, "objectClass=person"); assertEquals("Number of ldap users in gitblit user model", searchResult.getEntryCount(), countLdapUsersInUserManager()); } @Test public void addingUserInLdapShouldUpdateGitBlitUsersAndGroups() throws Exception { ds.addEntries(LDIFReader.readEntries(RESOURCE_DIR + "adduser.ldif")); for(String user : userManager.getAllUsernames()) { System.out.println(user); } ldap.synchronizeWithLdapService(); assertEquals("Number of ldap users in gitblit user model", 5, countLdapUsersInUserManager()); } private int countLdapUsersInUserManager() { int ldapAccountCount = 0; for (UserModel userModel : userManager.getAllUsers()) { if (AccountType.LDAP.equals(userModel.accountType)) { ldapAccountCount++; } } return ldapAccountCount; } } src/test/resources/ldap/adduser.ldif
New file @@ -0,0 +1,11 @@ dn: CN=UserFive,OU=Canada,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain objectClass: user objectClass: person sAMAccountName: UserFive userPassword: userFivePassword displayName: User Five givenName: User surname: Five personalTitle: Miss email: userfive@gitblit.com memberOf: CN=Git_Users,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain src/test/resources/ldap/users.conf
@@ -7,10 +7,17 @@ [user "userthree"] password = "#externalAccount" cookie = d7d3894fc517612aa6c595555b6e1ab8e147e597 displayName = User Three displayName = Mrs. User Three emailAddress = userthree@gitblit.com accountType = LDAP role = "#admin" [user "userfive"] password = "#externalAccount" cookie = 220bafef069b8b399b2597644015b6b0f4667982 displayName = Miss. User Five emailAddress = userfive@gitblit.com accountType = LDAP role = "#none" [user "userone"] password = "#externalAccount" cookie = c97cd38e50858cd0b389ec61b18fb9a89b4da54c @@ -21,7 +28,7 @@ [user "usertwo"] password = "#externalAccount" cookie = 498ca9bd2841d39050fa45d1d737b9f9f767858d displayName = User Two displayName = Mr. User Two emailAddress = usertwo@gitblit.com accountType = LDAP role = "#admin" @@ -37,6 +44,13 @@ cookie = dd94709528bb1c83d08f3088d4043f4742891f4f accountType = LOCAL role = "#create" [user "userfour"] password = "#externalAccount" cookie = d4fca47ebc70f0495947f8b6158ac6edb546e2fe displayName = Miss. User Four emailAddress = userfour@gitblit.com accountType = LDAP role = "#none" [team "Git_Admins"] role = "#none" accountType = LOCAL @@ -47,6 +61,7 @@ user = userone user = usertwo user = userthree user = userfour [team "Git Admins"] role = "#none" accountType = LOCAL