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;
028import org.forgerock.i18n.LocalizableMessage;
029
030import static org.opends.messages.AccessControlMessages.*;
031import org.opends.server.util.TimeThread;
032import java.util.regex.Pattern;
033
034/**
035 * This class represents the timeofday keyword in a bind rule.
036 */
037public class TimeOfDay implements KeywordBindRule {
038
039    /**
040     * Regular expression matching a valid timeofday rule value (0-2359).
041     */
042    private static final String timeofdayRegex = "[0-2]\\d[0-5]\\d";
043
044    /** Enumeration representing the bind rule operation type. */
045    private EnumBindRuleType type;
046
047    /** Holds the time value parsed from the ACI. */
048    private int timeRef;
049
050    /**
051     * Constructor to create a timeofday keyword class.
052     * @param timeVal The time value to check for (0-2359).
053     * @param type An enumeration of the type of the expression.
054     */
055    private TimeOfDay(int timeVal, EnumBindRuleType type) {
056        this.timeRef=timeVal;
057        this.type=type;
058    }
059
060    /**
061     * Decodes a string representation of a timeofday bind rule expression.
062     * @param expr A string representation of the expression.
063     * @param type An enumeration of the type of the expression.
064     * @return  A TimeOfDay class representing the expression.
065     * @throws AciException If the expression is invalid.
066     */
067    public static TimeOfDay decode(String expr,  EnumBindRuleType type)
068    throws AciException  {
069        int valueAsInt = 0;
070        if (!Pattern.matches(timeofdayRegex, expr))
071        {
072            LocalizableMessage message = WARN_ACI_SYNTAX_INVALID_TIMEOFDAY.get(expr);
073            throw new AciException(message);
074         }
075        try {
076            valueAsInt = Integer.parseInt(expr);
077        } catch (NumberFormatException nfe) {
078          LocalizableMessage message =
079           WARN_ACI_SYNTAX_INVALID_TIMEOFDAY_FORMAT.get(expr, nfe.getMessage());
080            throw new AciException(message);
081        }
082        if (valueAsInt < 0 || valueAsInt > 2359)
083        {
084            LocalizableMessage message = WARN_ACI_SYNTAX_INVALID_TIMEOFDAY_RANGE.get(expr);
085            throw new AciException(message);
086        }
087
088        return new TimeOfDay(valueAsInt, type);
089    }
090
091    /**
092     * Evaluates the timeofday bind rule using the evaluation context
093     * passed into the method.
094     * @param evalCtx  The evaluation context to use for the evaluation.
095     * @return  An enumeration result representing the result of the
096     * evaluation.
097     */
098    public EnumEvalResult evaluate(AciEvalContext evalCtx) {
099        EnumEvalResult matched=EnumEvalResult.FALSE;
100
101        int currentTime=TimeThread.getHourAndMinute();
102        //check the type
103        switch (type) {
104        case EQUAL_BINDRULE_TYPE:
105        case NOT_EQUAL_BINDRULE_TYPE:
106            if (currentTime != timeRef)
107            {
108                matched=EnumEvalResult.TRUE;
109            }
110            break;
111
112        case LESS_OR_EQUAL_BINDRULE_TYPE:
113            if (currentTime <= timeRef)
114            {
115                matched=EnumEvalResult.TRUE;
116            }
117            break;
118
119        case LESS_BINDRULE_TYPE:
120            if (currentTime < timeRef)
121            {
122                matched=EnumEvalResult.TRUE;
123            }
124            break;
125
126        case GREATER_OR_EQUAL_BINDRULE_TYPE:
127            if (currentTime >= timeRef)
128            {
129                matched=EnumEvalResult.TRUE;
130            }
131            break;
132
133        case GREATER_BINDRULE_TYPE:
134            if (currentTime > timeRef)
135            {
136                matched=EnumEvalResult.TRUE;
137            }
138        }
139        return matched.getRet(type, false);
140    }
141
142    /** {@inheritDoc} */
143    @Override
144    public String toString()
145    {
146        final StringBuilder sb = new StringBuilder();
147        toString(sb);
148        return sb.toString();
149    }
150
151    /** {@inheritDoc} */
152    @Override
153    public final void toString(StringBuilder buffer)
154    {
155        buffer.append(super.toString());
156    }
157
158}