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/