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: BaseRole.java,v 1.4 2008/06/25 05:41:44 qcheng Exp $
026 *
027 */
028
029/**
030 * Portions Copyrighted [2011] [ForgeRock AS]
031 */
032package com.iplanet.ums;
033
034import java.util.HashSet;
035import java.util.Iterator;
036
037import com.sun.identity.shared.debug.Debug;
038import com.iplanet.services.ldap.Attr;
039import com.iplanet.services.ldap.AttrSet;
040import com.iplanet.services.ldap.ModSet;
041import com.iplanet.services.ldap.aci.ACI;
042import com.iplanet.services.ldap.aci.ACIParseException;
043import com.iplanet.services.ldap.aci.QualifiedCollection;
044
045/**
046 * Abstract base class for all roles.
047 *
048 * @supported.api
049 */
050public abstract class BaseRole extends PersistentObject implements IRole {
051    private static Debug debug;
052    static {
053        debug = Debug.getInstance(IUMSConstants.UMS_DEBUG);
054    }
055
056    /**
057     * Default constructor
058     * 
059     * @see com.iplanet.ums.PersistentObject#PersistentObject()
060     */
061    protected BaseRole() {
062        super();
063    }
064
065    /**
066     * Constructs a BaseRole object from a principal and guid.
067     * 
068     * @see com.iplanet.ums.PersistentObject#PersistentObject(
069     *      java.security.Principal
070     *      p, String guid)
071     */
072    BaseRole(java.security.Principal p, String guid) throws UMSException {
073        super();
074    }
075
076    /**
077     * Constructs a BaseRole from a creation template
078     * and attribute set.
079     * 
080     * @see com.iplanet.ums.PersistentObject#PersistentObject(CreationTemplate
081     *      template, AttrSet attrSet)
082     *
083     * @supported.api
084     */
085    public BaseRole(CreationTemplate template, AttrSet attrSet)
086            throws UMSException {
087        super(template, attrSet);
088    }
089
090    /**
091     * Checks if a given identifier is a member of the role.
092     * 
093     * @param po
094     *            member to be checked for membership
095     * 
096     * @return <code>true</code> if it is a member
097     * @exception UMSException
098     *                on failure to read object for guid
099     *
100     * @supported.api
101     */
102    public boolean hasMember(PersistentObject po) throws UMSException {
103        boolean hasTheMember = false;
104        Attr attr = po.getAttribute(COMPUTED_MEMBER_ATTR_NAME);
105        if (attr != null) {
106            if (attr.contains(getGuid().getDn())
107                    || attr.contains(getGuid().getDn().toLowerCase())) {
108                hasTheMember = true;
109            }
110        }
111        return hasTheMember;
112    }
113
114    /**
115     * Returns the attribute access rights associated with the role.
116     * 
117     * @return AccessRightObject associated with the role
118     *
119     * @supported.api
120     */
121    public AccessRightObject getAccessRight() throws UMSException,
122            ACIParseException {
123
124        QualifiedCollection readPerm = null;
125        QualifiedCollection writePerm = null;
126
127        // get parent GUID
128        if (parentObject == null) {
129            parentObject = getParentObject();
130        }
131        // get ACIS from parent object
132        Iterator acis = parentObject.getACI().iterator();
133        // go throw each ACI to see if it sets the access right for the role
134        if (acis != null) {
135            String guid = getGuid().getDn().trim();
136            while (acis.hasNext()) {
137                ACI aci = (ACI) acis.next();
138                if (debug.messageEnabled()) {
139                    debug.message("BaseRole.getAccessRight ACI.toString ="
140                            + aci.toString());
141                }
142                // try to find out if this ACI is for this role
143                // checking the name of the aci,
144                // better solution is to check the roledn, TBD
145                String aciName = aci.getName();
146                if (aciName.equalsIgnoreCase(READ_PERM_HEADER + guid)) {
147                    readPerm = aci.getTargetAttributes();
148                    if (writePerm != null)
149                        break;
150                    else
151                        continue;
152                }
153                if (aciName.equalsIgnoreCase(WRITE_PERM_HEADER + guid)) {
154                    writePerm = aci.getTargetAttributes();
155                    if (readPerm != null)
156                        break;
157                    else
158                        continue;
159                }
160            }
161        }
162
163        if (readPerm == null) {
164            if (writePerm == null) {
165                return new AccessRightObject(null, null);
166            } else {
167                return new AccessRightObject(null, writePerm.getCollection());
168            }
169        } else {
170            if (writePerm == null) {
171                return new AccessRightObject(readPerm.getCollection(), null);
172            } else {
173                return new AccessRightObject(readPerm.getCollection(),
174                        writePerm.getCollection());
175            }
176        }
177    }
178
179    /**
180     * Creates attribute access rights for the role;
181     * existing attribute access rights for the role will be replaced.
182     * 
183     * @param accessRight
184     *            New access right to be set to the role
185     *
186     * @supported.api
187     */
188    public void newAccessRight(AccessRightObject accessRight)
189            throws UMSException, ACIParseException {
190
191        ACI readACI = null;
192        ACI writeACI = null;
193
194        // get parent GUID
195        if (parentObject == null) {
196            parentObject = getParentObject();
197        }
198
199        // get ACIS from parent object
200        Iterator acis = parentObject.getACI().iterator();
201        // go throw each ACI to see if it sets the access right for the role
202        if (acis != null) {
203            String guid = getGuid().getDn().trim();
204            while (acis.hasNext()) {
205                ACI aci = (ACI) acis.next();
206                if (debug.messageEnabled()) {
207                    debug.message("BaseRole.newAccessRight ACI.toString ="
208                            + aci.toString());
209                }
210                // try to find out if this ACI is for this role
211                // checking the name of the aci,
212                // better solution is to check the roledn, TBD
213                String aciName = aci.getName();
214                if (aciName.equals(READ_PERM_HEADER + guid)) {
215                    readACI = aci;
216                    if (writeACI != null)
217                        break;
218                    else
219                        continue;
220                }
221                if (aciName.equals(WRITE_PERM_HEADER + guid)) {
222                    writeACI = aci;
223                    if (readACI != null)
224                        break;
225                    else
226                        continue;
227                }
228            }
229        }
230
231        if (readACI != null) {
232            debug.message("modify existing read aci");
233            // modify existing read ACI
234            Attr attr = new Attr(ACI.ACI, readACI.getACIText());
235            if (debug.messageEnabled()) {
236                debug.message("readaci.ACIText :" + readACI.getACIText());
237            }
238            parentObject.modify(attr, ModSet.DELETE);
239            ACI newReadACI = ACI.valueOf(readACI.toString());
240            QualifiedCollection readAttrs = new QualifiedCollection(accessRight
241                    .getReadableAttributeNames(), false);
242            newReadACI.setTargetAttributes(readAttrs);
243            attr = new Attr(ACI.ACI, newReadACI.toString());
244            parentObject.modify(attr, ModSet.ADD);
245        } else {
246            debug.message("new read aci");
247            // add new read ACI
248            ACI newReadACI = new ACI(READ_PERM_HEADER + getGuid().getDn());
249            newReadACI.setName(READ_PERM_HEADER + getGuid().getDn());
250            QualifiedCollection readAttrs = new QualifiedCollection(accessRight
251                    .getReadableAttributeNames(), false);
252            newReadACI.setTargetAttributes(readAttrs);
253
254            // set Allow "read" permission
255            HashSet hs = new HashSet();
256            hs.add(READ_PERM_STRING);
257            QualifiedCollection perm = new QualifiedCollection(hs, false);
258            newReadACI.setPermissions(perm);
259
260            // set applied role
261            hs = new HashSet();
262            hs.add(getGuid().getDn());
263            newReadACI.setRoles(hs);
264            Attr attr = new Attr(ACI.ACI, newReadACI.toString());
265            if (debug.messageEnabled()) {
266                debug.message("READ " + getGuid().getDn() + "="
267                        + newReadACI.toString());
268            }
269            parentObject.modify(attr, ModSet.ADD);
270        }
271
272        if (writeACI != null) {
273            debug.message("modify existing write aci");
274            // modify existing read ACI
275            Attr attr = new Attr(ACI.ACI, writeACI.getACIText());
276            if (debug.messageEnabled()) {
277                debug.message("writeaci.ACIText :" + writeACI.getACIText());
278            }
279            parentObject.modify(attr, ModSet.DELETE);
280            ACI newWriteACI = ACI.valueOf(writeACI.toString());
281            QualifiedCollection qual = new QualifiedCollection(accessRight
282                    .getWritableAttributeNames(), false);
283            newWriteACI.setTargetAttributes(qual);
284            attr = new Attr(ACI.ACI, newWriteACI.toString());
285            parentObject.modify(attr, ModSet.ADD);
286        } else {
287            debug.message("new write aci");
288            // add new write ACI
289            ACI newWriteACI = new ACI(WRITE_PERM_HEADER + getGuid().getDn());
290            newWriteACI.setName(WRITE_PERM_HEADER + getGuid().getDn());
291            QualifiedCollection writeAttrs = new QualifiedCollection(
292                    accessRight.getWritableAttributeNames(), false);
293            newWriteACI.setTargetAttributes(writeAttrs);
294
295            // set Allow "write" permission
296            HashSet hs = new HashSet();
297            hs.add(WRITE_PERM_STRING);
298            QualifiedCollection perm = new QualifiedCollection(hs, false);
299            newWriteACI.setPermissions(perm);
300
301            // set applied role
302            hs = new HashSet();
303            hs.add(getGuid().getDn());
304            newWriteACI.setRoles(hs);
305            Attr attr = new Attr(ACI.ACI, newWriteACI.toString());
306            if (debug.messageEnabled()) {
307                debug.message("Write " + getGuid().getDn() + "="
308                        + newWriteACI.toString());
309            }
310            parentObject.modify(attr, ModSet.ADD);
311        }
312
313        // save ACI changes to parent persistent store
314        parentObject.save();
315    }
316
317    // need to set cosattribute to be "operational" to avoid adding objectclass
318    // to every user entry, but need to get response back from DS team (TBD)
319    // but for now, just set cosattribute operational
320    private PersistentObject parentObject = null;
321
322    private static final String READ_PERM_STRING = "read";
323
324    private static final String READ_PERM_HEADER = "Read permission for ";
325
326    private static final String WRITE_PERM_STRING = "write";
327
328    private static final String WRITE_PERM_HEADER = "Write permission for ";
329}