001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2020, 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.openid.connect.sdk.federation.api; 019 020 021import java.net.URI; 022import java.util.*; 023 024import net.jcip.annotations.Immutable; 025 026import com.nimbusds.common.contenttype.ContentType; 027import com.nimbusds.jwt.SignedJWT; 028import com.nimbusds.jwt.util.DateUtils; 029import com.nimbusds.oauth2.sdk.ParseException; 030import com.nimbusds.oauth2.sdk.http.HTTPRequest; 031import com.nimbusds.oauth2.sdk.id.Identifier; 032import com.nimbusds.oauth2.sdk.id.Subject; 033import com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils; 034import com.nimbusds.oauth2.sdk.util.StringUtils; 035import com.nimbusds.oauth2.sdk.util.URLUtils; 036import com.nimbusds.openid.connect.sdk.federation.entities.EntityID; 037 038 039/** 040 * Trust mark status request. 041 * 042 * <p>Related specifications: 043 * 044 * <ul> 045 * <li>OpenID Connect Federation 1.0, section 7.4.1. 046 * </ul> 047 */ 048@Immutable 049public class TrustMarkStatusRequest extends FederationAPIRequest { 050 051 052 /** 053 * The trust mark subject. 054 */ 055 private final Subject subject; 056 057 058 /** 059 * The trust mark identifier. 060 */ 061 private final Identifier id; 062 063 064 /** 065 * The trust mark issue time. 066 */ 067 private final Date iat; 068 069 070 /** 071 * The trust mark. 072 */ 073 private final SignedJWT trustMark; 074 075 076 /** 077 * Creates a new trust mark status request. 078 * 079 * @param endpoint The trust mark status endpoint. Must not be 080 * {@code null}. 081 * @param subject The subject. Must not be {@code null}. 082 * @param id The trust mark identifier. Must not be {@code null}. 083 * @param iat The trust mark issue time, {@code null} if not 084 * specified. 085 */ 086 public TrustMarkStatusRequest(final URI endpoint, 087 final Subject subject, 088 final Identifier id, 089 final Date iat) { 090 091 super(endpoint); 092 093 if (subject == null) { 094 throw new IllegalArgumentException("The subject must not be null"); 095 } 096 this.subject = subject; 097 098 if (id == null) { 099 throw new IllegalArgumentException("The ID must not be null"); 100 } 101 this.id = id; 102 103 this.iat = iat; 104 105 trustMark = null; 106 } 107 108 109 /** 110 * Creates a new trust mark status request. 111 * 112 * @param endpoint The trust mark status endpoint. Must not be 113 * {@code null}. 114 * @param trustMark The trust mark. Must not be {@code null}. 115 */ 116 public TrustMarkStatusRequest(final URI endpoint, 117 final SignedJWT trustMark) { 118 super(endpoint); 119 120 if (trustMark == null) { 121 throw new IllegalArgumentException("The trust mark must not be null"); 122 } 123 this.trustMark = trustMark; 124 125 subject = null; 126 id = null; 127 iat = null; 128 } 129 130 131 /** 132 * Returns the trust mark subject. 133 * 134 * @return The trust mark subject, {@code null} if not specified. 135 */ 136 public Subject getSubject() { 137 return subject; 138 } 139 140 141 /** 142 * Returns the trust mark subject entity ID. 143 * 144 * @return The trust mark subject entity ID, {@code null} if not 145 * specified. 146 */ 147 public EntityID getSubjectEntityID() { 148 return subject != null ? new EntityID(subject) : null; 149 } 150 151 152 /** 153 * Returns the trust mark ID. 154 * 155 * @return The trust mark ID, {@code null} if not specified. 156 */ 157 public Identifier getID() { 158 return id; 159 } 160 161 162 /** 163 * Returns the trust mark issue time. 164 * 165 * @return The trust mark issue time, {@code null} if not specified. 166 */ 167 public Date getIssueTime() { 168 return iat; 169 } 170 171 172 /** 173 * Returns the trust mark. 174 * 175 * @return The trust mark, {@code null} if not specified. 176 */ 177 public SignedJWT getTrustMark() { 178 return trustMark; 179 } 180 181 182 @Override 183 public Map<String, List<String>> toParameters() { 184 Map<String, List<String>> params = new LinkedHashMap<>(); 185 if (getSubject() != null) { 186 params.put("sub", Collections.singletonList(getSubject().getValue())); 187 } 188 if (getID() != null) { 189 params.put("id", Collections.singletonList(getID().getValue())); 190 } 191 if (getIssueTime() != null) { 192 params.put("iat", Collections.singletonList(DateUtils.toSecondsSinceEpoch(getIssueTime()) + "")); 193 } 194 if (getTrustMark() != null) { 195 params.put("trust_mark", Collections.singletonList(getTrustMark().serialize())); 196 } 197 return params; 198 } 199 200 201 @Override 202 public HTTPRequest toHTTPRequest() { 203 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, getEndpointURI()); 204 httpRequest.setEntityContentType(ContentType.APPLICATION_URLENCODED); 205 httpRequest.setQuery(URLUtils.serializeParameters(toParameters())); 206 return httpRequest; 207 } 208 209 210 /** 211 * Parses a trust mark status request from the specified request 212 * parameters. 213 * 214 * @param params The request parameters. Must not be {@code null}. 215 * 216 * @return The trust mark status request. 217 * 218 * @throws ParseException If parsing failed. 219 */ 220 public static TrustMarkStatusRequest parse(final Map<String, List<String>> params) 221 throws ParseException { 222 223 Subject subject = null; 224 String value = MultivaluedMapUtils.getFirstValue(params, "sub"); 225 if (StringUtils.isNotBlank(value)) { 226 subject = new Subject(value); 227 } 228 229 Identifier id = null; 230 value = MultivaluedMapUtils.getFirstValue(params, "id"); 231 if (StringUtils.isNotBlank(value)) { 232 id = new Identifier(value); 233 } 234 235 Date iat = null; 236 value = MultivaluedMapUtils.getFirstValue(params, "iat"); 237 if (StringUtils.isNotBlank(value)) { 238 try { 239 iat = DateUtils.fromSecondsSinceEpoch(Long.parseLong(value)); 240 } catch (NumberFormatException e) { 241 throw new ParseException("Illegal iat"); 242 } 243 } 244 245 SignedJWT trustMark = null; 246 value = MultivaluedMapUtils.getFirstValue(params, "trust_mark"); 247 if (StringUtils.isNotBlank(value)) { 248 try { 249 trustMark = SignedJWT.parse(value); 250 } catch (java.text.ParseException e) { 251 throw new ParseException("Invalid trust mark: " + e.getMessage(), e); 252 } 253 } 254 255 if (trustMark != null) { 256 return new TrustMarkStatusRequest(null, trustMark); 257 } 258 259 try { 260 return new TrustMarkStatusRequest(null, subject, id, iat); 261 } catch (IllegalArgumentException e) { 262 throw new ParseException("Invalid request: " + e.getMessage()); 263 } 264 } 265 266 267 /** 268 * Parses a trust mark status request from the specified HTTP request. 269 * 270 * @param httpRequest The HTTP request. Must not be {@code null}. 271 * 272 * @return The trust negotiation request. 273 * 274 * @throws ParseException If parsing failed. 275 */ 276 public static TrustMarkStatusRequest parse(final HTTPRequest httpRequest) 277 throws ParseException { 278 279 httpRequest.ensureMethod(HTTPRequest.Method.POST); 280 httpRequest.ensureEntityContentType(ContentType.APPLICATION_URLENCODED); 281 282 TrustMarkStatusRequest request = TrustMarkStatusRequest.parse(httpRequest.getQueryParameters()); 283 284 if (request.getTrustMark() != null) { 285 return new TrustMarkStatusRequest( 286 httpRequest.getURI(), 287 request.trustMark 288 ); 289 } else { 290 return new TrustMarkStatusRequest( 291 httpRequest.getURI(), 292 request.getSubject(), 293 request.getID(), 294 request.getIssueTime() 295 ); 296 } 297 } 298}