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}