Package org.projectforge.ldap

Source Code of org.projectforge.ldap.LdapSlaveLoginHandlerTest

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.ldap;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.projectforge.test.TestBase;
import org.projectforge.user.Login;
import org.projectforge.user.LoginHandler;
import org.projectforge.user.LoginResult;
import org.projectforge.user.LoginResultStatus;
import org.projectforge.user.PFUserDO;
import org.projectforge.user.PasswordCheckResult;

public class LdapSlaveLoginHandlerTest extends TestBase
{
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LdapSlaveLoginHandlerTest.class);

  private LdapUserDao ldapUserDao;

  private LdapRealTestHelper ldapRealTestHelper;

  @Before
  public void setup()
  {
    ldapRealTestHelper = new LdapRealTestHelper().setup();
    ldapUserDao = ldapRealTestHelper.ldapUserDao;
  }

  @After
  public void tearDown()
  {
    ldapRealTestHelper.tearDown();
  }

  @Test
  public void testMockedSimpleMode()
  {
    final String userBase = "ou=pf-mock-test-users";
    final String testUsername = "mockedLdapSlaveTestuser";
    ldapUserDao = mock(LdapUserDao.class);
    when(ldapUserDao.authenticate(Mockito.eq(testUsername), Mockito.eq("successful"), Mockito.eq(userBase))).thenReturn(
        (LdapUser) new LdapUser().setUid(testUsername));
    when(ldapUserDao.authenticate(Mockito.anyString(), Mockito.eq("fail"), Mockito.eq(userBase))).thenReturn(null);
    final LdapSlaveLoginHandler loginHandler = new LdapSlaveLoginHandler();
    loginHandler.ldapConfig = new LdapConfig().setUserBase(userBase);
    loginHandler.userDao = userDao;
    loginHandler.ldapUserDao = ldapUserDao;
    loginHandler.ldapOrganizationalUnitDao = mock(LdapOrganizationalUnitDao.class);
    loginHandler.initialize();
    loginHandler.setMode(LdapSlaveLoginHandler.Mode.SIMPLE);
    testSimpleMode(loginHandler, testUsername);
  }

  @Test
  public void testSimpleMode()
  {
    if (ldapRealTestHelper.isAvailable() == false) {
      log.info("No LDAP server configured for tests. Skipping test.");
      return;
    }
    final LdapSlaveLoginHandler loginHandler = createLoginHandler();
    loginHandler.setMode(LdapSlaveLoginHandler.Mode.SIMPLE);
    final String testUsername = "ldapSlaveTestuser";
    final LdapUser ldapUser = (LdapUser) new LdapUser().setUid(testUsername).setGivenName("Kai").setSurname("Reinhard")
        .setEmployeeNumber("42");
    createLdapUser(ldapUser, "successful");
    testSimpleMode(loginHandler, testUsername);
    ldapUserDao.delete(ldapUser);
  }

  private LdapSlaveLoginHandler createLoginHandler()
  {
    final LdapSlaveLoginHandler loginHandler = new LdapSlaveLoginHandler();
    loginHandler.ldapConfig = ldapRealTestHelper.ldapConfig;
    loginHandler.userDao = userDao;
    loginHandler.ldapUserDao = ldapUserDao;
    loginHandler.ldapOrganizationalUnitDao = ldapRealTestHelper.ldapOrganizationalUnitDao;
    loginHandler.initialize();
    Login.getInstance().setLoginHandler(loginHandler);
    return loginHandler;
  }

  private void createLdapUser(final LdapUser ldapUser, final String password)
  {
    final String userBase = ldapRealTestHelper.ldapConfig.getUserBase();
    ldapUser.setOrganizationalUnit(userBase);
    ldapUserDao.create(userBase, ldapUser);
    ldapUserDao.changePassword(ldapUser, null, password);
  }

  private void testSimpleMode(final LoginHandler loginHandler, final String testUsername)
  {
    logon(TEST_ADMIN_USER);
    Assert.assertNull("If failed, a previous test run didn't cleared the data-base.", userDao.getUserGroupCache().getUser(testUsername));

    // Check failed login:
    LoginResult result = loginHandler.checkLogin(testUsername, "fail");
    Assert.assertEquals("User login failed against LDAP therefore login should be failed.", LoginResultStatus.FAILED,
        result.getLoginResultStatus());

    // Check successful login for new ProjectForge users:
    result = loginHandler.checkLogin(testUsername, "successful");
    Assert.assertEquals(LoginResultStatus.SUCCESS, result.getLoginResultStatus());
    Assert.assertNotNull("User should be returned.", result.getUser());
    PFUserDO user = userDao.getInternalByName(testUsername);
    Assert.assertNotNull("User should be created by login handler.", user);
    Assert.assertEquals(testUsername, user.getUsername());
    Assert.assertEquals(result.getUser().getId(), user.getId());

    // Check successful login for existing ProjectForge users:
    result = loginHandler.checkLogin(testUsername, "successful");
    Assert.assertEquals(LoginResultStatus.SUCCESS, result.getLoginResultStatus());
    Assert.assertNotNull("User should be returned.", result.getUser());
    user = userDao.getInternalByName(testUsername);
    Assert.assertNotNull("User should be created by login handler.", user);
    Assert.assertEquals(testUsername, user.getUsername());
    Assert.assertEquals(result.getUser().getId(), user.getId());

    // Check that LDAP is ignored for local users:
    user.setLocalUser(true);
    userDao.internalUpdate(user);
    result = loginHandler.checkLogin(testUsername, "successful");
    Assert.assertEquals("User is a local user, thus the LDAP authentication should be ignored.", LoginResultStatus.FAILED,
        result.getLoginResultStatus());
    userDao.createEncryptedPassword(user, "test");
    userDao.internalUpdate(user);
    result = loginHandler.checkLogin(testUsername, "test");
    Assert.assertEquals("User is a local user, thus authentication should be done by the login default handler.",
        LoginResultStatus.SUCCESS, result.getLoginResultStatus());
    user = result.getUser();
    Assert.assertEquals(testUsername, user.getUsername());
  }

  @Test
  public void loginInMockedSlaveMode()
  {
    final String userBase = "ou=pf-mock-test-users";
    final LdapUserDao ldapUserDao = mock(LdapUserDao.class);
    LoginResult loginResult;
    final LdapUser kai = (LdapUser) new LdapUser().setUid("kai").setDescription("Developer").setGivenName("Kai")
        .setMail("k.reinhard@acme.com").setOrganization("Micromata").setSurname("Reinhard");
    when(ldapUserDao.authenticate("kai", "successful", userBase)).thenReturn(kai);
    when(ldapUserDao.authenticate("kai", "fail", userBase)).thenReturn(null);
    when(ldapUserDao.findByUsername("kai", userBase)).thenReturn(kai);
    final LdapSlaveLoginHandler loginHandler = new LdapSlaveLoginHandler();
    loginHandler.ldapUserDao = ldapUserDao;
    loginHandler.ldapConfig = new LdapConfig().setUserBase(userBase);
    loginHandler.userDao = userDao;
    Assert.assertEquals(LoginResultStatus.FAILED, loginHandler.checkLogin("kai", "fail").getLoginResultStatus());

    Assert.assertFalse("User shouldn't be available yet in the data-base.",
        userDao.doesUsernameAlreadyExist(new PFUserDO().setUsername("kai")));
    loginResult = loginHandler.checkLogin("kai", "successful");
    Assert.assertEquals(LoginResultStatus.SUCCESS, loginResult.getLoginResultStatus());
    LdapTestUtils.assertUser(loginResult.getUser(), "kai", "Kai", "Reinhard", "k.reinhard@acme.com", "Micromata", "Developer");
    Assert.assertTrue("User should be created in data-base as a new user (in ldap).",
        userDao.doesUsernameAlreadyExist(new PFUserDO().setUsername("kai")));
    final PFUserDO user = userDao.getInternalByName("kai");
    LdapTestUtils.assertUser(user, "kai", "Kai", "Reinhard", "k.reinhard@acme.com", "Micromata", "Developer");
    Assert.assertEquals(userDao.checkPassword(user, "successful"), PasswordCheckResult.OK);

    userDao.internalMarkAsDeleted(user);
    Assert.assertEquals("User is deleted in data-base. Login not possible.", LoginResultStatus.LOGIN_EXPIRED,
        loginHandler.checkLogin("kai", "successful").getLoginResultStatus());
  }

  @Test
  public void testUserMode()
  {
    if (ldapRealTestHelper.isAvailable() == false) {
      log.info("No LDAP server configured for tests. Skipping test.");
      return;
    }
    final LdapSlaveLoginHandler loginHandler = createLoginHandler();
    loginHandler.setMode(LdapSlaveLoginHandler.Mode.USERS);
    final String testUsername1 = "ldapSlaveTestuserUserMode1";
    final String testUsername2 = "ldapSlaveTestuserUserMode2";
    final LdapUser ldapUser1 = (LdapUser) new LdapUser().setUid(testUsername1).setGivenName("Kai").setSurname("Reinhard")
        .setEmployeeNumber("100");
    createLdapUser(ldapUser1, "successful");
    final LdapUser ldapUser2 = (LdapUser) new LdapUser().setUid(testUsername2).setGivenName("Kai").setSurname("Reinhard")
        .setEmployeeNumber("101");
    createLdapUser(ldapUser2, "successful");

    logon(TEST_ADMIN_USER);
    Assert.assertNull("If failed, a previous test run didn't cleared the data-base.", userDao.getUserGroupCache().getUser(testUsername1));
    Assert.assertNull("If failed, a previous test run didn't cleared the data-base.", userDao.getUserGroupCache().getUser(testUsername2));

    // Check failed login:
    LoginResult result = loginHandler.checkLogin(testUsername1, "fail");
    Assert.assertEquals("User login failed against LDAP therefore login should be failed.", LoginResultStatus.FAILED,
        result.getLoginResultStatus());

    // Check successful login for new ProjectForge users:
    result = loginHandler.checkLogin(testUsername1, "successful");
    Assert.assertEquals(LoginResultStatus.SUCCESS, result.getLoginResultStatus());
    Assert.assertNotNull("User should be returned.", result.getUser());
    synchronizeLdapUsers(loginHandler);
    PFUserDO user = userDao.authenticateUser(testUsername1, "successful");
    Assert.assertNotNull("User should be created by login handler.", user);
    Assert.assertEquals(testUsername1, user.getUsername());
    result = loginHandler.checkLogin(testUsername1, "successful");
    Assert.assertEquals(result.getUser().getId(), user.getId());
    user = userDao.getInternalByName(testUsername2);
    result = loginHandler.checkLogin(testUsername2, "successful");
    Assert.assertNotNull("User should be created by login handler.", user);
    Assert.assertEquals(testUsername2, user.getUsername());
    Assert.assertEquals(result.getUser().getId(), user.getId());

    // Delete user2
    ldapUserDao.delete(ldapUser2);
    synchronizeLdapUsers(loginHandler);
    user = userDao.getInternalByName(testUsername2);
    Assert.assertTrue("User isn't available in LDAP, therefore should be deleted.", user.isDeleted());
    createLdapUser(ldapUser2, "successful");
    synchronizeLdapUsers(loginHandler);
    user = userDao.getInternalByName(testUsername2);
    Assert.assertFalse("User isn't available in LDAP, therefore should be deleted.", user.isDeleted());

    // Check that LDAP is ignored for local users:
    user.setLocalUser(true);
    userDao.createEncryptedPassword(user, "test");
    userDao.internalUpdate(user);
    result = loginHandler.checkLogin(testUsername2, "successful");
    Assert.assertEquals("User is a local user, thus the LDAP authentication should be ignored.", LoginResultStatus.FAILED,
        result.getLoginResultStatus());
    result = loginHandler.checkLogin(testUsername2, "test");
    Assert.assertEquals("User is a local user, thus the data-base authentication should be used.", LoginResultStatus.SUCCESS,
        result.getLoginResultStatus());

    // Delete all users
    ldapUserDao.delete(ldapUser1);
    ldapUserDao.delete(ldapUser2);
  }

  private void synchronizeLdapUsers(final LdapSlaveLoginHandler loginHandler)
  {
    userDao.getUserGroupCache().forceReload(); // Synchronize ldap users.
    while (true) {
      try {
        Thread.sleep(200);
      } catch (final InterruptedException ex) {
      }
      if (userDao.getUserGroupCache().isRefreshInProgress() == false && loginHandler.isRefreshInProgress() == false) {
        break;
      }
    }
  }
}
TOP

Related Classes of org.projectforge.ldap.LdapSlaveLoginHandlerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.