001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.oauth2.sdk;
019
020
021import java.util.Collections;
022import java.util.LinkedHashMap;
023import java.util.List;
024import java.util.Map;
025
026import com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils;
027import net.jcip.annotations.Immutable;
028
029import com.nimbusds.oauth2.sdk.token.RefreshToken;
030
031
032/**
033 * Refresh token grant. Used in refresh token requests.
034 *
035 * <p>Note that the optional scope parameter is not supported.
036 *
037 * <p>Related specifications:
038 *
039 * <ul>
040 *     <li>OAuth 2.0 (RFC 6749), section 6.
041 * </ul>
042 */
043@Immutable
044public class RefreshTokenGrant extends AuthorizationGrant {
045
046
047        /**
048         * The grant type.
049         */
050        public static final GrantType GRANT_TYPE = GrantType.REFRESH_TOKEN;
051
052
053        /**
054         * The refresh token.
055         */
056        private final RefreshToken refreshToken;
057
058
059        /**
060         * Creates a new refresh token grant.
061         *
062         * @param refreshToken The refresh token. Must not be {@code null}.
063         */
064        public RefreshTokenGrant(final RefreshToken refreshToken) {
065
066
067                super(GRANT_TYPE);
068
069                if (refreshToken == null)
070                        throw new IllegalArgumentException("The refresh token must not be null");
071
072                this.refreshToken = refreshToken;
073        }
074
075
076        /**
077         * Gets the refresh token.
078         *
079         * @return The refresh token.
080         */
081        public RefreshToken getRefreshToken() {
082
083                return refreshToken;
084        }
085
086
087        @Override
088        public Map<String,List<String>> toParameters() {
089
090                Map<String,List<String>> params = new LinkedHashMap<>();
091                params.put("grant_type", Collections.singletonList(GRANT_TYPE.getValue()));
092                params.put("refresh_token", Collections.singletonList(refreshToken.getValue()));
093                return params;
094        }
095
096
097        @Override
098        public boolean equals(Object o) {
099                if (this == o) return true;
100                if (o == null || getClass() != o.getClass()) return false;
101
102                RefreshTokenGrant grant = (RefreshTokenGrant) o;
103
104                return refreshToken.equals(grant.refreshToken);
105
106        }
107
108
109        @Override
110        public int hashCode() {
111                return refreshToken.hashCode();
112        }
113
114
115        /**
116         * Parses a refresh token grant from the specified request body
117         * parameters.
118         *
119         * <p>Example:
120         *
121         * <pre>
122         * grant_type=refresh_token
123         * refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
124         * </pre>
125         *
126         * @param params The parameters.
127         *
128         * @return The refresh token grant.
129         *
130         * @throws ParseException If parsing failed.
131         */
132        public static RefreshTokenGrant parse(final Map<String,List<String>> params)
133                throws ParseException {
134
135                // Parse grant type
136                String grantTypeString = MultivaluedMapUtils.getFirstValue(params, "grant_type");
137
138                if (grantTypeString == null) {
139                        String msg = "Missing \"grant_type\" parameter";
140                        throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg));
141                }
142
143                if (! GrantType.parse(grantTypeString).equals(GRANT_TYPE)) {
144                        String msg = "The \"grant_type\" must be \"" + GRANT_TYPE + "\"";
145                        throw new ParseException(msg, OAuth2Error.UNSUPPORTED_GRANT_TYPE.appendDescription(": " + msg));
146                }
147
148                // Parse refresh token
149                String refreshTokenString = MultivaluedMapUtils.getFirstValue(params, "refresh_token");
150
151                if (refreshTokenString == null || refreshTokenString.trim().isEmpty()) {
152                        String msg = "Missing or empty \"refresh_token\" parameter";
153                        throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg));
154                }
155
156                RefreshToken refreshToken = new RefreshToken(refreshTokenString);
157
158                return new RefreshTokenGrant(refreshToken);
159        }
160}