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 @@ -997,15 +997,6 @@ protected Object buildPatchValue(
}).collect(Collectors.toList());
break;

case "roles.default.value":
patchValue = values.stream().filter(Objects::nonNull).map(v -> {
SCIMGenericComplex<String> value = new SCIMGenericComplex<>();
value.setValue(v.toString());
value.setType("default");
return value;
}).collect(Collectors.toList());
break;

case "entitlements.default.value":
patchValue = values.stream().filter(Objects::nonNull).map(v -> {
SCIMGenericComplex<String> value = new SCIMGenericComplex<>();
Expand All @@ -1031,10 +1022,23 @@ protected Object buildPatchValue(
break;

default:
// this is mainly useful to manage custom attributes
patchValue = CollectionUtil.isEmpty(values) ? null
: attributeDefinition != null && attributeDefinition.getMultiValued() ? values
: values.get(0).toString();
// manage and entitlements roles
if (name.startsWith(SCIMAttributeUtils.SCIM_USER_ROLES + ".")
|| name.startsWith(SCIMAttributeUtils.SCIM_USER_ENTITLEMENTS + ".")) {
patchValue = values.stream().filter(Objects::nonNull).map(v -> {
SCIMGenericComplex<String> value = new SCIMGenericComplex<>();
value.setValue(v.toString());
value.setType(SCIMUtils.getTypeFromAttributeName(name));
return value;
}).collect(Collectors.toList());
} else {
// this is mainly useful to manage custom attributes
patchValue = CollectionUtil.isEmpty(values)
? null
: attributeDefinition != null && attributeDefinition.getMultiValued()
? values
: values.get(0).toString();
}
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,14 +815,6 @@ private void doSetAttribute(final String name, final List<Object> values) {
handleSCIMUserAddressObject(AddressCanonicalType.other, s -> s.setOperation(String.class.cast(value)));
break;

case "roles.default.value":
handleRoles(value);
break;

case "entitlements.default.value":
handleDefaultEntitlement(value);
break;

case "x509Certificates.default.value":
handlex509Certificates(value);
break;
Expand All @@ -832,15 +824,21 @@ private void doSetAttribute(final String name, final List<Object> values) {
break;

default:
// manage all other custom roles abd entitlements
if (name.startsWith(SCIMAttributeUtils.SCIM_USER_ENTITLEMENTS + ".")) {
handleEntitlement(SCIMUtils.getTypeFromAttributeName(name), value);
} else if (name.startsWith(SCIMAttributeUtils.SCIM_USER_ROLES + ".")) {
handleRole(SCIMUtils.getTypeFromAttributeName(name), value);
}
break;
}
}

protected abstract void handleRoles(Object value);
protected abstract void handleRole(String type, Object value);

protected abstract void handlex509Certificates(Object value);

protected abstract void handleDefaultEntitlement(Object value);
protected abstract void handleEntitlement(String type, Object value);

@JsonIgnore
protected <T extends Serializable> void handleSCIMComplexObject(final T type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,8 @@ 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);
"While executing SCIM request: status is " + response.getStatus() + " and response "
+ responseAsString);
}
return responseAsString;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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;
Expand Down Expand Up @@ -229,6 +231,14 @@ public static String getPath(final String id, final SCIMConnectorConfiguration c
return config.getEnableURLPathEncoding() ? URLEncoder.encode(id, StandardCharsets.UTF_8) : id;
}

public static String getTypeFromAttributeName(final String attributeName) {
if (StringUtil.isBlank(attributeName)) {
return null;
}
Matcher matcher = Pattern.compile("^[^.]+\\.([^.]+)\\.[^.]+$").matcher(attributeName);
return matcher.find() ? matcher.group(1) : null;
}

private SCIMUtils() {
// private constructor for static utility class
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public SCIMv11User() {
}

@Override
protected void handleRoles(final Object value) {
protected void handleRole(final String type, final Object value) {
handleSCIMDefaultObject(
String.class.cast(value),
this.roles,
Expand All @@ -59,7 +59,7 @@ protected void handlex509Certificates(final Object value) {
}

@Override
protected void handleDefaultEntitlement(final Object value) {
protected void handleEntitlement(final String type, final Object value) {
handleBaseResourceReference(
String.class.cast(value),
this.entitlements,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ protected SCIMv2Patch buildPatchFromGroup(final SCIMv2Group group) {
}

@Override
@SuppressWarnings("unchecked")
protected SCIMv2Patch buildUserPatch(
final Set<AttributeDelta> modifications,
final SCIMv2User currentUser,
Expand Down Expand Up @@ -191,7 +192,24 @@ protected SCIMv2Patch buildUserPatch(
&& !attrDelta.is(SCIMAttributeUtils.SCIM_USER_GROUPS)
// custom attributes are going to be managed further
&& !isCustomAttribute(attrDelta.getName(), configuration.getUseColonOnExtensionAttributes())) {
patch.addOperations(buildPatchOperations(attrDelta, null));

if (CollectionUtil.isEmpty(attrDelta.getValuesToReplace())) {
patch.addOperations(buildPatchOperations(attrDelta, null));
} else {
// build the patch operation
SCIMv2PatchOperation replacePatchOperation =
buildReplacePatchOperation(attrDelta.getName(), attrDelta.getValuesToReplace(), null);
// check if the attribute has already been added as a patch operation or not, if so aggregate
// values in a single patch operation
patch.getOperations()
.stream()
.filter(op -> op.getValue() instanceof List && replacePatchOperation.getPath()
.equalsIgnoreCase(op.getPath()))
.findFirst()
.ifPresentOrElse(op -> ((List<Object>) op.getValue()).addAll(
(List<Object>) replacePatchOperation.getValue()),
() -> patch.addOperation(replacePatchOperation));
}
}
}
// manage addresses patches
Expand Down Expand Up @@ -340,12 +358,8 @@ protected List<SCIMv2PatchOperation> buildPatchOperations(
operations.add(removePatchOperation);
}
} else {
SCIMv2PatchOperation replacePatchOperation = new SCIMv2PatchOperation();
replacePatchOperation.setPath(SCIMAttributeUtils.getBaseAttributeName(currentDelta.getName()));
replacePatchOperation.setOperation(SCIMAttributeUtils.SCIM_REPLACE);
replacePatchOperation.setValue(
buildPatchValue(currentDelta.getName(), currentDelta.getValuesToReplace(), attributeDefinition));
operations.add(replacePatchOperation);
operations.add(buildReplacePatchOperation(currentDelta.getName(), currentDelta.getValuesToReplace(),
attributeDefinition));
}

return operations;
Expand Down Expand Up @@ -571,7 +585,7 @@ private static void setAddressAttribute(
protected void manageEntitlements(final SCIMv2User user, final List<String> values) {
List<SCIMv2EntitlementResource> scimEntitlementRefs = values == null
? Collections.emptyList()
: values.stream().map(client::getEntitlement).filter(g -> g != null).collect(Collectors.toList());
: values.stream().map(client::getEntitlement).filter(Objects::nonNull).collect(Collectors.toList());
scimEntitlementRefs.forEach(e -> user.getEntitlements().add(new SCIMv2Entitlement.Builder().value(e.getId())
.ref(configuration.getBaseAddress() + "Entitlements/" + e.getId()).display(e.getDisplayName())
.primary(true).type(e.getType()).build()));
Expand Down Expand Up @@ -610,4 +624,16 @@ protected BaseResourceReference buildPatchValue(final SCIMv2User user) {
}
return builder.build();
}

protected SCIMv2PatchOperation buildReplacePatchOperation(
final String attrName,
final List<Object> valuesToReplace,
final SCIMBaseAttribute<?> attributeDefinition) {
SCIMv2PatchOperation replacePatchOperation = new SCIMv2PatchOperation();
replacePatchOperation.setPath(SCIMAttributeUtils.getBaseAttributeName(attrName));
replacePatchOperation.setOperation(SCIMAttributeUtils.SCIM_REPLACE);
replacePatchOperation.setValue(
buildPatchValue(attrName, valuesToReplace, attributeDefinition));
return replacePatchOperation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ public SCIMv2User() {
}

@Override
protected void handleRoles(final Object value) {
protected void handleRole(final String type, final Object value) {
handleSCIMComplexObject(
SCIMAttributeUtils.SCIM_SCHEMA_TYPE_DEFAULT,
type,
this.roles,
s -> s.setValue(String.class.cast(value)));
s -> s.setValue((String) value));
}

@Override
Expand All @@ -65,10 +65,10 @@ protected void handlex509Certificates(final Object value) {
}

@Override
protected void handleDefaultEntitlement(final Object value) {
protected void handleEntitlement(final String type, final Object value) {
handleSCIMv2Entitlement(this.entitlements, s -> {
s.setValue(String.class.cast(value));
s.setType(SCIMAttributeUtils.SCIM_SCHEMA_TYPE_DEFAULT);
s.setType(type);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ private static Uid createUser(final UUID uid, final String... groups) {
SCIMv2ConnectorTestsUtils.VALUE_PHONE_NUMBER));
userAttrs.add(AttributeBuilder.build(SCIMv2ConnectorTestsUtils.USER_ATTRIBUTE_PHONE_OTHER_PRIMARY, false));
userAttrs.add(AttributeBuilder.build(SCIMAttributeUtils.USER_ATTRIBUTE_ACTIVE, true));
userAttrs.add(AttributeBuilder.build(SCIMAttributeUtils.SCIM_USER_ROLES + ".default.value", "mytestrole"));
userAttrs.add(password);

if (PROPS.containsKey("auth.defaultEntitlement") && StringUtil.isNotBlank(
Expand Down Expand Up @@ -331,6 +332,7 @@ private static Set<Attribute> updateUserAttributes(final Uid created, final Stri
userAttrs.add(AttributeBuilder.build(SCIMv2ConnectorTestsUtils.USER_ATTRIBUTE_ENTITLEMENTS_DEFAULT_VALUE,
PROPS.getProperty("auth.defaultEntitlement")));
}
userAttrs.add(AttributeBuilder.build(SCIMAttributeUtils.SCIM_USER_ROLES + ".default.value", "mytestrole"));

// custom attributes
addCustomAttributes(userAttrs);
Expand Down Expand Up @@ -481,6 +483,8 @@ private static SCIMv2User readUser(final String id, final SCIMv2Client client)
SCIMv2ConnectorTestsUtils.USER_ATTRIBUTE_EMAIL_WORK_VALUE));
assertTrue(SCIMv2ConnectorTestsUtils.hasAttribute(toAttributes, SCIMAttributeUtils.SCIM_USER_SCHEMAS));
assertTrue(SCIMv2ConnectorTestsUtils.hasAttribute(toAttributes, SCIMAttributeUtils.USER_ATTRIBUTE_ACTIVE));
assertTrue(SCIMv2ConnectorTestsUtils.hasAttribute(toAttributes,
SCIMAttributeUtils.SCIM_USER_ROLES + ".default.value", "mytestrole"));
if (PROPS.containsKey("auth.defaultEntitlement") && StringUtil.isNotBlank(
PROPS.getProperty("auth.defaultEntitlement"))) {
assertTrue(SCIMv2ConnectorTestsUtils.containsAttribute(toAttributes,
Expand Down Expand Up @@ -1044,8 +1048,8 @@ public void search() {

SearchResult result = FACADE.search(ObjectClass.ACCOUNT, null, handler,
new OperationOptionsBuilder().setAttributesToGet("name", "emails.work.value", "name.familyName",
"displayName", "active", "entitlements.default.value", "entitlements",
"urn:mem:params:scim:schemas:extension:LuckyNumberExtension:luckyNumber",
"displayName", "active", "entitlements.default.value", "roles.default.value", "roles",
"entitlements", "urn:mem:params:scim:schemas:extension:LuckyNumberExtension:luckyNumber",
SCIMv2EnterpriseUser.SCHEMA_URI + ":employeeNumber",
SCIMv2EnterpriseUser.SCHEMA_URI + ":manager.value").build());
assertNotNull(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.tirasa.connid.bundles.scim.v2;

import java.util.List;
import java.util.Map;
import java.util.Set;
import net.tirasa.connid.bundles.scim.common.SCIMConnectorConfiguration;
Expand Down Expand Up @@ -156,10 +157,11 @@ public static boolean isConfigurationValid(final SCIMConnectorConfiguration conn
return true;
}

public static boolean hasAttribute(final Set<Attribute> attrs, final String name) {
public static boolean hasAttribute(final Set<Attribute> attrs, final String name, final Object... values) {
for (Attribute attr : attrs) {
if (attr.getName().equals(name)) {
return true;
return values.length == 0 || (attr.getValue() != null && !attr.getValue().isEmpty() && attr.getValue()
.containsAll(List.of(values)));
}
}
return false;
Expand Down