Skip to content

Commit 5f4efaa

Browse files
committed
Basic Authorization as trait
This change updates the Basic Authorization behavior to be automatically applied to requests that are implementation of the BasicAuthorized interface. This change ensures that implementations do not have to remember to add this behavior to their invocation.
1 parent 0688a9d commit 5f4efaa

File tree

7 files changed

+104
-64
lines changed

7 files changed

+104
-64
lines changed

cloudfoundry-client-spring/src/main/java/org/cloudfoundry/reactor/uaa/AbstractUaaOperations.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.cloudfoundry.reactor.uaa;
1818

1919
import com.fasterxml.jackson.databind.ObjectMapper;
20-
import io.netty.util.AsciiString;
2120
import org.cloudfoundry.reactor.client.QueryBuilder;
2221
import org.cloudfoundry.reactor.util.AbstractReactorOperations;
2322
import org.cloudfoundry.reactor.util.AuthorizationProvider;
@@ -27,13 +26,10 @@
2726
import reactor.io.netty.http.HttpInbound;
2827
import reactor.io.netty.http.HttpOutbound;
2928

30-
import java.util.Base64;
3129
import java.util.function.Function;
3230

3331
public abstract class AbstractUaaOperations extends AbstractReactorOperations {
3432

35-
private static final AsciiString BASIC_PREAMBLE = new AsciiString("Basic ");
36-
3733
protected AbstractUaaOperations(AuthorizationProvider authorizationProvider, HttpClient httpClient, ObjectMapper objectMapper, Mono<String> root) {
3834
super(authorizationProvider, httpClient, objectMapper, root);
3935
}
@@ -45,12 +41,6 @@ protected static Function<UriComponentsBuilder, UriComponentsBuilder> getUriAugm
4541
};
4642
}
4743

48-
protected final HttpOutbound basicAuth(HttpOutbound outbound, String clientId, String clientSecret) {
49-
String encoded = Base64.getEncoder().encodeToString(new AsciiString(clientId).concat(":").concat(clientSecret).toByteArray());
50-
outbound.headers().set(AUTHORIZATION, BASIC_PREAMBLE + encoded);
51-
return outbound;
52-
}
53-
5444
protected final <T> Mono<T> delete(Object request, Class<T> responseType, Function<UriComponentsBuilder, UriComponentsBuilder> uriTransformer) {
5545
return doDelete(request, responseType, getUriAugmenter(request, uriTransformer), getRequestTransformer(request));
5646
}
@@ -85,12 +75,29 @@ protected final <T> Mono<T> post(Object request, Class<T> responseType, Function
8575
return doPost(request, responseType, getUriAugmenter(request, uriTransformer), getRequestTransformer(request));
8676
}
8777

78+
protected final <T> Mono<T> postForm(Object request, Class<T> responseType, Function<UriComponentsBuilder, UriComponentsBuilder> uriTransformer) {
79+
return postForm(request, responseType, uriTransformer, outbound -> outbound);
80+
}
81+
82+
protected final <T> Mono<T> postForm(Object request, Class<T> responseType, Function<UriComponentsBuilder, UriComponentsBuilder> uriTransformer, Function<HttpOutbound, HttpOutbound>
83+
requestTransformer) {
84+
return doPost(responseType, getUriAugmenter(request, uriTransformer), outbound -> {
85+
outbound.headers().remove(AUTHORIZATION);
86+
getRequestTransformer(request).apply(outbound);
87+
return requestTransformer.apply(outbound)
88+
.addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED)
89+
.removeTransferEncodingChunked()
90+
.sendHeaders();
91+
});
92+
}
93+
8894
protected final <T> Mono<T> put(Object request, Class<T> responseType, Function<UriComponentsBuilder, UriComponentsBuilder> uriTransformer) {
8995
return doPut(request, responseType, getUriAugmenter(request, uriTransformer), getRequestTransformer(request));
9096
}
9197

