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