Skip to content

Commit

Permalink
rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
strehle committed May 24, 2024
1 parent f6e6375 commit 73f0c83
Show file tree
Hide file tree
Showing 5 changed files with 1 addition and 222 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
Expand Down Expand Up @@ -411,7 +410,6 @@ protected void patchSensitiveData(String id, IdentityProvider provider) {
definition.setBindPassword(existingDefinition.getBindPassword());
}
}
}
break;
}
case OAUTH20, OIDC10 : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,79 +329,6 @@ void retrieve_by_origin_providers_redacts_data() {
assertEquals(ClientAuthentication.CLIENT_SECRET_BASIC, oidc.getConfig().getAuthMethod());
}

@Test
void delete_secret_and_retrieve_by_origin_providers_redacts_data() {
IdentityProvider idp = getExternalOAuthProvider();
when(mockIdpAliasHandler.ensureConsistencyOfAliasEntity(null, idp)).thenReturn(idp);
when(mockIdentityProviderProvisioning.retrieve("puppyId", "uaa")).thenReturn(idp);
ResponseEntity<IdentityProvider> oidcBody = identityProviderEndpoints.deleteSecret("puppyId");
IdentityProvider<?> oidc = oidcBody.getBody();
assertNotNull(oidc);
assertNotNull(oidc.getConfig());
assertTrue(oidc.getConfig() instanceof AbstractExternalOAuthIdentityProviderDefinition);
assertNull(((AbstractExternalOAuthIdentityProviderDefinition) oidc.getConfig()).getRelyingPartySecret());
assertEquals(ClientAuthentication.NONE, ((AbstractExternalOAuthIdentityProviderDefinition) oidc.getConfig()).getAuthMethod());
}

@Test
void delete_secret_on_ldap_fails() {
when(mockIdentityProviderProvisioning.retrieve("puppyId", "uaa")).thenReturn(getLdapDefinition());
ResponseEntity<IdentityProvider> oidcBody = identityProviderEndpoints.deleteSecret("puppyId");
IdentityProvider<?> oidc = oidcBody.getBody();
assertEquals(UNPROCESSABLE_ENTITY, oidcBody.getStatusCode());
assertNull(oidc);
}

@Test
void change_bindPassword_and_retrieve_by_origin_providers_redacts_data() {
IdentityProvider idp = getLdapDefinition();
when(mockIdentityProviderProvisioning.retrieve("puppyId", "uaa")).thenReturn(idp);
IdentityProviderSecretChange identityProviderSecretChange = new IdentityProviderSecretChange();
identityProviderSecretChange.setSecret("newSecret");
ResponseEntity<IdentityProvider> oidcBody = identityProviderEndpoints.changeSecret("puppyId", identityProviderSecretChange);
IdentityProvider<?> oidc = oidcBody.getBody();
assertNotNull(oidc);
assertNotNull(oidc.getConfig());
assertTrue(oidc.getConfig() instanceof LdapIdentityProviderDefinition);
assertNull(((LdapIdentityProviderDefinition) oidc.getConfig()).getBindPassword());
}

@Test
void change_secret_and_retrieve_by_origin_providers_redacts_data() {
IdentityProvider idp = getExternalOAuthProvider();
when(mockIdpAliasHandler.ensureConsistencyOfAliasEntity(null, idp)).thenReturn(idp);
when(mockIdentityProviderProvisioning.retrieve("puppyId", "uaa")).thenReturn(idp);
IdentityProviderSecretChange identityProviderSecretChange = new IdentityProviderSecretChange();
identityProviderSecretChange.setSecret("newSecret");
ResponseEntity<IdentityProvider> oidcBody = identityProviderEndpoints.changeSecret("puppyId", identityProviderSecretChange);
IdentityProvider<?> oidc = oidcBody.getBody();
assertNotNull(oidc);
assertNotNull(oidc.getConfig());
assertTrue(oidc.getConfig() instanceof AbstractExternalOAuthIdentityProviderDefinition);
assertNull(((AbstractExternalOAuthIdentityProviderDefinition) oidc.getConfig()).getRelyingPartySecret());
assertEquals(ClientAuthentication.CLIENT_SECRET_BASIC, ((AbstractExternalOAuthIdentityProviderDefinition) oidc.getConfig()).getAuthMethod());
}

