Skip to content

Commit 59afa2c

Browse files
authored
refactor: show client jwt configuration (#3302)
* refactor: show client jwt configuration These entries are not visible with uaac client get cf: jwks_uri jwks keys jwt_creds * refactor: add need entries only to ClientDetailsModification * add test to check expected results * test change because of sonar * test fix
1 parent 97ec983 commit 59afa2c

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/ClientDetailsModification.java renamed to server/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/ClientDetailsModification.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@
44
import com.fasterxml.jackson.annotation.JsonIgnore;
55
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
66
import com.fasterxml.jackson.annotation.JsonInclude;
7+
import com.fasterxml.jackson.annotation.JsonProperty;
78
import com.fasterxml.jackson.annotation.JsonSetter;
9+
import org.cloudfoundry.identity.uaa.client.ClientJwtConfiguration;
810
import org.cloudfoundry.identity.uaa.client.UaaClientDetails;
11+
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKey;
12+
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKeySet;
913
import org.cloudfoundry.identity.uaa.oauth.provider.ClientDetails;
1014

15+
import java.util.List;
16+
import java.util.Objects;
17+
1118
@JsonInclude(JsonInclude.Include.NON_NULL)
1219
@JsonIgnoreProperties(ignoreUnknown = true)
1320
public class ClientDetailsModification extends UaaClientDetails {
@@ -22,6 +29,15 @@ public class ClientDetailsModification extends UaaClientDetails {
2229
@JsonIgnore
2330
private String action = NONE;
2431

32+
@JsonProperty("jwks_uri")
33+
private String jwksUri;
34+
35+
@JsonProperty("jwks")
36+
private transient JsonWebKeySet<JsonWebKey> jwkSet;
37+
38+
@JsonProperty("jwt_creds")
39+
private transient List<ClientJwtCredential> clientJwtCredentials;
40+
2541
public ClientDetailsModification() {
2642
}
2743

@@ -32,6 +48,12 @@ public ClientDetailsModification(ClientDetails prototype) {
3248
if (baseClientDetails.getAutoApproveScopes() != null) {
3349
this.setAutoApproveScopes(baseClientDetails.getAutoApproveScopes());
3450
}
51+
if (baseClientDetails.getClientJwtConfig() instanceof String ) {
52+
ClientJwtConfiguration clientJwtConfiguration = ClientJwtConfiguration.readValue(baseClientDetails);
53+
this.setJwksUri(clientJwtConfiguration.getJwksUri());
54+
this.setJwkSet(clientJwtConfiguration.getJwkSet());
55+
this.setClientJwtCredentials(clientJwtConfiguration.getClientJwtCredentials());
56+
}
3557
}
3658
if (prototype instanceof ClientDetailsModification modification) {
3759
this.action = modification.getAction();
@@ -87,4 +109,63 @@ private boolean valid(String action) {
87109
|| UPDATE_SECRET.equals(action)
88110
|| SECRET.equals(action);
89111
}
112+
113+
public String getJwksUri() {
114+
return this.jwksUri;
115+
}
116+
117+
public void setJwksUri(String jwksUri) {
118+
this.jwksUri = jwksUri;
119+
}
120+
121+
public JsonWebKeySet<JsonWebKey> getJwkSet() {
122+
return this.jwkSet;
123+
}
124+
125+
public void setJwkSet(final JsonWebKeySet<JsonWebKey> jwkSet) {
126+
this.jwkSet = jwkSet;
127+
}
128+
129+
public List<ClientJwtCredential> getClientJwtCredentials() {
130+
return this.clientJwtCredentials;
131+
}
132+
133+
public void setClientJwtCredentials(final List<ClientJwtCredential> clientJwtCredentials) {
134+
this.clientJwtCredentials = clientJwtCredentials;
135+
}
136+
137+
@Override
138+
public boolean equals(Object other) {
139+
if (this == other) {
140+
return true;
141+
}
142+
if (other == null || getClass() != other.getClass()) {
143+
return false;
144+
}
145+
if (!super.equals(other)) {
146+
return false;
147+
}
148+
ClientDetailsModification that = (ClientDetailsModification) other;
149+
if (!Objects.equals(jwksUri, that.jwksUri)) {
150+
return false;
151+
}
152+
if (!Objects.equals(jwkSet, that.jwkSet)) {
153+
return false;
154+
}
155+
if (!Objects.equals(clientJwtCredentials, that.clientJwtCredentials)) {
156+
return false;
157+
}
158+
return Objects.equals(action, that.action);
159+
}
160+
161+
@Override
162+
public int hashCode() {
163+
final int prime = 31;
164+
int result = super.hashCode();
165+
result = prime * result + (action != null ? action.hashCode() : 0);
166+
result = prime * result + (jwksUri == null ? 0 : jwksUri.hashCode());
167+
result = prime * result + (jwkSet == null ? 0 : jwkSet.hashCode());
168+
result = prime * result + (clientJwtCredentials == null ? 0 : clientJwtCredentials.hashCode());
169+
return result;
170+
}
90171
}

server/src/test/java/org/cloudfoundry/identity/uaa/client/ClientAdminEndpointsTests.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,44 @@ void updateClientWithAutoapproveScopesList() {
985985
assertThat(updated.isAutoApprove("foo.write")).isFalse();
986986
}
987987

988+
@Test
989+
void getClientWithFederatedJwt() {
990+
// Given
991+
UaaClientDetails uaaClientDetails = new UaaClientDetails(input);
992+
uaaClientDetails.setAutoApproveScopes(uaaClientDetails.getScope());
993+
List<ClientJwtCredential> jwtCredentials = List.of(new ClientJwtCredential("subject", "issuer", null));
994+
ClientJwtConfiguration clientJwtConfiguration = new ClientJwtConfiguration(jwtCredentials);
995+
clientJwtConfiguration.setJwksUri("http://localhost:8080/uaa/token_keys");
996+
clientJwtConfiguration.writeValue(uaaClientDetails);
997+
when(clientDetailsService.retrieve(input.getClientId(), IdentityZoneHolder.get().getId())).thenReturn(
998+
uaaClientDetails);
999+
when(mockSecurityContextAccessor.getClientId()).thenReturn(detail.getClientId());
1000+
when(mockSecurityContextAccessor.isClient()).thenReturn(true);
1001+
// Then
1002+
ClientDetails result = endpoints.getClientDetails(input.getClientId());
1003+
// When
1004+
assertThat(result.getClientSecret()).isNull();
1005+
ClientDetailsModification modification = (ClientDetailsModification) result;
1006+
assertThat(modification.getClientJwtCredentials()).size().isEqualTo(1);
1007+
assertThat(modification.getJwkSet()).isNull();
1008+
assertThat(modification.getJwksUri()).isEqualTo("http://localhost:8080/uaa/token_keys");
1009+
ClientJwtCredential clientJwtCredential = modification.getClientJwtCredentials().get(0);
1010+
assertThat(clientJwtCredential).isNotNull();
1011+
assertThat(clientJwtCredential.getIssuer()).isEqualTo("issuer");
1012+
assertThat(clientJwtCredential.getSubject()).isEqualTo("subject");
1013+
assertThat(clientJwtCredential.getAudience()).isNull();
1014+
ClientDetailsModification modification2 = new ClientDetailsModification(uaaClientDetails);
1015+
modification2.setAction("add");
1016+
// Compare results and original with and without secret
1017+
assertThat(modification).isNotEqualTo(modification2);
1018+
assertThat(modification.hashCode()).isNotEqualTo(modification2.hashCode());
1019+
uaaClientDetails.setClientSecret(null);
1020+
ClientDetailsModification modification3 = new ClientDetailsModification(uaaClientDetails);
1021+
assertThat(modification).isEqualTo(modification3).hasSameHashCodeAs(modification3);
1022+
assertThat(modification.getAction()).isNotEqualTo(modification2.getAction());
1023+
assertThat(modification.getAction()).isEqualTo(modification3.getAction());
1024+
}
1025+
9881026
@Test
9891027
void updateClientWithAutoapproveScopesTrue() {
9901028
Mockito.when(clientDetailsService.retrieve(input.getClientId(), IdentityZoneHolder.get().getId())).thenReturn(

0 commit comments

Comments
 (0)