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.*;
020
021import org.forgerock.i18n.LocalizableMessage;
022
023/** The class represents the ssf keyword in a bind rule.SSF stands for security strength factor. */
024public class SSF implements KeywordBindRule {
025    private static final int MAX_KEY_BITS=1024;
026
027    /** Enumeration representing the bind rule operation type. */
028    private final EnumBindRuleType type;
029    private final int ssf;
030
031    private SSF(int ssf, EnumBindRuleType type) {
032        this.ssf = ssf;
033        this.type = type;
034    }
035
036    /**
037     * Create SSF instance using the specified expression string and bind rule
038     * type enumeration.
039     * @param expr The expression string.
040     * @param type The bind rule type enumeration.
041     * @return A SSF instance.
042     * @throws AciException If the SSF instance cannot be created.
043     */
044    static SSF decode(String expr, EnumBindRuleType type) throws AciException {
045        int valueAsInt = 0;
046        try {
047            valueAsInt = Integer.parseInt(expr);
048        } catch (NumberFormatException nfe) {
049            LocalizableMessage message =
050                 WARN_ACI_SYNTAX_INVALID_SSF_FORMAT.get(expr, nfe.getMessage());
051            throw new AciException(message);
052        }
053        if (valueAsInt <= 0 || valueAsInt > MAX_KEY_BITS) {
054            throw new AciException(WARN_ACI_SYNTAX_INVALID_SSF_RANGE.get(expr));
055        }
056        return new SSF(valueAsInt, type);
057    }
058
059    /**
060     * Evaluate the specified evaluation context.
061     * @param evalCtx The evaluation context to evaluate.
062     *
063     * @return An evaluation result enumeration containing the result of the
064     *         context evaluation.
065     */
066    @Override
067    public EnumEvalResult evaluate(AciEvalContext evalCtx) {
068        EnumEvalResult matched = getMatched(evalCtx.getCurrentSSF());
069        return matched.getRet(type, false);
070    }
071
072    private EnumEvalResult getMatched(int currentSSF) {
073      return getMatched0(currentSSF) ? EnumEvalResult.TRUE : EnumEvalResult.FALSE;
074    }
075
076    private boolean getMatched0(int currentSSF)
077    {
078      switch (type) {
079      case EQUAL_BINDRULE_TYPE:
080      case NOT_EQUAL_BINDRULE_TYPE:
081          return currentSSF == ssf;
082      case LESS_OR_EQUAL_BINDRULE_TYPE:
083          return currentSSF <= ssf;
084      case LESS_BINDRULE_TYPE:
085          return currentSSF < ssf;
086      case GREATER_OR_EQUAL_BINDRULE_TYPE:
087          return currentSSF >= ssf;
088      case GREATER_BINDRULE_TYPE:
089          return currentSSF > ssf;
090      default:
091          return false;
092      }
093    }
094
095    @Override
096    public String toString()
097    {
098        final StringBuilder sb = new StringBuilder();
099        toString(sb);
100        return sb.toString();
101    }
102
103    @Override
104    public final void toString(StringBuilder buffer)
105    {
106        buffer.append(super.toString());
107    }
108}