Commit fd5b6407 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

user is automatically created when local user doesn't exist and authentication goes via ldap

parent 8d0dc7af
...@@ -221,7 +221,7 @@ public enum ConfigurationElementType { ...@@ -221,7 +221,7 @@ public enum ConfigurationElementType {
ConfigurationElementTypeGroup.LDAP_CONFIGURATION), // ConfigurationElementTypeGroup.LDAP_CONFIGURATION), //
LDAP_EMAIL_ATTRIBUTE("LDAP email attribute", "mail", ConfigurationElementEditType.STRING, true, LDAP_EMAIL_ATTRIBUTE("LDAP email attribute", "mail", ConfigurationElementEditType.STRING, true,
ConfigurationElementTypeGroup.LDAP_CONFIGURATION),// ConfigurationElementTypeGroup.LDAP_CONFIGURATION),//
LDAP_FILTER("LDAP filter ", "(memberof=cn=gitlab,cn=groups,cn=accounts,dc=uni,dc=lu)", ConfigurationElementEditType.STRING, true, LDAP_FILTER("LDAP filter ", "(memberof=cn=minerva,cn=groups,cn=accounts,dc=uni,dc=lu)", ConfigurationElementEditType.STRING, true,
ConfigurationElementTypeGroup.LDAP_CONFIGURATION), // ConfigurationElementTypeGroup.LDAP_CONFIGURATION), //
; ;
......
...@@ -118,8 +118,13 @@ public class User implements Serializable { ...@@ -118,8 +118,13 @@ public class User implements Serializable {
*/ */
private boolean removed = false; private boolean removed = false;
@Column(name="terms_of_use_consent") /**
private boolean termsOfUseConsent = false; * User is connected to LDAP directory.
*/
private boolean connectedToLdap = false;
@Column(name = "terms_of_use_consent")
private boolean termsOfUseConsent = false;
/** /**
* Set of user privileges. * Set of user privileges.
...@@ -378,4 +383,12 @@ public class User implements Serializable { ...@@ -378,4 +383,12 @@ public class User implements Serializable {
this.termsOfUseConsent = termsOfUseConsent; this.termsOfUseConsent = termsOfUseConsent;
} }
public boolean isConnectedToLdap() {
return connectedToLdap;
}
public void setConnectedToLdap(boolean connectedToLdap) {
this.connectedToLdap = connectedToLdap;
}
} }
-- user account can be connected to LDAP directory
alter table user_table add column connectedtoldap boolean default false;
...@@ -2,9 +2,6 @@ package lcsb.mapviewer.persist.dao.user; ...@@ -2,9 +2,6 @@ package lcsb.mapviewer.persist.dao.user;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.persist.dao.BaseDao; import lcsb.mapviewer.persist.dao.BaseDao;
...@@ -16,102 +13,80 @@ import lcsb.mapviewer.persist.dao.BaseDao; ...@@ -16,102 +13,80 @@ import lcsb.mapviewer.persist.dao.BaseDao;
*/ */
public class UserDao extends BaseDao<User> { public class UserDao extends BaseDao<User> {
/** /**
* Service that provides password encoding. * Default constructor.
*/ */
@Autowired public UserDao() {
private PasswordEncoder passwordEncoder; super(User.class, "removed");
}
/**
* Default constructor.
*/
public UserDao() {
super(User.class, "removed");
}
/**
* Returns user with a given login and password.
*
* @param login
* user login
* @param password
* - user password (plain text)
* @return user for given login and password
*/
public User getUserByLoginAndPassword(String login, String password) {
if (password == null) {
return getUserByLoginAndCryptedPassword(login, null);
}
return getUserByLoginAndCryptedPassword(login, passwordEncoder.encode(password));
}
/** /**
* Returns user with a given login and password. * Returns user with a given login and password.
* *
* @param login * @param login
* user login * user login
* @param password * @param password
* - user password (encrypted) * - user password (encrypted)
* @return user for given login and password * @return user for given login and password
*/ */
public User getUserByLoginAndCryptedPassword(String login, String password) { public User getUserByLoginAndCryptedPassword(String login, String password) {
List<?> list = getSession() List<?> list = getSession()
.createQuery(" from User where login=:login and cryptedPassword =:passwd " + removableAndStatemant()).setParameter("login", login) .createQuery(" from User where login=:login and cryptedPassword =:passwd " + removableAndStatemant())
.setParameter("passwd", password).list(); .setParameter("login", login).setParameter("passwd", password).list();
if (list.size() == 0) { if (list.size() == 0) {
return null; return null;
} else { } else {
User user = (User) list.get(0); User user = (User) list.get(0);
return user; return user;
} }
} }
/** /**
* Returns user with a given login. * Returns user with a given login.
* *
* @param login * @param login
* user login * user login
* @return user for a given login * @return user for a given login
*/ */
public User getUserByLogin(String login) { public User getUserByLogin(String login) {
return getByParameter("login", login); return getByParameter("login", login);
} }
/** /**
* Returns user with a given email. * Returns user with a given email.
* *
* @param email * @param email
* user email * user email
* @return user for a given email * @return user for a given email
*/ */
public User getUserByEmail(String email) { public User getUserByEmail(String email) {
return getByParameter("email", email); return getByParameter("email", email);
} }
@Override @Override
public void delete(User object) { public void delete(User object) {
object.setRemoved(true); object.setRemoved(true);
object.setLogin("[REMOVED]_" + object.getId() + "_" + object.getLogin()); object.setLogin("[REMOVED]_" + object.getId() + "_" + object.getLogin());
update(object); update(object);
} }
/** /**
* Returns {@link User} for given "name surname" string. * Returns {@link User} for given "name surname" string.
* *
* @param nameSurnameString * @param nameSurnameString
* string identifing user with name and surname separated by single * string identifing user with name and surname separated by single
* space * space
* @return {@link User} for given "name surname" string * @return {@link User} for given "name surname" string
*/ */
public User getUserByNameSurname(String nameSurnameString) { public User getUserByNameSurname(String nameSurnameString) {
List<?> list = getSession() List<?> list = getSession().createQuery(" from " + this.getClazz().getSimpleName()
.createQuery(" from " + this.getClazz().getSimpleName() + " where concat(name, ' ', surname) " + " = :param_val " + removableAndStatemant()) + " where concat(name, ' ', surname) " + " = :param_val " + removableAndStatemant())
.setParameter("param_val", nameSurnameString).list(); .setParameter("param_val", nameSurnameString).list();
if (list.size() == 0) { if (list.size() == 0) {
return null; return null;
} else { } else {
return (User) list.get(0); return (User) list.get(0);
} }
} }
} }
...@@ -122,49 +122,6 @@ public class UserDaoTest extends PersistTestFunctions { ...@@ -122,49 +122,6 @@ public class UserDaoTest extends PersistTestFunctions {
} }
} }
@Test
public void testGetUserByLoginAndPassword() throws Exception {
try {
User user = new User();
user.setCryptedPassword(passwordEncoder.encode(testPasswd));
user.setLogin(testLogin);
userDao.add(user);
User user2 = userDao.getUserByLoginAndPassword(testLogin, testPasswd);
assertNotNull(user2);
assertEquals(user2.getId(), user.getId());
assertEquals(user2.getLogin(), user.getLogin());
assertEquals(user2.getCryptedPassword(), user.getCryptedPassword());
userDao.delete(user);
// after we remove it we shouldn't be able to get it
User user3 = userDao.getUserByLoginAndPassword(testLogin, testPasswd);
assertNull(user3);
// after we remove it we shouldn't be able to get the removed and modified
// object
User user4 = userDao.getUserByLoginAndPassword(user2.getLogin(), testPasswd);
assertNull(user4);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testGetUserByLoginAndEmptyPassword() throws Exception {
try {
User user = new User();
user.setCryptedPassword(passwordEncoder.encode(testPasswd));
user.setLogin(testLogin);
userDao.add(user);
User user2 = userDao.getUserByLoginAndPassword(testLogin, null);
assertNull(user2);
userDao.delete(user);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test @Test
public void testGetUserByLogin() throws Exception { public void testGetUserByLogin() throws Exception {
try { try {
......
...@@ -78,7 +78,7 @@ public class LdapService implements ILdapService { ...@@ -78,7 +78,7 @@ public class LdapService implements ILdapService {
@Override @Override
public boolean login(String login, String password) throws LDAPException { public boolean login(String login, String password) throws LDAPException {
if (!isValidConfiguratio()) { if (!isValidConfiguration()) {
logger.warn("Invalid LDAP configuration"); logger.warn("Invalid LDAP configuration");
return false; return false;
} }
...@@ -98,7 +98,7 @@ public class LdapService implements ILdapService { ...@@ -98,7 +98,7 @@ public class LdapService implements ILdapService {
@Override @Override
public List<String> getUsernames() throws LDAPException { public List<String> getUsernames() throws LDAPException {
if (!isValidConfiguratio()) { if (!isValidConfiguration()) {
logger.warn("Invalid LDAP configuration"); logger.warn("Invalid LDAP configuration");
return new ArrayList<>(); return new ArrayList<>();
} }
...@@ -128,7 +128,7 @@ public class LdapService implements ILdapService { ...@@ -128,7 +128,7 @@ public class LdapService implements ILdapService {
@Override @Override
public UserDTO getUserByLogin(String login) throws LDAPException { public UserDTO getUserByLogin(String login) throws LDAPException {
if (!isValidConfiguratio()) { if (!isValidConfiguration()) {
logger.warn("Invalid LDAP configuration"); logger.warn("Invalid LDAP configuration");
return null; return null;
} }
...@@ -187,11 +187,11 @@ public class LdapService implements ILdapService { ...@@ -187,11 +187,11 @@ public class LdapService implements ILdapService {
} }
} }
private Filter createObjectClassFilter() { private Filter createObjectClassFilter() throws LDAPException {
String objectClass = configurationService.getConfigurationValue(ConfigurationElementType.LDAP_OBJECT_CLASS); String objectClass = configurationService.getConfigurationValue(ConfigurationElementType.LDAP_OBJECT_CLASS);
if (objectClass == null || objectClass.trim().isEmpty()) { if (objectClass == null || objectClass.trim().isEmpty() || objectClass .equals( "*")) {
objectClass = "*"; return Filter.create("objectClass=*");
} }
return Filter.createEqualityFilter("objectClass", objectClass); return Filter.createEqualityFilter("objectClass", objectClass);
...@@ -220,7 +220,7 @@ public class LdapService implements ILdapService { ...@@ -220,7 +220,7 @@ public class LdapService implements ILdapService {
} }
@Override @Override
public boolean isValidConfiguratio() { public boolean isValidConfiguration() {
try { try {
String baseDn = configurationService.getConfigurationValue(ConfigurationElementType.LDAP_BASE_DN); String baseDn = configurationService.getConfigurationValue(ConfigurationElementType.LDAP_BASE_DN);
if (baseDn == null || baseDn.trim().isEmpty()) { if (baseDn == null || baseDn.trim().isEmpty()) {
......
...@@ -5,7 +5,6 @@ import java.io.FileInputStream; ...@@ -5,7 +5,6 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
...@@ -60,7 +59,6 @@ import lcsb.mapviewer.converter.zip.ZipEntryFile; ...@@ -60,7 +59,6 @@ import lcsb.mapviewer.converter.zip.ZipEntryFile;
import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.Project;
import lcsb.mapviewer.model.ProjectStatus; import lcsb.mapviewer.model.ProjectStatus;
import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.cache.UploadedFileEntry;
import lcsb.mapviewer.model.graphics.MapCanvasType;
import lcsb.mapviewer.model.log.LogType; import lcsb.mapviewer.model.log.LogType;
import lcsb.mapviewer.model.map.BioEntity; import lcsb.mapviewer.model.map.BioEntity;
import lcsb.mapviewer.model.map.MiriamData; import lcsb.mapviewer.model.map.MiriamData;
...@@ -477,20 +475,7 @@ public class ProjectService implements IProjectService { ...@@ -477,20 +475,7 @@ public class ProjectService implements IProjectService {
for (User user : userDao.getAll()) { for (User user : userDao.getAll()) {
if (!processedUser.contains(user)) { if (!processedUser.contains(user)) {
processedUser.add(user); processedUser.add(user);
for (PrivilegeType type : PrivilegeType.values()) { userService.createDefaultProjectPrivilegesForUser(project, user);
if (Project.class.equals(type.getPrivilegeObjectType())) {
int level = userService.getUserPrivilegeLevel(user, type, (Integer) null);
if (level < 0) {
if (configurationService.getValue(type).getValue().equalsIgnoreCase("true")) {
level = 1;
} else {
level = 0;
}
}
ObjectPrivilege privilege = new ObjectPrivilege(project, level, type, user);
userService.setUserPrivilege(user, privilege);
}
}
} }
} }
......
...@@ -56,6 +56,6 @@ public interface ILdapService { ...@@ -56,6 +56,6 @@ public interface ILdapService {
* @return true if LDAP configuration * @return true if LDAP configuration
* ({@link ConfigurationElementTypeGroup#LDAP_CONFIGURATION}) is valid * ({@link ConfigurationElementTypeGroup#LDAP_CONFIGURATION}) is valid
*/ */
boolean isValidConfiguratio(); boolean isValidConfiguration();
} }
...@@ -3,6 +3,7 @@ package lcsb.mapviewer.services.interfaces; ...@@ -3,6 +3,7 @@ package lcsb.mapviewer.services.interfaces;
import java.util.List; import java.util.List;
import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.commands.ColorExtractor;
import lcsb.mapviewer.model.Project;
import lcsb.mapviewer.model.user.BasicPrivilege; import lcsb.mapviewer.model.user.BasicPrivilege;
import lcsb.mapviewer.model.user.PrivilegeType; import lcsb.mapviewer.model.user.PrivilegeType;
import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.model.user.User;
...@@ -198,4 +199,10 @@ public interface IUserService { ...@@ -198,4 +199,10 @@ public interface IUserService {
String login(String login, String password, String id); String login(String login, String password, String id);
ILdapService getLdapService();
void setLdapService(ILdapService ldapService);
void createDefaultProjectPrivilegesForUser(Project project, User user);
} }
...@@ -6,13 +6,14 @@ import org.junit.runners.Suite.SuiteClasses; ...@@ -6,13 +6,14 @@ import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class) @RunWith(Suite.class)
@SuiteClasses({ CommentServiceTest.class, // @SuiteClasses({ CommentServiceTest.class, //
ConfigurationServiceTest.class, // ConfigurationServiceTest.class, //
ExternalServicesServiceTest.class, // ExternalServicesServiceTest.class, //
LayoutServiceTest.class, // LayoutServiceTest.class, //
Md5PasswordEncoderTest.class, // LdapServiceTest.class, //
ProjectServiceTest.class, // Md5PasswordEncoderTest.class, //
SearchServiceTest.class, // ProjectServiceTest.class, //
UserServiceTest.class,// SearchServiceTest.class, //
UserServiceTest.class,//
}) })
public class AllImplServiceTests { public class AllImplServiceTests {
......
...@@ -69,9 +69,9 @@ public class LdapServiceTest extends ServiceTestFunctions { ...@@ -69,9 +69,9 @@ public class LdapServiceTest extends ServiceTestFunctions {
@Test @Test
public void testIsValidConfiguration() throws Exception { public void testIsValidConfiguration() throws Exception {
try { try {
assertTrue(ldapService.isValidConfiguratio()); assertTrue(ldapService.isValidConfiguration());
configurationService.setConfigurationValue(ConfigurationElementType.LDAP_BASE_DN, ""); configurationService.setConfigurationValue(ConfigurationElementType.LDAP_BASE_DN, "");
assertFalse(ldapService.isValidConfiguratio()); assertFalse(ldapService.isValidConfiguration());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
throw e; throw e;
......
...@@ -11,14 +11,24 @@ import org.apache.log4j.Logger; ...@@ -11,14 +11,24 @@ import org.apache.log4j.Logger;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.test.annotation.Rollback; import org.springframework.test.annotation.Rollback;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPException;
import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.Project;
import lcsb.mapviewer.model.user.BasicPrivilege; import lcsb.mapviewer.model.user.BasicPrivilege;
import lcsb.mapviewer.model.user.ConfigurationElementType;
import lcsb.mapviewer.model.user.ObjectPrivilege; import lcsb.mapviewer.model.user.ObjectPrivilege;
import lcsb.mapviewer.model.user.PrivilegeType; import lcsb.mapviewer.model.user.PrivilegeType;
import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.services.ServiceTestFunctions; import lcsb.mapviewer.services.ServiceTestFunctions;
import lcsb.mapviewer.services.interfaces.ILdapService;
@Rollback(true) @Rollback(true)
public class UserServiceTest extends ServiceTestFunctions { public class UserServiceTest extends ServiceTestFunctions {
...@@ -46,6 +56,58 @@ public class UserServiceTest extends ServiceTestFunctions { ...@@ -46,6 +56,58 @@ public class UserServiceTest extends ServiceTestFunctions {
} }
} }
@Test
public void testLoginFromLdap() throws Exception {
ILdapService originalLdapService = userService.getLdapService();
try {
String login = "john.doe.test";
String passwd = "test_passwd";
assertNull(userService.getUserByLogin(login));
LdapService ldapService = createMockLdapService("testFiles/ldap/john-doe-test-example.ldif", login, passwd);
userService.setLdapService(ldapService);
assertNull(userService.login(login, "incorrect password"));
assertNotNull("User from LDAP wasn't authenticated", userService.login(login, passwd));
User user = userService.getUserByLogin(login);
assertNotNull("After authentication from LDAP user is not present in the system", user);
assertTrue(user.isConnectedToLdap());
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
userService.setLdapService(originalLdapService);
}
}
private LdapService createMockLdapService(String filename, String login, String passwd) throws LDAPException {
configurationService.setConfigurationValue(ConfigurationElementType.LDAP_BASE_DN, "dc=uni,dc=lu");
configurationService.setConfigurationValue(ConfigurationElementType.LDAP_OBJECT_CLASS, "person");