/************************************************************************* * Copyright 2009-2012 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. * * This file may incorporate work covered under the following copyright * and permission notice: * * Software License Agreement (BSD License) * * Copyright (c) 2008, Regents of the University of California * All rights reserved. * * Redistribution and use of this software in source and binary forms, * with or without modification, are permitted provided that the * following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE * THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL, * COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE, * AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, * SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, * WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, * REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO * IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT * NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS. ************************************************************************/ package com.eucalyptus.auth.policy.condition; import java.util.Map; import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.eucalyptus.util.Strings; import com.google.common.collect.Maps; /** * IAM condition constants */ public class Conditions { public static final String STRINGEQUALS = "StringEquals"; public static final String STRINGEQUALS_S = "streq"; public static final String STRINGNOTEQUALS = "StringNotEquals"; public static final String STRINGNOTEQUALS_S = "strneq"; public static final String STRINGEQUALSIGNORECASE = "StringEqualsIgnoreCase"; public static final String STRINGEQUALSIGNORECASE_S = "streqi"; public static final String STRINGNOTEQUALSIGNORECASE = "StringNotEqualsIgnoreCase"; public static final String STRINGNOTEQUALSIGNORECASE_S = "strneqi"; public static final String STRINGLIKE = "StringLike"; public static final String STRINGLIKE_S = "strl"; public static final String STRINGNOTLIKE = "StringNotLike"; public static final String STRINGNOTLIKE_S = "strnl"; public static final String NUMERICEQUALS = "NumericEquals"; public static final String NUMERICEQUALS_S = "numeq"; public static final String NUMERICNOTEQUALS = "NumericNotEquals"; public static final String NUMERICNOTEQUALS_S = "numneq"; public static final String NUMERICLESSTHAN = "NumericLessThan"; public static final String NUMERICLESSTHAN_S = "numlt"; public static final String NUMERICLESSTHANEQUALS = "NumericLessThanEquals"; public static final String NUMERICLESSTHANEQUALS_S = "numlteq"; public static final String NUMERICGREATERTHAN = "NumericGreaterThan"; public static final String NUMERICGREATERTHAN_S = "numgt"; public static final String NUMERICGREATERTHANEQUALS = "NumericGreaterThanEquals"; public static final String NUMERICGREATERTHANEQUALS_S = "numgteq"; public static final String DATEEQUALS = "DateEquals"; public static final String DATEEQUALS_S = "dateeq"; public static final String DATENOTEQUALS = "DateNotEquals"; public static final String DATENOTEQUALS_S = "dateneq"; public static final String DATELESSTHAN = "DateLessThan"; public static final String DATELESSTHAN_S = "datelt"; public static final String DATELESSTHANEQUALS = "DateLessThanEquals"; public static final String DATELESSTHANEQUALS_S = "datelteq"; public static final String DATEGREATERTHAN = "DateGreaterThan"; public static final String DATEGREATERTHAN_S = "dategt"; public static final String DATEGREATERTHANEQUALS = "DateGreaterThanEquals"; public static final String DATEGREATERTHANEQUALS_S = "dategteq"; public static final String BOOL = "Bool"; public static final String IPADDRESS = "IpAddress"; public static final String NOTIPADDRESS = "NotIpAddress"; public static final String IF_EXISTS_SUFFIX = "IfExists"; public static final String FOR_ALL_VALUES_PREFIX = "ForAllValues:"; public static final String FOR_ANY_VALUE_PREFIX = "ForAnyValue:"; private static final Map<String, Class<? extends ConditionOp>> CONDITION_MAP = Maps.newHashMap( ); public synchronized static boolean registerCondition( @Nonnull final String op, @Nonnull final Class<? extends ConditionOp> conditionClass, final boolean addIfExists ) { if ( CONDITION_MAP.containsKey( op ) ) { return false; } CONDITION_MAP.put( op, conditionClass ); if ( addIfExists ) { CONDITION_MAP.put( op + IF_EXISTS_SUFFIX, conditionClass ); } return true; } public static Class<? extends ConditionOp> getConditionOpClass( String op ) { return CONDITION_MAP.get( stripPrefix( op ) ); } public static ConditionOp getOpInstance( final String op ) { final Class<? extends ConditionOp> opClass = getConditionOpClass( op ); try { return set( op, conditional( op, opClass.newInstance( ) ) ); } catch ( final IllegalAccessException | InstantiationException | SecurityException | ExceptionInInitializerError e ) { throw new RuntimeException( "Can not find condition type " + opClass.getName( ), e ); } } private static ConditionOp conditional( final String name, final ConditionOp conditionOp ) { if ( name.endsWith( IF_EXISTS_SUFFIX ) ) { return new IfExistsDelegatingConditionOp( conditionOp ); } else { return conditionOp; } } private static ConditionOp set( final String name, final ConditionOp conditionOp ) { if ( name.startsWith( FOR_ANY_VALUE_PREFIX ) ) { return new ForAnyValueDelegatingConditionOp( conditionOp ); } else if ( name.startsWith( FOR_ALL_VALUES_PREFIX ) ) { return new ForAllValuesDelegatingConditionOp( conditionOp ); } else { return conditionOp; } } private static String stripPrefix( final String op ) { return Strings.trimPrefix( FOR_ANY_VALUE_PREFIX, Strings.trimPrefix( FOR_ALL_VALUES_PREFIX, op ) ); } private static class IfExistsDelegatingConditionOp implements ConditionOp { private final ConditionOp delegate; private IfExistsDelegatingConditionOp( final ConditionOp conditionOp ) { this.delegate = conditionOp; } @Override public boolean check( @Nullable final String key, final String value ) { return key == null || delegate.check( key, value ); } } private static class ForAnyValueDelegatingConditionOp implements ConditionOp { private final ConditionOp delegate; private ForAnyValueDelegatingConditionOp( final ConditionOp conditionOp ) { this.delegate = conditionOp; } @Override public boolean check( @Nullable final String key, final String value ) { return delegate.check( key, value ); } @Override public boolean check( final Set<String> keys, final Set<String> values ) { boolean success = false; for ( final String key : keys ) { for ( final String value : values ) { success = check( key, value ); if ( success ) break; } if ( success ) break; } return success; } } private static class ForAllValuesDelegatingConditionOp implements ConditionOp { private final ConditionOp delegate; private ForAllValuesDelegatingConditionOp( final ConditionOp conditionOp ) { this.delegate = conditionOp; } @Override public boolean check( @Nullable final String key, final String value ) { return delegate.check( key, value ); } @Override public boolean check( @Nullable final Set<String> keys, final Set<String> values ) { boolean success = true; for ( final String key : keys ) { for ( final String value : values ) { success = check( key, value ); if ( success ) break; } if ( !success ) break; } return success; } } }