summaryrefslogtreecommitdiffstats
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/com/gitblit/tests/LdapAuthenticationTest.java617
-rw-r--r--src/test/java/com/gitblit/tests/MarkdownUtilsTest.java74
-rw-r--r--src/test/resources/ldap/users.conf6
3 files changed, 661 insertions, 36 deletions
diff --git a/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java
index 84dd138d..b7a77fc2 100644
--- a/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java
+++ b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java
@@ -16,17 +16,26 @@
*/
package com.gitblit.tests;
+import static org.junit.Assume.*;
+
import java.io.File;
-import java.io.FileInputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.FileUtils;
+import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import com.gitblit.Constants.AccountType;
import com.gitblit.IStoredSettings;
@@ -43,9 +52,24 @@ import com.gitblit.utils.XssFilter;
import com.gitblit.utils.XssFilter.AllowXssFilter;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
+import com.unboundid.ldap.listener.InMemoryDirectoryServerSnapshot;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
+import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedRequest;
+import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedResult;
+import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchEntry;
+import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchRequest;
+import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
+import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSimpleBindResult;
+import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
+import com.unboundid.ldap.sdk.BindRequest;
+import com.unboundid.ldap.sdk.BindResult;
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.LDAPResult;
+import com.unboundid.ldap.sdk.OperationType;
+import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.SearchResult;
import com.unboundid.ldap.sdk.SearchScope;
+import com.unboundid.ldap.sdk.SimpleBindRequest;
import com.unboundid.ldif.LDIFReader;
/**
@@ -55,19 +79,71 @@ import com.unboundid.ldif.LDIFReader;
* @author jcrygier
*
*/
+@RunWith(Parameterized.class)
public class LdapAuthenticationTest extends GitblitUnitTest {
- @Rule
- public TemporaryFolder folder = new TemporaryFolder();
private static final String RESOURCE_DIR = "src/test/resources/ldap/";
+ private static final String DIRECTORY_MANAGER = "cn=Directory Manager";
+ private static final String USER_MANAGER = "cn=UserManager";
+ private static final String ACCOUNT_BASE = "OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain";
+ private static final String GROUP_BASE = "OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain";
+
+
+ /**
+ * Enumeration of different test modes, representing different use scenarios.
+ * With ANONYMOUS anonymous binds are used to search LDAP.
+ * DS_MANAGER will use a DIRECTORY_MANAGER to search LDAP. Normal users are prohibited to search the DS.
+ * With USR_MANAGER, a USER_MANAGER account is used to search in LDAP. This account can only search users
+ * but not groups. Normal users can search groups, though.
+ *
+ */
+ enum AuthMode {
+ ANONYMOUS(1389),
+ DS_MANAGER(2389),
+ USR_MANAGER(3389);
+
+
+ private int ldapPort;
+ private InMemoryDirectoryServer ds;
+ private InMemoryDirectoryServerSnapshot dsSnapshot;
+
+ AuthMode(int port) {
+ this.ldapPort = port;
+ }
+
+ int ldapPort() {
+ return this.ldapPort;
+ }
+
+ void setDS(InMemoryDirectoryServer ds) {
+ if (this.ds == null) {
+ this.ds = ds;
+ this.dsSnapshot = ds.createSnapshot();
+ };
+ }
+
+ InMemoryDirectoryServer getDS() {
+ return ds;
+ }
+
+ void restoreSnapshot() {
+ ds.restoreSnapshot(dsSnapshot);
+ }
+ };
+
+
- private File usersConf;
+ @Parameter
+ public AuthMode authMode;
- private LdapAuthProvider ldap;
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
- static int ldapPort = 1389;
+ private File usersConf;
- private static InMemoryDirectoryServer ds;
+
+
+ private LdapAuthProvider ldap;
private IUserManager userManager;
@@ -75,21 +151,82 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
private MemorySettings settings;
+
+ /**
+ * Run the tests with each authentication scenario once.
+ */
+ @Parameters(name = "{0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] { {AuthMode.ANONYMOUS}, {AuthMode.DS_MANAGER}, {AuthMode.USR_MANAGER} });
+ }
+
+
+
+ /**
+ * Create three different in memory DS.
+ *
+ * Each DS has a different configuration:
+ * The first allows anonymous binds.
+ * The second requires authentication for all operations. It will only allow the DIRECTORY_MANAGER account
+ * to search for users and groups.
+ * The third one is like the second, but it allows users to search for users and groups, and restricts the
+ * USER_MANAGER from searching for groups.
+ */
@BeforeClass
- public static void createInMemoryLdapServer() throws Exception {
+ public static void init() throws Exception {
+ InMemoryDirectoryServer ds;
+ InMemoryDirectoryServerConfig config = createInMemoryLdapServerConfig(AuthMode.ANONYMOUS);
+ config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", AuthMode.ANONYMOUS.ldapPort()));
+ ds = createInMemoryLdapServer(config);
+ AuthMode.ANONYMOUS.setDS(ds);
+
+
+ config = createInMemoryLdapServerConfig(AuthMode.DS_MANAGER);
+ config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", AuthMode.DS_MANAGER.ldapPort()));
+ config.setAuthenticationRequiredOperationTypes(EnumSet.allOf(OperationType.class));
+ ds = createInMemoryLdapServer(config);
+ AuthMode.DS_MANAGER.setDS(ds);
+
+
+ config = createInMemoryLdapServerConfig(AuthMode.USR_MANAGER);
+ config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", AuthMode.USR_MANAGER.ldapPort()));
+ config.setAuthenticationRequiredOperationTypes(EnumSet.allOf(OperationType.class));
+ ds = createInMemoryLdapServer(config);
+ AuthMode.USR_MANAGER.setDS(ds);
+
+ }
+
+ @AfterClass
+ public static void destroy() throws Exception {
+ for (AuthMode am : AuthMode.values()) {
+ am.getDS().shutDown(true);
+ }
+ }
+
+ public static InMemoryDirectoryServer createInMemoryLdapServer(InMemoryDirectoryServerConfig config) throws Exception {
+ InMemoryDirectoryServer imds = new InMemoryDirectoryServer(config);
+ imds.importFromLDIF(true, RESOURCE_DIR + "sampledata.ldif");
+ imds.startListening();
+ return imds;
+ }
+
+ public static InMemoryDirectoryServerConfig createInMemoryLdapServerConfig(AuthMode authMode) throws Exception {
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=MyDomain");
- config.addAdditionalBindCredentials("cn=Directory Manager", "password");
- config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", ldapPort));
+ config.addAdditionalBindCredentials(DIRECTORY_MANAGER, "password");
+ config.addAdditionalBindCredentials(USER_MANAGER, "passwd");
config.setSchema(null);
- ds = new InMemoryDirectoryServer(config);
- ds.startListening();
+ config.addInMemoryOperationInterceptor(new AccessInterceptor(authMode));
+
+ return config;
}
+
+
@Before
- public void init() throws Exception {
- ds.clear();
- ds.importFromLDIF(true, new LDIFReader(new FileInputStream(RESOURCE_DIR + "sampledata.ldif")));
+ public void setup() throws Exception {
+ authMode.restoreSnapshot();
+
usersConf = folder.newFile("users.conf");
FileUtils.copyFile(new File(RESOURCE_DIR + "users.conf"), usersConf);
settings = getSettings();
@@ -117,15 +254,30 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
private MemorySettings getSettings() {
Map<String, Object> backingMap = new HashMap<String, Object>();
backingMap.put(Keys.realm.userService, usersConf.getAbsolutePath());
- backingMap.put(Keys.realm.ldap.server, "ldap://localhost:" + ldapPort);
-// backingMap.put(Keys.realm.ldap.domain, "");
- backingMap.put(Keys.realm.ldap.username, "cn=Directory Manager");
- backingMap.put(Keys.realm.ldap.password, "password");
-// backingMap.put(Keys.realm.ldap.backingUserService, "users.conf");
+ switch(authMode) {
+ case ANONYMOUS:
+ backingMap.put(Keys.realm.ldap.server, "ldap://localhost:" + authMode.ldapPort());
+ backingMap.put(Keys.realm.ldap.username, "");
+ backingMap.put(Keys.realm.ldap.password, "");
+ break;
+ case DS_MANAGER:
+ backingMap.put(Keys.realm.ldap.server, "ldap://localhost:" + authMode.ldapPort());
+ backingMap.put(Keys.realm.ldap.username, DIRECTORY_MANAGER);
+ backingMap.put(Keys.realm.ldap.password, "password");
+ break;
+ case USR_MANAGER:
+ backingMap.put(Keys.realm.ldap.server, "ldap://localhost:" + authMode.ldapPort());
+ backingMap.put(Keys.realm.ldap.username, USER_MANAGER);
+ backingMap.put(Keys.realm.ldap.password, "passwd");
+ break;
+ default:
+ throw new RuntimeException("Unimplemented AuthMode case!");
+
+ }
backingMap.put(Keys.realm.ldap.maintainTeams, "true");
- backingMap.put(Keys.realm.ldap.accountBase, "OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain");
+ backingMap.put(Keys.realm.ldap.accountBase, ACCOUNT_BASE);
backingMap.put(Keys.realm.ldap.accountPattern, "(&(objectClass=person)(sAMAccountName=${username}))");
- backingMap.put(Keys.realm.ldap.groupBase, "OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain");
+ backingMap.put(Keys.realm.ldap.groupBase, GROUP_BASE);
backingMap.put(Keys.realm.ldap.groupMemberPattern, "(&(objectClass=group)(member=${dn}))");
backingMap.put(Keys.realm.ldap.admins, "UserThree @Git_Admins \"@Git Admins\"");
backingMap.put(Keys.realm.ldap.displayName, "displayName");
@@ -136,13 +288,14 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
return ms;
}
+
+
@Test
public void testAuthenticate() {
UserModel userOneModel = ldap.authenticate("UserOne", "userOnePassword".toCharArray());
assertNotNull(userOneModel);
assertNotNull(userOneModel.getTeam("git_admins"));
assertNotNull(userOneModel.getTeam("git_users"));
- assertTrue(userOneModel.canAdmin);
UserModel userOneModelFailedAuth = ldap.authenticate("UserOne", "userTwoPassword".toCharArray());
assertNull(userOneModelFailedAuth);
@@ -152,13 +305,101 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
assertNotNull(userTwoModel.getTeam("git_users"));
assertNull(userTwoModel.getTeam("git_admins"));
assertNotNull(userTwoModel.getTeam("git admins"));
- assertTrue(userTwoModel.canAdmin);
UserModel userThreeModel = ldap.authenticate("UserThree", "userThreePassword".toCharArray());
assertNotNull(userThreeModel);
assertNotNull(userThreeModel.getTeam("git_users"));
assertNull(userThreeModel.getTeam("git_admins"));
+
+ UserModel userFourModel = ldap.authenticate("UserFour", "userFourPassword".toCharArray());
+ assertNotNull(userFourModel);
+ assertNotNull(userFourModel.getTeam("git_users"));
+ assertNull(userFourModel.getTeam("git_admins"));
+ assertNull(userFourModel.getTeam("git admins"));
+ }
+
+ @Test
+ public void testAdminPropertyTeamsInLdap() {
+ UserModel userOneModel = ldap.authenticate("UserOne", "userOnePassword".toCharArray());
+ assertNotNull(userOneModel);
+ assertNotNull(userOneModel.getTeam("git_admins"));
+ assertNull(userOneModel.getTeam("git admins"));
+ assertNotNull(userOneModel.getTeam("git_users"));
+ assertFalse(userOneModel.canAdmin);
+ assertTrue(userOneModel.canAdmin());
+ assertTrue(userOneModel.getTeam("git_admins").canAdmin);
+ assertFalse(userOneModel.getTeam("git_users").canAdmin);
+
+ UserModel userTwoModel = ldap.authenticate("UserTwo", "userTwoPassword".toCharArray());
+ assertNotNull(userTwoModel);
+ assertNotNull(userTwoModel.getTeam("git_users"));
+ assertNull(userTwoModel.getTeam("git_admins"));
+ assertNotNull(userTwoModel.getTeam("git admins"));
+ assertFalse(userTwoModel.canAdmin);
+ assertTrue(userTwoModel.canAdmin());
+ assertTrue(userTwoModel.getTeam("git admins").canAdmin);
+ assertFalse(userTwoModel.getTeam("git_users").canAdmin);
+
+ UserModel userThreeModel = ldap.authenticate("UserThree", "userThreePassword".toCharArray());
+ assertNotNull(userThreeModel);
+ assertNotNull(userThreeModel.getTeam("git_users"));
+ assertNull(userThreeModel.getTeam("git_admins"));
+ assertNull(userThreeModel.getTeam("git admins"));
assertTrue(userThreeModel.canAdmin);
+ assertTrue(userThreeModel.canAdmin());
+ assertFalse(userThreeModel.getTeam("git_users").canAdmin);
+
+ UserModel userFourModel = ldap.authenticate("UserFour", "userFourPassword".toCharArray());
+ assertNotNull(userFourModel);
+ assertNotNull(userFourModel.getTeam("git_users"));
+ assertNull(userFourModel.getTeam("git_admins"));
+ assertNull(userFourModel.getTeam("git admins"));
+ assertFalse(userFourModel.canAdmin);
+ assertFalse(userFourModel.canAdmin());
+ assertFalse(userFourModel.getTeam("git_users").canAdmin);
+ }
+
+ @Test
+ public void testAdminPropertyTeamsNotInLdap() {
+ settings.put(Keys.realm.ldap.maintainTeams, "false");
+
+ UserModel userOneModel = ldap.authenticate("UserOne", "userOnePassword".toCharArray());
+ assertNotNull(userOneModel);
+ assertNotNull(userOneModel.getTeam("git_admins"));
+ assertNull(userOneModel.getTeam("git admins"));
+ assertNotNull(userOneModel.getTeam("git_users"));
+ assertTrue(userOneModel.canAdmin);
+ assertTrue(userOneModel.canAdmin());
+ assertFalse(userOneModel.getTeam("git_admins").canAdmin);
+ assertFalse(userOneModel.getTeam("git_users").canAdmin);
+
+ UserModel userTwoModel = ldap.authenticate("UserTwo", "userTwoPassword".toCharArray());
+ assertNotNull(userTwoModel);
+ assertNotNull(userTwoModel.getTeam("git_users"));
+ assertNull(userTwoModel.getTeam("git_admins"));
+ assertNotNull(userTwoModel.getTeam("git admins"));
+ assertFalse(userTwoModel.canAdmin);
+ assertTrue(userTwoModel.canAdmin());
+ assertTrue(userTwoModel.getTeam("git admins").canAdmin);
+ assertFalse(userTwoModel.getTeam("git_users").canAdmin);
+
+ UserModel userThreeModel = ldap.authenticate("UserThree", "userThreePassword".toCharArray());
+ assertNotNull(userThreeModel);
+ assertNotNull(userThreeModel.getTeam("git_users"));
+ assertNull(userThreeModel.getTeam("git_admins"));
+ assertNull(userThreeModel.getTeam("git admins"));
+ assertFalse(userThreeModel.canAdmin);
+ assertFalse(userThreeModel.canAdmin());
+ assertFalse(userThreeModel.getTeam("git_users").canAdmin);
+
+ UserModel userFourModel = ldap.authenticate("UserFour", "userFourPassword".toCharArray());
+ assertNotNull(userFourModel);
+ assertNotNull(userFourModel.getTeam("git_users"));
+ assertNull(userFourModel.getTeam("git_admins"));
+ assertNull(userFourModel.getTeam("git admins"));
+ assertFalse(userFourModel.canAdmin);
+ assertFalse(userFourModel.canAdmin());
+ assertFalse(userFourModel.getTeam("git_users").canAdmin);
}
@Test
@@ -204,13 +445,13 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
@Test
public void checkIfUsersConfContainsAllUsersFromSampleDataLdif() throws Exception {
- SearchResult searchResult = ds.search("OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain", SearchScope.SUB, "objectClass=person");
+ SearchResult searchResult = getDS().search(ACCOUNT_BASE, SearchScope.SUB, "objectClass=person");
assertEquals("Number of ldap users in gitblit user model", searchResult.getEntryCount(), countLdapUsersInUserManager());
}
@Test
public void addingUserInLdapShouldNotUpdateGitBlitUsersAndGroups() throws Exception {
- ds.addEntries(LDIFReader.readEntries(RESOURCE_DIR + "adduser.ldif"));
+ getDS().addEntries(LDIFReader.readEntries(RESOURCE_DIR + "adduser.ldif"));
ldap.sync();
assertEquals("Number of ldap users in gitblit user model", 5, countLdapUsersInUserManager());
}
@@ -218,33 +459,126 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
@Test
public void addingUserInLdapShouldUpdateGitBlitUsersAndGroups() throws Exception {
settings.put(Keys.realm.ldap.synchronize, "true");
- ds.addEntries(LDIFReader.readEntries(RESOURCE_DIR + "adduser.ldif"));
+ getDS().addEntries(LDIFReader.readEntries(RESOURCE_DIR + "adduser.ldif"));
ldap.sync();
assertEquals("Number of ldap users in gitblit user model", 6, countLdapUsersInUserManager());
}
@Test
public void addingGroupsInLdapShouldNotUpdateGitBlitUsersAndGroups() throws Exception {
- ds.addEntries(LDIFReader.readEntries(RESOURCE_DIR + "addgroup.ldif"));
+ getDS().addEntries(LDIFReader.readEntries(RESOURCE_DIR + "addgroup.ldif"));
ldap.sync();
assertEquals("Number of ldap groups in gitblit team model", 0, countLdapTeamsInUserManager());
}
@Test
+ public void addingGroupsInLdapShouldUpdateGitBlitUsersNotGroups2() throws Exception {
+ settings.put(Keys.realm.ldap.synchronize, "true");
+ settings.put(Keys.realm.ldap.maintainTeams, "false");
+ getDS().addEntries(LDIFReader.readEntries(RESOURCE_DIR + "adduser.ldif"));
+ getDS().addEntries(LDIFReader.readEntries(RESOURCE_DIR + "addgroup.ldif"));
+ ldap.sync();
+ assertEquals("Number of ldap users in gitblit user model", 6, countLdapUsersInUserManager());
+ assertEquals("Number of ldap groups in gitblit team model", 0, countLdapTeamsInUserManager());
+ }
+
+ @Test
public void addingGroupsInLdapShouldUpdateGitBlitUsersAndGroups() throws Exception {
+ // This test only makes sense if the authentication mode allows for synchronization.
+ assumeTrue(authMode == AuthMode.ANONYMOUS || authMode == AuthMode.DS_MANAGER);
+
settings.put(Keys.realm.ldap.synchronize, "true");
- ds.addEntries(LDIFReader.readEntries(RESOURCE_DIR + "addgroup.ldif"));
+ getDS().addEntries(LDIFReader.readEntries(RESOURCE_DIR + "addgroup.ldif"));
ldap.sync();
assertEquals("Number of ldap groups in gitblit team model", 1, countLdapTeamsInUserManager());
}
@Test
+ public void syncUpdateUsersAndGroupsAdminProperty() throws Exception {
+ // This test only makes sense if the authentication mode allows for synchronization.
+ assumeTrue(authMode == AuthMode.ANONYMOUS || authMode == AuthMode.DS_MANAGER);
+
+ settings.put(Keys.realm.ldap.synchronize, "true");
+ ldap.sync();
+
+ UserModel user = userManager.getUserModel("UserOne");
+ assertNotNull(user);
+ assertFalse(user.canAdmin);
+ assertTrue(user.canAdmin());
+
+ user = userManager.getUserModel("UserTwo");
+ assertNotNull(user);
+ assertFalse(user.canAdmin);
+ assertTrue(user.canAdmin());
+
+ user = userManager.getUserModel("UserThree");
+ assertNotNull(user);
+ assertTrue(user.canAdmin);
+ assertTrue(user.canAdmin());
+
+ user = userManager.getUserModel("UserFour");
+ assertNotNull(user);
+ assertFalse(user.canAdmin);
+ assertFalse(user.canAdmin());
+
+ TeamModel team = userManager.getTeamModel("Git_Admins");
+ assertNotNull(team);
+ assertTrue(team.canAdmin);
+
+ team = userManager.getTeamModel("Git Admins");
+ assertNotNull(team);
+ assertTrue(team.canAdmin);
+
+ team = userManager.getTeamModel("Git_Users");
+ assertNotNull(team);
+ assertFalse(team.canAdmin);
+ }
+
+ @Test
+ public void syncNotUpdateUsersAndGroupsAdminProperty() throws Exception {
+ settings.put(Keys.realm.ldap.synchronize, "true");
+ settings.put(Keys.realm.ldap.maintainTeams, "false");
+ ldap.sync();
+
+ UserModel user = userManager.getUserModel("UserOne");
+ assertNotNull(user);
+ assertTrue(user.canAdmin);
+ assertTrue(user.canAdmin());
+
+ user = userManager.getUserModel("UserTwo");
+ assertNotNull(user);
+ assertFalse(user.canAdmin);
+ assertTrue(user.canAdmin());
+
+ user = userManager.getUserModel("UserThree");
+ assertNotNull(user);
+ assertFalse(user.canAdmin);
+ assertFalse(user.canAdmin());
+
+ user = userManager.getUserModel("UserFour");
+ assertNotNull(user);
+ assertFalse(user.canAdmin);
+ assertFalse(user.canAdmin());
+
+ TeamModel team = userManager.getTeamModel("Git_Admins");
+ assertNotNull(team);
+ assertFalse(team.canAdmin);
+
+ team = userManager.getTeamModel("Git Admins");
+ assertNotNull(team);
+ assertTrue(team.canAdmin);
+
+ team = userManager.getTeamModel("Git_Users");
+ assertNotNull(team);
+ assertFalse(team.canAdmin);
+ }
+
+ @Test
public void testAuthenticationManager() {
UserModel userOneModel = auth.authenticate("UserOne", "userOnePassword".toCharArray(), null);
assertNotNull(userOneModel);
assertNotNull(userOneModel.getTeam("git_admins"));
assertNotNull(userOneModel.getTeam("git_users"));
- assertTrue(userOneModel.canAdmin);
UserModel userOneModelFailedAuth = auth.authenticate("UserOne", "userTwoPassword".toCharArray(), null);
assertNull(userOneModelFailedAuth);
@@ -254,18 +588,115 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
assertNotNull(userTwoModel.getTeam("git_users"));
assertNull(userTwoModel.getTeam("git_admins"));
assertNotNull(userTwoModel.getTeam("git admins"));
- assertTrue(userTwoModel.canAdmin);
UserModel userThreeModel = auth.authenticate("UserThree", "userThreePassword".toCharArray(), null);
assertNotNull(userThreeModel);
assertNotNull(userThreeModel.getTeam("git_users"));
assertNull(userThreeModel.getTeam("git_admins"));
+
+ UserModel userFourModel = auth.authenticate("UserFour", "userFourPassword".toCharArray(), null);
+ assertNotNull(userFourModel);
+ assertNotNull(userFourModel.getTeam("git_users"));
+ assertNull(userFourModel.getTeam("git_admins"));
+ assertNull(userFourModel.getTeam("git admins"));
+ }
+
+ @Test
+ public void testAuthenticationManagerAdminPropertyTeamsInLdap() {
+ UserModel userOneModel = auth.authenticate("UserOne", "userOnePassword".toCharArray(), null);
+ assertNotNull(userOneModel);
+ assertNotNull(userOneModel.getTeam("git_admins"));
+ assertNull(userOneModel.getTeam("git admins"));
+ assertNotNull(userOneModel.getTeam("git_users"));
+ assertFalse(userOneModel.canAdmin);
+ assertTrue(userOneModel.canAdmin());
+ assertTrue(userOneModel.getTeam("git_admins").canAdmin);
+ assertFalse(userOneModel.getTeam("git_users").canAdmin);
+
+ UserModel userOneModelFailedAuth = auth.authenticate("UserOne", "userTwoPassword".toCharArray(), null);
+ assertNull(userOneModelFailedAuth);
+
+ UserModel userTwoModel = auth.authenticate("UserTwo", "userTwoPassword".toCharArray(), null);
+ assertNotNull(userTwoModel);
+ assertNotNull(userTwoModel.getTeam("git_users"));
+ assertNull(userTwoModel.getTeam("git_admins"));
+ assertNotNull(userTwoModel.getTeam("git admins"));
+ assertFalse(userTwoModel.canAdmin);
+ assertTrue(userTwoModel.canAdmin());
+ assertTrue(userTwoModel.getTeam("git admins").canAdmin);
+ assertFalse(userTwoModel.getTeam("git_users").canAdmin);
+
+ UserModel userThreeModel = auth.authenticate("UserThree", "userThreePassword".toCharArray(), null);
+ assertNotNull(userThreeModel);
+ assertNotNull(userThreeModel.getTeam("git_users"));
+ assertNull(userThreeModel.getTeam("git_admins"));
+ assertNull(userThreeModel.getTeam("git admins"));
assertTrue(userThreeModel.canAdmin);
+ assertTrue(userThreeModel.canAdmin());
+ assertFalse(userThreeModel.getTeam("git_users").canAdmin);
+
+ UserModel userFourModel = auth.authenticate("UserFour", "userFourPassword".toCharArray(), null);
+ assertNotNull(userFourModel);
+ assertNotNull(userFourModel.getTeam("git_users"));
+ assertNull(userFourModel.getTeam("git_admins"));
+ assertNull(userFourModel.getTeam("git admins"));
+ assertFalse(userFourModel.canAdmin);
+ assertFalse(userFourModel.canAdmin());
+ assertFalse(userFourModel.getTeam("git_users").canAdmin);
+ }
+
+ @Test
+ public void testAuthenticationManagerAdminPropertyTeamsNotInLdap() {
+ settings.put(Keys.realm.ldap.maintainTeams, "false");
+
+ UserModel userOneModel = auth.authenticate("UserOne", "userOnePassword".toCharArray(), null);
+ assertNotNull(userOneModel);
+ assertNotNull(userOneModel.getTeam("git_admins"));
+ assertNull(userOneModel.getTeam("git admins"));
+ assertNotNull(userOneModel.getTeam("git_users"));
+ assertTrue(userOneModel.canAdmin);
+ assertTrue(userOneModel.canAdmin());
+ assertFalse(userOneModel.getTeam("git_admins").canAdmin);
+ assertFalse(userOneModel.getTeam("git_users").canAdmin);
+
+ UserModel userOneModelFailedAuth = auth.authenticate("UserOne", "userTwoPassword".toCharArray(), null);
+ assertNull(userOneModelFailedAuth);
+
+ UserModel userTwoModel = auth.authenticate("UserTwo", "userTwoPassword".toCharArray(), null);
+ assertNotNull(userTwoModel);
+ assertNotNull(userTwoModel.getTeam("git_users"));
+ assertNull(userTwoModel.getTeam("git_admins"));
+ assertNotNull(userTwoModel.getTeam("git admins"));
+ assertFalse(userTwoModel.canAdmin);
+ assertTrue(userTwoModel.canAdmin());
+ assertTrue(userTwoModel.getTeam("git admins").canAdmin);
+ assertFalse(userTwoModel.getTeam("git_users").canAdmin);
+
+ UserModel userThreeModel = auth.authenticate("UserThree", "userThreePassword".toCharArray(), null);
+ assertNotNull(userThreeModel);
+ assertNotNull(userThreeModel.getTeam("git_users"));
+ assertNull(userThreeModel.getTeam("git_admins"));
+ assertNull(userThreeModel.getTeam("git admins"));
+ assertFalse(userThreeModel.canAdmin);
+ assertFalse(userThreeModel.canAdmin());
+ assertFalse(userThreeModel.getTeam("git_users").canAdmin);
+
+ UserModel userFourModel = auth.authenticate("UserFour", "userFourPassword".toCharArray(), null);
+ assertNotNull(userFourModel);
+ assertNotNull(userFourModel.getTeam("git_users"));
+ assertNull(userFourModel.getTeam("git_admins"));
+ assertNull(userFourModel.getTeam("git admins"));
+ assertFalse(userFourModel.canAdmin);
+ assertFalse(userFourModel.canAdmin());
+ assertFalse(userFourModel.getTeam("git_users").canAdmin);
}
@Test
public void testBindWithUser() {
- settings.put(Keys.realm.ldap.bindpattern, "CN=${username},OU=US,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain");
+ // This test only makes sense if the user is not prevented from reading users and teams.
+ assumeTrue(authMode != AuthMode.DS_MANAGER);
+
+ settings.put(Keys.realm.ldap.bindpattern, "CN=${username},OU=US," + ACCOUNT_BASE);
settings.put(Keys.realm.ldap.username, "");
settings.put(Keys.realm.ldap.password, "");
@@ -276,6 +707,12 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
assertNull(userOneModelFailedAuth);
}
+
+ private InMemoryDirectoryServer getDS()
+ {
+ return authMode.getDS();
+ }
+
private int countLdapUsersInUserManager() {
int ldapAccountCount = 0;
for (UserModel userModel : userManager.getAllUsers()) {
@@ -296,4 +733,120 @@ public class LdapAuthenticationTest extends GitblitUnitTest {
return ldapAccountCount;
}
+
+
+
+ /**
+ * Operation interceptor for the in memory DS. This interceptor
+ * implements access restrictions for certain user/DN combinations.
+ *
+ * The USER_MANAGER is only allowed to search for users, but not for groups.
+ * This is to test the original behaviour where the teams were searched under
+ * the user binding.
+ * When running in a DIRECTORY_MANAGER scenario, only the manager account
+ * is allowed to search for users and groups, while a normal user may not do so.
+ * This tests the scenario where a normal user cannot read teams and thus the
+ * manager account needs to be used for all searches.
+ *
+ */
+ private static class AccessInterceptor extends InMemoryOperationInterceptor {
+ AuthMode authMode;
+ Map<Long,String> lastSuccessfulBindDN = new HashMap<>();
+ Map<Long,Boolean> resultProhibited = new HashMap<>();
+
+ public AccessInterceptor(AuthMode authMode) {
+ this.authMode = authMode;
+ }
+
+
+ @Override
+ public void processSimpleBindResult(InMemoryInterceptedSimpleBindResult bind) {
+ BindResult result = bind.getResult();
+ if (result.getResultCode() == ResultCode.SUCCESS) {
+ BindRequest bindRequest = bind.getRequest();
+ lastSuccessfulBindDN.put(bind.getConnectionID(), ((SimpleBindRequest)bindRequest).getBindDN());
+ resultProhibited.remove(bind.getConnectionID());
+ }
+ }
+
+
+
+ @Override
+ public void processSearchRequest(InMemoryInterceptedSearchRequest request) throws LDAPException {
+ String bindDN = getLastBindDN(request);
+
+ if (USER_MANAGER.equals(bindDN)) {
+ if (request.getRequest().getBaseDN().endsWith(GROUP_BASE)) {
+ throw new LDAPException(ResultCode.NO_SUCH_OBJECT);
+ }
+ }
+ else if(authMode == AuthMode.DS_MANAGER && !DIRECTORY_MANAGER.equals(bindDN)) {
+ throw new LDAPException(ResultCode.NO_SUCH_OBJECT);
+ }
+ }
+
+
+ @Override
+ public void processSearchEntry(InMemoryInterceptedSearchEntry entry) {
+ String bindDN = getLastBindDN(entry);
+
+ boolean prohibited = false;
+
+ if (USER_MANAGER.equals(bindDN)) {
+ if (entry.getSearchEntry().getDN().endsWith(GROUP_BASE)) {
+ prohibited = true;
+ }
+ }
+ else if(authMode == AuthMode.DS_MANAGER && !DIRECTORY_MANAGER.equals(bindDN)) {
+ prohibited = true;
+ }
+
+ if (prohibited) {
+ // Found entry prohibited for bound user. Setting entry to null.
+ entry.setSearchEntry(null);
+ resultProhibited.put(entry.getConnectionID(), Boolean.TRUE);
+ }
+ }
+
+ @Override
+ public void processSearchResult(InMemoryInterceptedSearchResult result) {
+ String bindDN = getLastBindDN(result);
+
+ boolean prohibited = false;
+
+ Boolean rspb = resultProhibited.get(result.getConnectionID());
+ if (USER_MANAGER.equals(bindDN)) {
+ if (rspb != null && rspb) {
+ prohibited = true;
+ }
+ }
+ else if(authMode == AuthMode.DS_MANAGER && !DIRECTORY_MANAGER.equals(bindDN)) {
+ if (rspb != null && rspb) {
+ prohibited = true;
+ }
+ }
+
+ if (prohibited) {
+ // Result prohibited for bound user. Returning error
+ result.setResult(new LDAPResult(result.getMessageID(), ResultCode.INSUFFICIENT_ACCESS_RIGHTS));
+ resultProhibited.remove(result.getConnectionID());
+ }
+ }
+
+ private String getLastBindDN(InMemoryInterceptedResult result) {
+ String bindDN = lastSuccessfulBindDN.get(result.getConnectionID());
+ if (bindDN == null) {
+ return "UNKNOWN";
+ }
+ return bindDN;
+ }
+ private String getLastBindDN(InMemoryInterceptedRequest request) {
+ String bindDN = lastSuccessfulBindDN.get(request.getConnectionID());
+ if (bindDN == null) {
+ return "UNKNOWN";
+ }
+ return bindDN;
+ }
+ }
+
}
diff --git a/src/test/java/com/gitblit/tests/MarkdownUtilsTest.java b/src/test/java/com/gitblit/tests/MarkdownUtilsTest.java
index e40f1057..bc7aad49 100644
--- a/src/test/java/com/gitblit/tests/MarkdownUtilsTest.java
+++ b/src/test/java/com/gitblit/tests/MarkdownUtilsTest.java
@@ -15,8 +15,14 @@
*/
package com.gitblit.tests;
+import java.util.HashMap;
+import java.util.Map;
+
import org.junit.Test;
+import com.gitblit.IStoredSettings;
+import com.gitblit.Keys;
+import com.gitblit.tests.mock.MemorySettings;
import com.gitblit.utils.MarkdownUtils;
public class MarkdownUtilsTest extends GitblitUnitTest {
@@ -39,4 +45,70 @@ public class MarkdownUtilsTest extends GitblitUnitTest {
assertEquals("<table><tr><td>&lt;test&gt;</td></tr></table>",
MarkdownUtils.transformMarkdown("<table><tr><td>&lt;test&gt;</td></tr></table>"));
}
-} \ No newline at end of file
+
+
+ @Test
+ public void testUserMentions() {
+ IStoredSettings settings = getSettings();
+ String repositoryName = "test3";
+ String mentionHtml = "<strong><a href=\"http://localhost/user/%1$s\">@%1$s</a></strong>";
+
+ String input = "@j.doe";
+ String output = "<p>" + String.format(mentionHtml, "j.doe") + "</p>";
+ assertEquals(output, MarkdownUtils.transformGFM(settings, input, repositoryName));
+
+ input = " @j.doe";
+ output = "<p>" + String.format(mentionHtml, "j.doe") + "</p>";
+ assertEquals(output, MarkdownUtils.transformGFM(settings, input, repositoryName));
+
+ input = "@j.doe.";
+ output = "<p>" + String.format(mentionHtml, "j.doe") + ".</p>";
+ assertEquals(output, MarkdownUtils.transformGFM(settings, input, repositoryName));
+
+ input = "To @j.doe: ask @jim.beam!";
+ output = "<p>To " + String.format(mentionHtml, "j.doe")
+ + ": ask " + String.format(mentionHtml, "jim.beam") + "!</p>";
+ assertEquals(output, MarkdownUtils.transformGFM(settings, input, repositoryName));
+
+ input = "@sta.rt\n"
+ + "\n"
+ + "User mentions in tickets are broken.\n"
+ + "So:\n"
+ + "@mc_guyver can fix this.\n"
+ + "@j.doe, can you test after the fix by @m+guyver?\n"
+ + "Please review this, @jim.beam!\n"
+ + "Was reported by @jill and @j!doe from jane@doe yesterday.\n"
+ + "\n"
+ + "@jack.daniels can vote for john@wayne.name hopefully.\n"
+ + "@en.de";
+ output = "<p>" + String.format(mentionHtml, "sta.rt") + "</p>"
+ + "<p>" + "User mentions in tickets are broken.<br/>"
+ + "So:<br/>"
+ + String.format(mentionHtml, "mc_guyver") + " can fix this.<br/>"
+ + String.format(mentionHtml, "j.doe") + ", can you test after the fix by " + String.format(mentionHtml, "m+guyver") + "?<br/>"
+ + "Please review this, " + String.format(mentionHtml, "jim.beam") + "!<br/>"
+ + "Was reported by " + String.format(mentionHtml, "jill")
+ + " and " + String.format(mentionHtml, "j!doe")
+ + " from <a href=\"mailto:&#106;a&#110;&#x65;&#x40;&#x64;&#x6f;&#101;\">&#106;a&#110;&#x65;&#x40;&#x64;&#x6f;&#101;</a> yesterday."
+ + "</p>"
+ + "<p>" + String.format(mentionHtml, "jack.daniels") + " can vote for "
+ + "<a href=\"mailto:&#x6a;&#x6f;h&#110;&#x40;&#119;a&#121;&#110;&#101;.&#110;a&#x6d;&#101;\">&#x6a;&#x6f;h&#110;&#x40;&#119;a&#121;&#110;&#101;.&#110;a&#x6d;&#101;</a> hopefully.<br/>"
+ + String.format(mentionHtml, "en.de")
+ + "</p>";
+ assertEquals(output, MarkdownUtils.transformGFM(settings, input, repositoryName));
+
+ }
+
+
+
+
+ private MemorySettings getSettings() {
+ Map<String, Object> backingMap = new HashMap<String, Object>();
+
+ backingMap.put(Keys.web.canonicalUrl, "http://localhost");
+ backingMap.put(Keys.web.shortCommitIdLength, "7");
+
+ MemorySettings ms = new MemorySettings(backingMap);
+ return ms;
+ }
+}
diff --git a/src/test/resources/ldap/users.conf b/src/test/resources/ldap/users.conf
index 7d1e3197..a2390fa9 100644
--- a/src/test/resources/ldap/users.conf
+++ b/src/test/resources/ldap/users.conf
@@ -10,7 +10,7 @@
displayName = Mrs. User Three
emailAddress = userthree@gitblit.com
accountType = LDAP
- role = "#admin"
+ role = "#none"
[user "userfive"]
password = "#externalAccount"
cookie = 220bafef069b8b399b2597644015b6b0f4667982
@@ -31,7 +31,7 @@
displayName = Mr. User Two
emailAddress = usertwo@gitblit.com
accountType = LDAP
- role = "#admin"
+ role = "#none"
[user "basic"]
password = MD5:f17aaabc20bfe045075927934fed52d2
cookie = dd94709528bb1c83d08f3088d4043f4742891f4f
@@ -63,6 +63,6 @@
user = userthree
user = userfour
[team "Git Admins"]
- role = "#none"
+ role = "#admin"
accountType = LOCAL
user = usertwo