001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008 Sun Microsystems, Inc.
015 * Portions Copyright 2013-2016 ForgeRock AS.
016 */
017package org.opends.server.authorization.dseecompat;
018
019import static org.opends.messages.AccessControlMessages.*;
020import static org.opends.server.authorization.dseecompat.Aci.*;
021
022import java.util.Iterator;
023import java.util.Set;
024import java.util.regex.Pattern;
025
026import org.forgerock.i18n.LocalizableMessage;
027
028/**
029 * A class representing the permissions of an bind rule. The permissions
030 * of an ACI look like deny(search, write).
031 */
032public class Permission {
033
034    /** Regular expression token representing the separator. */
035    private static final String separatorToken = ",";
036
037    /** Regular expression used to match the ACI rights string. */
038    private static final String rightsRegex = ZERO_OR_MORE_WHITESPACE +
039            WORD_GROUP + ZERO_OR_MORE_WHITESPACE +
040            "(," + ZERO_OR_MORE_WHITESPACE + WORD_GROUP +
041            ZERO_OR_MORE_WHITESPACE +  ")*";
042
043    /** The access type (allow,deny) corresponding to the ACI permission value. */
044    private final EnumAccessType accessType;
045    /** The rights (search, add, delete, ...) corresponding to the ACI rights value. */
046    private int rights;
047
048    /**
049     * Constructor creating a class representing a permission part of an bind
050     * rule.
051     * @param accessType A string representing access type.
052     * @param rights  A string representing the rights.
053     * @throws AciException If the access type string or rights string
054     * is invalid.
055     */
056    private Permission(String accessType, String rights)
057    throws AciException {
058        this.accessType = EnumAccessType.decode(accessType);
059        if (this.accessType == null){
060            LocalizableMessage message =
061                WARN_ACI_SYNTAX_INVALID_ACCESS_TYPE_VERSION.get(accessType);
062            throw new AciException(message);
063        }
064        if (!Pattern.matches(rightsRegex, rights)){
065            LocalizableMessage message = WARN_ACI_SYNTAX_INVALID_RIGHTS_SYNTAX.get(rights);
066            throw new AciException(message);
067        }
068        else {
069            Pattern separatorPattern = Pattern.compile(separatorToken);
070            String[] rightsStr =
071                separatorPattern.split(rights.replaceAll("\\s", ""));
072            for (String r : rightsStr) {
073                EnumRight right = EnumRight.decode(r);
074                if (right != null) {
075                  this.rights|= EnumRight.getMask(right);
076                } else {
077                    LocalizableMessage message =
078                        WARN_ACI_SYNTAX_INVALID_RIGHTS_KEYWORD.get(rights);
079                    throw new AciException(message);
080                }
081            }
082        }
083    }
084
085    /**
086     * Decode an string representation of bind rule permission into a Permission
087     * class.
088     * @param accessType  A string representing the access type.
089     * @param rights   A string representing the rights.
090     * @return  A Permission class representing the permissions of the bind
091     * rule.
092     * @throws AciException  If the accesstype or rights strings are invalid.
093     */
094    public static Permission decode (String accessType, String rights)
095            throws AciException {
096        return new Permission(accessType, rights);
097    }
098
099    /**
100     * Checks if a given access type enumeration is equal to this classes
101     * access type.
102     * @param accessType An enumeration representing an access type.
103     * @return True if the access types are equal.
104     */
105    public boolean hasAccessType(EnumAccessType accessType) {
106        return this.accessType == accessType;
107    }
108
109    /**
110     * Checks if the permission's rights has the specified rights.
111     * @param  rights The rights to check for.
112     * @return True if the permission's rights has the specified rights.
113     */
114    public boolean hasRights(int rights) {
115        return (this.rights & rights) != 0;
116    }
117
118    @Override
119    public String toString() {
120        final StringBuilder sb = new StringBuilder();
121        toString(sb);
122        return sb.toString();
123    }
124
125    /**
126     * Appends a string representation of this object to the provided buffer.
127     *
128     * @param buffer
129     *          The buffer into which a string representation of this object
130     *          should be appended.
131     */
132    public final void toString(StringBuilder buffer) {
133        if (this.accessType != null) {
134            buffer.append(accessType.toString().toLowerCase());
135            Set<EnumRight> enumRights = EnumRight.getEnumRight(rights);
136            if (enumRights != null) {
137                buffer.append("(");
138                for (Iterator<EnumRight> iter = enumRights.iterator(); iter.hasNext();) {
139                    buffer.append(iter.next().getRight());
140                    if (iter.hasNext()) {
141                        buffer.append(",");
142                    }
143                }
144                buffer.append(")");
145            } else {
146                buffer.append("(all)");
147            }
148        }
149    }
150}