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 java.net.URI; 022import java.net.URISyntaxException; 023import java.util.Collections; 024import java.util.HashSet; 025import java.util.Set; 026 027import net.jcip.annotations.Immutable; 028import net.minidev.json.JSONObject; 029 030import com.nimbusds.common.contenttype.ContentType; 031import com.nimbusds.oauth2.sdk.ErrorObject; 032import com.nimbusds.oauth2.sdk.OAuth2Error; 033import com.nimbusds.oauth2.sdk.ParseException; 034import com.nimbusds.oauth2.sdk.http.HTTPRequest; 035import com.nimbusds.oauth2.sdk.token.BearerAccessToken; 036import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 037 038 039/** 040 * CIBA error push delivery to the client notification endpoint. 041 * 042 * <p>Related specifications: 043 * 044 * <ul> 045 * <li>OpenID Connect CIBA Flow - Core 1.0, section 12. 046 * </ul> 047 */ 048@Immutable 049public class CIBAErrorDelivery extends CIBAPushCallback { 050 051 052 /** 053 * The standard OAuth 2.0 errors for a CIBA error delivery. 054 */ 055 private static final Set<ErrorObject> STANDARD_ERRORS; 056 057 static { 058 Set<ErrorObject> errors = new HashSet<>(); 059 errors.add(OAuth2Error.ACCESS_DENIED); 060 errors.add(CIBAError.EXPIRED_TOKEN); 061 errors.add(CIBAError.TRANSACTION_FAILED); 062 STANDARD_ERRORS = Collections.unmodifiableSet(errors); 063 } 064 065 066 /** 067 * Gets the standard OAuth 2.0 errors for a CIBA error delivery. 068 * 069 * @return The standard errors, as a read-only set. 070 */ 071 public static Set<ErrorObject> getStandardErrors() { 072 073 return STANDARD_ERRORS; 074 } 075 076 077 /** 078 * The error object. 079 */ 080 private final ErrorObject errorObject; 081 082 083 /** 084 * Creates a new CIBA error push delivery. 085 * 086 * @param endpoint The client notification endpoint. Must not be 087 * {@code null}. 088 * @param accessToken The client notification token. Must not be 089 * {@code null}. 090 * @param authRequestID The CIBA request ID. Must not be {@code null}. 091 * @param errorObject The error object. Must not be {@code null}. 092 */ 093 public CIBAErrorDelivery(final URI endpoint, 094 final BearerAccessToken accessToken, 095 final AuthRequestID authRequestID, 096 final ErrorObject errorObject) { 097 098 super(endpoint, accessToken, authRequestID); 099 100 if (endpoint == null) { 101 throw new IllegalArgumentException("The error object must not be null"); 102 } 103 this.errorObject = errorObject; 104 } 105 106 107 @Override 108 public boolean indicatesSuccess() { 109 110 return false; 111 } 112 113 114 /** 115 * Returns the error object. 116 * 117 * @return The error object. 118 */ 119 public ErrorObject getErrorObject() { 120 121 return errorObject; 122 } 123 124 125 @Override 126 public HTTPRequest toHTTPRequest() { 127 128 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, getEndpointURI()); 129 httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader()); 130 httpRequest.setEntityContentType(ContentType.APPLICATION_JSON); 131 JSONObject jsonObject = new JSONObject(); 132 jsonObject.put("auth_req_id", getAuthRequestID().getValue()); 133 jsonObject.putAll(getErrorObject().toJSONObject()); 134 httpRequest.setQuery(jsonObject.toJSONString()); 135 return httpRequest; 136 } 137 138 139 /** 140 * Parses a CIBA error push delivery from the specified HTTP request. 141 * 142 * @param httpRequest The HTTP request. Must not be {@code null}. 143 * 144 * @return The CIBA error push delivery. 145 * 146 * @throws ParseException If parsing failed. 147 */ 148 public static CIBAErrorDelivery parse(final HTTPRequest httpRequest) 149 throws ParseException { 150 151 URI uri; 152 try { 153 uri = httpRequest.getURL().toURI(); 154 } catch (URISyntaxException e) { 155 throw new ParseException(e.getMessage(), e); 156 } 157 158 httpRequest.ensureMethod(HTTPRequest.Method.POST); 159 httpRequest.ensureEntityContentType(ContentType.APPLICATION_JSON); 160 161 BearerAccessToken clientNotificationToken = BearerAccessToken.parse(httpRequest); 162 163 AuthRequestID authRequestID = new AuthRequestID( 164 JSONObjectUtils.getString( 165 httpRequest.getQueryAsJSONObject(), 166 "auth_req_id") 167 ); 168 169 ErrorObject errorObject = ErrorObject.parse(httpRequest.getQueryAsJSONObject()); 170 171 return new CIBAErrorDelivery(uri, clientNotificationToken, authRequestID, errorObject); 172 } 173}