1/*
2 * Copyright 2008 Google, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package net.oauth;
17
18import java.io.IOException;
19import java.net.URISyntaxException;
20
21import net.oauth.signature.OAuthSignatureMethod;
22
23/**
24 * A simple OAuthValidator, which checks the version, whether the timestamp
25 * is close to now and the signature is valid. Each check may be overridden.
26 *
27 * @author Dirk Balfanz
28 * @author John Kristian
29 * @hide
30 */
31public class SimpleOAuthValidator implements OAuthValidator {
32
33    // default window for timestamps is 5 minutes
34    public static final long DEFAULT_TIMESTAMP_WINDOW = 5 * 60 * 1000L;
35
36    /**
37     * Construct a validator that rejects messages more than five minutes out
38     * of date, or with a OAuth version other than 1.0, or with an invalid
39     * signature.
40     */
41    public SimpleOAuthValidator() {
42        this(DEFAULT_TIMESTAMP_WINDOW, Double.parseDouble(OAuth.VERSION_1_0));
43    }
44
45    /**
46     * Public constructor.
47     *
48     * @param timestampWindowSec
49     *            specifies, in seconds, the windows (into the past and
50     *            into the future) in which we'll accept timestamps.
51     * @param maxVersion
52     *            the maximum acceptable oauth_version
53     */
54    public SimpleOAuthValidator(long timestampWindowMsec, double maxVersion) {
55        this.timestampWindow = timestampWindowMsec;
56        this.maxVersion = maxVersion;
57    }
58
59    protected final double minVersion = 1.0;
60    protected final double maxVersion;
61    protected final long timestampWindow;
62
63    /** {@inherit}
64     * @throws URISyntaxException */
65    public void validateMessage(OAuthMessage message, OAuthAccessor accessor)
66    throws OAuthException, IOException, URISyntaxException {
67        validateVersion(message);
68        validateTimestampAndNonce(message);
69        validateSignature(message, accessor);
70    }
71
72    protected void validateVersion(OAuthMessage message)
73    throws OAuthException, IOException {
74        String versionString = message.getParameter(OAuth.OAUTH_VERSION);
75        if (versionString != null) {
76            double version = Double.parseDouble(versionString);
77            if (version < minVersion || maxVersion < version) {
78                OAuthProblemException problem = new OAuthProblemException("version_rejected");
79                problem.setParameter("oauth_acceptable_versions", minVersion + "-" + maxVersion);
80                throw problem;
81            }
82        }
83    }
84
85    /** This implementation doesn't check the nonce value. */
86    protected void validateTimestampAndNonce(OAuthMessage message)
87    throws IOException, OAuthProblemException {
88        message.requireParameters(OAuth.OAUTH_TIMESTAMP, OAuth.OAUTH_NONCE);
89        long timestamp = Long.parseLong(message.getParameter(OAuth.OAUTH_TIMESTAMP)) * 1000L;
90        long now = currentTimeMsec();
91        long min = now - timestampWindow;
92        long max = now + timestampWindow;
93        if (timestamp < min || max < timestamp) {
94            OAuthProblemException problem = new OAuthProblemException("timestamp_refused");
95            problem.setParameter("oauth_acceptable_timestamps", min + "-" + max);
96            throw problem;
97        }
98    }
99
100    protected void validateSignature(OAuthMessage message, OAuthAccessor accessor)
101    throws OAuthException, IOException, URISyntaxException {
102        message.requireParameters(OAuth.OAUTH_CONSUMER_KEY,
103                OAuth.OAUTH_SIGNATURE_METHOD, OAuth.OAUTH_SIGNATURE);
104        OAuthSignatureMethod.newSigner(message, accessor).validate(message);
105    }
106
107    protected long currentTimeMsec() {
108        return System.currentTimeMillis();
109    }
110
111}
112