Skip to content

Commit

Permalink
geosolutions-it#195: LDAP User and UserGroup DAOs (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbarto committed Nov 4, 2019
1 parent 15b4ac8 commit 6ee8c47
Show file tree
Hide file tree
Showing 4 changed files with 534 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Copyright (C) 2019 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* GPLv3 + Classpath exception
*
* This program 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, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 it.geosolutions.geostore.core.dao.ldap.impl;

import java.util.List;
import javax.naming.directory.DirContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.ldap.control.SortControlDirContextProcessor;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.DirContextProcessor;
import org.springframework.ldap.core.LdapTemplate;
import com.googlecode.genericdao.search.Filter;
import com.googlecode.genericdao.search.ISearch;
import it.geosolutions.geostore.core.dao.ldap.impl.LdapBaseDAOImpl.NullDirContextProcessor;

public abstract class LdapBaseDAOImpl {

public static final class NullDirContextProcessor implements DirContextProcessor {
public void postProcess(DirContext ctx) {
// Do nothing
}

public void preProcess(DirContext ctx) {
// Do nothing
}
}

protected String searchBase = "";
protected String baseFilter = "cn=*";
protected String nameAttribute = "cn";
protected String descriptionAttribute = "description";
protected boolean sortEnabled = false;

protected ContextSource contextSource;
protected LdapTemplate template;

public LdapBaseDAOImpl(ContextSource contextSource) {
this.contextSource = contextSource;
template = new LdapTemplate(contextSource);
}

public String getSearchBase() {
return searchBase;
}

public void setSearchBase(String searchBase) {
this.searchBase = searchBase;
}

public String getFilter() {
return baseFilter;
}

public void setFilter(String filter) {
this.baseFilter = filter;
}

public String getNameAttribute() {
return nameAttribute;
}

public void setNameAttribute(String nameAttribute) {
this.nameAttribute = nameAttribute;
}

public String getDescriptionAttribute() {
return descriptionAttribute;
}

public void setDescriptionAttribute(String descriptionAttribute) {
this.descriptionAttribute = descriptionAttribute;
}


protected DirContextProcessor getProcessorForSearch(ISearch search) {
if (sortEnabled && search.getSorts() != null && search.getSorts().size() == 1) {
return new SortControlDirContextProcessor(nameAttribute);
}
return new NullDirContextProcessor();
}

public boolean isSortEnabled() {
return sortEnabled;
}

public void setSortEnabled(boolean sortEnabled) {
this.sortEnabled = sortEnabled;
}

protected String combineFilters(String baseFilter, String ldapFilter) {
if ("".equals(baseFilter)) {
return ldapFilter;
}
if ("".equals(ldapFilter)) {
return baseFilter;
}
return "(& ("+baseFilter+") ("+ldapFilter+"))";
}

protected String getLdapFilter(ISearch search) {
String currentFilter = "";
for (Filter filter : search.getFilters()) {
currentFilter = combineFilters(currentFilter, getLdapFilter(filter));
}
return currentFilter;
}

private String getLdapFilter(Filter filter) {
switch(filter.getOperator()) {
case Filter.OP_EQUAL:
return filter.getProperty() + "=" + filter.getValue().toString();
//TODO: implement all operators
}
return "";
}

protected Expression getSearchExpression(List<Filter> filters) {
String expression = "";
for (Filter filter: filters) {
expression = combineExpressions(expression, getSearchExpression(filter));
}
if ("".equals(expression)) {
expression = "true";
}
ExpressionParser parser = new SpelExpressionParser();
return parser.parseExpression(expression);
}

protected String combineExpressions(String expression, String searchExpression) {
if ("".equals(expression)) {
return searchExpression;
}
if ("".equals(searchExpression)) {
return expression;
}
return "("+expression+") && ("+searchExpression+")";
}

private String getSearchExpression(Filter filter) {
switch(filter.getOperator()) {
case Filter.OP_EQUAL:
return filter.getProperty() + "==" + filter.getValue().toString();
//TODO: implement all operators
}
return "";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* Copyright (C) 2019 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* GPLv3 + Classpath exception
*
* This program 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, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 it.geosolutions.geostore.core.dao.ldap.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.directory.SearchControls;
import org.apache.log4j.Logger;
import org.springframework.ldap.control.SortControlDirContextProcessor;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.DirContextProcessor;
import org.springframework.ldap.core.support.AbstractContextMapper;
import org.springframework.transaction.annotation.Transactional;
import com.googlecode.genericdao.search.ISearch;
import it.geosolutions.geostore.core.dao.UserDAO;
import it.geosolutions.geostore.core.model.User;
import it.geosolutions.geostore.core.model.UserAttribute;

/**
* Class UserDAOImpl.
*
* @author Tobia di Pisa (tobia.dipisa at geo-solutions.it)
* @author ETj (etj at geo-solutions.it)
*/
@Transactional(value = "geostoreTransactionManager")
public class UserDAOImpl extends LdapBaseDAOImpl implements UserDAO {

private static final Logger LOGGER = Logger.getLogger(UserDAOImpl.class);

protected Map<String, String> attributesMapper = new HashMap<String, String>();

public UserDAOImpl(ContextSource contextSource) {
super(contextSource);
}

public Map<String, String> getAttributesMapper() {
return attributesMapper;
}

public void setAttributesMapper(Map<String, String> attributesMapper) {
this.attributesMapper = attributesMapper;
}

/*
* (non-Javadoc)
*
* @see com.trg.dao.jpa.GenericDAOImpl#persist(T[])
*/
@Override
public void persist(User... entities) {

}

/*
* (non-Javadoc)
*
* @see com.trg.dao.jpa.GenericDAOImpl#findAll()
*/
@Override
public List<User> findAll() {
return ldapSearch(baseFilter, new NullDirContextProcessor());
}

/*
* (non-Javadoc)
*
* @see com.trg.dao.jpa.GenericDAOImpl#search(com.trg.search.ISearch)
*/
@SuppressWarnings("unchecked")
@Override
public List<User> search(ISearch search) {
return ldapSearch(combineFilters(baseFilter, getLdapFilter(search)), getProcessorForSearch(search));
}

protected List<User> ldapSearch(String filter, DirContextProcessor processor) {
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
return template.search(searchBase, filter, controls, new AbstractContextMapper() {
int counter = 1;
@Override
protected User doMapFromContext(DirContextOperations ctx) {
User user = new User();
user.setId((long)counter++);
user.setEnabled(true);
user.setName(ctx.getStringAttribute(nameAttribute));
List<UserAttribute> attributes = new ArrayList<UserAttribute>();
for (String ldapAttr : attributesMapper.keySet()) {
String value = ctx.getStringAttribute(ldapAttr);
String userAttr = attributesMapper.get(ldapAttr);
UserAttribute attr = new UserAttribute();
attr.setName(userAttr);
attr.setValue(value);
}
user.setAttribute(attributes);
return user;
}

}, processor);
}

/*
* (non-Javadoc)
*
* @see com.trg.dao.jpa.GenericDAOImpl#merge(java.lang.Object)
*/
@Override
public User merge(User entity) {
return entity;
}

/*
* (non-Javadoc)
*
* @see com.trg.dao.jpa.GenericDAOImpl#remove(java.lang.Object)
*/
@Override
public boolean remove(User entity) {
return true;
}

/*
* (non-Javadoc)
*
* @see com.trg.dao.jpa.GenericDAOImpl#removeById(java.io.Serializable)
*/
@Override
public boolean removeById(Long id) {
return true;
}

/*
* (non-Javadoc)
*
* @see com.trg.dao.jpa.GenericDAOImpl#find(java.io.Serializable)
*/
@Override
public User find(Long id) {
return null;
}

/*
* (non-Javadoc)
*
* @see com.trg.dao.jpa.GenericDAOImpl#save(T[])
*/
@Override
public User[] save(User... entities) {
return entities;
}

@Override
public int count(ISearch search) {
return search(search).size();
}

}
Loading

0 comments on commit 6ee8c47

Please sign in to comment.