org.apache.syncope.core.logic.AbstractAnyLogic.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.syncope.core.logic.AbstractAnyLogic.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.syncope.core.logic;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.patch.AnyPatch;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.spring.ImplementationManager;
import org.springframework.beans.factory.annotation.Autowired;

public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch>
        extends AbstractResourceAssociator<TO> {

    @Autowired
    protected UserDAO userDAO;

    @Autowired
    protected GroupDAO groupDAO;

    @Autowired
    protected AnyObjectDAO anyObjectDAO;

    @Autowired
    private RealmDAO realmDAO;

    @Autowired
    private AnyTypeDAO anyTypeDAO;

    @Autowired
    private TemplateUtils templateUtils;

    private List<LogicActions> getActions(final Realm realm) {
        List<LogicActions> actions = new ArrayList<>();

        realm.getActions().forEach(impl -> {
            try {
                actions.add(ImplementationManager.build(impl));
            } catch (Exception e) {
                LOG.warn("While building {}", impl, e);
            }
        });

        return actions;
    }

    protected Pair<TO, List<LogicActions>> beforeCreate(final TO input) {
        Realm realm = realmDAO.findByFullPath(input.getRealm());
        if (realm == null) {
            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
            sce.getElements().add(input.getRealm());
            throw sce;
        }

        AnyType anyType = input instanceof UserTO ? anyTypeDAO.findUser()
                : input instanceof GroupTO ? anyTypeDAO.findGroup() : anyTypeDAO.find(input.getType());
        if (anyType == null) {
            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
            sce.getElements().add(input.getType());
            throw sce;
        }

        TO any = input;

        templateUtils.apply(any, realm.getTemplate(anyType));

        List<LogicActions> actions = getActions(realm);
        for (LogicActions action : actions) {
            any = action.beforeCreate(any);
        }

        LOG.debug("Input: {}\nOutput: {}\n", input, any);

        return ImmutablePair.of(any, actions);
    }

    protected Pair<P, List<LogicActions>> beforeUpdate(final P input, final String realmPath) {
        Realm realm = realmDAO.findByFullPath(realmPath);
        if (realm == null) {
            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
            sce.getElements().add(realmPath);
            throw sce;
        }

        P mod = input;

        List<LogicActions> actions = getActions(realm);
        for (LogicActions action : actions) {
            mod = action.beforeUpdate(mod);
        }

        LOG.debug("Input: {}\nOutput: {}\n", input, mod);

        return ImmutablePair.of(mod, actions);
    }

    protected Pair<TO, List<LogicActions>> beforeDelete(final TO input) {
        Realm realm = realmDAO.findByFullPath(input.getRealm());
        if (realm == null) {
            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
            sce.getElements().add(input.getRealm());
            throw sce;
        }

        TO any = input;

        List<LogicActions> actions = getActions(realm);
        for (LogicActions action : actions) {
            any = action.beforeDelete(any);
        }

        LOG.debug("Input: {}\nOutput: {}\n", input, any);

        return ImmutablePair.of(any, actions);
    }

    protected ProvisioningResult<TO> afterCreate(final TO input, final List<PropagationStatus> statuses,
            final List<LogicActions> actions) {

        TO any = input;

        for (LogicActions action : actions) {
            any = action.afterCreate(any);
        }

        ProvisioningResult<TO> result = new ProvisioningResult<>();
        result.setEntity(any);
        result.getPropagationStatuses().addAll(statuses);

        return result;
    }

    protected ProvisioningResult<TO> afterUpdate(final TO input, final List<PropagationStatus> statuses,
            final List<LogicActions> actions, final boolean authDynRealms, final Set<String> dynRealmsBefore) {

        Set<String> dynRealmsAfter = new HashSet<>(input.getDynRealms());
        if (authDynRealms && !dynRealmsBefore.equals(dynRealmsAfter)) {
            throw new DelegatedAdministrationException(
                    this instanceof UserLogic ? AnyTypeKind.USER
                            : this instanceof GroupLogic ? AnyTypeKind.GROUP : AnyTypeKind.ANY_OBJECT,
                    input.getKey());
        }

        TO any = input;

        for (LogicActions action : actions) {
            any = action.afterUpdate(any);
        }

        ProvisioningResult<TO> result = new ProvisioningResult<>();
        result.setEntity(any);
        result.getPropagationStatuses().addAll(statuses);

        return result;
    }

    protected ProvisioningResult<TO> afterDelete(final TO input, final List<PropagationStatus> statuses,
            final List<LogicActions> actions) {

        TO any = input;

        for (LogicActions action : actions) {
            any = action.afterDelete(any);
        }

        ProvisioningResult<TO> result = new ProvisioningResult<>();
        result.setEntity(any);
        result.getPropagationStatuses().addAll(statuses);

        return result;
    }

    protected boolean securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
        boolean authorized = effectiveRealms.stream().anyMatch(ownedRealm -> realm.startsWith(ownedRealm));
        if (!authorized) {
            AnyDAO<?> anyDAO = this instanceof UserLogic ? userDAO
                    : this instanceof GroupLogic ? groupDAO : anyObjectDAO;
            authorized = anyDAO.findDynRealms(key).stream()
                    .anyMatch(dynRealm -> effectiveRealms.contains(dynRealm));
        }
        if (!authorized) {
            throw new DelegatedAdministrationException(realm, (this instanceof UserLogic ? AnyTypeKind.USER
                    : this instanceof GroupLogic ? AnyTypeKind.GROUP : AnyTypeKind.ANY_OBJECT).name(), key);
        }

        return effectiveRealms.stream().anyMatch(new RealmUtils.DynRealmsPredicate());
    }

    public abstract TO read(String key);

    public abstract Pair<Integer, List<TO>> search(SearchCond searchCond, int page, int size,
            List<OrderByClause> orderBy, String realm, boolean details);

    public abstract ProvisioningResult<TO> update(P anyPatch, boolean nullPriorityAsync);

    public abstract ProvisioningResult<TO> delete(String key, boolean nullPriorityAsync);
}