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