001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 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: SubjectTypeManager.java,v 1.5 2009/01/28 05:35:01 ww203982 Exp $
026 *
027 * Portions Copyrighted 2014 ForgeRock AS.
028 */
029
030
031
032
033package com.sun.identity.policy;
034
035import java.util.*;
036
037import com.iplanet.sso.SSOToken;
038import com.iplanet.sso.SSOException;
039import com.sun.identity.sm.*;
040import com.sun.identity.policy.interfaces.Subject;
041import com.sun.identity.shared.locale.AMResourceBundleCache;
042import com.sun.identity.shared.debug.Debug;
043import com.sun.identity.shared.locale.Locale;
044
045import com.sun.identity.shared.ldap.util.DN;
046
047/**
048 * The class <code>SubjectTypeManager</code> provides
049 * methods to get a list of configured <code>Subject
050 * </code> objects, and to obtain a factory object for it.
051 *
052 * @supported.all.api
053 * @deprecated since 12.0.0
054 */
055@Deprecated
056public class SubjectTypeManager {
057
058    private static String SUBJECT = "Subject";
059
060    private SSOToken token;
061    private PolicyManager pm;
062
063    private ResourceBundle rb;
064    private Subjects realmSubjects = null;
065    private Map sharedSubjects = Collections.synchronizedMap(new HashMap());
066    private static AMResourceBundleCache amCache = 
067            AMResourceBundleCache.getInstance();
068    private String pmRealmName;
069
070    static Debug debug = PolicyManager.debug;
071
072    /**
073     * Constructs a <code>SubjectTypeManager</code> object
074     */
075    protected SubjectTypeManager() throws SSOException {
076        token = ServiceTypeManager.getSSOToken();
077        String lstr = token.getProperty("Locale");
078        java.util.Locale loc = com.sun.identity.shared.locale.Locale.getLocale(
079            lstr);
080        rb = amCache.getResBundle(ResBundleUtils.rbName, loc);
081    }
082
083    /**
084     * Constructs a <code>SubjectTypeManager</code> object
085     * @param pm <code>PolicyManager</code> to initialize
086     * <code>SubjectTypeManager</code> with
087     */
088    protected SubjectTypeManager(PolicyManager pm)  {
089        this.pm = pm;
090        pmRealmName = new DN(pm.getOrganizationDN()).toRFCString()
091                .toLowerCase();
092        token = pm.token;
093        java.util.Locale loc;
094        try {
095            String lstr = token.getProperty("Locale");
096            loc = com.sun.identity.shared.locale.Locale.getLocale(lstr);
097        } catch (SSOException ex) {
098            debug.error(
099                "SubjectTypeManager:Unable to retreive locale from SSOToken",
100                ex);
101            loc = Locale.getDefaultLocale();
102        }
103
104         if (debug.messageEnabled()) {
105            debug.message("SubjectManager locale="+loc+"\tI18nFileName = "+
106                     ResBundleUtils.rbName);
107        }
108        rb = amCache.getResBundle(ResBundleUtils.rbName, loc);
109    }
110
111    /**
112     * Returns a set of all valid subject type names defined by the policy
113     * service.
114     * Examples are <code>LDAPRole</code>, <code>LDAPGroup</code>, etc.
115     *
116     * @return a set of all valid subject type names defined by the policy
117     *         service.
118     * @throws SSOException if the <code>SSOToken</code> used to create 
119     *                      the <code>PolicyManager</code> has become invalid
120     * @throws PolicyException for any other abnormal condition
121     */
122    public Set getSubjectTypeNames() throws SSOException,
123            PolicyException {
124        return (PolicyManager.getPluginSchemaNames(SUBJECT));
125    }
126
127    /**
128     * Returns a set of valid subject type names configured for the
129     * organization.
130     * Examples are <code>LDAPRole</code>, <code>LDAPGroup</code>, etc.
131     *
132     * @return a set of valid subject type names configured for the
133     *         organization.
134     * @throws SSOException if the <code>SSOToken</code> used to create 
135     *                      the <code>PolicyManager</code> has become invalid
136     * @throws PolicyException for any other abnormal condition
137     */
138    public Set getSelectedSubjectTypeNames() throws SSOException,
139            PolicyException {
140        Map policyConfig = pm.getPolicyConfig();
141        Set selectedSubjects = null;
142        if (policyConfig != null) {
143            selectedSubjects = 
144                    (Set)policyConfig.get(PolicyConfig.SELECTED_SUBJECTS); 
145        }
146        if ( selectedSubjects == null) {
147            selectedSubjects = Collections.EMPTY_SET;
148        }
149        return selectedSubjects;
150    }
151
152    /**
153     * Returns the type of the <code>Subject</code> implementation.
154     * For example <code>LDAPRoles</code>, <code>LDAPGroups</code> etc.
155     *
156     * @param subject <code>Subject</code> for which this method will
157     * return its associated type
158     *
159     * @return type of the <code>Subject</code>, e.g., <code>LDAPRoles</code>,
160     *         <code>LDAPGroups</code>, etc. Returns <code>null</code> if
161     *         not present.
162     */
163    public String getSubjectTypeName(Subject subject) {
164        return (subjectTypeName(subject));
165    }
166
167    /**
168     * Returns the I18N properties file name that should be
169     * used to localize display names for the given
170     * subject type.
171     *
172     * @param subjectType subject type name
173     *
174     * @return i18n properties file name
175     */
176    protected String getI18NPropertiesFileName(String subjectType) {
177        // %%% Need to get the file name from plugin schema
178        return (null);
179    }
180
181    /**
182     * Returns the I18N key to be used to localize the
183     * display name for the subject type name.
184     *
185     * @param subjectType subject type name
186     *
187     * @return i18n key to obtain the display name
188     */
189    public String getI18NKey(String subjectType) {
190        PluginSchema ps = PolicyManager.getPluginSchema(SUBJECT, subjectType);
191        if (ps != null) {
192            return (ps.getI18NKey());
193        }
194        return (null);
195    }
196
197    /**
198     * Returns the display name for the subject type
199     * @param subjectType subject type
200     * @return display name for the subject type
201     */
202    public String getDisplayName(String subjectType) {
203        String displayName = null;
204        String i18nKey = getI18NKey(subjectType);
205        if (i18nKey == null || i18nKey.length() == 0) {
206            displayName = subjectType;
207        } else {
208            displayName = Locale.getString(rb,i18nKey,debug);
209        }
210        return displayName;
211    }
212
213    /**
214     * Returns an instance of the <code>Subject</code> given the subject type
215     * name.
216     *
217     * @param subjectType subject type.
218     * @return an instance of the <code>Subject</code> given the subject type
219     * name.
220     * @throws NameNotFoundException if the <code>Subject</code> for the
221     *            <code>subjectType</code> name is not found
222     * @throws PolicyException for any other abnormal condition
223     */
224    public Subject getSubject(String subjectType)
225        throws NameNotFoundException, PolicyException {
226        PluginSchema ps = PolicyManager.getPluginSchema(SUBJECT, subjectType);
227        if (ps == null) {
228            throw (new NameNotFoundException(ResBundleUtils.rbName,
229                "invalid_subject", null,
230                subjectType, PolicyException.USER_COLLECTION));
231        }
232
233        // Construct the object
234        Subject answer = null;
235        try {
236            String className = ps.getClassName();
237            answer = (Subject) Class.forName(className).newInstance();
238        } catch (Exception e) {
239            throw (new PolicyException(e));
240        }
241
242        //initialize with policy config
243        answer.initialize(pm.getPolicyConfig());
244        return (answer);
245    }
246
247    /**
248     * Adds a policy subject at realm. 
249     *
250     * @param subjectName name of the Subject instance 
251     * @param subject Subject object to be added 
252     *
253     * @throws NameAlreadyExistsException if a Subject with the given name
254     *          already exists at the realm
255     * @throws InvalidNameException if the subject name is invalid
256     *
257     * @throws PolicyException if can not add the Subject 
258     */
259    public void addSubject(String subjectName, Subject subject) 
260            throws NameAlreadyExistsException, InvalidNameException,
261            PolicyException, SSOException {
262
263        //we  really do not use the exclusive flag at realm level
264        addSubject(subjectName, subject, false);
265    }
266
267    /**
268     * Adds a policy subject at realm. 
269     *
270     * @param subjectName name of the Subject instance 
271     * @param subject Subject object to be added 
272     *
273     * @param exclusive boolean flag indicating whether the subject 
274     *        is to be exclusive subject. If subject is exclusive, 
275     *        policy applies to users who are not members of the 
276     *        subject. Otherwise, policy applies to members of the subject.
277     *
278     * @throws NameAlreadyExistsException if a Subject with the given name
279     *          already exists at the realm
280     * @throws InvalidNameException if the subject name is invalid
281     *
282     * @throws PolicyException if can not add the Subject 
283     *
284     *
285     */
286    private void addSubject(String subjectName, Subject subject, 
287            boolean exclusive) 
288            throws NameAlreadyExistsException, InvalidNameException,
289            PolicyException, SSOException {
290        if (debug.messageEnabled()) {
291            debug.message("Adding realm subject : " + subjectName
292                    + ", in realm:" + pmRealmName);
293        }
294        if (realmSubjects == null) {
295            initRealmSubjects();
296        }
297        realmSubjects.addSubject(subjectName, subject, exclusive);
298        saveSubjects();
299        if (debug.messageEnabled()) {
300            debug.message("Added realm subject : " + subjectName
301                    + ", in realm:" + pmRealmName);
302        }
303    }
304
305    /**
306     * Removes the subject with the given name  from the realm.
307     * This method would throw PolicyException if the subject 
308     * is being used by any policy.
309     *
310     * @param subjectName name of the Subject
311     *
312     * @return returns the Subject object being removed,
313     *         returns <code>null</code> if Subject with 
314     *         the given subjectName is not present 
315     *
316     * @throws PolicyException if can not remove the Subject 
317     */
318    public Subject removeSubject(String subjectName) 
319            throws ObjectInUseException, PolicyException, SSOException {
320        return removeSubject(subjectName, false);
321    }
322
323    /**
324     * Removes the subject with the given name  from the realm.
325     * This method would throw PolicyException if the subject 
326     * is being used by any policy unless <code>forcedRemove</code> 
327     * argument  is set to <code>true</code>. 
328     * If the <code>forcedRemove</code> argument is set to 
329     * <code>true</code> policies that are using the subject would 
330     * be modified to  remove the references to the subject
331     *
332     * @param subjectName name of the Subject
333     * @param forcedRemove if set to <code>true</code>, policies that
334     *    use the subject would be modifed to remove the references
335     *    to the subject. Otherwise, <code>ObjectInUseException</code>
336     *    would be thrown if there is any policy using the subject
337     *
338     * @return returns the Subject object being removed,
339     *         returns <code>null</code> if Subject with 
340     *         the given subjectName is not present 
341     *
342     * @throws PolicyException if can not remove the Subject 
343     */
344    public Subject removeSubject(String subjectName, boolean forcedRemove) 
345            throws ObjectInUseException, PolicyException, SSOException {
346        if (debug.messageEnabled()) {
347            debug.message("Removing realm subject : " + subjectName
348                    + ", in realm:" + pmRealmName);
349        }
350        if (realmSubjects == null) {
351            initRealmSubjects();
352        }
353        if (forcedRemove) {
354            Set userPolicies = pm.getPoliciesUsingRealmSubject(subjectName);
355            for (Iterator policyIter = userPolicies.iterator();
356                    policyIter.hasNext();) {
357                Policy policy = (Policy)policyIter.next();
358                policy.removeSubject(subjectName);
359            }
360        } else {
361            Policy p = pm.getPolicyUsingRealmSubject(subjectName);
362            if ( p != null) {
363                //ObjectInUseException(String rbName, String errCode,         
364                //Object[] args, String name, Object user) 
365                throw new ObjectInUseException(null, null, null, null, null);
366            }
367        }
368        Subject subject = realmSubjects.removeSubject(subjectName);
369        saveSubjects();
370        if (debug.messageEnabled()) {
371            debug.message("Removed realm subject : " + subjectName
372                    + ", in realm:" + pmRealmName);
373        }
374        return subject;
375    }
376
377    /**
378     * Replaces an existing subject with the same name by the
379     * current one at the realm. If a subject with the same name does 
380     * not exist, it will be added.
381     *
382     * @param subjectName name of the Subject instance 
383     * @param subject Subject that will replace an existing Subject
384     *         with the same name
385     *
386     * @throws NameNotFoundException if a Subject instance
387     *         with the given name is not present
388     *
389     * @throws PolicyException if can not replace the Subject 
390     */
391    public void replaceSubject(String subjectName, Subject subject) 
392            throws NameNotFoundException, PolicyException, SSOException {
393
394        //we  really do not use the exclusive flag at realm level
395        replaceSubject(subjectName, subject, false);
396    }
397
398    /**
399     * Replaces an existing subject with the same name by the
400     * current one at the realm. If a subject with the same name does 
401     * not exist, it will be added.
402     *
403     * @param subjectName name of the Subject instance 
404     * @param subject Subject that will replace an existing Subject
405     *         with the same name
406     *
407     * @param exclusive boolean flag indicating whether the subject 
408     *        is to be exclusive subject. If subject is exclusive, 
409     *        policy applies to users who are not members of the 
410     *        subject. Otherwise, policy applies to members of the subject.
411     *
412     * @throws NameNotFoundException if a Subject instance
413     *         with the given name is not present
414     *
415     * @throws PolicyException if can not replace the Subject 
416     *
417     *
418     */
419    private void replaceSubject(String subjectName, Subject subject, 
420            boolean exclusive) 
421            throws NameNotFoundException, PolicyException, SSOException {
422        if (debug.messageEnabled()) {
423            debug.message("Replacing realm subject : " + subjectName
424                    + ", in realm:" + pmRealmName);
425        }
426        if (realmSubjects == null) {
427            initRealmSubjects();
428        }
429        realmSubjects.replaceSubject(subjectName, subject, exclusive);
430        saveSubjects();
431        if (debug.messageEnabled()) {
432            debug.message("Replaced realm subject : " + subjectName
433                    + ", in realm:" + pmRealmName);
434        }
435    }
436
437    /**
438     * Get the set of names of Subject(s) defined at the realm
439     *
440     * @return set of subject names
441     */
442    public Set getSubjectNames() throws PolicyException, SSOException {
443        if (debug.messageEnabled()) {
444            debug.message("Getting subject names from realm: " 
445                    +  pmRealmName);
446        }
447        if (realmSubjects == null) {
448            initRealmSubjects();
449        }
450        Set subjectNames = realmSubjects.getSubjectNames();
451        if (debug.messageEnabled()) {
452            debug.message("Returning subject names from realm: " 
453                    +  pmRealmName + ",subjectNames=" + subjectNames);
454        }
455        return subjectNames;
456    }
457
458    /**
459     * Returns the Subject object identified by subjectName defined at 
460     * the realm
461     *
462     * @param subjectName name of subject.
463     *
464     * @return Subject object
465     *
466     * @throws NameNotFoundException if a Subject with the given name
467     * does not exist
468     *
469     * @throws PolicyException if can not get the Subject
470     */
471    public Subject getSubjectByName(String subjectName) 
472            throws NameNotFoundException, PolicyException {
473        if (debug.messageEnabled()) {
474            debug.message("Getting subject by name from realm: " 
475                    +  pmRealmName + ", subjectName=" + subjectName);
476        }
477        if (realmSubjects == null) {
478            initRealmSubjects();
479        }
480        if (debug.messageEnabled()) {
481            debug.message("Returning subject by name from realm: " 
482                    +  pmRealmName + ", subjectName=" + subjectName);
483        }
484        return (Subject)realmSubjects.getSubject(subjectName).clone();
485    }
486
487    synchronized Subject getCachedSubjectByName(String subjectName) 
488            throws  PolicyException {
489        if (debug.messageEnabled()) {
490            debug.message("Getting cached subject by name from realm: " 
491                    +  pmRealmName + ", subjectName=" + subjectName);
492        }
493        if (realmSubjects == null) {
494            initRealmSubjects();
495        }
496        if (debug.messageEnabled()) {
497            debug.message("Returning cached subject by name from realm: " 
498                    +  pmRealmName + ", subjectName=" + subjectName);
499        }
500        return (Subject)realmSubjects.fetchSubject(subjectName);
501    }
502
503    /**
504     * Returns a handle to the Subject object identified by subjectName 
505     * defined at the realm, to add to a policy. 
506     * Returned Subject is backed by 
507     * the Subject at the realm. However, you can not change the values
508     * using the returned Subject. 
509     *
510     * @param subjectName name of subject.
511     *
512     * @return Subject object
513     *
514     * @throws NameNotFoundException if a Subject with the given name
515     * does not exist
516     *
517     * @throws PolicyException if can not get the Subject
518     *
519     */
520    Subject getSharedSubject(String subjectName) 
521            throws  PolicyException {
522        if (debug.messageEnabled()) {
523            debug.message("Getting shared subject from realm: " 
524                    +  pmRealmName + ", subjectName=" + subjectName);
525        }
526        Subject subject = (Subject)sharedSubjects.get(subjectName);
527        if (subject == null) {
528            subject = new SharedSubject(subjectName, this);
529            sharedSubjects.put(subjectName, subject);
530        }
531        if (debug.messageEnabled()) {
532            debug.message("Returning shared subject from realm: " 
533                    +  pmRealmName + ", subjectName=" + subjectName);
534        }
535        return subject;
536    }
537
538    /**
539     * Returns subject type name for the given <code>subject</code>
540     * @return subject type name for the given <code>subject</code>
541     */
542    static String subjectTypeName(Subject subject) {
543        if (subject == null) {
544            return (null);
545        }
546        String answer = null;
547        String className = subject.getClass().getName();
548        Iterator items = PolicyManager.getPluginSchemaNames(SUBJECT).iterator();
549        while (items.hasNext()) {
550            String pluginName = (String) items.next();
551            PluginSchema ps = PolicyManager.getPluginSchema(SUBJECT, 
552                pluginName);
553            if (className.equals(ps.getClassName())) {
554                answer = pluginName;
555                break;
556            }
557        }
558        return (answer);
559    }
560
561    /**
562     * Returns the view bean URL given the Subject
563     *
564     * @param subject subject for which to get the view bean URL
565     *
566     * @return view bean URL defined for the subject plugin in the policy
567     *         service <code>PluginSchema</code>.
568     */
569    public String getViewBeanURL(Subject subject) {
570        return PolicyManager.getViewBeanURL(SUBJECT, 
571            subject.getClass().getName());
572    }
573
574    /**
575     * Returns <code>PolicyManager</code> used by this object
576     */
577    PolicyManager getPolicyManager() {
578        return pm;
579    }
580
581    /**
582     * Saves the realm scoped <code>Subject</code> objects to persistent store
583     */
584    private void saveSubjects() throws PolicyException, SSOException {
585        if (realmSubjects != null) {
586            pm.saveRealmSubjects(realmSubjects);
587        }
588    }
589
590    /**
591     * Initializes the realm scoped <code>Subject</code> objects reading from
592     * persistent store
593     */
594    private void initRealmSubjects() throws PolicyException {
595        if (debug.messageEnabled()) {
596            debug.message("Initializing realm subjects in realm : " 
597                    +  pmRealmName); 
598        }
599        try {
600            realmSubjects = pm.readRealmSubjects();
601        } catch (SSOException ssoe){
602            throw new PolicyException(ResBundleUtils.rbName,
603                "could_not_initialize_realm_subjects", null, ssoe);
604        }
605        if (debug.messageEnabled()) {
606            debug.message("Initialized realm subjects in realm : " 
607                    +  pmRealmName); 
608        }
609    }
610
611    /**
612     * Resets the cached realm scoped <code>Subject</code> objects. 
613     * Would read from persistent store on next access to realm scoped
614     * <code>Subject</code> object
615     */
616    void resetRealmSubjects() {
617        if (debug.messageEnabled()) {
618            debug.message("Resetting realm subjects in realm : " 
619                    +  pmRealmName); 
620        }
621        synchronized(this) {
622            realmSubjects = null;
623        }
624        if (debug.messageEnabled()) {
625            debug.message("Reset realm subjects in realm : " 
626                    +  pmRealmName); 
627        }
628    }
629
630}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.