Search in sources :

Example 66 with UserPatch

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());
        }
    }
}
Also used : Assertions.fail(org.junit.jupiter.api.Assertions.fail) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) StringPatchItem(org.apache.syncope.common.lib.patch.StringPatchItem) StandardEntitlement(org.apache.syncope.common.lib.types.StandardEntitlement) DynRealmTO(org.apache.syncope.common.lib.to.DynRealmTO) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) ElasticsearchDetector(org.apache.syncope.fit.ElasticsearchDetector) UserService(org.apache.syncope.common.rest.api.service.UserService) GroupService(org.apache.syncope.common.rest.api.service.GroupService) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) ProvisioningResult(org.apache.syncope.common.lib.to.ProvisioningResult) DynRealmService(org.apache.syncope.common.rest.api.service.DynRealmService) AnyTypeKind(org.apache.syncope.common.lib.types.AnyTypeKind) GroupPatch(org.apache.syncope.common.lib.patch.GroupPatch) RoleTO(org.apache.syncope.common.lib.to.RoleTO) ClientExceptionType(org.apache.syncope.common.lib.types.ClientExceptionType) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) AbstractITCase(org.apache.syncope.fit.AbstractITCase) AnyQuery(org.apache.syncope.common.rest.api.beans.AnyQuery) PagedResult(org.apache.syncope.common.lib.to.PagedResult) GroupTO(org.apache.syncope.common.lib.to.GroupTO) GenericType(javax.ws.rs.core.GenericType) Test(org.junit.jupiter.api.Test) AttrPatch(org.apache.syncope.common.lib.patch.AttrPatch) Response(javax.ws.rs.core.Response) PatchOperation(org.apache.syncope.common.lib.types.PatchOperation) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) SyncopeClient(org.apache.syncope.client.lib.SyncopeClient) UserTO(org.apache.syncope.common.lib.to.UserTO) DynRealmService(org.apache.syncope.common.rest.api.service.DynRealmService) DynRealmTO(org.apache.syncope.common.lib.to.DynRealmTO) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) GroupPatch(org.apache.syncope.common.lib.patch.GroupPatch) UserService(org.apache.syncope.common.rest.api.service.UserService) ProvisioningResult(org.apache.syncope.common.lib.to.ProvisioningResult) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) RoleTO(org.apache.syncope.common.lib.to.RoleTO) GroupService(org.apache.syncope.common.rest.api.service.GroupService) SyncopeClient(org.apache.syncope.client.lib.SyncopeClient) AttrPatch(org.apache.syncope.common.lib.patch.AttrPatch) GroupTO(org.apache.syncope.common.lib.to.GroupTO) Response(javax.ws.rs.core.Response) UserTO(org.apache.syncope.common.lib.to.UserTO) StringPatchItem(org.apache.syncope.common.lib.patch.StringPatchItem) Test(org.junit.jupiter.api.Test)

Example 67 with UserPatch

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()));
}
Also used : ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) Member(org.apache.syncope.ext.scimv2.api.data.Member) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) BadRequestException(org.apache.syncope.ext.scimv2.api.BadRequestException) GroupTO(org.apache.syncope.common.lib.to.GroupTO)

Example 68 with UserPatch

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()));
}
Also used : Arrays(java.util.Arrays) BadRequestException(org.apache.syncope.ext.scimv2.api.BadRequestException) ErrorType(org.apache.syncope.ext.scimv2.api.type.ErrorType) OrderByClause(org.apache.syncope.core.persistence.api.dao.search.OrderByClause) ArrayUtils(org.apache.commons.lang3.ArrayUtils) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) ProvisioningResult(org.apache.syncope.common.lib.to.ProvisioningResult) StringUtils(org.apache.commons.lang3.StringUtils) HashSet(java.util.HashSet) MembershipPatch(org.apache.syncope.common.lib.patch.MembershipPatch) EntityTO(org.apache.syncope.common.lib.to.EntityTO) SortOrder(org.apache.syncope.ext.scimv2.api.type.SortOrder) ListResponse(org.apache.syncope.ext.scimv2.api.data.ListResponse) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) SyncopeConstants(org.apache.syncope.common.lib.SyncopeConstants) SCIMGroup(org.apache.syncope.ext.scimv2.api.data.SCIMGroup) SearchCond(org.apache.syncope.core.persistence.api.dao.search.SearchCond) Set(java.util.Set) GroupTO(org.apache.syncope.common.lib.to.GroupTO) Collectors(java.util.stream.Collectors) Resource(org.apache.syncope.ext.scimv2.api.type.Resource) Response(javax.ws.rs.core.Response) AnyDAO(org.apache.syncope.core.persistence.api.dao.AnyDAO) PatchOperation(org.apache.syncope.common.lib.types.PatchOperation) SCIMSearchRequest(org.apache.syncope.ext.scimv2.api.data.SCIMSearchRequest) Member(org.apache.syncope.ext.scimv2.api.data.Member) GroupService(org.apache.syncope.ext.scimv2.api.service.GroupService) MembershipCond(org.apache.syncope.core.persistence.api.dao.search.MembershipCond) Collections(java.util.Collections) AnyOperations(org.apache.syncope.common.lib.AnyOperations) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) MembershipCond(org.apache.syncope.core.persistence.api.dao.search.MembershipCond) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) BadRequestException(org.apache.syncope.ext.scimv2.api.BadRequestException) GroupTO(org.apache.syncope.common.lib.to.GroupTO) EntityTO(org.apache.syncope.common.lib.to.EntityTO) OrderByClause(org.apache.syncope.core.persistence.api.dao.search.OrderByClause) BadRequestException(org.apache.syncope.ext.scimv2.api.BadRequestException) SearchCond(org.apache.syncope.core.persistence.api.dao.search.SearchCond) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) HashSet(java.util.HashSet)