@Test
void change_secret_on_uaafails() {
IdentityProvider identityProvider = new IdentityProvider<>();
identityProvider.setConfig(new SamlIdentityProviderDefinition());
identityProvider.setName("my saml provider");
identityProvider.setIdentityZoneId(OriginKeys.UAA);
identityProvider.setType(OriginKeys.SAML);
IdentityProviderSecretChange identityProviderSecretChange = new IdentityProviderSecretChange();
when(mockIdentityProviderProvisioning.retrieve("puppyId", "uaa")).thenReturn(identityProvider);
ResponseEntity<IdentityProvider> oidcBody = identityProviderEndpoints.changeSecret("puppyId", identityProviderSecretChange);
IdentityProvider<?> oidc = oidcBody.getBody();
assertEquals(UNPROCESSABLE_ENTITY, oidcBody.getStatusCode());
assertNull(oidc);
identityProviderSecretChange.setSecret("newSecret");
oidcBody = identityProviderEndpoints.changeSecret("puppyId", identityProviderSecretChange);
oidc = oidcBody.getBody();
assertEquals(UNPROCESSABLE_ENTITY, oidcBody.getStatusCode());
assertNull(oidc);
}

@Test
void update_ldap_provider_patches_password() throws Exception {
IdentityProvider<LdapIdentityProviderDefinition> provider = retrieve_ldap_provider_by_id("id");
Expand Down
76 changes: 0 additions & 76 deletions uaa/slateCustomizations/source/index.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -1261,82 +1261,6 @@ _Error Codes_
| 403 | Forbidden - Insufficient scope |
| 422 | Unprocessable Entity - Invalid config |

## Change Secret

<aside class="success">
Added in UAA 77.10.0
</aside>
<br/>
Change a relyingPartySecret in the OAuth2 / OIDC IdP configuration or bindPassword in case of LDAP.
<br/>

<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenChangeSecret/curl-request.md') %>
<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenChangeSecret/http-request.md') %>
<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenChangeSecret/http-response.md') %>

_Path Parameters_

<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenChangeSecret/path-parameters.md') %>

_Request Headers_

<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenChangeSecret/request-headers.md') %>

<aside class="notice">
This example is for LDAP, OAuth2 and OIDC identity providers. <br/>
This updates option relyingPartySecret in case of OAuth2 / OIDC or bindPassword in case of LDAP. <br/>
</aside>

_Request and Response Fields_

<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenChangeSecret/response-fields.md') %>

_Error Codes_

| Error Code | Description |
|------------|-----------------------------------------------------------------------|
| 403 | Forbidden - Insufficient scope |
| 422 | Unprocessable Entity - Invalid config |

## Delete Secret

<aside class="success">
Added in UAA 77.10.0
</aside>
<br/>
Delete a secret from the OAuth2 / OIDC IdP configuration only, because these providers support usages without a secret.
<br/>

<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenDeleteSecret/curl-request.md') %>
<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenDeleteSecret/http-request.md') %>
<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenDeleteSecret/http-response.md') %>

_Path Parameters_

<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenDeleteSecret/path-parameters.md') %>

_Request Headers_

<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenDeleteSecret/request-headers.md') %>

<aside class="notice">
This example is for OAuth2 and OIDC identity providers <br/>
For a standard IdP the result of auth_method will be none, because the removal of the secret
lead to public flow.<br/>
If jwtClientAuthentication section is configured, then after this call, the result of auth_method is private_key_jwt.<br/>
If you want set again a secret or change the current secret, please use patch call, e.g. Change Secret<br/>
</aside>

_Request and Response Fields_

<%= render('IdentityProviderEndpointDocs/createOAuthIdentityProviderThenDeleteSecret/response-fields.md') %>

_Error Codes_

| Error Code | Description |
|------------|-----------------------------------------------------------------------|
| 403 | Forbidden - Insufficient scope |
| 422 | Unprocessable Entity - Invalid config |

# Users

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@
import org.cloudfoundry.identity.uaa.provider.AbstractExternalOAuthIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.provider.IdentityProvider;
import org.cloudfoundry.identity.uaa.provider.IdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.provider.IdentityProviderSecretChange;
import org.cloudfoundry.identity.uaa.provider.IdentityProviderStatus;
import org.cloudfoundry.identity.uaa.provider.JdbcIdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.provider.LdapIdentityProviderDefinition;
Expand Down Expand Up @@ -590,7 +589,6 @@ void createOAuthIdentityProvider() throws Exception {
fieldWithPath("config.userInfoUrl").optional(null).type(STRING).description("A URL for fetching user info attributes when queried with the obtained token authorization."),
fieldWithPath("config.showLinkText").optional(true).type(BOOLEAN).description("A flag controlling whether a link to this provider's login will be shown on the UAA login page"),
fieldWithPath("config.linkText").optional(null).type(STRING).description("Text to use for the login link to the provider"),
fieldWithPath("config.auth_method").optional(null).type(STRING).description("<small><mark>UAA 77.10.0</mark></small> Client authentication method. Possible strings are: client_secret_basic, client_secret_post, private_key_jwt, none."),
fieldWithPath("config.relyingPartyId").required().type(STRING).description("The client ID which is registered with the external OAuth provider for use by the UAA"),
fieldWithPath("config.skipSslValidation").optional(null).type(BOOLEAN).description("A flag controlling whether SSL validation should be skipped when communicating with the external OAuth server"),
fieldWithPath("config.scopes").optional(null).type(ARRAY).description("What scopes to request on a call to the external OAuth provider"),
Expand Down Expand Up @@ -635,7 +633,7 @@ void createOAuthIdentityProvider() throws Exception {
IDENTITY_ZONE_ID,
CREATED,
LAST_MODIFIED,
fieldWithPath("config.externalGroupsWhitelist").optional(null).type(ARRAY).description("Not currently used."),
fieldWithPath("config.externalGroupsWhitelist").optional(null).type(ARRAY).description("Not currently used.")
},
ALIAS_FIELDS_GET
)
Expand Down Expand Up @@ -697,7 +695,6 @@ void createOidcIdentityProvider() throws Exception {
fieldWithPath("config.tokenKey").optional(null).type(STRING).description("A verification key for validating token signatures. We recommend not setting this as it will not allow for key rotation. This can be left blank if a discovery URL is provided. If both are provided, this property overrides the discovery URL.").attributes(new Attributes.Attribute("constraints", "Required unless `discoveryUrl` is set.")),
fieldWithPath("config.showLinkText").optional(true).type(BOOLEAN).description("A flag controlling whether a link to this provider's login will be shown on the UAA login page"),
fieldWithPath("config.linkText").optional(null).type(STRING).description("Text to use for the login link to the provider"),
fieldWithPath("config.auth_method").optional(null).type(STRING).description("<small><mark>UAA 77.10.0</mark></small> Client authentication method. Possible strings are: client_secret_basic, client_secret_post, private_key_jwt, none."),
fieldWithPath("config.relyingPartyId").required().type(STRING).description("The client ID which is registered with the external OAuth provider for use by the UAA"),
fieldWithPath("config.skipSslValidation").optional(null).type(BOOLEAN).description("A flag controlling whether SSL validation should be skipped when communicating with the external OAuth server"),
fieldWithPath("config.scopes").optional(null).type(ARRAY).description("What scopes to request on a call to the external OAuth/OpenID provider. For example, can provide " +
Expand Down Expand Up @@ -1143,56 +1140,6 @@ void patchIdentityProviderStatus() throws Exception {

}

@Test
void createOAuthIdentityProviderThenChangeSecret() throws Exception {
IdentityProvider identityProvider = identityProviderProvisioning.retrieveByOrigin("my-oauth2-provider", IdentityZoneHolder.get().getId());

IdentityProviderSecretChange identityProviderSecretChange = new IdentityProviderSecretChange();
identityProviderSecretChange.setSecret("newSecret" + new AlphanumericRandomValueStringGenerator(10).generate());

FieldDescriptor[] idempotentFields = new FieldDescriptor[]{
fieldWithPath("secret").required().description("Set new secret and/or bind password, depending on provided IdP type.")
};

Snippet requestFields = requestFields(idempotentFields);

mockMvc.perform(patch("/identity-providers/{id}/secret", identityProvider.getId())
.header("Authorization", "Bearer " + adminToken)
.contentType(APPLICATION_JSON)
.content(serializeExcludingProperties(identityProviderSecretChange)))
.andExpect(status().isOk())
.andDo(document("{ClassName}/{methodName}",
preprocessResponse(prettyPrint()),
pathParameters(parameterWithName("id").description(ID_DESC)
),
requestHeaders(
headerWithName("Authorization").description("Bearer token containing `zones.<zone id>.admin` or `uaa.admin` or `idps.write` (only in the same zone that you are a user of)"),
IDENTITY_ZONE_ID_HEADER,
IDENTITY_ZONE_SUBDOMAIN_HEADER
),
requestFields,
responseFields(getCommonProviderFieldsAnyType())));
}

@Test
void createOAuthIdentityProviderThenDeleteSecret() throws Exception {
IdentityProvider identityProvider = identityProviderProvisioning.retrieveByOrigin("my-oauth2-provider", IdentityZoneHolder.get().getId());

mockMvc.perform(delete("/identity-providers/{id}/secret", identityProvider.getId())
.header("Authorization", "Bearer " + adminToken))
.andExpect(status().isOk())
.andDo(document("{ClassName}/{methodName}",
preprocessResponse(prettyPrint()),
pathParameters(parameterWithName("id").description(ID_DESC)
),
requestHeaders(
headerWithName("Authorization").description("Bearer token containing `zones.<zone id>.admin` or `uaa.admin` or `idps.write` (only in the same zone that you are a user of)"),
IDENTITY_ZONE_ID_HEADER,
IDENTITY_ZONE_SUBDOMAIN_HEADER
),
responseFields(getCommonProviderFieldsAnyType())));
}

@Test
void deleteIdentityProvider() throws Exception {
IdentityProvider identityProvider = JsonUtils.readValue(mockMvc.perform(post("/identity-providers")
Expand Down

0 comments on commit 73f0c83

Please sign in to comment.