001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2021, 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.ciba; 019 020 021import com.nimbusds.common.contenttype.ContentType; 022import com.nimbusds.oauth2.sdk.ParseException; 023import com.nimbusds.oauth2.sdk.SuccessResponse; 024import com.nimbusds.oauth2.sdk.http.HTTPResponse; 025import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 026import net.jcip.annotations.Immutable; 027import net.minidev.json.JSONObject; 028 029import java.util.Objects; 030 031 032/** 033 * Successful CIBA request acknowledgement from an OpenID provider / OAuth 2.0 034 * authorisation server backend authentication endpoint. 035 * 036 * <p>Example HTTP response: 037 * 038 * <pre> 039 * HTTP/1.1 200 OK 040 * Content-Type: application/json 041 * Cache-Control: no-store 042 * 043 * { 044 * "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1", 045 * "expires_in": 120, 046 * "interval": 2 047 * } 048 * </pre> 049 * 050 * <p>Related specifications: 051 * 052 * <ul> 053 * <li>OpenID Connect CIBA Flow - Core 1.0 054 * </ul> 055 */ 056@Immutable 057public class CIBARequestAcknowledgement extends CIBAResponse implements SuccessResponse { 058 059 060 /** 061 * The default minimal wait interval in seconds for polling the token 062 * endpoint for the poll and ping delivery modes. 063 */ 064 public static final int DEFAULT_MIN_WAIT_INTERVAL = 5; 065 066 067 /** 068 * The CIBA request ID. 069 */ 070 private final AuthRequestID authRequestID; 071 072 073 /** 074 * The expiration time of the CIBA request ID, in seconds. 075 */ 076 private final int expiresIn; 077 078 079 /** 080 * The minimal wait interval in seconds for polling the token endpoint 081 * for the poll or ping delivery modes. 082 */ 083 private final Integer minWaitInterval; 084 085 086 /** 087 * Creates a new successful CIBA request acknowledgement. 088 * 089 * @param authRequestID The CIBA request ID. 090 * @param expiresIn The expiration time of the CIBA request ID, 091 * in seconds. Must be positive. 092 * @param minWaitInterval The minimal wait interval in seconds for 093 * polling the token endpoint for the poll or 094 * ping delivery modes, {@code null} if not 095 * specified. 096 */ 097 public CIBARequestAcknowledgement(final AuthRequestID authRequestID, 098 final int expiresIn, 099 final Integer minWaitInterval) { 100 101 super(); 102 103 this.authRequestID = Objects.requireNonNull(authRequestID); 104 105 if (expiresIn < 1) { 106 throw new IllegalArgumentException("The expiration must be a positive integer"); 107 } 108 this.expiresIn = expiresIn; 109 110 if (minWaitInterval != null && minWaitInterval < 1) { 111 throw new IllegalArgumentException("The interval must be a positive integer"); 112 } 113 this.minWaitInterval = minWaitInterval; 114 } 115 116 117 @Override 118 public boolean indicatesSuccess() { 119 return true; 120 } 121 122 123 /** 124 * Returns the CIBA request ID. 125 * 126 * @return The CIBA request ID. 127 */ 128 public AuthRequestID getAuthRequestID() { 129 return authRequestID; 130 } 131 132 133 /** 134 * Returns the expiration time of the CIBA request ID in seconds. 135 * 136 * @return The expiration time in seconds. 137 */ 138 public int getExpiresIn() { 139 return expiresIn; 140 } 141 142 143 /** 144 * Returns the minimum wait interval in seconds for polling the token 145 * endpoint for the poll and ping delivery modes. 146 * 147 * @return The interval in seconds, {@code null} if not specified. 148 */ 149 public Integer getMinWaitInterval() { 150 return minWaitInterval; 151 } 152 153 154 /** 155 * Returns a JSON object representation of this CIBA request 156 * acknowledgement. 157 * 158 * @return The JSON object. 159 */ 160 public JSONObject toJSONObject() { 161 162 JSONObject o = new JSONObject(); 163 o.put("auth_req_id", authRequestID); 164 o.put("expires_in", expiresIn); 165 if (minWaitInterval != null) { 166 o.put("interval", minWaitInterval); 167 } 168 return o; 169 } 170 171 172 @Override 173 public HTTPResponse toHTTPResponse() { 174 175 HTTPResponse httpResponse = new HTTPResponse(HTTPResponse.SC_OK); 176 httpResponse.setEntityContentType(ContentType.APPLICATION_JSON); 177 httpResponse.setCacheControl("no-store"); 178 httpResponse.setPragma("no-cache"); 179 httpResponse.setBody(toJSONObject().toString()); 180 return httpResponse; 181 } 182 183 184 /** 185 * Parses a successful CIBA request acknowledgement from the specified 186 * JSON object. 187 * 188 * @param jsonObject The JSON object to parse. Must not be {@code null}. 189 * 190 * @return The CIBA request acknowledgement. 191 * 192 * @throws ParseException If parsing failed. 193 */ 194 public static CIBARequestAcknowledgement parse(final JSONObject jsonObject) 195 throws ParseException { 196 197 AuthRequestID authRequestID = AuthRequestID.parse(JSONObjectUtils.getNonBlankString(jsonObject, "auth_req_id")); 198 199 int expiresIn = JSONObjectUtils.getInt(jsonObject, "expires_in"); 200 201 if (expiresIn < 1) { 202 throw new ParseException("The expires_in parameter must be a positive integer"); 203 } 204 205 Integer minWaitInterval = null; 206 if (jsonObject.get("interval") != null) { 207 minWaitInterval = JSONObjectUtils.getInt(jsonObject, "interval"); 208 } 209 210 if (minWaitInterval != null && minWaitInterval < 1) { 211 throw new ParseException("The interval parameter must be a positive integer"); 212 } 213 214 return new CIBARequestAcknowledgement(authRequestID, expiresIn, minWaitInterval); 215 } 216 217 218 /** 219 * Parses a successful CIBA request acknowledgement from the specified 220 * HTTP response. 221 * 222 * @param httpResponse The HTTP response to parse. Must not be 223 * {@code null}. 224 * 225 * @return The CIBA request acknowledgement. 226 * 227 * @throws ParseException If parsing failed. 228 */ 229 public static CIBARequestAcknowledgement parse(final HTTPResponse httpResponse) 230 throws ParseException { 231 232 httpResponse.ensureStatusCode(HTTPResponse.SC_OK); 233 JSONObject jsonObject = httpResponse.getBodyAsJSONObject(); 234 return parse(jsonObject); 235 } 236}