9298
private static Function<HttpOutbound, HttpOutbound> getRequestTransformer(Object request) {
9399
return outbound -> {
100+
BasicAuthorizationBuilder.augment(outbound, request);
94101
IdentityZoneBuilder.augment(outbound, request);
95102
VersionBuilder.augment(outbound, request);
96103
return outbound;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2013-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.cloudfoundry.reactor.uaa;
18+
19+
import io.netty.util.AsciiString;
20+
import org.cloudfoundry.uaa.BasicAuthorized;
21+
import reactor.io.netty.http.HttpOutbound;
22+
23+
import java.util.Base64;
24+
25+
final class BasicAuthorizationBuilder {
26+
27+
private static final AsciiString AUTHORIZATION = new AsciiString("Authorization");
28+
29+
private static final AsciiString BASIC_PREAMBLE = new AsciiString("Basic ");
30+
31+
private BasicAuthorizationBuilder(){}
32+
33+
static void augment(HttpOutbound outbound, Object request) {
34+
if(request instanceof BasicAuthorized) {
35+
BasicAuthorized basicAuthorized = (BasicAuthorized)request;
36+
String encoded = Base64.getEncoder().encodeToString(new AsciiString(basicAuthorized.getClientId()).concat(":").concat(basicAuthorized.getClientSecret()).toByteArray());
37+
outbound.headers().set(AUTHORIZATION, BASIC_PREAMBLE + encoded);
38+
}
39+
}
40+
41+
}

cloudfoundry-client-spring/src/main/java/org/cloudfoundry/reactor/uaa/VersionBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ private VersionBuilder() {
2626

2727
static void augment(HttpOutbound outbound, Object request) {
2828
if (request instanceof Versioned) {
29-
Versioned identityZoned = (Versioned) request;
30-
outbound.addHeader("If-Match", identityZoned.getVersion());
29+
Versioned versioned = (Versioned) request;
30+
outbound.addHeader("If-Match", versioned.getVersion());
3131
}
3232
}
3333

cloudfoundry-client-spring/src/main/java/org/cloudfoundry/reactor/uaa/tokens/ReactorTokens.java

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,8 @@
3838
import org.cloudfoundry.uaa.tokens.RefreshTokenRequest;
3939
import org.cloudfoundry.uaa.tokens.RefreshTokenResponse;
4040
import org.cloudfoundry.uaa.tokens.Tokens;
41-
import org.springframework.web.util.UriComponentsBuilder;
4241
import reactor.core.publisher.Mono;
4342
import reactor.io.netty.http.HttpClient;
44-
import reactor.io.netty.http.HttpOutbound;
45-
46-
import java.util.function.Function;
4743

4844

4945
public final class ReactorTokens extends AbstractUaaOperations implements Tokens {
@@ -62,8 +58,7 @@ public ReactorTokens(AuthorizationProvider authorizationProvider, HttpClient htt
6258

6359
@Override
6460
public Mono<CheckTokenResponse> check(CheckTokenRequest request) {
65-
return post(request, CheckTokenResponse.class, builder -> builder.pathSegment("check_token"),
66-
outbound -> basicAuth(outbound, request.getClientId(), request.getClientSecret()));
61+
return post(request, CheckTokenResponse.class, builder -> builder.pathSegment("check_token"));
6762
}
6863

6964
@Override
@@ -80,9 +75,7 @@ public Mono<GetTokenByClientCredentialsResponse> getByClientCredentials(GetToken
8075

8176
@Override
8277
public Mono<GetTokenByOneTimePasscodeResponse> getByOneTimePasscode(GetTokenByOneTimePasscodeRequest request) {
83-
return postForm(request, GetTokenByOneTimePasscodeResponse.class,
84-
builder -> builder.pathSegment("oauth", "token").queryParam("grant_type", "password").queryParam("response_type", "token"),
85-
outbound -> basicAuth(outbound, request.getClientId(), request.getClientSecret()));
78+
return postForm(request, GetTokenByOneTimePasscodeResponse.class, builder -> builder.pathSegment("oauth", "token").queryParam("grant_type", "password").queryParam("response_type", "token"));
8679
}
8780

8881
@Override
@@ -111,19 +104,4 @@ public Mono<RefreshTokenResponse> refresh(RefreshTokenRequest request) {
111104
return postForm(request, RefreshTokenResponse.class, builder -> builder.pathSegment("oauth", "token").queryParam("grant_type", "refresh_token"));
112105
}
113106

114-
private <T> Mono<T> postForm(Object request, Class<T> responseType, Function<UriComponentsBuilder, UriComponentsBuilder> uriTransformer) {
115-
return postForm(request, responseType, uriTransformer, outbound -> outbound);
116-
}
117-
118-
private <T> Mono<T> postForm(Object request, Class<T> responseType, Function<UriComponentsBuilder, UriComponentsBuilder> uriTransformer, Function<HttpOutbound, HttpOutbound> requestTransformer) {
119-
return doPost(responseType, getUriAugmenter(request, uriTransformer), outbound -> {
120-
outbound.headers().remove(AUTHORIZATION);
121-
122-
return requestTransformer.apply(outbound)
123-
.addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED)
124-
.removeTransferEncodingChunked()
125-
.sendHeaders();
126-
});
127-
}
128-
129107
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2013-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.cloudfoundry.uaa;
18+
19+
import com.fasterxml.jackson.annotation.JsonIgnore;
20+
21+
/**
22+
* An interface that indicates that a UAA request should use basic authorization
23+
*/
24+
public interface BasicAuthorized {
25+
26+
/**
27+
* The client id
28+
*/
29+
@JsonIgnore
30+
String getClientId();
31+
32+
/**
33+
* The client secret
34+
*/
35+
@JsonIgnore
36+
String getClientSecret();
37+
38+
}

cloudfoundry-client/src/main/java/org/cloudfoundry/uaa/tokens/_CheckTokenRequest.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
package org.cloudfoundry.uaa.tokens;
1818

19-
import com.fasterxml.jackson.annotation.JsonIgnore;
2019
import org.cloudfoundry.Nullable;
2120
import org.cloudfoundry.QueryParameter;
21+
import org.cloudfoundry.uaa.BasicAuthorized;
2222
import org.immutables.value.Value;
2323

2424
import java.util.List;
@@ -27,19 +27,7 @@
2727
* The request payload for the check token operation
2828
*/
2929
@Value.Immutable
30-
abstract class _CheckTokenRequest {
31-
32-
/**
33-
* The client identifier
34-
*/
35-
@JsonIgnore
36-
abstract String getClientId();
37-
38-
/**
39-
* The client's secret passphrase
40-
*/
41-
@JsonIgnore
42-
abstract String getClientSecret();
30+
abstract class _CheckTokenRequest implements BasicAuthorized {
4331

4432
/**
4533
* The scopes authorized by the user for this client

cloudfoundry-client/src/main/java/org/cloudfoundry/uaa/tokens/_GetTokenByOneTimePasscodeRequest.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,16 @@
1616

1717
package org.cloudfoundry.uaa.tokens;
1818

19-
import com.fasterxml.jackson.annotation.JsonIgnore;
2019
import org.cloudfoundry.Nullable;
2120
import org.cloudfoundry.QueryParameter;
21+
import org.cloudfoundry.uaa.BasicAuthorized;
2222
import org.immutables.value.Value;
2323

2424
/**
2525
* The request payload for the get token by one-time passcode operation
2626
*/
2727
@Value.Immutable
28-
abstract class _GetTokenByOneTimePasscodeRequest {
29-
30-
/**
31-
* The client identifier
32-
*/
33-
@JsonIgnore
34-
abstract String getClientId();
35-
36-
/**
37-
* The client's secret passphrase
38-
*/
39-
@JsonIgnore
40-
abstract String getClientSecret();
28+
abstract class _GetTokenByOneTimePasscodeRequest implements BasicAuthorized {
4129

4230
/**
4331
* The passcode

0 commit comments

Comments
 (0)