001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: IdRepoListener.java,v 1.16 2009/01/28 05:34:59 ww203982 Exp $
026 *
027 */
028/**
029 * Portions Copyrighted 2011 ForgeRock AS
030 */
031package com.sun.identity.idm;
032
033import com.iplanet.sso.SSOException;
034import com.iplanet.sso.SSOToken;
035import com.sun.identity.security.AdminTokenAction;
036import com.sun.identity.shared.jaxrpc.SOAPClient;
037import com.sun.identity.shared.debug.Debug;
038import com.sun.identity.sm.SMSException;
039import com.sun.identity.sm.ServiceConfig;
040import com.sun.identity.sm.ServiceConfigManager;
041import com.sun.identity.sm.ServiceManager;
042import java.security.AccessController;
043import java.util.ArrayList;
044import java.util.Collections;
045import java.util.HashSet;
046import java.util.Map;
047import java.util.Set;
048import com.sun.identity.shared.ldap.LDAPDN;
049import com.sun.identity.shared.ldap.controls.LDAPPersistSearchControl;
050import com.sun.identity.shared.ldap.util.DN;
051
052/**
053 * Provides methods that can be called by IdRepo plugins to notify change
054 * events. Used to update cache and also to send notifications to registered
055 * listeners. Each IdRepo plugin will be given a unique instance of this object.
056 * 
057 * Additionally, this class maintains the configuration data for the IdRepo
058 * plugin and also to store the SMS Service attributes for the organization.
059 *
060 * @supported.all.api
061 */
062public final class IdRepoListener {
063
064    // Configuration data for the IdRepo plugin
065    // Must have "realm" key to correctly send the notifications to clients
066    private Map configMap = null;
067
068    // Listener registed by JAXRPC Impl to send notifications
069    private static IdEventListener remoteListener = null;
070
071    private static Debug debug = Debug.getInstance("idrepoListener");
072
073    // To serialize and deserialize configMap
074    protected static SOAPClient sclient;
075    
076    // Configured Identity Types
077    private static IdType[] defaultIdTypes;
078    
079    // Flags to check if caching is enabled and to clear them
080    private static boolean cacheChecked;
081    private static boolean cacheEnabled;
082    private static IdServices idServices;
083
084    /*
085     * (non-Javadoc)
086     * 
087     * @see com.iplanet.am.sdk.AMObjectListener#allObjectsChanged()
088     */
089    public void allObjectsChanged() {
090        if (debug.messageEnabled()) {
091            debug.message("IdRepoListener: allObjectsChanged Called!");
092        }
093
094        // Check if caching is enabled
095        if (!cacheChecked) {
096            idServices = IdServicesFactory.getDataStoreServices();
097            if (idServices instanceof IdCachedServices) {
098                // If Caching was enabled - then clear the cache!!
099                cacheEnabled = true;
100            }
101            cacheChecked = true;
102        }
103        if (cacheEnabled) {
104            // If Caching was enabled - then clear the cache!!
105            ((IdCachedServices) idServices).clearCache();
106        }
107
108        // Get the list of listeners setup with idRepo
109        String org = (String) configMap.get("realm");
110        ArrayList list = (ArrayList) AMIdentityRepository.listeners.get(org);
111        // Update any listeners registered with IdRepo
112        if (list != null) {
113            int size = list.size();
114            for (int j = 0; j < size; j++) {
115                IdEventListener l = (IdEventListener) list.get(j);
116                l.allIdentitiesChanged();
117            }
118        }
119        if (remoteListener != null) {
120            remoteListener.allIdentitiesChanged();
121        }
122    }
123
124    /**
125     * 
126     * This method has been deprecated as of OpenSSO Enterprise 8.0.
127     * 
128     * @param name name of the identity that changed
129     * @param type change type i.e., add, delete, modify, etc.
130     * @param cMap configuration map that contains realm and plugin-name
131     *
132     * @deprecated  As of Sun Java System Access Manager 7.1.
133     */
134    public void objectChanged(String name, int type, Map cMap) {
135        objectChanged(name, null, type, cMap);
136    }
137    
138    /**
139     * Notification mechanism for IdRepo plugins to specify the identiy name
140     * and identity type that has been changed.
141     * 
142     * @param name name of the identity that changed
143     * @param idType IdType i.e., user, group, etc.
144     * @param changeType change type i.e., add, delete, modify, etc.
145     * @param cMap configuration map that contains realm and plugin-name
146     */
147    public void objectChanged(String name, IdType idType, int changeType,
148        Map cMap) {
149        if (debug.messageEnabled()) {
150            debug.message("objectChanged called with IdType= name: " + name +
151                " IdType: " + idType + " ChangeType: " + changeType +
152                "\nConfigmap = " + cMap);
153        }
154        // Get the list of listeners setup with idRepo
155        String org = (String) configMap.get("realm");
156        ArrayList list = (ArrayList) AMIdentityRepository.listeners.get(org);
157
158        // Check if caching is enabled
159        if (!cacheChecked) {
160            idServices = IdServicesFactory.getDataStoreServices();
161            if (idServices instanceof IdCachedServices) {
162                // If Caching was enabled - then clear the cache!!
163                cacheEnabled = true;
164            }
165            cacheChecked = true;
166        }
167        
168        if (name.length() > 0) {
169            String[] changed = getChangedIds(name, idType, cMap);
170            for (int i = 0; i < changed.length; i++) {
171
172                if (cacheEnabled) {
173                    ((IdCachedServices) idServices).dirtyCache(changed[i],
174                        changeType, false, false, Collections.EMPTY_SET);
175                }
176
177                // Update any listeners registered with IdRepo
178                if (list != null) {
179                    int size = list.size();
180                    for (int j = 0; j < size; j++) {
181                        IdEventListener l = (IdEventListener) list.get(j);
182                        switch (changeType) {
183                        case OBJECT_CHANGED:
184                        case OBJECT_ADDED:
185                            l.identityChanged(changed[i]);
186                            break;
187                        case OBJECT_REMOVED:
188                            l.identityDeleted(changed[i]);
189                            break;
190                        case OBJECT_RENAMED:
191                            l.identityRenamed(changed[i]);
192                        }
193                    }
194                }
195                
196                // Handle remote listener, should not be mixed with
197                // IdRepo listeners, since it can null or empty
198                if (remoteListener != null) {
199                    switch (changeType) {
200                        case OBJECT_CHANGED:
201                        case OBJECT_ADDED:
202                            remoteListener.identityChanged(changed[i]);
203                            break;
204                        case OBJECT_REMOVED:
205                            remoteListener.identityDeleted(changed[i]);
206                            break;
207                        case OBJECT_RENAMED:
208                            remoteListener.identityRenamed(changed[i]);
209                    }
210                }
211            }
212        }
213    }
214
215    public static void addRemoteListener(IdEventListener l) {
216        remoteListener = l;
217    }
218    
219    /*
220     * Returns the configurations for the IdRepo plugins
221     */
222    public Map getConfigMap() {
223        return configMap;
224    }
225
226    /*
227     * Maintains the configurations for the IdRepo plugins
228     */
229    public void setConfigMap(Map cMap) {
230        configMap = cMap;
231    }
232
233    /**
234     * Stores service's dynamic attributes within the IdRepo plugin
235     * configuration. In the current implementation changes to dynamic
236     * attributes to LDAPv3Repo restart the plugin, since it triggers
237     * a configuration change notification.
238     * 
239     * @param sName service name for which attributes are being set
240     * @param attrs service synamic attributes
241     * @throws com.sun.identity.idm.IdRepoException
242     */
243    public void setServiceAttributes(String sName, Map attrs)
244            throws IdRepoException {
245        String realm = (String) configMap.get("realm");
246        String pluginName = (String) configMap.get("plugin-name");
247        if (realm == null || pluginName == null) {
248            AMIdentityRepository.debug.error(
249                    "IdRepoListener.setServiveAttribute: realm or plugin name"
250                    + " is null");
251            Object[] args = { sName, IdType.ROLE.getName() };
252            throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, "105", args);
253        }
254        try {
255            SSOToken token = (SSOToken) AccessController
256                    .doPrivileged(AdminTokenAction.getInstance());
257            ServiceConfigManager scm = new ServiceConfigManager(token,
258                    IdConstants.REPO_SERVICE, "1.0");
259            ServiceConfig sc = scm.getOrganizationConfig(realm, null);
260            if (sc == null) {
261                return;
262            }
263            
264            ServiceConfig subConfig = sc.getSubConfig(pluginName);
265            if (subConfig == null) {
266                return;
267            }
268            Map attributes = subConfig.getAttributes();
269            Set vals = (Set) attributes.get(IdConstants.SERVICE_ATTRS);
270            if (vals == null || vals == Collections.EMPTY_SET) {
271                vals = new HashSet();
272            }
273            if (sclient == null) {
274                sclient = new SOAPClient("dummy");    
275            }
276            String mapStr = sclient.encodeMap("result", attrs);
277            vals = new HashSet();
278            vals.add(mapStr);
279            attributes.put(IdConstants.SERVICE_ATTRS, vals);
280            subConfig.setAttributes(attributes);
281        } catch (SMSException smse) {
282            AMIdentityRepository.debug.error(
283                    "IdRepoListener: Unable to set service attributes", smse);
284            Object[] args = { sName, IdType.ROLE.getName() };
285            throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, "105", args);
286        } catch (SSOException ssoe) {
287            AMIdentityRepository.debug.error(
288                    "IdRepoListener: Unable to set service attributes", ssoe);
289            Object[] args = { sName, IdType.ROLE.getName() };
290            throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, "105", args);
291        }
292    }
293
294    private String[] getChangedIds(String name, IdType type, Map cMap) {
295        int size = IdUtils.supportedTypes.size();
296        // If configMap is null, then this is a "remote" cache update
297        if ((cMap == null) || cMap.isEmpty()) {
298            String ct[] = new String[1];
299            if (DN.isDN(name)) {
300                // Name should be the universal id
301                ct[0] = name;
302            } else {
303                if (type == null) {
304                    // Default to user
305                    type = IdType.USER;
306                }
307                ct[0] = "id=" + name + ",ou=" + type.getName() + "," +
308                        ServiceManager.getBaseDN();
309            }
310            return ct;
311        }
312        String changedTypes[] = null;
313        IdType types[] = null;
314        if (type == null) {
315            changedTypes = new String[size];
316            if (defaultIdTypes  == null) {
317                Set idtypes = IdUtils.supportedTypes;
318                defaultIdTypes = new IdType[idtypes.size()];
319                defaultIdTypes = (IdType[]) idtypes.toArray(defaultIdTypes);
320            }
321            types = defaultIdTypes;
322        } else {
323            changedTypes = new String[1];
324            types = new IdType[1];
325            types[0] = type;
326        }
327        String realm = (String) cMap.get("realm");
328        String Amsdk = (String) cMap.get("amsdk");
329        boolean isAmsdk = (Amsdk == null) ? false : true;
330
331        for (int i = 0; i < types.length; i++) {
332            IdType itype = types[i];
333            String n = DN.isDN(name) ? LDAPDN.explodeDN(name, true)[0] : name;
334            String id = "id=" + n + ",ou=" + itype.getName() + "," + realm;
335            if (isAmsdk) {
336                id = id + ",amsdkdn=" + name;
337            }
338            changedTypes[i] = id;
339        }
340        return changedTypes;
341    }
342    
343    // Constants for change type recevied from the IdRepo plugins
344    
345    /**
346     * Represents an object addition event type.
347     */
348    public static final int OBJECT_ADDED = LDAPPersistSearchControl.ADD;
349
350    /**
351     * Represents an object change event type.
352     */
353    public static final int OBJECT_CHANGED = LDAPPersistSearchControl.MODIFY;
354
355    /**
356     * Represents an object removal event type.
357     */
358    public static final int OBJECT_REMOVED = LDAPPersistSearchControl.DELETE;
359
360    /**
361     * Represents an object renaming event type.
362     */
363    public static final int OBJECT_RENAMED = LDAPPersistSearchControl.MODDN;
364}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.