001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.api.ldap.aci; 021 022 023import java.util.Collections; 024import java.util.HashSet; 025import java.util.Set; 026 027import org.apache.directory.api.ldap.model.subtree.SubtreeSpecification; 028 029 030/** 031 * Defines a set of zero or more users the permissions apply to. 032 * 033 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 034 */ 035public abstract class UserClass 036{ 037 /** 038 * Every directory user (with possible requirements for 039 * authenticationLevel). 040 */ 041 public static final AllUsers ALL_USERS = new AllUsers(); 042 043 /** 044 * The user with the same distinguished name as the entry being accessed, or 045 * if the entry is a member of a family, then additionally the user with the 046 * distinguished name of the ancestor. 047 */ 048 public static final ThisEntry THIS_ENTRY = new ThisEntry(); 049 050 /** 051 * The user as parent (ancestor) of accessed entry. 052 */ 053 public static final ParentOfEntry PARENT_OF_ENTRY = new ParentOfEntry(); 054 055 056 /** 057 * Creates a new instance. 058 */ 059 protected UserClass() 060 { 061 } 062 063 064 /** 065 * Every directory user (with possible requirements for 066 * authenticationLevel). 067 */ 068 public static final class AllUsers extends UserClass 069 { 070 /** 071 * Creates a new instance of AllUsers. 072 */ 073 private AllUsers() 074 { 075 } 076 077 078 /** 079 * {@inheritDoc} 080 */ 081 @Override 082 public String toString() 083 { 084 return "allUsers"; 085 } 086 } 087 088 089 /** 090 * The user with the same distinguished name as the entry being accessed, or 091 * if the entry is a member of a family, then additionally the user with the 092 * distinguished name of the ancestor. 093 */ 094 public static final class ThisEntry extends UserClass 095 { 096 /** 097 * Creates a new instance of ThisEntry. 098 */ 099 private ThisEntry() 100 { 101 } 102 103 104 /** 105 * {@inheritDoc} 106 */ 107 @Override 108 public String toString() 109 { 110 return "thisEntry"; 111 } 112 } 113 114 115 /** 116 * The user as parent (ancestor) of accessed entry. 117 */ 118 public static final class ParentOfEntry extends UserClass 119 { 120 /** 121 * Creates a new instance of ParentOfEntry. 122 */ 123 private ParentOfEntry() 124 { 125 } 126 127 128 /** 129 * {@inheritDoc} 130 */ 131 @Override 132 public String toString() 133 { 134 return "parentOfEntry"; 135 } 136 } 137 138 139 /** 140 * A base class for all user classes which has a set of DNs. 141 */ 142 private abstract static class NamedUserClass extends UserClass 143 { 144 /** The names. */ 145 protected final Set<String> names; 146 147 148 /** 149 * Creates a new instance. 150 * 151 * @param names a set of names 152 */ 153 protected NamedUserClass( Set<String> names ) 154 { 155 if ( names == null ) 156 { 157 this.names = Collections.unmodifiableSet( new HashSet<String>() ); 158 } 159 else 160 { 161 this.names = Collections.unmodifiableSet( new HashSet<String>( names ) ); 162 } 163 } 164 165 166 /** 167 * Returns the set of all names. 168 * 169 * @return The set of all names 170 */ 171 public Set<String> getNames() 172 { 173 return names; 174 } 175 176 177 /** 178 * {@inheritDoc} 179 */ 180 @Override 181 public boolean equals( Object o ) 182 { 183 if ( this == o ) 184 { 185 return true; 186 } 187 188 if ( !( o instanceof NamedUserClass ) ) 189 { 190 return false; 191 } 192 193 if ( getClass().isAssignableFrom( o.getClass() ) ) 194 { 195 Name that = ( Name ) o; 196 197 return names.equals( that.names ); 198 } 199 200 return false; 201 } 202 203 204 /** 205 * {@inheritDoc} 206 */ 207 @Override 208 public int hashCode() 209 { 210 int result = 37; 211 212 // Use a slightly different hashcode here : we multiple 213 // each DN in the set with the result to have a result that 214 // is not dependent on the DN order in the Set. 215 // In order to avoid result of 0 if one of the DN hashcode, 216 // we discard them. 217 for ( String dn : names ) 218 { 219 int h = dn.hashCode(); 220 221 if ( h != 0 ) 222 { 223 result = result * h; 224 } 225 } 226 227 return result; 228 } 229 230 231 /** 232 * {@inheritDoc} 233 */ 234 @Override 235 public String toString() 236 { 237 StringBuilder buffer = new StringBuilder(); 238 239 boolean isFirst = true; 240 buffer.append( "{ " ); 241 242 for ( String name : names ) 243 { 244 if ( isFirst ) 245 { 246 isFirst = false; 247 } 248 else 249 { 250 buffer.append( ", " ); 251 } 252 253 buffer.append( '"' ); 254 buffer.append( name ); 255 buffer.append( '"' ); 256 } 257 258 buffer.append( " }" ); 259 260 return buffer.toString(); 261 } 262 } 263 264 265 /** 266 * The user with the specified distinguished name. 267 */ 268 public static class Name extends NamedUserClass 269 { 270 /** 271 * Creates a new instance. 272 * 273 * @param usernames the set of user DNs. 274 */ 275 public Name( Set<String> usernames ) 276 { 277 super( usernames ); 278 } 279 280 281 /** 282 * {@inheritDoc} 283 */ 284 @Override 285 public String toString() 286 { 287 return "name " + super.toString(); 288 } 289 } 290 291 292 /** 293 * The set of users who are members of the groupOfUniqueNames entry, 294 * identified by the specified distinguished name. Members of a group of 295 * unique names are treated as individual object names, and not as the names 296 * of other groups of unique names. 297 */ 298 public static class UserGroup extends NamedUserClass 299 { 300 /** 301 * Creates a new instance. 302 * 303 * @param groupNames the set of group DNs. 304 */ 305 public UserGroup( Set<String> groupNames ) 306 { 307 super( groupNames ); 308 } 309 310 311 /** 312 * {@inheritDoc} 313 */ 314 @Override 315 public String toString() 316 { 317 return "userGroup " + super.toString(); 318 } 319 } 320 321 322 /** 323 * The set of users whose distinguished names fall within the definition of 324 * the (unrefined) subtree. 325 */ 326 public static class Subtree extends UserClass 327 { 328 /** The subtree specifications. */ 329 protected final Set<SubtreeSpecification> subtreeSpecifications; 330 331 332 /** 333 * Creates a new instance. 334 * 335 * @param subtreeSpecs the collection of unrefined {@link SubtreeSpecification}s. 336 */ 337 public Subtree( Set<SubtreeSpecification> subtreeSpecs ) 338 { 339 subtreeSpecifications = Collections.unmodifiableSet( subtreeSpecs ); 340 } 341 342 343 /** 344 * Returns the collection of unrefined {@link SubtreeSpecification}s. 345 * 346 * @return the subtree specifications 347 */ 348 public Set<SubtreeSpecification> getSubtreeSpecifications() 349 { 350 return subtreeSpecifications; 351 } 352 353 354 /** 355 * {@inheritDoc} 356 */ 357 @Override 358 public int hashCode() 359 { 360 int hash = 37; 361 hash = hash * 17 + subtreeSpecifications.hashCode(); 362 363 return hash; 364 } 365 366 367 /** 368 * {@inheritDoc} 369 */ 370 @Override 371 public boolean equals( Object o ) 372 { 373 if ( this == o ) 374 { 375 return true; 376 } 377 378 if ( o instanceof Subtree ) 379 { 380 Subtree that = ( Subtree ) o; 381 382 return subtreeSpecifications.equals( that.subtreeSpecifications ); 383 } 384 385 return false; 386 } 387 388 389 /** 390 * {@inheritDoc} 391 */ 392 @Override 393 public String toString() 394 { 395 StringBuilder buffer = new StringBuilder(); 396 397 boolean isFirst = true; 398 buffer.append( "subtree { " ); 399 400 for ( SubtreeSpecification ss : subtreeSpecifications ) 401 { 402 if ( isFirst ) 403 { 404 isFirst = false; 405 } 406 else 407 { 408 buffer.append( ", " ); 409 } 410 411 ss.toString( buffer ); 412 } 413 414 buffer.append( " }" ); 415 416 return buffer.toString(); 417 } 418 } 419}