1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * * Neither the name of Google LLC nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package com.google.auth.oauth2; 33 34 import static com.google.common.base.Preconditions.checkNotNull; 35 36 import com.google.errorprone.annotations.CanIgnoreReturnValue; 37 import java.util.List; 38 import javax.annotation.Nullable; 39 40 /** 41 * Defines an OAuth 2.0 token exchange request. Based on 42 * https://tools.ietf.org/html/rfc8693#section-2.1. 43 */ 44 final class StsTokenExchangeRequest { 45 private static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange"; 46 47 private final String subjectToken; 48 private final String subjectTokenType; 49 50 @Nullable private final ActingParty actingParty; 51 @Nullable private final List<String> scopes; 52 @Nullable private final String resource; 53 @Nullable private final String audience; 54 @Nullable private final String requestedTokenType; 55 @Nullable private final String internalOptions; 56 StsTokenExchangeRequest( String subjectToken, String subjectTokenType, @Nullable ActingParty actingParty, @Nullable List<String> scopes, @Nullable String resource, @Nullable String audience, @Nullable String requestedTokenType, @Nullable String internalOptions)57 private StsTokenExchangeRequest( 58 String subjectToken, 59 String subjectTokenType, 60 @Nullable ActingParty actingParty, 61 @Nullable List<String> scopes, 62 @Nullable String resource, 63 @Nullable String audience, 64 @Nullable String requestedTokenType, 65 @Nullable String internalOptions) { 66 this.subjectToken = checkNotNull(subjectToken); 67 this.subjectTokenType = checkNotNull(subjectTokenType); 68 this.actingParty = actingParty; 69 this.scopes = scopes; 70 this.resource = resource; 71 this.audience = audience; 72 this.requestedTokenType = requestedTokenType; 73 this.internalOptions = internalOptions; 74 } 75 newBuilder(String subjectToken, String subjectTokenType)76 public static Builder newBuilder(String subjectToken, String subjectTokenType) { 77 return new Builder(subjectToken, subjectTokenType); 78 } 79 getGrantType()80 public String getGrantType() { 81 return GRANT_TYPE; 82 } 83 getSubjectToken()84 public String getSubjectToken() { 85 return subjectToken; 86 } 87 getSubjectTokenType()88 public String getSubjectTokenType() { 89 return subjectTokenType; 90 } 91 92 @Nullable getResource()93 public String getResource() { 94 return resource; 95 } 96 97 @Nullable getAudience()98 public String getAudience() { 99 return audience; 100 } 101 102 @Nullable getRequestedTokenType()103 public String getRequestedTokenType() { 104 return requestedTokenType; 105 } 106 107 @Nullable getScopes()108 public List<String> getScopes() { 109 return scopes; 110 } 111 112 @Nullable getActingParty()113 public ActingParty getActingParty() { 114 return actingParty; 115 } 116 117 @Nullable getInternalOptions()118 public String getInternalOptions() { 119 return internalOptions; 120 } 121 hasResource()122 public boolean hasResource() { 123 return resource != null && !resource.isEmpty(); 124 } 125 hasAudience()126 public boolean hasAudience() { 127 return audience != null && !audience.isEmpty(); 128 } 129 hasRequestedTokenType()130 public boolean hasRequestedTokenType() { 131 return requestedTokenType != null && !requestedTokenType.isEmpty(); 132 } 133 hasScopes()134 public boolean hasScopes() { 135 return scopes != null && !scopes.isEmpty(); 136 } 137 hasActingParty()138 public boolean hasActingParty() { 139 return actingParty != null; 140 } 141 142 public static class Builder { 143 private final String subjectToken; 144 private final String subjectTokenType; 145 146 @Nullable private String resource; 147 @Nullable private String audience; 148 @Nullable private String requestedTokenType; 149 @Nullable private List<String> scopes; 150 @Nullable private ActingParty actingParty; 151 @Nullable private String internalOptions; 152 Builder(String subjectToken, String subjectTokenType)153 private Builder(String subjectToken, String subjectTokenType) { 154 this.subjectToken = subjectToken; 155 this.subjectTokenType = subjectTokenType; 156 } 157 158 @CanIgnoreReturnValue setResource(String resource)159 public StsTokenExchangeRequest.Builder setResource(String resource) { 160 this.resource = resource; 161 return this; 162 } 163 164 @CanIgnoreReturnValue setAudience(String audience)165 public StsTokenExchangeRequest.Builder setAudience(String audience) { 166 this.audience = audience; 167 return this; 168 } 169 170 @CanIgnoreReturnValue setRequestTokenType(String requestedTokenType)171 public StsTokenExchangeRequest.Builder setRequestTokenType(String requestedTokenType) { 172 this.requestedTokenType = requestedTokenType; 173 return this; 174 } 175 176 @CanIgnoreReturnValue setScopes(List<String> scopes)177 public StsTokenExchangeRequest.Builder setScopes(List<String> scopes) { 178 this.scopes = scopes; 179 return this; 180 } 181 182 @CanIgnoreReturnValue setActingParty(ActingParty actingParty)183 public StsTokenExchangeRequest.Builder setActingParty(ActingParty actingParty) { 184 this.actingParty = actingParty; 185 return this; 186 } 187 188 @CanIgnoreReturnValue setInternalOptions(String internalOptions)189 public StsTokenExchangeRequest.Builder setInternalOptions(String internalOptions) { 190 this.internalOptions = internalOptions; 191 return this; 192 } 193 build()194 public StsTokenExchangeRequest build() { 195 return new StsTokenExchangeRequest( 196 subjectToken, 197 subjectTokenType, 198 actingParty, 199 scopes, 200 resource, 201 audience, 202 requestedTokenType, 203 internalOptions); 204 } 205 } 206 } 207