use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.
the class DynRealmITCase method delegatedAdmin.
@Test
public void delegatedAdmin() {
DynRealmTO dynRealm = null;
RoleTO role = null;
try {
// 1. create dynamic realm for all users and groups having resource-ldap assigned
dynRealm = new DynRealmTO();
dynRealm.setKey("LDAPLovers" + getUUIDString());
dynRealm.getDynMembershipConds().put(AnyTypeKind.USER.name(), "$resources==resource-ldap");
dynRealm.getDynMembershipConds().put(AnyTypeKind.GROUP.name(), "$resources==resource-ldap");
Response response = dynRealmService.create(dynRealm);
dynRealm = getObject(response.getLocation(), DynRealmService.class, DynRealmTO.class);
assertNotNull(dynRealm);
// 2. create role for such dynamic realm
role = new RoleTO();
role.setKey("Administer LDAP" + getUUIDString());
role.getEntitlements().add(StandardEntitlement.USER_SEARCH);
role.getEntitlements().add(StandardEntitlement.USER_READ);
role.getEntitlements().add(StandardEntitlement.USER_UPDATE);
role.getEntitlements().add(StandardEntitlement.GROUP_READ);
role.getEntitlements().add(StandardEntitlement.GROUP_UPDATE);
role.getDynRealms().add(dynRealm.getKey());
role = createRole(role);
assertNotNull(role);
// 3. create new user and assign the new role
UserTO dynRealmAdmin = UserITCase.getUniqueSampleTO("dynRealmAdmin@apache.org");
dynRealmAdmin.setPassword("password123");
dynRealmAdmin.getRoles().add(role.getKey());
dynRealmAdmin = createUser(dynRealmAdmin).getEntity();
assertNotNull(dynRealmAdmin);
// 4. create new user and group, assign resource-ldap
UserTO user = UserITCase.getUniqueSampleTO("dynRealmUser@apache.org");
user.setRealm("/even/two");
user.getResources().clear();
user.getResources().add(RESOURCE_NAME_LDAP);
user = createUser(user).getEntity();
assertNotNull(user);
final String userKey = user.getKey();
GroupTO group = GroupITCase.getSampleTO("dynRealmGroup");
group.setRealm("/odd");
group.getResources().clear();
group.getResources().add(RESOURCE_NAME_LDAP);
group = createGroup(group).getEntity();
assertNotNull(group);
final String groupKey = group.getKey();
if (ElasticsearchDetector.isElasticSearchEnabled(syncopeService)) {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
// ignore
}
}
// 5. verify that the new user and group are found when searching by dynamic realm
PagedResult<UserTO> matchingUsers = userService.search(new AnyQuery.Builder().realm("/").fiql(SyncopeClient.getUserSearchConditionBuilder().inDynRealms(dynRealm.getKey()).query()).build());
assertTrue(matchingUsers.getResult().stream().anyMatch(object -> object.getKey().equals(userKey)));
PagedResult<GroupTO> matchingGroups = groupService.search(new AnyQuery.Builder().realm("/").fiql(SyncopeClient.getGroupSearchConditionBuilder().inDynRealms(dynRealm.getKey()).query()).build());
assertTrue(matchingGroups.getResult().stream().anyMatch(object -> object.getKey().equals(groupKey)));
// 6. prepare to act as delegated admin
SyncopeClient delegatedClient = clientFactory.create(dynRealmAdmin.getUsername(), "password123");
UserService delegatedUserService = delegatedClient.getService(UserService.class);
GroupService delegatedGroupService = delegatedClient.getService(GroupService.class);
// 7. verify delegated administration
// USER_READ
assertNotNull(delegatedUserService.read(userKey));
// GROUP_READ
assertNotNull(delegatedGroupService.read(groupKey));
// USER_SEARCH
matchingUsers = delegatedUserService.search(new AnyQuery.Builder().realm("/").build());
assertTrue(matchingUsers.getResult().stream().anyMatch(object -> object.getKey().equals(userKey)));
// USER_UPDATE
UserPatch userPatch = new UserPatch();
userPatch.setKey(userKey);
userPatch.getResources().add(new StringPatchItem.Builder().value(RESOURCE_NAME_LDAP).operation(PatchOperation.DELETE).build());
// this will fail because unassigning resource-ldap would result in removing the user from the dynamic realm
try {
delegatedUserService.update(userPatch);
fail("This should not happen");
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
}
// this will succeed instead
userPatch.getResources().clear();
userPatch.getResources().add(new StringPatchItem.Builder().value(RESOURCE_NAME_NOPROPAGATION).build());
user = delegatedUserService.update(userPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
}).getEntity();
assertNotNull(user);
assertTrue(user.getResources().contains(RESOURCE_NAME_NOPROPAGATION));
// GROUP_UPDATE
GroupPatch groupPatch = new GroupPatch();
groupPatch.setKey(groupKey);
groupPatch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO("icon", "modified")).build());
group = delegatedGroupService.update(groupPatch).readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
}).getEntity();
assertNotNull(group);
assertEquals("modified", group.getPlainAttr("icon").get().getValues().get(0));
} finally {
if (role != null) {
roleService.delete(role.getKey());
}
if (dynRealm != null) {
dynRealmService.delete(dynRealm.getKey());
}
}
}
use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.
the class GroupServiceImpl method create.
@Override
public Response create(final SCIMGroup group) {
// first create group, no members assigned
ProvisioningResult<GroupTO> result = groupLogic().create(binder().toGroupTO(group), false);
// then assign members
for (Member member : group.getMembers()) {
UserPatch patch = new UserPatch();
patch.setKey(member.getValue());
patch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).group(result.getEntity().getKey()).build());
try {
userLogic().update(patch, false);
} catch (Exception e) {
LOG.error("While setting membership of {} to {}", result.getEntity().getKey(), member.getValue(), e);
}
}
return createResponse(result.getEntity().getKey(), binder().toSCIMGroup(result.getEntity(), uriInfo.getAbsolutePathBuilder().path(result.getEntity().getKey()).build().toASCIIString(), Collections.<String>emptyList(), Collections.<String>emptyList()));
}
use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.
the class GroupServiceImpl method replace.
@Override
public Response replace(final String id, final SCIMGroup group) {
if (!id.equals(group.getId())) {
throw new BadRequestException(ErrorType.invalidPath, "Expected " + id + ", found " + group.getId());
}
ResponseBuilder builder = checkETag(Resource.Group, id);
if (builder != null) {
return builder.build();
}
// save current group members
Set<String> beforeMembers = new HashSet<>();
MembershipCond membCond = new MembershipCond();
membCond.setGroup(id);
SearchCond searchCond = SearchCond.getLeafCond(membCond);
int count = userLogic().search(searchCond, 1, 1, Collections.<OrderByClause>emptyList(), SyncopeConstants.ROOT_REALM, false).getLeft();
for (int page = 1; page <= (count / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
beforeMembers.addAll(userLogic().search(searchCond, page, AnyDAO.DEFAULT_PAGE_SIZE, Collections.<OrderByClause>emptyList(), SyncopeConstants.ROOT_REALM, false).getRight().stream().map(EntityTO::getKey).collect(Collectors.toSet()));
}
// update group, don't change members
ProvisioningResult<GroupTO> result = groupLogic().update(AnyOperations.diff(binder().toGroupTO(group), groupLogic().read(id), false), false);
// assign new members
Set<String> afterMembers = new HashSet<>();
group.getMembers().forEach(member -> {
afterMembers.add(member.getValue());
if (!beforeMembers.contains(member.getValue())) {
UserPatch patch = new UserPatch();
patch.setKey(member.getValue());
patch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).group(result.getEntity().getKey()).build());
try {
userLogic().update(patch, false);
} catch (Exception e) {
LOG.error("While setting membership of {} to {}", result.getEntity().getKey(), member.getValue(), e);
}
}
});
// remove unconfirmed members
beforeMembers.stream().filter(member -> !afterMembers.contains(member)).forEach(user -> {
UserPatch patch = new UserPatch();
patch.setKey(user);
patch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.DELETE).group(result.getEntity().getKey()).build());
try {
userLogic().update(patch, false);
} catch (Exception e) {
LOG.error("While removing membership of {} from {}", result.getEntity().getKey(), user, e);
}
});
return updateResponse(result.getEntity().getKey(), binder().toSCIMGroup(result.getEntity(), uriInfo.getAbsolutePathBuilder().path(result.getEntity().getKey()).build().toASCIIString(), Collections.<String>emptyList(), Collections.<String>emptyList()));
}
use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.
the class SetUMembershipsJob method execute.
@Override
public void execute(final JobExecutionContext context) throws JobExecutionException {
try {
AuthContextUtils.execWithAuthContext(context.getMergedJobDataMap().getString(JobManager.DOMAIN_KEY), () -> {
@SuppressWarnings("unchecked") Map<String, Set<String>> memberships = (Map<String, Set<String>>) context.getMergedJobDataMap().get(MEMBERSHIPS_KEY);
LOG.debug("About to set memberships (User -> Groups) {}", memberships);
memberships.entrySet().stream().map(membership -> {
UserPatch userPatch = new UserPatch();
userPatch.setKey(membership.getKey());
membership.getValue().forEach(groupKey -> {
userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).group(groupKey).build());
});
return userPatch;
}).filter(userPatch -> (!userPatch.isEmpty())).map((userPatch) -> {
LOG.debug("About to update User {}", userPatch.getKey());
return userPatch;
}).forEachOrdered((userPatch) -> {
userProvisioningManager.update(userPatch, true);
});
return null;
});
} catch (RuntimeException e) {
LOG.error("While setting memberships", e);
throw new JobExecutionException("While executing memberships", e);
}
}
use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.
the class AbstractAnyService method bulk.
@Override
public Response bulk(final BulkAction bulkAction) {
AbstractAnyLogic<TO, P> logic = getAnyLogic();
BulkActionResult result = new BulkActionResult();
switch(bulkAction.getType()) {
case MUSTCHANGEPASSWORD:
if (logic instanceof UserLogic) {
bulkAction.getTargets().forEach(key -> {
try {
final UserPatch userPatch = new UserPatch();
userPatch.setKey(key);
userPatch.setMustChangePassword(new BooleanReplacePatchItem.Builder().value(true).build());
result.getResults().put(((UserLogic) logic).update(userPatch, false).getEntity().getKey(), BulkActionResult.Status.SUCCESS);
} catch (Exception e) {
LOG.error("Error performing delete for user {}", key, e);
result.getResults().put(key, BulkActionResult.Status.FAILURE);
}
});
} else {
throw new BadRequestException();
}
break;
case DELETE:
bulkAction.getTargets().forEach(key -> {
try {
result.getResults().put(logic.delete(key, isNullPriorityAsync()).getEntity().getKey(), BulkActionResult.Status.SUCCESS);
} catch (Exception e) {
LOG.error("Error performing delete for user {}", key, e);
result.getResults().put(key, BulkActionResult.Status.FAILURE);
}
});
break;
case SUSPEND:
if (logic instanceof UserLogic) {
bulkAction.getTargets().forEach(key -> {
StatusPatch statusPatch = new StatusPatch.Builder().key(key).type(StatusPatchType.SUSPEND).onSyncope(true).build();
try {
result.getResults().put(((UserLogic) logic).status(statusPatch, isNullPriorityAsync()).getEntity().getKey(), BulkActionResult.Status.SUCCESS);
} catch (Exception e) {
LOG.error("Error performing suspend for user {}", key, e);
result.getResults().put(key, BulkActionResult.Status.FAILURE);
}
});
} else {
throw new BadRequestException();
}
break;
case REACTIVATE:
if (logic instanceof UserLogic) {
bulkAction.getTargets().forEach(key -> {
StatusPatch statusPatch = new StatusPatch.Builder().key(key).type(StatusPatchType.REACTIVATE).onSyncope(true).build();
try {
result.getResults().put(((UserLogic) logic).status(statusPatch, isNullPriorityAsync()).getEntity().getKey(), BulkActionResult.Status.SUCCESS);
} catch (Exception e) {
LOG.error("Error performing reactivate for user {}", key, e);
result.getResults().put(key, BulkActionResult.Status.FAILURE);
}
});
} else {
throw new BadRequestException();
}
break;
default:
}
return modificationResponse(result);
}
Aggregations