Example 69 with UserPatch

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);
    }
}
Also used : JobExecutionContext(org.quartz.JobExecutionContext) Logger(org.slf4j.Logger) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) Autowired(org.springframework.beans.factory.annotation.Autowired) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) JobManager(org.apache.syncope.core.provisioning.api.job.JobManager) JobExecutionException(org.quartz.JobExecutionException) MembershipPatch(org.apache.syncope.common.lib.patch.MembershipPatch) UserProvisioningManager(org.apache.syncope.core.provisioning.api.UserProvisioningManager) PatchOperation(org.apache.syncope.common.lib.types.PatchOperation) Map(java.util.Map) AuthContextUtils(org.apache.syncope.core.spring.security.AuthContextUtils) MembershipPatch(org.apache.syncope.common.lib.patch.MembershipPatch) Set(java.util.Set) JobExecutionException(org.quartz.JobExecutionException) Map(java.util.Map) UserPatch(org.apache.syncope.common.lib.patch.UserPatch)

Example 70 with UserPatch

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);
}
Also used : UserLogic(org.apache.syncope.core.logic.UserLogic) BadRequestException(javax.ws.rs.BadRequestException) StatusPatch(org.apache.syncope.common.lib.patch.StatusPatch) BulkActionResult(org.apache.syncope.common.lib.to.BulkActionResult) AttrTO(org.apache.syncope.common.lib.to.AttrTO) AnyTO(org.apache.syncope.common.lib.to.AnyTO) BooleanReplacePatchItem(org.apache.syncope.common.lib.patch.BooleanReplacePatchItem) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) BadRequestException(javax.ws.rs.BadRequestException) NotFoundException(org.apache.syncope.core.persistence.api.dao.NotFoundException)

Aggregations

UserPatch (org.apache.syncope.common.lib.patch.UserPatch)102 UserTO (org.apache.syncope.common.lib.to.UserTO)73 Test (org.junit.jupiter.api.Test)59 PasswordPatch (org.apache.syncope.common.lib.patch.PasswordPatch)37 SyncopeClientException (org.apache.syncope.common.lib.SyncopeClientException)18 AttrTO (org.apache.syncope.common.lib.to.AttrTO)17 MembershipTO (org.apache.syncope.common.lib.to.MembershipTO)17 Response (javax.ws.rs.core.Response)16 Map (java.util.Map)12 StringReplacePatchItem (org.apache.syncope.common.lib.patch.StringReplacePatchItem)12 ConnObjectTO (org.apache.syncope.common.lib.to.ConnObjectTO)11 GroupTO (org.apache.syncope.common.lib.to.GroupTO)11 PropagationByResource (org.apache.syncope.core.provisioning.api.PropagationByResource)11 WorkflowResult (org.apache.syncope.core.provisioning.api.WorkflowResult)11 JdbcTemplate (org.springframework.jdbc.core.JdbcTemplate)11 GenericType (javax.ws.rs.core.GenericType)10 Pair (org.apache.commons.lang3.tuple.Pair)10 PatchOperation (org.apache.syncope.common.lib.types.PatchOperation)10 List (java.util.List)9 AttrPatch (org.apache.syncope.common.lib.patch.AttrPatch)9