public Pair toUserUpdate()

in ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java [792:992]


    public Pair<UserUR, StatusR> toUserUpdate(
            final UserTO before,
            final Collection<String> resources,
            final SCIMPatchOperation op) {
        StatusR statusR = null;

        if (op.getPath() == null && op.getOp() != PatchOp.remove
                && !CollectionUtils.isEmpty(op.getValue())
                && op.getValue().getFirst() instanceof final SCIMUser after) {

            if (after.getActive() != null && before.isSuspended() == after.isActive()) {
                statusR = new StatusR.Builder(
                        before.getKey(),
                        after.isActive() ? StatusRType.REACTIVATE : StatusRType.SUSPEND).
                        resources(resources).
                        build();
            }

            UserTO updated = toUserTO(after, false);
            updated.setKey(before.getKey());
            return Pair.of(AnyOperations.diff(updated, before, true), statusR);
        }

        UserUR userUR = new UserUR.Builder(before.getKey()).build();

        SCIMConf conf = confManager.get();
        if (conf == null) {
            return Pair.of(userUR, statusR);
        }

        switch (op.getPath().getAttribute()) {
            case "externalId" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getExternalId(), op);

            case "userName" -> {
                if (op.getOp() != PatchOp.remove && !CollectionUtils.isEmpty(op.getValue())) {
                    userUR.setUsername(
                            new StringReplacePatchItem.Builder().value(op.getValue().getFirst().toString()).build());
                }
            }

            case "password" -> {
                if (op.getOp() != PatchOp.remove && !CollectionUtils.isEmpty(op.getValue())) {
                    userUR.setPassword(new PasswordPatch.Builder().value(op.getValue().getFirst().toString()).resources(
                            resources).build());
                }
            }

            case "active" -> {
                if (!CollectionUtils.isEmpty(op.getValue())) {

                    // Workaround for Microsoft Entra being not SCIM compliant on PATCH requests
                    if (op.getValue().getFirst() instanceof String a) {
                        op.setValue(List.of(BooleanUtils.toBoolean(a)));
                    }

                    statusR = new StatusR.Builder(before.getKey(),
                            (boolean) op.getValue().getFirst()
                            ? StatusRType.REACTIVATE
                            : StatusRType.SUSPEND).resources(resources).build();
                }
            }

            case "name" -> {
                if (conf.getUserConf().getName() != null) {
                    if (op.getPath().getSub() == null || "familyName".equals(op.getPath().getSub())) {
                        setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getName().getFamilyName(), op);
                    }
                    if (op.getPath().getSub() == null || "formatted".equals(op.getPath().getSub())) {
                        setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getName().getFormatted(), op);
                    }
                    if (op.getPath().getSub() == null || "givenName".equals(op.getPath().getSub())) {
                        setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getName().getGivenName(), op);
                    }
                    if (op.getPath().getSub() == null || "honorificPrefix".equals(op.getPath().getSub())) {
                        setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getName().getHonorificPrefix(), op);
                    }
                    if (op.getPath().getSub() == null || "honorificSuffix".equals(op.getPath().getSub())) {
                        setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getName().getHonorificSuffix(), op);
                    }
                    if (op.getPath().getSub() == null || "middleName".equals(op.getPath().getSub())) {
                        setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getName().getMiddleName(), op);
                    }
                }
            }

            case "displayName" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getDisplayName(), op);

            case "nickName" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getNickName(), op);

            case "profileUrl" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getProfileUrl(), op);

            case "title" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getTitle(), op);

            case "userType" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getUserType(), op);

            case "preferredLanguage" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getPreferredLanguage(), op);

            case "locale" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getLocale(), op);

            case "timezone" ->
                setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getTimezone(), op);

            case "emails" -> {
                if (!CollectionUtils.isEmpty(op.getValue()) && op.getValue().getFirst() instanceof SCIMUser) {
                    setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getEmails(),
                            ((SCIMUser) op.getValue().getFirst()).getEmails(), op.getOp());
                } else if (op.getPath().getFilter() != null) {
                    setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getEmails(), op);
                }
            }

            case "phoneNumbers" -> {
                if (!CollectionUtils.isEmpty(op.getValue()) && op.getValue().getFirst() instanceof SCIMUser) {
                    setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getPhoneNumbers(),
                            ((SCIMUser) op.getValue().getFirst()).getPhoneNumbers(), op.getOp());
                } else if (op.getPath().getFilter() != null) {
                    setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getPhoneNumbers(), op);
                }
            }

            case "ims" -> {
                if (!CollectionUtils.isEmpty(op.getValue()) && op.getValue().getFirst() instanceof SCIMUser) {
                    setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getIms(),
                            ((SCIMUser) op.getValue().getFirst()).getIms(), op.getOp());
                } else if (op.getPath().getFilter() != null) {
                    setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getIms(), op);
                }
            }

            case "photos" -> {
                if (!CollectionUtils.isEmpty(op.getValue()) && op.getValue().getFirst() instanceof SCIMUser) {
                    setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getPhotos(),
                            ((SCIMUser) op.getValue().getFirst()).getPhotos(), op.getOp());
                } else if (op.getPath().getFilter() != null) {
                    setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getPhotos(), op);
                }
            }

            case "addresses" -> {
                if (!CollectionUtils.isEmpty(op.getValue())
                        && op.getValue().getFirst() instanceof final SCIMUser after) {
                    after.getAddresses().stream().filter(address -> address.getType() != null).forEach(
                            address -> conf.getUserConf().getAddresses().stream()
                                    .filter(object -> address.getType().equals(object.getType().name())).findFirst()
                                    .ifPresent(addressConf -> setAttribute(userUR.getPlainAttrs(), addressConf, op)));
                } else if (op.getPath().getFilter() != null) {
                    conf.getUserConf().getAddresses().stream().filter(addressConf -> BooleanUtils.toBoolean(
                            JexlUtils.evaluateExpr(filter2JexlExpression(op.getPath().getFilter()),
                                    new MapContext(Map.of("type", addressConf.getType().name()))).toString()))
                            .findFirst()
                            .ifPresent(addressConf -> setAttribute(userUR.getPlainAttrs(), addressConf, op));
                }
            }

            case "employeeNumber" ->
                setAttribute(userUR.getPlainAttrs(),
                        Optional.ofNullable(conf.getEnterpriseUserConf()).
                                map(SCIMEnterpriseUserConf::getEmployeeNumber).orElse(null), op);

            case "costCenter" ->
                setAttribute(userUR.getPlainAttrs(),
                        Optional.ofNullable(conf.getEnterpriseUserConf()).
                                map(SCIMEnterpriseUserConf::getCostCenter).orElse(null), op);

            case "organization" ->
                setAttribute(userUR.getPlainAttrs(),
                        Optional.ofNullable(conf.getEnterpriseUserConf()).
                                map(SCIMEnterpriseUserConf::getOrganization).orElse(null), op);

            case "division" ->
                setAttribute(userUR.getPlainAttrs(),
                        Optional.ofNullable(conf.getEnterpriseUserConf()).
                                map(SCIMEnterpriseUserConf::getDivision).orElse(null), op);

            case "department" ->
                setAttribute(userUR.getPlainAttrs(),
                        Optional.ofNullable(conf.getEnterpriseUserConf()).
                                map(SCIMEnterpriseUserConf::getDepartment).orElse(null), op);

            case "manager" ->
                setAttribute(userUR.getPlainAttrs(),
                        Optional.ofNullable(conf.getEnterpriseUserConf()).
                                map(SCIMEnterpriseUserConf::getManager).map(SCIMManagerConf::getKey).orElse(null), op);

            default -> {
                Optional.ofNullable(conf.getExtensionUserConf()).
                        flatMap(schema -> Optional.ofNullable(schema.asMap().get(op.getPath().getAttribute()))).
                        ifPresent(schema -> setAttribute(userUR.getPlainAttrs(), schema, op));
            }
        }

        return Pair.of(userUR, statusR);
    }