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,7 +118,12 @@ public class User implements Serializable { ...@@ -118,7 +118,12 @@ public class User implements Serializable {
*/ */
private boolean removed = false; private boolean removed = false;
@Column(name="terms_of_use_consent") /**
* User is connected to LDAP directory.
*/
private boolean connectedToLdap = false;
@Column(name = "terms_of_use_consent")
private boolean termsOfUseConsent = false; private boolean termsOfUseConsent = false;
/** /**
...@@ -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,12 +13,6 @@ import lcsb.mapviewer.persist.dao.BaseDao; ...@@ -16,12 +13,6 @@ import lcsb.mapviewer.persist.dao.BaseDao;
*/ */
public class UserDao extends BaseDao<User> { public class UserDao extends BaseDao<User> {
/**
* Service that provides password encoding.
*/
@Autowired
private PasswordEncoder passwordEncoder;
/** /**
* Default constructor. * Default constructor.
*/ */
...@@ -29,22 +20,6 @@ public class UserDao extends BaseDao<User> { ...@@ -29,22 +20,6 @@ public class UserDao extends BaseDao<User> {
super(User.class, "removed"); 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.
* *
...@@ -56,8 +31,8 @@ public class UserDao extends BaseDao<User> { ...@@ -56,8 +31,8 @@ public class UserDao extends BaseDao<User> {
*/ */
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 {
...@@ -104,8 +79,8 @@ public class UserDao extends BaseDao<User> { ...@@ -104,8 +79,8 @@ public class UserDao extends BaseDao<User> {
* @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;
......
...@@ -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);
}
}
} }
} }
......
...@@ -15,6 +15,8 @@ import org.springframework.security.core.session.SessionRegistry; ...@@ -15,6 +15,8 @@ import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.unboundid.ldap.sdk.LDAPException;
import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.commands.ColorExtractor;
import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.Configuration;
import lcsb.mapviewer.common.ObjectUtils; import lcsb.mapviewer.common.ObjectUtils;
...@@ -32,7 +34,9 @@ import lcsb.mapviewer.persist.dao.ProjectDao; ...@@ -32,7 +34,9 @@ import lcsb.mapviewer.persist.dao.ProjectDao;
import lcsb.mapviewer.persist.dao.user.PrivilegeDao; import lcsb.mapviewer.persist.dao.user.PrivilegeDao;
import lcsb.mapviewer.persist.dao.user.UserDao; import lcsb.mapviewer.persist.dao.user.UserDao;
import lcsb.mapviewer.services.SecurityException; import lcsb.mapviewer.services.SecurityException;
import lcsb.mapviewer.services.UserDTO;
import lcsb.mapviewer.services.interfaces.IConfigurationService; import lcsb.mapviewer.services.interfaces.IConfigurationService;
import lcsb.mapviewer.services.interfaces.ILdapService;
import lcsb.mapviewer.services.interfaces.ILogService; import lcsb.mapviewer.services.interfaces.ILogService;
import lcsb.mapviewer.services.interfaces.ILogService.LogParams; import lcsb.mapviewer.services.interfaces.ILogService.LogParams;
import lcsb.mapviewer.services.interfaces.IUserService; import lcsb.mapviewer.services.interfaces.IUserService;
...@@ -57,12 +61,6 @@ public class UserService implements IUserService { ...@@ -57,12 +61,6 @@ public class UserService implements IUserService {
@Autowired @Autowired
private UserDao userDao; private UserDao userDao;
/**
* Data access object for projects.
*/
@Autowired
private ProjectDao projectDao;
/** /**
* Data access object for privileges. * Data access object for privileges.
*/ */
...@@ -84,6 +82,12 @@ public class UserService implements IUserService { ...@@ -84,6 +82,12 @@ public class UserService implements IUserService {
@Autowired @Autowired
private ILogService logService; private ILogService logService;
@Autowired
private ILdapService ldapService;
@Autowired
private ProjectDao projectDao;
/** /**
* Service used for accessing configuration parameters. * Service used for accessing configuration parameters.
*/ */
...@@ -176,7 +180,7 @@ public class UserService implements IUserService { ...@@ -176,7 +180,7 @@ public class UserService implements IUserService {
// users and drop privileges one by one) // users and drop privileges one by one)
List<User> users = userDao.getAll(); List<User> users = userDao.getAll();
for (User user : users) { for (User user : users) {
List<BasicPrivilege> toRemove = new ArrayList<BasicPrivilege>(); List<BasicPrivilege> toRemove = new ArrayList<>();
for (BasicPrivilege privilege : user.getPrivileges()) { for (BasicPrivilege privilege : user.getPrivileges()) {
if (privilege.getType().equals(type) && privilege instanceof ObjectPrivilege if (privilege.getType().equals(type) && privilege instanceof ObjectPrivilege
&& integerComparator.compare(((ObjectPrivilege) privilege).getIdObject(), id) == 0) { && integerComparator.compare(((ObjectPrivilege) privilege).getIdObject(), id) == 0) {
...@@ -282,23 +286,6 @@ public class UserService implements IUserService { ...@@ -282,23 +286,6 @@ public class UserService implements IUserService {
this.userDao = userDao; this.userDao = userDao;
} }
/**
* @return the projectDao
* @see #projectDao
*/
public ProjectDao getProjectDao() {
return projectDao;
}
/**
* @param projectDao
* the projectDao to set
* @see #projectDao
*/
public void setProjectDao(ProjectDao projectDao) {
this.projectDao = projectDao;
}
/** /**
* @return the privilegeDao * @return the privilegeDao
* @see #privilegeDao * @see #privilegeDao
...@@ -514,7 +501,23 @@ public class UserService implements IUserService { ...@@ -514,7 +501,23 @@ public class UserService implements IUserService {
@Override @Override
public String login(String login, String password, String token) { public String login(String login, String password, String token) {
User user = userDao.getUserByLoginAndPassword(login, password); User user = userDao.getUserByLogin(login);
if (user == null) {
user = createUserFromLdap(login, password, user);
} else if (!user.isConnectedToLdap()) {
String cryptedPassword;
if (password != null) {
cryptedPassword = passwordEncoder.encode(password);
} else {
cryptedPassword = "";
}
user = userDao.getUserByLoginAndCryptedPassword(login, cryptedPassword);
} else {
if (!authenticateOverLdap(login, password)) {
user = null;
}
}
if (user == null && Configuration.ANONYMOUS_LOGIN.equals(login) && "".equals(password)) { if (user == null && Configuration.ANONYMOUS_LOGIN.equals(login) && "".equals(password)) {
user = getUserByLogin(Configuration.ANONYMOUS_LOGIN); user = getUserByLogin(Configuration.ANONYMOUS_LOGIN);
} }
...@@ -527,4 +530,71 @@ public class UserService implements IUserService { ...@@ -527,4 +530,71 @@ public class UserService implements IUserService {
} }
} }
private boolean authenticateOverLdap(String login, String password) {
if (!ldapService.isValidConfiguration()) {
return false;
}
try {
return ldapService.login(login, password);
} catch (LDAPException e) {
logger.warn("Problem with accessing LDAP directory", e);
return false;
}
}
private User createUserFromLdap(String login, String password, User user) {
if (!ldapService.isValidConfiguration()) {
return null;
}
try {
boolean authenticatedOverLdap = ldapService.login(login, password);
if (authenticatedOverLdap) {
UserDTO ldapUserData = ldapService.getUserByLogin(login);
user = new User();
user.setLogin(login);
user.setCryptedPassword(passwordEncoder.encode(password));
user.setName(ldapUserData.getFirstName());
user.setSurname(ldapUserData.getLastName());
user.setEmail(ldapUserData.getEmail());
user.setConnectedToLdap(true);
addUser(user);
for (Project project : projectDao.getAll()) {
createDefaultProjectPrivilegesForUser(project, user);
}
}
return user;
} catch (LDAPException e) {
logger.warn("Problem with accessing LDAP directory", e);
return null;
}
}
@Override
public ILdapService getLdapService() {
return ldapService;
}
@Override
public void setLdapService(ILdapService ldapService) {
this.ldapService = ldapService;
}
@Override
public void createDefaultProjectPrivilegesForUser(Project project, User user) {
for (PrivilegeType type : PrivilegeType.values()) {
if (Project.class.equals(type.getPrivilegeObjectType())) {
int level = 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);
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);
} }
...@@ -9,6 +9,7 @@ import org.junit.runners.Suite.SuiteClasses; ...@@ -9,6 +9,7 @@ import org.junit.runners.Suite.SuiteClasses;
ConfigurationServiceTest.class, // ConfigurationServiceTest.class, //
ExternalServicesServiceTest.class, // ExternalServicesServiceTest.class, //
LayoutServiceTest.class, // LayoutServiceTest.class, //
LdapServiceTest.class, //
Md5PasswordEncoderTest.class