Skip to content
Merged
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 @@ -102,6 +102,8 @@ public class SCIMConnectorConfiguration extends AbstractConfiguration implements

private GuardedString authHttpHeaderValue;

private boolean enableURLPathEncoding = false;

@ConfigurationProperty(order = 1,
displayMessageKey = "baseAddress.display",
helpMessageKey = "baseAddress.help",
Expand Down Expand Up @@ -430,6 +432,17 @@ public void setAuthHttpHeaderValue(final GuardedString authHttpHeaderValue) {
this.authHttpHeaderValue = authHttpHeaderValue;
}

@ConfigurationProperty(displayMessageKey = "enableURLPathEncoding.display",
helpMessageKey = "enableURLPathEncoding.help",
order = 31)
public boolean getEnableURLPathEncoding() {
return enableURLPathEncoding;
}

public void setEnableURLPathEncoding(final boolean enableURLPathEncoding) {
this.enableURLPathEncoding = enableURLPathEncoding;
}

@Override
public void validate() {
if (StringUtil.isBlank(baseAddress)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ public AbstractSCIMService(final SCIMConnectorConfiguration config) {
protected WebClient getWebclient(final String path, final Map<String, String> params) {
WebClient webClient;
if (checkBearerToken()) {

webClient = WebClient.create(config.getBaseAddress()).
header(HttpHeaders.AUTHORIZATION, "Bearer " + getBearerToken(false));
} else {
Expand Down Expand Up @@ -122,7 +121,7 @@ protected WebClient getWebclient(final String path, final Map<String, String> pa
if (StringUtil.isNotBlank(config.getAuthHttpHeaderName())) {
webClient.header(config.getAuthHttpHeaderName(), SecurityUtil.decrypt(config.getAuthHttpHeaderValue()));
}

webClient.type(config.getContentType()).accept(config.getAccept()).path(path);

Optional.ofNullable(params).ifPresent(p -> p.forEach((k, v) -> webClient.query(k, v)));
Expand Down Expand Up @@ -366,7 +365,7 @@ protected String checkServiceErrors(final Response response) {
if (response.getStatusInfo().getFamily() != Status.Family.SUCCESSFUL) {
SCIMUtils.handleGeneralError(
"While executing SCIM request: status is " + response.getStatus() + " and reponse "
+ responseAsString);
+ responseAsString);
}
return responseAsString;
}
Expand Down Expand Up @@ -521,7 +520,7 @@ protected void readCustomAttributes(final PagedResults<UT> resources, final Json
*/
@Override
public void deleteUser(final String userId) {
doDeleteUser(userId, getWebclient("Users", null).path(userId));
doDeleteUser(userId, getWebclient("Users", null).path(SCIMUtils.getPath(userId, config)));
}

/**
Expand Down Expand Up @@ -567,7 +566,8 @@ protected UT doCreateUser(final UT user) {

protected UT doUpdateUser(final String userId, final P userPatch, final Class<UT> userType) {
UT updated = null;
JsonNode node = doUpdatePatch(userPatch, Collections.emptySet(), getWebclient("Users", null).path(userId));
JsonNode node = doUpdatePatch(userPatch, Collections.emptySet(),
getWebclient("Users", null).path(SCIMUtils.getPath(userId, config)));
if (node == null) {
SCIMUtils.handleGeneralError("While running update patch on service");
}
Expand All @@ -592,9 +592,11 @@ protected UT doUpdateUser(final UT user, final Set<Attribute> replaceAttributes,

UT updated = null;
JsonNode node =
config.getUpdateUserMethod().equalsIgnoreCase("PATCH") && !replaceAttributes.isEmpty() ? doUpdatePatch(
replaceAttributes, getWebclient("Users", null).path(user.getId()))
: doUpdate(user, getWebclient("Users", null).path(user.getId()));
config.getUpdateUserMethod().equalsIgnoreCase("PATCH") && !replaceAttributes.isEmpty()
? doUpdatePatch(replaceAttributes, getWebclient("Users", null).path(
SCIMUtils.getPath(user.getId(), config)))
: doUpdate(user, getWebclient("Users", null).path(
SCIMUtils.getPath(user.getId(), config)));
if (node == null) {
SCIMUtils.handleGeneralError("While running update on service");
}
Expand Down Expand Up @@ -810,7 +812,8 @@ protected PagedResults<GT> doGetAllGroups(final WebClient webClient) {

@Override
public void deleteGroup(final String groupId) {
doDeleteGroup(groupId, getWebclient("Groups", null).path(groupId));
doDeleteGroup(groupId,
getWebclient("Groups", null).path(SCIMUtils.getPath(groupId, config)));
}

@Override
Expand Down Expand Up @@ -875,11 +878,11 @@ protected GT doUpdateGroup(final GT group, final Set<Attribute> replaceAttribute
}

GT updated = null;
JsonNode node =
config.getUpdateGroupMethod().equalsIgnoreCase("PATCH") && patch != null
JsonNode node = config.getUpdateGroupMethod().equalsIgnoreCase("PATCH") && patch != null
? doUpdatePatch(patch, replaceAttributes,
getWebclient("Groups", null).path(group.getId()))
: doUpdate(group, getWebclient("Groups", null).path(group.getId()));
getWebclient("Groups", null).path(SCIMUtils.getPath(group.getId(), config)))
: doUpdate(group, getWebclient("Groups", null).path(
SCIMUtils.getPath(group.getId(), config)));
if (node == null) {
SCIMUtils.handleGeneralError("While running update group on service");
}
Expand Down Expand Up @@ -914,7 +917,8 @@ protected JsonNode doUpdate(final GT group, final WebClient webClient) {
String responseEntity = checkServiceErrors(response);
// some servers like Salesforce return empty response on group update with PUT, thus a re-read is needed
result = StringUtil.isNotBlank(responseEntity) ? SCIMUtils.MAPPER.readTree(responseEntity)
: doGet(getWebclient("Groups", null).path(group.getId()));
: doGet(getWebclient("Groups", null).path(
SCIMUtils.getPath(group.getId(), config)));
checkServiceResultErrors(result, response);
} catch (IOException ex) {
LOG.error(ex, "Unable to update entity");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import net.tirasa.connid.bundles.scim.common.SCIMConnectorConfiguration;
import net.tirasa.connid.bundles.scim.common.SCIMProvider;
import net.tirasa.connid.bundles.scim.common.dto.BaseResourceReference;
import net.tirasa.connid.bundles.scim.common.dto.SCIMBaseAttribute;
Expand All @@ -43,7 +46,7 @@ public final class SCIMUtils {

public static final ObjectMapper MAPPER = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
.setDefaultPropertyInclusion(JsonInclude.Include.NON_EMPTY);

public static List<Field> getAllFieldsList(final Class<?> cls) {
List<Field> allFields = new ArrayList<>();
Expand Down Expand Up @@ -222,6 +225,10 @@ public static <T extends SCIMBaseAttribute<T>> Optional<SCIMSchema<T>> extractSC
return groupMemberBuilder.build();
}

public static String getPath(final String id, final SCIMConnectorConfiguration config) {
return config.getEnableURLPathEncoding() ? URLEncoder.encode(id, StandardCharsets.UTF_8) : id;
}

private SCIMUtils() {
// private constructor for static utility class
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public SCIMv11Client(final SCIMConnectorConfiguration config) {
*/
@Override
public SCIMv11User getUser(final String userId) {
WebClient webClient = getWebclient("Users", null).path(userId);
WebClient webClient = getWebclient("Users", null).path(SCIMUtils.getPath(userId, config));
return doGetUser(webClient, SCIMv11User.class, SCIMv11Attribute.class);
}

Expand Down Expand Up @@ -84,7 +84,9 @@ public boolean testService() {

@Override
public SCIMv11Group getGroup(final String groupId) {
return doGetGroup(getWebclient("Groups", null).path(groupId), SCIMv11Group.class);
return doGetGroup(
getWebclient("Groups", null).path(SCIMUtils.getPath(groupId, config)),
SCIMv11Group.class);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ public SCIMv2Client(final SCIMConnectorConfiguration config) {
*/
@Override
public SCIMv2User getUser(final String userId) {
return doGetUser(getWebclient("Users", null).path(userId), SCIMv2User.class, SCIMv2Attribute.class);
return doGetUser(
getWebclient("Users", null).path(SCIMUtils.getPath(userId, config)),
SCIMv2User.class, SCIMv2Attribute.class);
}

/**
Expand Down Expand Up @@ -79,13 +81,15 @@ public SCIMv2User updateUser(final String userId, final SCIMv2Patch userPatch) {

@Override
public SCIMv2Group getGroup(final String groupId) {
return doGetGroup(getWebclient("Groups", null).path(groupId), SCIMv2Group.class);
return doGetGroup(
getWebclient("Groups", null).path(SCIMUtils.getPath(groupId, config)),
SCIMv2Group.class);
}

@Override
public SCIMv2EntitlementResource getEntitlement(final String entitlementId) {
return doGetEntitlement(
getWebclient("Entitlements", null).path(entitlementId), SCIMv2EntitlementResource.class);
return doGetEntitlement(getWebclient("Entitlements", null).path(
SCIMUtils.getPath(entitlementId, config)), SCIMv2EntitlementResource.class);
}

@Override
Expand All @@ -105,7 +109,7 @@ public SCIMv2Group updateGroup(final SCIMv2Group group, final Set<Attribute> rep

@Override
public void deleteGroup(final String groupId) {
doDeleteGroup(groupId, getWebclient("Groups", null).path(groupId));
doDeleteGroup(groupId, getWebclient("Groups", null).path(SCIMUtils.getPath(groupId, config)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,7 @@ authHttpHeaderName.display=Auth http header name
authHttpHeaderName.help=Specifies the name of the additional header sent on requests containing the authentication information. If empty header won't be added.
authHttpHeaderValue.display=Auth http header value
authHttpHeaderValue.help=The auth http header value to use to authenticate against the server.
enableURLPathEncoding.display=Enable url path encoding
enableURLPathEncoding.help=Whether to enable encoding on url path while performing requests to the SCIM server, for example the user id on user read.


Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,5 @@ authHttpHeaderName.display=Nome header per autenticazione
authHttpHeaderName.help=Specifica il nome dell \u0027header aggiuntivo inviato nelle richieste, contenente informazioni di authenticazione. Se vuota l \u0027header non viene aggiunto.
authHttpHeaderValue.display=Valore http header per l \u0027autenticazione
authHttpHeaderValue.help=Il valore dell \u0027header da usare per l \u0027autenticazione sul server.

enableURLPathEncoding.display=Abilita encoding del percorso nella URL
enableURLPathEncoding.help=Specifica se abilitare oppure no l \u0027 encoding del percorso della richiesta inviate al server SCIM. Per esempio lo user id in fase di lettura utente.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ public static SCIMConnectorConfiguration buildConfiguration(
break;
}
}
// enable url encoding only for test purposes
connectorConfiguration.setEnableURLPathEncoding(true);
return connectorConfiguration;
}

Expand Down