001/*
002 *  Copyright 2016 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.contentio.synchronize.impl;
017
018import java.util.List;
019import java.util.Map;
020
021import org.apache.avalon.framework.activity.Initializable;
022import org.apache.avalon.framework.component.Component;
023import org.apache.avalon.framework.configuration.Configuration;
024import org.apache.avalon.framework.configuration.ConfigurationException;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.slf4j.Logger;
028
029import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection;
030
031/**
032 * Implementation of {@link SynchronizableContentsCollection} to be synchronized with a LDAP data source
033 */
034public class LDAPSynchronizableContentsCollection extends AbstractDataSourceSynchronizableContentsCollection implements Component, Initializable
035{
036    private static final String __PARAM_LDAP_SCOPE = "scope";
037    private static final String __PARAM_LDAP_RELATIVE_DN = "peopleDN";
038    private static final String __PARAM_LDAP_FILTER = "baseFilter";
039    
040    private static final int __DEFAULT_PAGE_SIZE = 1000;
041    
042    /** URL connection to the ldap server. */
043    protected String _ldapUrl; 
044    /** Base DN to the ldap server. */
045    protected String _ldapBaseDN;
046    /** Distinguished name of the admin used for searching. */
047    protected String _ldapAdminRelativeDN;
048    /** Password associated with the admin. */
049    protected String _ldapAdminPassword;
050    /** Authentication method used. */
051    protected String _ldapAuthenticationMethod;
052    /** Use ssl for connecting to ldap server. */
053    protected boolean _ldapUseSSL;
054    /** Enable following referrals. */
055    protected boolean _ldapFollowReferrals;
056    /** Alias dereferencing mode. */
057    protected String _ldapAliasDerefMode;
058    
059    /** The page size */
060    protected int _pageSize;
061    /** Indicates if the LDAP server supports paging feature. */
062    protected boolean _pagingSupported;
063    /** Indicates if the testing of the LDAP server paging feature has already been made. */
064    protected boolean _pagingSupportedInitialized;
065
066    /** The helper for LDAP connection */
067    protected LDAPCollectionHelper _ldapHelper;
068    
069    @Override
070    public void service(ServiceManager serviceManager) throws ServiceException
071    {
072        super.service(serviceManager);
073        _ldapHelper = (LDAPCollectionHelper) serviceManager.lookup(LDAPCollectionHelper.ROLE);
074    }
075    
076    @Override
077    public void initialize() throws Exception
078    {
079        _ldapHelper._delayedInitialize(getDataSourceId());
080    }
081    
082    @Override
083    public void configure(Configuration configuration) throws ConfigurationException
084    {
085        super.configure(configuration);
086        _pageSize = configuration.getChild("pageSize").getValueAsInteger(__DEFAULT_PAGE_SIZE);
087    }
088    
089    @Override
090    protected void _internalPopulate(Logger logger)
091    {
092        String idField = getIdField();
093        Map<String, List<String>> mapping = getMapping();
094        
095        List<String> remoteKeys = mapping.get(idField);
096        if (remoteKeys != null && remoteKeys.size() > 0)
097        {
098            Map<String, Map<String, List<Object>>> remoteValuesByContent = _ldapHelper.search(getId(), _pageSize, getRelativeDN(), getFilter(), getSearchScope(), getMapping(), remoteKeys.get(0), logger);
099            _nbError = _ldapHelper.getNbErrors();
100            _hasGlobalError = _ldapHelper.hasGlobalError();
101            
102            for (String idValue : remoteValuesByContent.keySet())
103            {
104                Map<String, List<Object>> remoteValues = remoteValuesByContent.get(idValue);
105                importContent(idValue, remoteValues, logger);
106            }
107        }
108        else
109        {
110            _nbError = 1;
111            logger.error("Missing LDAP attribute in mapping for field '{}' holding the unique identifier", idField);
112        }
113        
114        
115    }
116    
117    /**
118     * Get the scope for LDAP search
119     * @return The scope
120     */
121    protected String getSearchScope()
122    {
123        return (String) _modelParamValues.get(__PARAM_LDAP_SCOPE);
124    }
125    
126    /**
127     * Get the LDAP filter
128     * @return the filter
129     */
130    protected String getFilter()
131    {
132        return (String) _modelParamValues.get(__PARAM_LDAP_FILTER);
133    }
134    
135    /**
136     * Get the LDAP relative DN
137     * @return the relative DN 
138     */
139    protected String getRelativeDN()
140    {
141        return (String) _modelParamValues.get(__PARAM_LDAP_RELATIVE_DN);
142    }
143}