Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: filter IdP retrival #2882

Merged
merged 29 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2c203c7
WIP: idp secret
strehle May 9, 2024
de0009a
Merge remote-tracking branch 'refs/remotes/origin/develop' into featu…
strehle May 10, 2024
189cf06
feature: delete secret on existing IdP
strehle May 10, 2024
e896c0b
Documentation
strehle May 10, 2024
b35b9ed
fix names
strehle May 10, 2024
75542a1
sonar
strehle May 10, 2024
5664553
Merge remote-tracking branch 'refs/remotes/origin/develop' into featu…
strehle May 10, 2024
0b3a672
sonar
strehle May 10, 2024
cd32e61
Add patch call to change a secret from an external IdP
strehle May 13, 2024
be8892e
Merge remote-tracking branch 'refs/remotes/origin/develop' into featu…
strehle May 13, 2024
a89ce12
Alias handling
strehle May 14, 2024
ede8431
Sonar refactorings
strehle May 14, 2024
c7774ea
remove dead code
strehle May 14, 2024
d1e706e
more sonar smell fixes
strehle May 14, 2024
672b8d3
no log change
strehle May 14, 2024
771bc91
revert and allow test endpoint again
strehle May 14, 2024
2e2f04d
warnings
strehle May 14, 2024
b9ec17e
Merge remote-tracking branch 'refs/remotes/origin/develop' into featu…
strehle May 16, 2024
6d6b5c3
Merge remote-tracking branch 'refs/remotes/origin/develop' into refac…
strehle May 23, 2024
441c13d
rebase
strehle May 23, 2024
a07632e
Merge remote-tracking branch 'refs/remotes/origin/develop' into refac…
strehle May 24, 2024
d7a1c35
rebase
strehle May 24, 2024
ae4a539
test setup
strehle May 24, 2024
3d087dc
Merge remote-tracking branch 'refs/remotes/origin/develop' into refac…
strehle May 24, 2024
f6e6375
Merge remote-tracking branch 'refs/remotes/origin/refactorIdp2' into …
strehle May 24, 2024
73f0c83
rebase
strehle May 24, 2024
a09a181
Merge remote-tracking branch 'refs/remotes/origin/develop' into featu…
strehle May 29, 2024
e5678e9
Merge remote-tracking branch 'refs/remotes/origin/develop' into featu…
strehle May 31, 2024
59e35d5
review
strehle May 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.cloudfoundry.identity.uaa.scim.ScimGroupProvisioning;
import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.cloudfoundry.identity.uaa.util.ObjectUtils;
import org.cloudfoundry.identity.uaa.util.UaaStringUtils;
import org.cloudfoundry.identity.uaa.zone.beans.IdentityZoneManager;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
import org.slf4j.Logger;
Expand Down Expand Up @@ -293,10 +294,19 @@ public ResponseEntity<IdentityProviderStatus> updateIdentityProviderStatus(@Path
}

