Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -239,11 +239,13 @@ private ActionExecutionRequest buildActionExecutionRequest(ActionType actionType
request.setAdditionalHeaders(RequestFilter.getFilteredHeaders(
request.getAdditionalHeaders(),
action.getEndpoint().getAllowedHeaders(),
actionType));
actionType,
action.getActionVersion()));
request.setAdditionalParams(RequestFilter.getFilteredParams(
request.getAdditionalParams(),
action.getEndpoint().getAllowedParameters(),
actionType));
actionType,
action.getActionVersion()));
return actionExecutionRequest;
} catch (ActionExecutionRequestBuilderException e) {
throw new ActionExecutionException("Failed to build the request payload for action type: " + actionType, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ public class RequestFilter {
public static List<Header> getFilteredHeaders(List<Header> requestHeaders, List<String> allowedHeadersInAction,
ActionType actionType) {

return getFilteredHeaders(requestHeaders, allowedHeadersInAction, actionType, null);
}

public static List<Header> getFilteredHeaders(List<Header> requestHeaders, List<String> allowedHeadersInAction,
ActionType actionType, String actionVersion) {

Set<String> allowedHeadersInServer = Optional.ofNullable(ActionExecutorConfig.getInstance()
.getAllowedHeadersForActionType(actionType)).orElse(Collections.emptySet());
Set<String> excludedHeadersInServer = Optional.ofNullable(ActionExecutorConfig.getInstance()
Expand All @@ -67,8 +73,8 @@ public static List<Header> getFilteredHeaders(List<Header> requestHeaders, List<
allowedHeaders.addAll(allowedHeadersInAction);
} else if (hasServerAllowedHeaders) {
allowedHeaders.addAll(allowedHeadersInServer);
} else if (ActionType.PRE_ISSUE_ACCESS_TOKEN.equals(actionType)) {
// This is to preserve backward compatibility.
} else if (ActionType.PRE_ISSUE_ACCESS_TOKEN.equals(actionType) && !isV2OrLater(actionVersion)) {
// To preserve backward compatibility for v1 actions.
allowedHeaders.addAll(requestHeaders.stream()
.map(Header::getName)
.collect(Collectors.toSet()));
Expand All @@ -92,7 +98,7 @@ public static List<Header> getFilteredHeaders(List<Header> requestHeaders, List<

/**
* Filters request parameters based on the allowedParameters and excludedParameters configured.

*
* List of allowed parameters can be configured per action or globally at server level.
* If allowed parameters per action have been configured, then the server config will be ignored.
* List of excluded parameters can be configured only at server level. These will be filtered out from the
Expand All @@ -105,6 +111,12 @@ public static List<Header> getFilteredHeaders(List<Header> requestHeaders, List<
public static List<Param> getFilteredParams(List<Param> requestParameters, List<String> allowedParamsInAction,
ActionType actionType) {

return getFilteredParams(requestParameters, allowedParamsInAction, actionType, null);
}

public static List<Param> getFilteredParams(List<Param> requestParameters, List<String> allowedParamsInAction,
ActionType actionType, String actionVersion) {

Set<String> allowedParamsInServer = ActionExecutorConfig.getInstance()
.getAllowedParamsForActionType(actionType);
Set<String> excludedParamsInServer = ActionExecutorConfig.getInstance()
Expand All @@ -118,8 +130,8 @@ public static List<Param> getFilteredParams(List<Param> requestParameters, List<
allAllowedParamsSet.addAll(allowedParamsInAction);
} else if (hasServerAllowedParams) {
allAllowedParamsSet.addAll(allowedParamsInServer);
} else if (ActionType.PRE_ISSUE_ACCESS_TOKEN.equals(actionType)) {
// This is to preserve backward compatibility.
} else if (ActionType.PRE_ISSUE_ACCESS_TOKEN.equals(actionType) && !isV2OrLater(actionVersion)) {
// To preserve backward compatibility for v1 actions.
allAllowedParamsSet.addAll(requestParameters.stream()
.map(Param::getName)
.collect(Collectors.toSet()));
Expand All @@ -131,4 +143,17 @@ public static List<Param> getFilteredParams(List<Param> requestParameters, List<
.filter(param -> allAllowedParamsSet.contains(param.getName()))
.collect(Collectors.toList());
}

private static boolean isV2OrLater(String actionVersion) {

if (actionVersion == null) {
return false;
}
try {
int version = Integer.parseInt(actionVersion.replace("v", ""));
return version >= 2;
} catch (NumberFormatException e) {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,90 @@ public void testGetFilteredHeadersWhenNeitherAllowedOrExcludedParamsAreConfigure
ActionType.PRE_UPDATE_PASSWORD);
assertEquals(filteredParams.size(), 0);
}

@Test(description = "Ensures that for pre-issue access token v2 with no allowed headers configured, " +
"no headers are returned by default.")
public void testGetFilteredHeadersForV2PreIssueAccessTokenReturnsEmptyByDefault() {

ActionExecutorConfig config = ActionExecutorConfig.getInstance();
Mockito.when(config.getAllowedHeadersForActionType(ActionType.PRE_ISSUE_ACCESS_TOKEN))
.thenReturn(Collections.emptySet());
Mockito.when(config.getExcludedHeadersInActionRequestForActionType(ActionType.PRE_ISSUE_ACCESS_TOKEN))
.thenReturn(Collections.emptySet());

List<Header> filteredHeaders = RequestFilter.getFilteredHeaders(requestHeaders, Collections.emptyList(),
ActionType.PRE_ISSUE_ACCESS_TOKEN, "v2");

assertEquals(filteredHeaders.size(), 0);
}

@Test(description = "Ensures that for pre-issue access token v2 with no allowed params configured, " +
"no params are returned by default.")
public void testGetFilteredParamsForV2PreIssueAccessTokenReturnsEmptyByDefault() {

ActionExecutorConfig config = ActionExecutorConfig.getInstance();
Mockito.when(config.getAllowedParamsForActionType(ActionType.PRE_ISSUE_ACCESS_TOKEN))
.thenReturn(Collections.emptySet());
Mockito.when(config.getExcludedParamsInActionRequestForActionType(ActionType.PRE_ISSUE_ACCESS_TOKEN))
.thenReturn(Collections.emptySet());

List<Param> filteredParams = RequestFilter.getFilteredParams(requestParams, Collections.emptyList(),
ActionType.PRE_ISSUE_ACCESS_TOKEN, "v2");

assertEquals(filteredParams.size(), 0);
}

@Test(description = "Ensures that for pre-issue access token v2 with action-level allowed headers, " +
"only the allowed headers are returned.")
public void testGetFilteredHeadersForV2PreIssueAccessTokenWithActionAllowedHeaders() {

ActionExecutorConfig config = ActionExecutorConfig.getInstance();
Mockito.when(config.getAllowedHeadersForActionType(ActionType.PRE_ISSUE_ACCESS_TOKEN))
.thenReturn(Collections.emptySet());
Mockito.when(config.getExcludedHeadersInActionRequestForActionType(ActionType.PRE_ISSUE_ACCESS_TOKEN))
.thenReturn(Collections.emptySet());

List<String> allowedHeadersInAction = new ArrayList<>();
allowedHeadersInAction.add("X-Header-1");
allowedHeadersInAction.add("X-Header-3");

List<Header> filteredHeaders = RequestFilter.getFilteredHeaders(requestHeaders, allowedHeadersInAction,
ActionType.PRE_ISSUE_ACCESS_TOKEN, "v2");

assertEquals(filteredHeaders.size(), 2);
filteredHeaders.forEach(filteredHeader -> {
if (filteredHeader.getName().equals("x-header-1")) {
assertEquals(filteredHeader.getValue(), new String[]{"X-header-1-value"});
} else if (filteredHeader.getName().equals("x-header-3")) {
assertEquals(filteredHeader.getValue(), new String[]{"X-header-3-value"});
}
});
}

@Test(description = "Ensures that for pre-issue access token v2 with action-level allowed params, " +
"only the allowed params are returned.")
public void testGetFilteredParamsForV2PreIssueAccessTokenWithActionAllowedParams() {

ActionExecutorConfig config = ActionExecutorConfig.getInstance();
Mockito.when(config.getAllowedParamsForActionType(ActionType.PRE_ISSUE_ACCESS_TOKEN))
.thenReturn(Collections.emptySet());
Mockito.when(config.getExcludedParamsInActionRequestForActionType(ActionType.PRE_ISSUE_ACCESS_TOKEN))
.thenReturn(Collections.emptySet());

List<String> allowedParamsInAction = new ArrayList<>();
allowedParamsInAction.add("x-param-1");
allowedParamsInAction.add("x-param-3");

List<Param> filteredParams = RequestFilter.getFilteredParams(requestParams, allowedParamsInAction,
ActionType.PRE_ISSUE_ACCESS_TOKEN, "v2");

assertEquals(filteredParams.size(), 2);
filteredParams.forEach(filteredParam -> {
if (filteredParam.getName().equals("x-param-1")) {
assertEquals(filteredParam.getValue(), new String[]{"X-param-1-value"});
} else if (filteredParam.getName().equals("x-param-3")) {
assertEquals(filteredParam.getValue(), new String[]{"X-param-3-value"});
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@
{
"name": "client_credentials",
"displayName": "client credentials"
},
{
"name": "urn:ietf:params:oauth:grant-type:token-exchange",
"displayName": "token exchange"
},
{
"name": "urn:ietf:params:oauth:grant-type:device_code",
"displayName": "device code"
},
{
"name": "organization_switch",
"displayName": "organization switch"
},
{
"name": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"displayName": "jwt bearer"
},
{
"name": "urn:ietf:params:oauth:grant-type:saml2-bearer",
"displayName": "saml2 bearer"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2105,7 +2105,7 @@
"actions.http_client.retry_count": "2",
"actions.maximum_actions_per_action_type": "1",
"actions.types.pre_issue_access_token.enable": true,
"actions.types.pre_issue_access_token.version.latest": "v1",
"actions.types.pre_issue_access_token.version.latest": "v2",
"actions.types.pre_issue_id_token.enable": true,
"actions.types.pre_issue_id_token.version.latest": "v1",
"actions.types.authentication.enable": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@
{
"name": "client_credentials",
"displayName": "client credentials"
},
{
"name": "urn:ietf:params:oauth:grant-type:token-exchange",
"displayName": "token exchange"
},
{
"name": "urn:ietf:params:oauth:grant-type:device_code",
"displayName": "device code"
},
{
"name": "organization_switch",
"displayName": "organization switch"
},
{
"name": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"displayName": "jwt bearer"
},
{
"name": "urn:ietf:params:oauth:grant-type:saml2-bearer",
"displayName": "saml2 bearer"
}
]
}
Expand Down
Loading