From 04a98505a4ab8f48aee22800fcac193d9367d0ae Mon Sep 17 00:00:00 2001 From: James Moger Date: Sun, 24 Nov 2013 23:18:50 -0500 Subject: Refactor user services and separate authentication (issue-281) Change-Id: I336e005e02623fc5e11a4f8b4408bea5465a43fd --- src/test/java/com/gitblit/tests/GitBlitSuite.java | 4 +- src/test/java/com/gitblit/tests/GitBlitTest.java | 2 +- .../java/com/gitblit/tests/GitblitUnitTest.java | 6 +- .../gitblit/tests/HtpasswdAuthenticationTest.java | 365 +++++++++++++ .../com/gitblit/tests/HtpasswdUserServiceTest.java | 569 --------------------- .../com/gitblit/tests/LdapAuthenticationTest.java | 165 ++++++ .../com/gitblit/tests/LdapUserServiceTest.java | 170 ------ .../gitblit/tests/RedmineAuthenticationTest.java | 65 +++ .../com/gitblit/tests/RedmineUserServiceTest.java | 66 --- .../java/com/gitblit/tests/UserServiceTest.java | 7 +- .../tests/resources/ldapUserServiceSampleData.ldif | 108 ---- 11 files changed, 602 insertions(+), 925 deletions(-) create mode 100644 src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java delete mode 100644 src/test/java/com/gitblit/tests/HtpasswdUserServiceTest.java create mode 100644 src/test/java/com/gitblit/tests/LdapAuthenticationTest.java delete mode 100644 src/test/java/com/gitblit/tests/LdapUserServiceTest.java create mode 100644 src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java delete mode 100644 src/test/java/com/gitblit/tests/RedmineUserServiceTest.java delete mode 100644 src/test/java/com/gitblit/tests/resources/ldapUserServiceSampleData.ldif (limited to 'src/test/java/com/gitblit') diff --git a/src/test/java/com/gitblit/tests/GitBlitSuite.java b/src/test/java/com/gitblit/tests/GitBlitSuite.java index 7fc6fe0e..81180276 100644 --- a/src/test/java/com/gitblit/tests/GitBlitSuite.java +++ b/src/test/java/com/gitblit/tests/GitBlitSuite.java @@ -56,12 +56,12 @@ import com.gitblit.utils.JGitUtils; @RunWith(Suite.class) @SuiteClasses({ ArrayUtilsTest.class, FileUtilsTest.class, TimeUtilsTest.class, StringUtilsTest.class, Base64Test.class, JsonUtilsTest.class, ByteFormatTest.class, - ObjectCacheTest.class, PermissionsTest.class, UserServiceTest.class, LdapUserServiceTest.class, + ObjectCacheTest.class, PermissionsTest.class, UserServiceTest.class, LdapAuthenticationTest.class, MarkdownUtilsTest.class, JGitUtilsTest.class, SyndicationUtilsTest.class, DiffUtilsTest.class, MetricUtilsTest.class, X509UtilsTest.class, GitBlitTest.class, FederationTests.class, RpcTests.class, GitServletTest.class, GitDaemonTest.class, GroovyScriptTest.class, LuceneExecutorTest.class, RepositoryModelTest.class, - FanoutServiceTest.class, Issue0259Test.class, Issue0271Test.class, HtpasswdUserServiceTest.class, + FanoutServiceTest.class, Issue0259Test.class, Issue0271Test.class, HtpasswdAuthenticationTest.class, ModelUtilsTest.class, JnaUtilsTest.class }) public class GitBlitSuite { diff --git a/src/test/java/com/gitblit/tests/GitBlitTest.java b/src/test/java/com/gitblit/tests/GitBlitTest.java index d3913513..c01862fe 100644 --- a/src/test/java/com/gitblit/tests/GitBlitTest.java +++ b/src/test/java/com/gitblit/tests/GitBlitTest.java @@ -172,7 +172,7 @@ public class GitBlitTest extends GitblitUnitTest { @Test public void testAuthentication() throws Exception { - assertTrue(session().authenticate("admin", "admin".toCharArray()) != null); + assertTrue(authentication().authenticate("admin", "admin".toCharArray()) != null); } @Test diff --git a/src/test/java/com/gitblit/tests/GitblitUnitTest.java b/src/test/java/com/gitblit/tests/GitblitUnitTest.java index 500e9b9f..1885f127 100644 --- a/src/test/java/com/gitblit/tests/GitblitUnitTest.java +++ b/src/test/java/com/gitblit/tests/GitblitUnitTest.java @@ -22,7 +22,7 @@ import com.gitblit.manager.INotificationManager; import com.gitblit.manager.IProjectManager; import com.gitblit.manager.IRepositoryManager; import com.gitblit.manager.IRuntimeManager; -import com.gitblit.manager.ISessionManager; +import com.gitblit.manager.IAuthenticationManager; import com.gitblit.manager.IUserManager; import com.gitblit.servlet.GitblitContext; @@ -45,8 +45,8 @@ public class GitblitUnitTest extends org.junit.Assert { return GitblitContext.getManager(IUserManager.class); } - public static ISessionManager session() { - return GitblitContext.getManager(ISessionManager.class); + public static IAuthenticationManager authentication() { + return GitblitContext.getManager(IAuthenticationManager.class); } public static IRepositoryManager repositories() { diff --git a/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java b/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java new file mode 100644 index 00000000..3b1d51e1 --- /dev/null +++ b/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java @@ -0,0 +1,365 @@ +/* + * 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.tests; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.HashMap; + +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.gitblit.IStoredSettings; +import com.gitblit.auth.HtpasswdAuthProvider; +import com.gitblit.manager.RuntimeManager; +import com.gitblit.manager.UserManager; +import com.gitblit.models.UserModel; +import com.gitblit.tests.mock.MemorySettings; + +/** + * Test the Htpasswd user service. + * + */ +public class HtpasswdAuthenticationTest extends GitblitUnitTest { + + private static final String RESOURCE_DIR = "src/test/resources/htpasswd/"; + private static final String KEY_SUPPORT_PLAINTEXT_PWD = "realm.htpasswd.supportPlaintextPasswords"; + + private static final int NUM_USERS_HTPASSWD = 10; + + private static final MemorySettings MS = new MemorySettings(new HashMap()); + + private HtpasswdAuthProvider htpasswd; + + + private MemorySettings getSettings(String userfile, String groupfile, Boolean overrideLA) + { + MS.put("realm.userService", RESOURCE_DIR + "users.conf"); + MS.put("realm.htpasswd.userfile", (userfile == null) ? (RESOURCE_DIR + "htpasswd") : userfile); + MS.put("realm.htpasswd.groupfile", (groupfile == null) ? (RESOURCE_DIR + "htgroup") : groupfile); + MS.put("realm.htpasswd.overrideLocalAuthentication", (overrideLA == null) ? "false" : overrideLA.toString()); + // Default to keep test the same on all platforms. + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); + + return MS; + } + + private MemorySettings getSettings() + { + return getSettings(null, null, null); + } + + private void setupUS() + { + htpasswd = newHtpasswdAuthentication(getSettings()); + } + + private HtpasswdAuthProvider newHtpasswdAuthentication(IStoredSettings settings) { + RuntimeManager runtime = new RuntimeManager(settings, GitBlitSuite.BASEFOLDER).start(); + UserManager users = new UserManager(runtime).start(); + HtpasswdAuthProvider htpasswd = new HtpasswdAuthProvider(); + htpasswd.setup(runtime, users); + return htpasswd; + } + + + private void copyInFiles() throws IOException + { + File dir = new File(RESOURCE_DIR); + FilenameFilter filter = new FilenameFilter() { + @Override + public boolean accept(File dir, String file) { + return file.endsWith(".in"); + } + }; + for (File inf : dir.listFiles(filter)) { + File dest = new File(inf.getParent(), inf.getName().substring(0, inf.getName().length() - 3)); + FileUtils.copyFile(inf, dest); + } + } + + + private void deleteGeneratedFiles() + { + File dir = new File(RESOURCE_DIR); + FilenameFilter filter = new FilenameFilter() { + @Override + public boolean accept(File dir, String file) { + return !(file.endsWith(".in")); + } + }; + for (File file : dir.listFiles(filter)) { + file.delete(); + } + } + + + @Before + public void setup() throws IOException + { + copyInFiles(); + setupUS(); + } + + + @After + public void tearDown() + { + deleteGeneratedFiles(); + } + + + + @Test + public void testSetup() throws IOException + { + assertEquals(NUM_USERS_HTPASSWD, htpasswd.getNumberHtpasswdUsers()); + } + + + @Test + public void testAuthenticate() + { + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); + UserModel user = htpasswd.authenticate("user1", "pass1".toCharArray()); + assertNotNull(user); + assertEquals("user1", user.username); + + user = htpasswd.authenticate("user2", "pass2".toCharArray()); + assertNotNull(user); + assertEquals("user2", user.username); + + // Test different encryptions + user = htpasswd.authenticate("plain", "passWord".toCharArray()); + assertNotNull(user); + assertEquals("plain", user.username); + + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); + user = htpasswd.authenticate("crypt", "password".toCharArray()); + assertNotNull(user); + assertEquals("crypt", user.username); + + user = htpasswd.authenticate("md5", "password".toCharArray()); + assertNotNull(user); + assertEquals("md5", user.username); + + user = htpasswd.authenticate("sha", "password".toCharArray()); + assertNotNull(user); + assertEquals("sha", user.username); + + + // Test leading and trailing whitespace + user = htpasswd.authenticate("trailing", "whitespace".toCharArray()); + assertNotNull(user); + assertEquals("trailing", user.username); + + user = htpasswd.authenticate("tabbed", "frontAndBack".toCharArray()); + assertNotNull(user); + assertEquals("tabbed", user.username); + + user = htpasswd.authenticate("leading", "whitespace".toCharArray()); + assertNotNull(user); + assertEquals("leading", user.username); + } + + + @Test + public void testAttributes() + { + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); + UserModel user = htpasswd.authenticate("user1", "pass1".toCharArray()); + assertNotNull(user); + assertEquals("El Capitan", user.displayName); + assertEquals("cheffe@example.com", user.emailAddress); + assertTrue(user.canAdmin); + + user = htpasswd.authenticate("user2", "pass2".toCharArray()); + assertNotNull(user); + assertEquals("User Two", user.displayName); + assertTrue(user.canCreate); + assertTrue(user.canFork); + } + + + @Test + public void testAuthenticateDenied() + { + UserModel user = null; + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); + user = htpasswd.authenticate("user1", "".toCharArray()); + assertNull("User 'user1' falsely authenticated.", user); + + user = htpasswd.authenticate("user1", "pass2".toCharArray()); + assertNull("User 'user1' falsely authenticated.", user); + + user = htpasswd.authenticate("user2", "lalala".toCharArray()); + assertNull("User 'user2' falsely authenticated.", user); + + + user = htpasswd.authenticate("user3", "disabled".toCharArray()); + assertNull("User 'user3' falsely authenticated.", user); + + user = htpasswd.authenticate("user4", "disabled".toCharArray()); + assertNull("User 'user4' falsely authenticated.", user); + + + user = htpasswd.authenticate("plain", "text".toCharArray()); + assertNull("User 'plain' falsely authenticated.", user); + + user = htpasswd.authenticate("plain", "password".toCharArray()); + assertNull("User 'plain' falsely authenticated.", user); + + + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); + + user = htpasswd.authenticate("crypt", "".toCharArray()); + assertNull("User 'cyrpt' falsely authenticated.", user); + + user = htpasswd.authenticate("crypt", "passwd".toCharArray()); + assertNull("User 'crypt' falsely authenticated.", user); + + user = htpasswd.authenticate("md5", "".toCharArray()); + assertNull("User 'md5' falsely authenticated.", user); + + user = htpasswd.authenticate("md5", "pwd".toCharArray()); + assertNull("User 'md5' falsely authenticated.", user); + + user = htpasswd.authenticate("sha", "".toCharArray()); + assertNull("User 'sha' falsely authenticated.", user); + + user = htpasswd.authenticate("sha", "letmein".toCharArray()); + assertNull("User 'sha' falsely authenticated.", user); + + + user = htpasswd.authenticate(" tabbed", "frontAndBack".toCharArray()); + assertNull("User 'tabbed' falsely authenticated.", user); + + user = htpasswd.authenticate(" leading", "whitespace".toCharArray()); + assertNull("User 'leading' falsely authenticated.", user); + } + + + @Test + public void testCleartextIntrusion() + { + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); + assertNull(htpasswd.authenticate("md5", "$apr1$qAGGNfli$sAn14mn.WKId/3EQS7KSX0".toCharArray())); + assertNull(htpasswd.authenticate("sha", "{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=".toCharArray())); + + assertNull(htpasswd.authenticate("user1", "#externalAccount".toCharArray())); + + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); + assertNull(htpasswd.authenticate("md5", "$apr1$qAGGNfli$sAn14mn.WKId/3EQS7KSX0".toCharArray())); + assertNull(htpasswd.authenticate("sha", "{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=".toCharArray())); + + assertNull(htpasswd.authenticate("user1", "#externalAccount".toCharArray())); + } + + + @Test + public void testCryptVsPlaintext() + { + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); + assertNull(htpasswd.authenticate("crypt", "6TmlbxqZ2kBIA".toCharArray())); + assertNotNull(htpasswd.authenticate("crypt", "password".toCharArray())); + + MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); + assertNotNull(htpasswd.authenticate("crypt", "6TmlbxqZ2kBIA".toCharArray())); + assertNull(htpasswd.authenticate("crypt", "password".toCharArray())); + } + + @Test + public void testChangeHtpasswdFile() + { + UserModel user; + + // User default set up. + user = htpasswd.authenticate("md5", "password".toCharArray()); + assertNotNull(user); + assertEquals("md5", user.username); + + user = htpasswd.authenticate("sha", "password".toCharArray()); + assertNotNull(user); + assertEquals("sha", user.username); + + user = htpasswd.authenticate("blueone", "GoBlue!".toCharArray()); + assertNull(user); + + user = htpasswd.authenticate("bluetwo", "YayBlue!".toCharArray()); + assertNull(user); + + + // Switch to different htpasswd file. + getSettings(RESOURCE_DIR + "htpasswd-user", null, null); + + user = htpasswd.authenticate("md5", "password".toCharArray()); + assertNull(user); + + user = htpasswd.authenticate("sha", "password".toCharArray()); + assertNull(user); + + user = htpasswd.authenticate("blueone", "GoBlue!".toCharArray()); + assertNotNull(user); + assertEquals("blueone", user.username); + + user = htpasswd.authenticate("bluetwo", "YayBlue!".toCharArray()); + assertNotNull(user); + assertEquals("bluetwo", user.username); + } + + + @Test + public void testChangeHtpasswdFileNotExisting() + { + UserModel user; + + // User default set up. + user = htpasswd.authenticate("md5", "password".toCharArray()); + assertNotNull(user); + assertEquals("md5", user.username); + + user = htpasswd.authenticate("sha", "password".toCharArray()); + assertNotNull(user); + assertEquals("sha", user.username); + + user = htpasswd.authenticate("blueone", "GoBlue!".toCharArray()); + assertNull(user); + + user = htpasswd.authenticate("bluetwo", "YayBlue!".toCharArray()); + assertNull(user); + + + // Switch to different htpasswd file that doesn't exist. + // Currently we stop working with old users upon this change. + getSettings(RESOURCE_DIR + "no-such-file", null, null); + + user = htpasswd.authenticate("md5", "password".toCharArray()); + assertNull(user); + + user = htpasswd.authenticate("sha", "password".toCharArray()); + assertNull(user); + + user = htpasswd.authenticate("blueone", "GoBlue!".toCharArray()); + assertNull(user); + + user = htpasswd.authenticate("bluetwo", "YayBlue!".toCharArray()); + assertNull(user); + } + +} diff --git a/src/test/java/com/gitblit/tests/HtpasswdUserServiceTest.java b/src/test/java/com/gitblit/tests/HtpasswdUserServiceTest.java deleted file mode 100644 index 282debb3..00000000 --- a/src/test/java/com/gitblit/tests/HtpasswdUserServiceTest.java +++ /dev/null @@ -1,569 +0,0 @@ -/* - * 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.tests; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.HashMap; - -import org.apache.commons.io.FileUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.gitblit.HtpasswdUserService; -import com.gitblit.models.UserModel; -import com.gitblit.tests.mock.MemorySettings; -import com.gitblit.tests.mock.MockRuntimeManager; -import com.gitblit.utils.StringUtils; - -/** - * Test the Htpasswd user service. - * - */ -public class HtpasswdUserServiceTest extends GitblitUnitTest { - - private static final String RESOURCE_DIR = "src/test/resources/htpasswdUSTest/"; - private static final String KEY_SUPPORT_PLAINTEXT_PWD = "realm.htpasswd.supportPlaintextPasswords"; - - private static final int NUM_USERS_HTPASSWD = 10; - - private static final MemorySettings MS = new MemorySettings(new HashMap()); - - private HtpasswdUserService htpwdUserService; - - - private MemorySettings getSettings( String userfile, String groupfile, Boolean overrideLA) - { - MS.put("realm.htpasswd.backingUserService", RESOURCE_DIR + "users.conf"); - MS.put("realm.htpasswd.userfile", (userfile == null) ? (RESOURCE_DIR+"htpasswd") : userfile); - MS.put("realm.htpasswd.groupfile", (groupfile == null) ? (RESOURCE_DIR+"htgroup") : groupfile); - MS.put("realm.htpasswd.overrideLocalAuthentication", (overrideLA == null) ? "false" : overrideLA.toString()); - // Default to keep test the same on all platforms. - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); - - return MS; - } - - private MemorySettings getSettings() - { - return getSettings(null, null, null); - } - - private MemorySettings getSettings(boolean overrideLA) - { - return getSettings(null, null, new Boolean(overrideLA)); - } - - - private void setupUS() - { - htpwdUserService = new HtpasswdUserService(); - htpwdUserService.setup(new MockRuntimeManager(getSettings())); - } - - private void setupUS(boolean overrideLA) - { - htpwdUserService = new HtpasswdUserService(); - htpwdUserService.setup(new MockRuntimeManager(getSettings(overrideLA))); - } - - - private void copyInFiles() throws IOException - { - File dir = new File(RESOURCE_DIR); - FilenameFilter filter = new FilenameFilter() { - @Override - public boolean accept(File dir, String file) { - return file.endsWith(".in"); - } - }; - for (File inf : dir.listFiles(filter)) { - File dest = new File(inf.getParent(), inf.getName().substring(0, inf.getName().length()-3)); - FileUtils.copyFile(inf, dest); - } - } - - - private void deleteGeneratedFiles() - { - File dir = new File(RESOURCE_DIR); - FilenameFilter filter = new FilenameFilter() { - @Override - public boolean accept(File dir, String file) { - return !(file.endsWith(".in")); - } - }; - for (File file : dir.listFiles(filter)) { - file.delete(); - } - } - - - @Before - public void setup() throws IOException - { - copyInFiles(); - setupUS(); - } - - - @After - public void tearDown() - { - deleteGeneratedFiles(); - } - - - - @Test - public void testSetup() throws IOException - { - assertEquals(NUM_USERS_HTPASSWD, htpwdUserService.getNumberHtpasswdUsers()); - } - - - @Test - public void testAuthenticate() - { - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); - UserModel user = htpwdUserService.authenticate("user1", "pass1".toCharArray()); - assertNotNull(user); - assertEquals("user1", user.username); - - user = htpwdUserService.authenticate("user2", "pass2".toCharArray()); - assertNotNull(user); - assertEquals("user2", user.username); - - // Test different encryptions - user = htpwdUserService.authenticate("plain", "passWord".toCharArray()); - assertNotNull(user); - assertEquals("plain", user.username); - - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); - user = htpwdUserService.authenticate("crypt", "password".toCharArray()); - assertNotNull(user); - assertEquals("crypt", user.username); - - user = htpwdUserService.authenticate("md5", "password".toCharArray()); - assertNotNull(user); - assertEquals("md5", user.username); - - user = htpwdUserService.authenticate("sha", "password".toCharArray()); - assertNotNull(user); - assertEquals("sha", user.username); - - - // Test leading and trailing whitespace - user = htpwdUserService.authenticate("trailing", "whitespace".toCharArray()); - assertNotNull(user); - assertEquals("trailing", user.username); - - user = htpwdUserService.authenticate("tabbed", "frontAndBack".toCharArray()); - assertNotNull(user); - assertEquals("tabbed", user.username); - - user = htpwdUserService.authenticate("leading", "whitespace".toCharArray()); - assertNotNull(user); - assertEquals("leading", user.username); - - - // Test local account - user = htpwdUserService.authenticate("admin", "admin".toCharArray()); - assertNotNull(user); - assertEquals("admin", user.username); - } - - - @Test - public void testAttributes() - { - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); - UserModel user = htpwdUserService.authenticate("user1", "pass1".toCharArray()); - assertNotNull(user); - assertEquals("El Capitan", user.displayName); - assertEquals("cheffe@example.com", user.emailAddress); - assertTrue(user.canAdmin); - - user = htpwdUserService.authenticate("user2", "pass2".toCharArray()); - assertNotNull(user); - assertEquals("User Two", user.displayName); - assertTrue(user.canCreate); - assertTrue(user.canFork); - - - user = htpwdUserService.authenticate("admin", "admin".toCharArray()); - assertNotNull(user); - assertTrue(user.canAdmin); - - user = htpwdUserService.authenticate("staylocal", "localUser".toCharArray()); - assertNotNull(user); - assertEquals("Local User", user.displayName); - assertFalse(user.canCreate); - assertFalse(user.canFork); - assertFalse(user.canAdmin); - } - - - @Test - public void testAuthenticateDenied() - { - UserModel user = null; - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); - user = htpwdUserService.authenticate("user1", "".toCharArray()); - assertNull("User 'user1' falsely authenticated.", user); - - user = htpwdUserService.authenticate("user1", "pass2".toCharArray()); - assertNull("User 'user1' falsely authenticated.", user); - - user = htpwdUserService.authenticate("user2", "lalala".toCharArray()); - assertNull("User 'user2' falsely authenticated.", user); - - - user = htpwdUserService.authenticate("user3", "disabled".toCharArray()); - assertNull("User 'user3' falsely authenticated.", user); - - user = htpwdUserService.authenticate("user4", "disabled".toCharArray()); - assertNull("User 'user4' falsely authenticated.", user); - - - user = htpwdUserService.authenticate("plain", "text".toCharArray()); - assertNull("User 'plain' falsely authenticated.", user); - - user = htpwdUserService.authenticate("plain", "password".toCharArray()); - assertNull("User 'plain' falsely authenticated.", user); - - - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); - - user = htpwdUserService.authenticate("crypt", "".toCharArray()); - assertNull("User 'cyrpt' falsely authenticated.", user); - - user = htpwdUserService.authenticate("crypt", "passwd".toCharArray()); - assertNull("User 'crypt' falsely authenticated.", user); - - user = htpwdUserService.authenticate("md5", "".toCharArray()); - assertNull("User 'md5' falsely authenticated.", user); - - user = htpwdUserService.authenticate("md5", "pwd".toCharArray()); - assertNull("User 'md5' falsely authenticated.", user); - - user = htpwdUserService.authenticate("sha", "".toCharArray()); - assertNull("User 'sha' falsely authenticated.", user); - - user = htpwdUserService.authenticate("sha", "letmein".toCharArray()); - assertNull("User 'sha' falsely authenticated.", user); - - - user = htpwdUserService.authenticate(" tabbed", "frontAndBack".toCharArray()); - assertNull("User 'tabbed' falsely authenticated.", user); - - user = htpwdUserService.authenticate(" leading", "whitespace".toCharArray()); - assertNull("User 'leading' falsely authenticated.", user); - } - - - @Test - public void testNewLocalAccount() - { - UserModel newUser = new UserModel("newlocal"); - newUser.displayName = "Local User 2"; - newUser.password = StringUtils.MD5_TYPE + StringUtils.getMD5("localPwd2"); - assertTrue("Failed to add local account.", htpwdUserService.updateUserModel(newUser)); - - UserModel localAccount = htpwdUserService.authenticate(newUser.username, "localPwd2".toCharArray()); - assertNotNull(localAccount); - assertEquals(newUser, localAccount); - - localAccount = htpwdUserService.authenticate(newUser.username, "localPwd2".toCharArray()); - assertNotNull(localAccount); - assertEquals(newUser, localAccount); - - assertTrue("Failed to delete local account.", htpwdUserService.deleteUser(localAccount.username)); - assertNull(htpwdUserService.authenticate(newUser.username, "localPwd2".toCharArray())); - } - - - @Test - public void testCleartextIntrusion() - { - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); - assertNull(htpwdUserService.authenticate("md5", "$apr1$qAGGNfli$sAn14mn.WKId/3EQS7KSX0".toCharArray())); - assertNull(htpwdUserService.authenticate("sha", "{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=".toCharArray())); - - assertNull(htpwdUserService.authenticate("user1", "#externalAccount".toCharArray())); - - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); - assertNull(htpwdUserService.authenticate("md5", "$apr1$qAGGNfli$sAn14mn.WKId/3EQS7KSX0".toCharArray())); - assertNull(htpwdUserService.authenticate("sha", "{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=".toCharArray())); - - assertNull(htpwdUserService.authenticate("user1", "#externalAccount".toCharArray())); - } - - - @Test - public void testCryptVsPlaintext() - { - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); - assertNull(htpwdUserService.authenticate("crypt", "6TmlbxqZ2kBIA".toCharArray())); - assertNotNull(htpwdUserService.authenticate("crypt", "password".toCharArray())); - - MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); - assertNotNull(htpwdUserService.authenticate("crypt", "6TmlbxqZ2kBIA".toCharArray())); - assertNull(htpwdUserService.authenticate("crypt", "password".toCharArray())); - } - - - /* - * Test case: User exists in user.conf with a local password and in htpasswd with an external password. - * If overrideLocalAuthentication is false, the local account takes precedence and is never updated. - */ - @Test - public void testPreparedAccountPreferLocal() throws IOException - { - setupUS(false); - - UserModel user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("staylocal", "localUser".toCharArray()); - assertNotNull(user); - assertEquals("staylocal", user.getName()); - - - deleteGeneratedFiles(); - copyInFiles(); - setupUS(false); - - user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("staylocal", "localUser".toCharArray()); - assertNotNull(user); - assertEquals("staylocal", user.getName()); - } - - - /* - * Test case: User exists in user.conf with a local password and in htpasswd with an external password. - * If overrideLocalAuthentication is true, the external account takes precedence, - * the initial local password is never used and discarded. - */ - @Test - public void testPreparedAccountPreferExternal() throws IOException - { - setupUS(true); - - UserModel user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("staylocal", "localUser".toCharArray()); - assertNotNull(user); - assertEquals("staylocal", user.getName()); - - - deleteGeneratedFiles(); - copyInFiles(); - setupUS(true); - - - user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("staylocal", "localUser".toCharArray()); - assertNotNull(user); - assertEquals("staylocal", user.getName()); - - // Make sure no authentication by using the string constant for external accounts is possible. - user = htpwdUserService.authenticate("leaderred", "#externalAccount".toCharArray()); - assertNull(user); - } - - - /* - * Test case: User exists in user.conf with a local password and in htpasswd with an external password. - * If overrideLocalAuthentication is true, the external account takes precedence, - * the initial local password is never used and discarded. - */ - @Test - public void testPreparedAccountChangeSetting() throws IOException - { - getSettings(false); - - UserModel user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("staylocal", "localUser".toCharArray()); - assertNotNull(user); - assertEquals("staylocal", user.getName()); - - - getSettings(true); - - - user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("staylocal", "localUser".toCharArray()); - assertNotNull(user); - assertEquals("staylocal", user.getName()); - - // Make sure no authentication by using the string constant for external accounts is possible. - user = htpwdUserService.authenticate("leaderred", "#externalAccount".toCharArray()); - assertNull(user); - - - getSettings(false); - // The preference is now back to local accounts but since the prepared account got switched - // to an external account, it will stay this way. - - user = htpwdUserService.authenticate("leaderred", "localPassword".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("leaderred", "externalPassword".toCharArray()); - assertNotNull(user); - assertEquals("leaderred", user.getName()); - - user = htpwdUserService.authenticate("staylocal", "localUser".toCharArray()); - assertNotNull(user); - assertEquals("staylocal", user.getName()); - - // Make sure no authentication by using the string constant for external accounts is possible. - user = htpwdUserService.authenticate("leaderred", "#externalAccount".toCharArray()); - assertNull(user); - } - - - @Test - public void testChangeHtpasswdFile() - { - UserModel user; - - // User default set up. - user = htpwdUserService.authenticate("md5", "password".toCharArray()); - assertNotNull(user); - assertEquals("md5", user.username); - - user = htpwdUserService.authenticate("sha", "password".toCharArray()); - assertNotNull(user); - assertEquals("sha", user.username); - - user = htpwdUserService.authenticate("blueone", "GoBlue!".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("bluetwo", "YayBlue!".toCharArray()); - assertNull(user); - - - // Switch to different htpasswd file. - getSettings(RESOURCE_DIR + "htpasswd-user", null, null); - - user = htpwdUserService.authenticate("md5", "password".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("sha", "password".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("blueone", "GoBlue!".toCharArray()); - assertNotNull(user); - assertEquals("blueone", user.username); - - user = htpwdUserService.authenticate("bluetwo", "YayBlue!".toCharArray()); - assertNotNull(user); - assertEquals("bluetwo", user.username); - } - - - @Test - public void testChangeHtpasswdFileNotExisting() - { - UserModel user; - - // User default set up. - user = htpwdUserService.authenticate("md5", "password".toCharArray()); - assertNotNull(user); - assertEquals("md5", user.username); - - user = htpwdUserService.authenticate("sha", "password".toCharArray()); - assertNotNull(user); - assertEquals("sha", user.username); - - user = htpwdUserService.authenticate("blueone", "GoBlue!".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("bluetwo", "YayBlue!".toCharArray()); - assertNull(user); - - - // Switch to different htpasswd file that doesn't exist. - // Currently we stop working with old users upon this change. - getSettings(RESOURCE_DIR + "no-such-file", null, null); - - user = htpwdUserService.authenticate("md5", "password".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("sha", "password".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("blueone", "GoBlue!".toCharArray()); - assertNull(user); - - user = htpwdUserService.authenticate("bluetwo", "YayBlue!".toCharArray()); - assertNull(user); - } - -} diff --git a/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java new file mode 100644 index 00000000..3cd2dc72 --- /dev/null +++ b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java @@ -0,0 +1,165 @@ +/* + * Copyright 2012 John Crygier + * Copyright 2012 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.tests; + +import java.io.FileInputStream; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.gitblit.IStoredSettings; +import com.gitblit.auth.LdapAuthProvider; +import com.gitblit.manager.RuntimeManager; +import com.gitblit.manager.UserManager; +import com.gitblit.models.UserModel; +import com.gitblit.tests.mock.MemorySettings; +import com.unboundid.ldap.listener.InMemoryDirectoryServer; +import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; +import com.unboundid.ldap.listener.InMemoryListenerConfig; +import com.unboundid.ldif.LDIFReader; + +/** + * An Integration test for LDAP that tests going against an in-memory UnboundID + * LDAP server. + * + * @author jcrygier + * + */ +public class LdapAuthenticationTest extends GitblitUnitTest { + + private static final String RESOURCE_DIR = "src/test/resources/ldap/"; + + private LdapAuthProvider ldap; + + static int ldapPort = 1389; + + @BeforeClass + public static void createInMemoryLdapServer() throws Exception { + InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=MyDomain"); + config.addAdditionalBindCredentials("cn=Directory Manager", "password"); + config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", ldapPort)); + config.setSchema(null); + + InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); + ds.importFromLDIF(true, new LDIFReader(new FileInputStream(RESOURCE_DIR + "sampledata.ldif"))); + ds.startListening(); + } + + @Before + public void newLdapAuthentication() { + ldap = newLdapAuthentication(getSettings()); + } + + public LdapAuthProvider newLdapAuthentication(IStoredSettings settings) { + RuntimeManager runtime = new RuntimeManager(settings, GitBlitSuite.BASEFOLDER).start(); + UserManager users = new UserManager(runtime).start(); + LdapAuthProvider ldap = new LdapAuthProvider(); + ldap.setup(runtime, users); + return ldap; + } + + private MemorySettings getSettings() { + Map backingMap = new HashMap(); + backingMap.put("realm.userService", RESOURCE_DIR + "users.conf"); + backingMap.put("realm.ldap.server", "ldap://localhost:" + ldapPort); + backingMap.put("realm.ldap.domain", ""); + backingMap.put("realm.ldap.username", "cn=Directory Manager"); + backingMap.put("realm.ldap.password", "password"); + backingMap.put("realm.ldap.backingUserService", "users.conf"); + backingMap.put("realm.ldap.maintainTeams", "true"); + backingMap.put("realm.ldap.accountBase", "OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain"); + backingMap.put("realm.ldap.accountPattern", "(&(objectClass=person)(sAMAccountName=${username}))"); + backingMap.put("realm.ldap.groupBase", "OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain"); + backingMap.put("realm.ldap.groupPattern", "(&(objectClass=group)(member=${dn}))"); + backingMap.put("realm.ldap.admins", "UserThree @Git_Admins \"@Git Admins\""); + backingMap.put("realm.ldap.displayName", "displayName"); + backingMap.put("realm.ldap.email", "email"); + + MemorySettings ms = new MemorySettings(backingMap); + 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); + + UserModel userTwoModel = ldap.authenticate("UserTwo", "userTwoPassword".toCharArray()); + assertNotNull(userTwoModel); + 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")); + assertTrue(userThreeModel.canAdmin); + } + + @Test + public void testDisplayName() { + UserModel userOneModel = ldap.authenticate("UserOne", "userOnePassword".toCharArray()); + assertNotNull(userOneModel); + assertEquals("User One", userOneModel.displayName); + + // Test more complicated scenarios - concat + MemorySettings ms = getSettings(); + ms.put("realm.ldap.displayName", "${personalTitle}. ${givenName} ${surname}"); + ldap = newLdapAuthentication(ms); + + userOneModel = ldap.authenticate("UserOne", "userOnePassword".toCharArray()); + assertNotNull(userOneModel); + assertEquals("Mr. User One", userOneModel.displayName); + } + + @Test + public void testEmail() { + UserModel userOneModel = ldap.authenticate("UserOne", "userOnePassword".toCharArray()); + assertNotNull(userOneModel); + assertEquals("userone@gitblit.com", userOneModel.emailAddress); + + // Test more complicated scenarios - concat + MemorySettings ms = getSettings(); + ms.put("realm.ldap.email", "${givenName}.${surname}@gitblit.com"); + ldap = newLdapAuthentication(ms); + + userOneModel = ldap.authenticate("UserOne", "userOnePassword".toCharArray()); + assertNotNull(userOneModel); + assertEquals("User.One@gitblit.com", userOneModel.emailAddress); + } + + @Test + public void testLdapInjection() { + // Inject so "(&(objectClass=person)(sAMAccountName=${username}))" becomes "(&(objectClass=person)(sAMAccountName=*)(userPassword=userOnePassword))" + // Thus searching by password + + UserModel userOneModel = ldap.authenticate("*)(userPassword=userOnePassword", "userOnePassword".toCharArray()); + assertNull(userOneModel); + } + +} diff --git a/src/test/java/com/gitblit/tests/LdapUserServiceTest.java b/src/test/java/com/gitblit/tests/LdapUserServiceTest.java deleted file mode 100644 index 8bd90147..00000000 --- a/src/test/java/com/gitblit/tests/LdapUserServiceTest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2012 John Crygier - * Copyright 2012 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.tests; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.gitblit.LdapUserService; -import com.gitblit.models.UserModel; -import com.gitblit.tests.mock.MemorySettings; -import com.gitblit.tests.mock.MockRuntimeManager; -import com.gitblit.utils.StringUtils; -import com.unboundid.ldap.listener.InMemoryDirectoryServer; -import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; -import com.unboundid.ldap.listener.InMemoryListenerConfig; -import com.unboundid.ldif.LDIFReader; - -/** - * An Integration test for LDAP that tests going against an in-memory UnboundID - * LDAP server. - * - * @author jcrygier - * - */ -public class LdapUserServiceTest extends GitblitUnitTest { - - private LdapUserService ldapUserService; - - static int ldapPort = 1389; - - @BeforeClass - public static void createInMemoryLdapServer() throws Exception { - InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=MyDomain"); - config.addAdditionalBindCredentials("cn=Directory Manager", "password"); - config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", ldapPort)); - config.setSchema(null); - - InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); - ds.importFromLDIF(true, new LDIFReader(LdapUserServiceTest.class.getResourceAsStream("resources/ldapUserServiceSampleData.ldif"))); - ds.startListening(); - } - - @Before - public void createLdapUserService() { - ldapUserService = new LdapUserService(); - ldapUserService.setup(new MockRuntimeManager(getSettings())); - } - - private MemorySettings getSettings() { - Map backingMap = new HashMap(); - backingMap.put("realm.ldap.server", "ldap://localhost:" + ldapPort); - backingMap.put("realm.ldap.domain", ""); - backingMap.put("realm.ldap.username", "cn=Directory Manager"); - backingMap.put("realm.ldap.password", "password"); - backingMap.put("realm.ldap.backingUserService", "users.conf"); - backingMap.put("realm.ldap.maintainTeams", "true"); - backingMap.put("realm.ldap.accountBase", "OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain"); - backingMap.put("realm.ldap.accountPattern", "(&(objectClass=person)(sAMAccountName=${username}))"); - backingMap.put("realm.ldap.groupBase", "OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain"); - backingMap.put("realm.ldap.groupPattern", "(&(objectClass=group)(member=${dn}))"); - backingMap.put("realm.ldap.admins", "UserThree @Git_Admins \"@Git Admins\""); - backingMap.put("realm.ldap.displayName", "displayName"); - backingMap.put("realm.ldap.email", "email"); - - MemorySettings ms = new MemorySettings(backingMap); - return ms; - } - - @Test - public void testAuthenticate() { - UserModel userOneModel = ldapUserService.authenticate("UserOne", "userOnePassword".toCharArray()); - assertNotNull(userOneModel); - assertNotNull(userOneModel.getTeam("git_admins")); - assertNotNull(userOneModel.getTeam("git_users")); - assertTrue(userOneModel.canAdmin); - - UserModel userOneModelFailedAuth = ldapUserService.authenticate("UserOne", "userTwoPassword".toCharArray()); - assertNull(userOneModelFailedAuth); - - UserModel userTwoModel = ldapUserService.authenticate("UserTwo", "userTwoPassword".toCharArray()); - assertNotNull(userTwoModel); - assertNotNull(userTwoModel.getTeam("git_users")); - assertNull(userTwoModel.getTeam("git_admins")); - assertNotNull(userTwoModel.getTeam("git admins")); - assertTrue(userTwoModel.canAdmin); - - UserModel userThreeModel = ldapUserService.authenticate("UserThree", "userThreePassword".toCharArray()); - assertNotNull(userThreeModel); - assertNotNull(userThreeModel.getTeam("git_users")); - assertNull(userThreeModel.getTeam("git_admins")); - assertTrue(userThreeModel.canAdmin); - } - - @Test - public void testDisplayName() { - UserModel userOneModel = ldapUserService.authenticate("UserOne", "userOnePassword".toCharArray()); - assertNotNull(userOneModel); - assertEquals("User One", userOneModel.displayName); - - // Test more complicated scenarios - concat - MemorySettings ms = getSettings(); - ms.put("realm.ldap.displayName", "${personalTitle}. ${givenName} ${surname}"); - ldapUserService = new LdapUserService(); - ldapUserService.setup(new MockRuntimeManager(ms)); - - userOneModel = ldapUserService.authenticate("UserOne", "userOnePassword".toCharArray()); - assertNotNull(userOneModel); - assertEquals("Mr. User One", userOneModel.displayName); - } - - @Test - public void testEmail() { - UserModel userOneModel = ldapUserService.authenticate("UserOne", "userOnePassword".toCharArray()); - assertNotNull(userOneModel); - assertEquals("userone@gitblit.com", userOneModel.emailAddress); - - // Test more complicated scenarios - concat - MemorySettings ms = getSettings(); - ms.put("realm.ldap.email", "${givenName}.${surname}@gitblit.com"); - ldapUserService = new LdapUserService(); - ldapUserService.setup(new MockRuntimeManager(ms)); - - userOneModel = ldapUserService.authenticate("UserOne", "userOnePassword".toCharArray()); - assertNotNull(userOneModel); - assertEquals("User.One@gitblit.com", userOneModel.emailAddress); - } - - @Test - public void testLdapInjection() { - // Inject so "(&(objectClass=person)(sAMAccountName=${username}))" becomes "(&(objectClass=person)(sAMAccountName=*)(userPassword=userOnePassword))" - // Thus searching by password - - UserModel userOneModel = ldapUserService.authenticate("*)(userPassword=userOnePassword", "userOnePassword".toCharArray()); - assertNull(userOneModel); - } - - @Test - public void testLocalAccount() { - UserModel localAccount = new UserModel("bruce"); - localAccount.displayName = "Bruce Campbell"; - localAccount.password = StringUtils.MD5_TYPE + StringUtils.getMD5("gimmesomesugar"); - ldapUserService.deleteUser(localAccount.username); - assertTrue("Failed to add local account", - ldapUserService.updateUserModel(localAccount)); - assertEquals("Accounts are not equal!", - localAccount, - ldapUserService.authenticate(localAccount.username, "gimmesomesugar".toCharArray())); - assertTrue("Failed to delete local account!", - ldapUserService.deleteUser(localAccount.username)); - } - -} diff --git a/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java b/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java new file mode 100644 index 00000000..1fe8459f --- /dev/null +++ b/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java @@ -0,0 +1,65 @@ +package com.gitblit.tests; + +import static org.hamcrest.CoreMatchers.is; + +import java.util.HashMap; + +import org.junit.Test; + +import com.gitblit.IStoredSettings; +import com.gitblit.auth.RedmineAuthProvider; +import com.gitblit.manager.RuntimeManager; +import com.gitblit.manager.UserManager; +import com.gitblit.models.UserModel; +import com.gitblit.tests.mock.MemorySettings; + +public class RedmineAuthenticationTest extends GitblitUnitTest { + + private static final String JSON = "{\"user\":{\"created_on\":\"2011-03-28T00:41:29Z\",\"lastname\":\"foo\"," + + "\"last_login_on\":\"2012-09-06T23:59:26Z\",\"firstname\":\"baz\"," + + "\"id\":4,\"login\":\"RedmineUserId\",\"mail\":\"baz@example.com\"}}"; + + private static final String NOT_ADMIN_JSON = "{\"user\":{\"lastname\":\"foo\"," + + "\"last_login_on\":\"2012-09-08T13:59:01Z\",\"created_on\":\"2009-03-17T14:25:50Z\"," + + "\"mail\":\"baz@example.com\",\"id\":5,\"firstname\":\"baz\"}}"; + + MemorySettings getSettings() { + return new MemorySettings(new HashMap()); + } + + RedmineAuthProvider newRedmineAuthentication(IStoredSettings settings) { + RuntimeManager runtime = new RuntimeManager(settings, GitBlitSuite.BASEFOLDER).start(); + UserManager users = new UserManager(runtime).start(); + RedmineAuthProvider redmine = new RedmineAuthProvider(); + redmine.setup(runtime, users); + return redmine; + } + + RedmineAuthProvider newRedmineAuthentication() { + return newRedmineAuthentication(getSettings()); + } + + @Test + public void testAuthenticate() throws Exception { + RedmineAuthProvider redmine = newRedmineAuthentication(); + redmine.setTestingCurrentUserAsJson(JSON); + UserModel userModel = redmine.authenticate("RedmineAdminId", "RedmineAPIKey".toCharArray()); + assertThat(userModel.getName(), is("redmineadminid")); + assertThat(userModel.getDisplayName(), is("baz foo")); + assertThat(userModel.emailAddress, is("baz@example.com")); + assertNotNull(userModel.cookie); + assertThat(userModel.canAdmin, is(true)); + } + + @Test + public void testAuthenticateNotAdminUser() throws Exception { + RedmineAuthProvider redmine = newRedmineAuthentication(); + redmine.setTestingCurrentUserAsJson(NOT_ADMIN_JSON); + UserModel userModel = redmine.authenticate("RedmineUserId", "RedmineAPIKey".toCharArray()); + assertThat(userModel.getName(), is("redmineuserid")); + assertThat(userModel.getDisplayName(), is("baz foo")); + assertThat(userModel.emailAddress, is("baz@example.com")); + assertNotNull(userModel.cookie); + assertThat(userModel.canAdmin, is(false)); + } +} diff --git a/src/test/java/com/gitblit/tests/RedmineUserServiceTest.java b/src/test/java/com/gitblit/tests/RedmineUserServiceTest.java deleted file mode 100644 index 3c6769f0..00000000 --- a/src/test/java/com/gitblit/tests/RedmineUserServiceTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.gitblit.tests; - -import static org.hamcrest.CoreMatchers.is; - -import org.junit.Test; - -import com.gitblit.RedmineUserService; -import com.gitblit.models.UserModel; -import com.gitblit.tests.mock.MockRuntimeManager; -import com.gitblit.utils.StringUtils; - -public class RedmineUserServiceTest extends GitblitUnitTest { - - private static final String JSON = "{\"user\":{\"created_on\":\"2011-03-28T00:41:29Z\",\"lastname\":\"foo\"," - + "\"last_login_on\":\"2012-09-06T23:59:26Z\",\"firstname\":\"baz\"," - + "\"id\":4,\"login\":\"RedmineUserId\",\"mail\":\"baz@example.com\"}}"; - - private static final String NOT_ADMIN_JSON = "{\"user\":{\"lastname\":\"foo\"," - + "\"last_login_on\":\"2012-09-08T13:59:01Z\",\"created_on\":\"2009-03-17T14:25:50Z\"," - + "\"mail\":\"baz@example.com\",\"id\":5,\"firstname\":\"baz\"}}"; - - @Test - public void testAuthenticate() throws Exception { - RedmineUserService redmineUserService = new RedmineUserService(); - redmineUserService.setup(new MockRuntimeManager()); - redmineUserService.setTestingCurrentUserAsJson(JSON); - UserModel userModel = redmineUserService.authenticate("RedmineAdminId", "RedmineAPIKey".toCharArray()); - assertThat(userModel.getName(), is("redmineadminid")); - assertThat(userModel.getDisplayName(), is("baz foo")); - assertThat(userModel.emailAddress, is("baz@example.com")); - assertNotNull(userModel.cookie); - assertThat(userModel.canAdmin, is(true)); - } - - @Test - public void testAuthenticateNotAdminUser() throws Exception { - RedmineUserService redmineUserService = new RedmineUserService(); - redmineUserService.setup(new MockRuntimeManager()); - redmineUserService.setTestingCurrentUserAsJson(NOT_ADMIN_JSON); - UserModel userModel = redmineUserService.authenticate("RedmineUserId", "RedmineAPIKey".toCharArray()); - assertThat(userModel.getName(), is("redmineuserid")); - assertThat(userModel.getDisplayName(), is("baz foo")); - assertThat(userModel.emailAddress, is("baz@example.com")); - assertNotNull(userModel.cookie); - assertThat(userModel.canAdmin, is(false)); - } - - @Test - public void testLocalAccount() { - RedmineUserService redmineUserService = new RedmineUserService(); - redmineUserService.setup(new MockRuntimeManager()); - - UserModel localAccount = new UserModel("bruce"); - localAccount.displayName = "Bruce Campbell"; - localAccount.password = StringUtils.MD5_TYPE + StringUtils.getMD5("gimmesomesugar"); - redmineUserService.deleteUser(localAccount.username); - assertTrue("Failed to add local account", - redmineUserService.updateUserModel(localAccount)); - assertEquals("Accounts are not equal!", - localAccount, - redmineUserService.authenticate(localAccount.username, "gimmesomesugar".toCharArray())); - assertTrue("Failed to delete local account!", - redmineUserService.deleteUser(localAccount.username)); - } - -} diff --git a/src/test/java/com/gitblit/tests/UserServiceTest.java b/src/test/java/com/gitblit/tests/UserServiceTest.java index 613e46df..cdb0a330 100644 --- a/src/test/java/com/gitblit/tests/UserServiceTest.java +++ b/src/test/java/com/gitblit/tests/UserServiceTest.java @@ -85,14 +85,9 @@ public class UserServiceTest extends GitblitUnitTest { assertTrue(newUser.hasRepositoryPermission("repo2")); assertTrue(newUser.hasRepositoryPermission("sub/repo3")); - // confirm authentication of test user - UserModel testUser = service.authenticate("test", "testPassword".toCharArray()); - assertEquals("test", testUser.username); - assertEquals("testPassword", testUser.password); - // delete a repository role and confirm role removal from test user service.deleteRepositoryRole("repo2"); - testUser = service.getUserModel("test"); + UserModel testUser = service.getUserModel("test"); assertEquals(2, testUser.permissions.size()); // delete garbage user and confirm user count diff --git a/src/test/java/com/gitblit/tests/resources/ldapUserServiceSampleData.ldif b/src/test/java/com/gitblit/tests/resources/ldapUserServiceSampleData.ldif deleted file mode 100644 index df79333e..00000000 --- a/src/test/java/com/gitblit/tests/resources/ldapUserServiceSampleData.ldif +++ /dev/null @@ -1,108 +0,0 @@ -dn: DC=MyDomain -dc: MyDomain -objectClass: top -objectClass: domain - -dn: OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: organizationalUnit -ou: MyOrganization - -dn: OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: organizationalUnit -ou: UserControl - -dn: OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: organizationalUnit -ou: Groups - -dn: CN=Git_Admins,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: group -cn: Git_Admins -sAMAccountName: Git_Admins -member: CN=UserOne,OU=US,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain - -dn: CN=Git Admins,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: group -cn: Git Admins -sAMAccountName: Git_Admins_With_Space -member: CN=UserTwo,OU=US,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain - -dn: CN=Git_Users,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: group -cn: Git_Users -sAMAccountName: Git_Users -member: CN=UserOne,OU=US,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -member: CN=UserTwo,OU=US,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -member: CN=UserThree,OU=Canada,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -member: CN=UserFour,OU=Canada,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain - -dn: OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: organizationalUnit -ou: Users - -dn: OU=US,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: organizationalUnit -ou: US - -dn: OU=Canada,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: top -objectClass: organizationalUnit -ou: Canada - -dn: CN=UserOne,OU=US,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: user -objectClass: person -sAMAccountName: UserOne -userPassword: userOnePassword -displayName: User One -givenName: User -surname: One -personalTitle: Mr -email: userone@gitblit.com -memberOf: CN=Git_Admins,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain -memberOf: CN=Git_Users,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain - -dn: CN=UserTwo,OU=US,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: user -objectClass: person -sAMAccountName: UserTwo -userPassword: userTwoPassword -displayName: User Two -givenName: User -surname: Two -personalTitle: Mr -email: usertwo@gitblit.com -memberOf: CN=Git_Users,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain -memberOf: CN=Git Admins,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain - -dn: CN=UserThree,OU=Canada,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: user -objectClass: person -sAMAccountName: UserThree -userPassword: userThreePassword -displayName: User Three -givenName: User -surname: Three -personalTitle: Mrs -email: userthree@gitblit.com -memberOf: CN=Git_Users,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain - -dn: CN=UserFour,OU=Canada,OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain -objectClass: user -objectClass: person -sAMAccountName: UserFour -userPassword: userFourPassword -displayName: User Four -givenName: User -surname: Four -personalTitle: Miss -email: userfour@gitblit.com -memberOf: CN=Git_Users,OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain \ No newline at end of file -- cgit v1.2.3