On 27/09/2016 15:00, Adrian Gonzalez wrote:
Hello,

We're trying to build a POC on SCIM APIs on top of Syncope.

That's very good to hear: looks it is for SCIM 2.0, correct?
Looking forward to take a look at it!

Problem is when we're using some basic SCIM APIs to update the groups membership of a given user, we got a OptimisticLockException.

This is due to the fact that SCIM group membership can be updated only from the Group endpoint (not from the User endpoint).
From https://tools.ietf.org/html/rfc7643#page-24
groups
A list of groups to which the user belongs,...
Since this attribute has a mutability of "readOnly", group membership changes MUST be applied via the "Group" Resource (Section 4.2). This attribute has a mutability of "readOnly".

So, we have the following scenario :
 * we have a user1 member of 2 groups (group1 and group2).
 * we want to remove the user1 from both groups from a UI console.
* the UI then needs to send 2 HTTP PUT on SCIM /Groups endpoint (one for each group).
    /PUT Groups/group1
    /PUT Groups/group2
* we get a OptimisticLockException since both calls are made for a relation on the same user - because on the SCIM side for the Group endpoint, we must call
userService.update(userTO) to update a user <-> group relation.

i.e.
        MembershipTO membershipTO =
new MembershipTO.Builder().group(userTO.getKey(), "USER").group(groupTO.getKey(), groupTO.getName()).build();
        userTO.getMemberships().add(membershipTO);
        try {
            userService.update(userTO);
        } catch (SyncopeClientException e) {
throw new SCIMException(String.format("User %s was not added to the group %s", userId, groupTO.getName()), e);
        }

Is there an API to update user or group membership without testing @Version field ? (i.e like a syncope REST API on top of a jpql update ?) Perhaps we're not using the good API here (is there an API to handle membership from the group's side ? Do you see another possible solution (besides updating membership from the Group side/screen) ?

You are right about the fact that Syncope manages groups memberships by modifying users.

I am a bit confused about your snippet above, so let me rephrase it a bit.
Assuming your scenario:

 * we have a user1 member of 2 groups (group1 and group2).
 * we want to remove the user1 from both groups from a UI console.
* the UI then needs to send 2 HTTP PUT on SCIM /Groups endpoint (one for each group).
    /PUT Groups/group1
    /PUT Groups/group2

the Group endpoint should perform as following:

UserPatch userPatch = new UserPatch();
userPatch.setKey("the key of user1");
userPatch.getMemberships().add(new MembershipPatch.Builder().
        operation(PatchOperation.DELETE).
        group("the key of the group passed to the endpoint").
        build());
userLogic.update(userPatch, true);

As you can see, I am rather using the logic layer (e.g. UserLogic as done in UserServiceImpl) to interact with Syncope core, rather than the external service layer (e.g. how REST clients do).

HTH
Regards.

--
Francesco Chicchiriccò

Tirasa - Open Source Excellence
http://www.tirasa.net/

Member at The Apache Software Foundation
Syncope, Cocoon, Olingo, CXF, OpenJPA, PonyMail
http://home.apache.org/~ilgrosso/

Reply via email to