@GetMapping()
public ResponseEntity<List<IdentityProvider>> retrieveIdentityProviders(@RequestParam(value = "active_only", required = false) String activeOnly, @RequestParam(required = false, defaultValue = "false") boolean rawConfig) {
public ResponseEntity<List<IdentityProvider>> retrieveIdentityProviders(
@RequestParam(value = "active_only", required = false) String activeOnly,
@RequestParam(required = false, defaultValue = "false") boolean rawConfig,
@RequestParam(required = false, defaultValue = "") String origin)
{
boolean retrieveActiveOnly = Boolean.parseBoolean(activeOnly);
List<IdentityProvider> identityProviderList = identityProviderProvisioning.retrieveAll(retrieveActiveOnly, identityZoneManager.getCurrentIdentityZoneId());
for(IdentityProvider idp : identityProviderList) {
List<IdentityProvider> identityProviderList;
if (UaaStringUtils.isNotEmpty(origin)) {
identityProviderList = List.of(identityProviderProvisioning.retrieveByOrigin(origin, identityZoneManager.getCurrentIdentityZoneId()));
} else {
identityProviderList = identityProviderProvisioning.retrieveAll(retrieveActiveOnly, identityZoneManager.getCurrentIdentityZoneId());
}
for(IdentityProvider<?> idp : identityProviderList) {
idp.setSerializeConfigRaw(rawConfig);
setAuthMethod(idp);
redactSensitiveData(idp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ void patch_bind_password_non_ldap() {
void retrieve_all_providers_redacts_data() {
when(mockIdentityProviderProvisioning.retrieveAll(anyBoolean(), anyString()))
.thenReturn(Arrays.asList(getLdapDefinition(), getExternalOAuthProvider()));
ResponseEntity<List<IdentityProvider>> ldapList = identityProviderEndpoints.retrieveIdentityProviders("false", true);
ResponseEntity<List<IdentityProvider>> ldapList = identityProviderEndpoints.retrieveIdentityProviders("false", true, "");
assertNotNull(ldapList);
assertNotNull(ldapList.getBody());
assertEquals(2, ldapList.getBody().size());
Expand All @@ -313,6 +313,22 @@ void retrieve_all_providers_redacts_data() {
assertNull(oauth.getConfig().getRelyingPartySecret());
}

@Test
void retrieve_by_origin_providers_redacts_data() {
when(mockIdentityProviderProvisioning.retrieveByOrigin(anyString(), anyString()))
.thenReturn(getExternalOAuthProvider());
ResponseEntity<List<IdentityProvider>> puppyList = identityProviderEndpoints.retrieveIdentityProviders("false", true, "puppy");
assertNotNull(puppyList);
assertNotNull(puppyList.getBody());
assertEquals(1, puppyList.getBody().size());
IdentityProvider<OIDCIdentityProviderDefinition> oidc = puppyList.getBody().get(0);
assertNotNull(oidc);
assertNotNull(oidc.getConfig());
assertTrue(oidc.getConfig() instanceof AbstractExternalOAuthIdentityProviderDefinition);
assertNull(oidc.getConfig().getRelyingPartySecret());
assertEquals(ClientAuthentication.CLIENT_SECRET_BASIC, oidc.getConfig().getAuthMethod());
}

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

## Retrieve with Filtering

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

_Request Headers_

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

_Request Parameters_

<%= render('IdentityProviderEndpointDocs/getFilteredIdentityProviders/request-parameters.md') %>

_Response Fields_

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

_Error Codes_

| Error Code | Description |
|------------|-----------------------------------------------------------------------|
| 403 | Forbidden - Insufficient scope |


## Retrieve

<%= render('IdentityProviderEndpointDocs/getIdentityProvider/curl-request.md') %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,47 @@ void getAllIdentityProviders() throws Exception {
responseFields));
}

@Test
void getFilteredIdentityProviders() throws Exception {
Snippet responseFields = responseFields(
fieldWithPath("[].type").description("Type of the identity provider."),
fieldWithPath("[].originKey").description("Unique identifier for the identity provider."),
fieldWithPath("[].name").description(NAME_DESC),
fieldWithPath("[].config").description(CONFIG_DESCRIPTION),
fieldWithPath("[]." + FIELD_ALIAS_ID).description(ALIAS_ID_DESC).attributes(key("constraints").value("Optional")).optional().type(STRING),
fieldWithPath("[]." + FIELD_ALIAS_ZID).description(ALIAS_ZID_DESC).attributes(key("constraints").value("Optional")).optional().type(STRING),

fieldWithPath("[].version").description(VERSION_DESC),
fieldWithPath("[].active").description(ACTIVE_DESC),

fieldWithPath("[].id").description(ID_DESC),
fieldWithPath("[].identityZoneId").description(IDENTITY_ZONE_ID_DESC),
fieldWithPath("[].created").description(CREATED_DESC),
fieldWithPath("[].last_modified").description(LAST_MODIFIED_DESC)
);

mockMvc.perform(get("/identity-providers")
.param("rawConfig", "false")
.param("active_only", "false")
.param("origin", "my-oauth2-provider")
.header("Authorization", "Bearer " + adminToken)
.contentType(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("{ClassName}/{methodName}",
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("Authorization").description("Bearer token containing `zones.<zone id>.admin` or `zones.<zone id>.idps.read` or `uaa.admin` or `idps.read` (only in the same zone that you are a user of)"),
headerWithName("X-Identity-Zone-Id").description("May include this header to administer another zone if using `zones.<zoneId>.admin` or `zones.<zone id>.idps.read` or `uaa.admin` scope against the default UAA zone.").optional(),
IDENTITY_ZONE_SUBDOMAIN_HEADER
),
requestParameters(
parameterWithName("rawConfig").optional("false").type(BOOLEAN).description("Flag indicating whether the response should use raw, unescaped JSON for the `config` field of the IDP, rather than the default behavior of encoding the JSON as a string."),
parameterWithName("active_only").optional("false").type(BOOLEAN).description("Flag indicating whether only active IdPs should be returned or all."),
parameterWithName("origin").optional(null).type(STRING).description("<small><mark>UAA 77.10.0</mark></small> Return only IdPs with specific origin.")
strehle marked this conversation as resolved.
Show resolved Hide resolved
),
responseFields));
}

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