<commit_before>/*
 * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.com).
 *
 * WSO2 Inc. 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.wso2.carbon.identity.scim2.common.listener;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.identity.core.AbstractIdentityGroupResolver;
import org.wso2.carbon.identity.core.util.IdentityCoreConstants;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.scim2.common.DAO.GroupDAO;
import org.wso2.carbon.identity.scim2.common.exceptions.IdentitySCIMException;
import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonConstants;
import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils;
import org.wso2.carbon.user.core.UserCoreConstants;
import org.wso2.carbon.user.core.UserStoreConfigConstants;
import org.wso2.carbon.user.core.UserStoreException;
import org.wso2.carbon.user.core.UserStoreManager;
import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
import org.wso2.carbon.user.core.common.Group;
import org.wso2.carbon.user.core.model.Condition;
import org.wso2.carbon.user.core.model.ExpressionCondition;
import org.wso2.carbon.user.core.model.OperationalCondition;
import org.wso2.carbon.user.core.util.UserCoreUtil;
import org.wso2.charon3.core.schema.SCIMConstants;

import java.util.List;
import java.util.Map;

import static org.wso2.carbon.user.core.UserCoreConstants.RealmConfig.PROPERTY_DOMAIN_NAME;

/**
 * Implementation of group domain resolver.
 */
public class SCIMGroupResolver extends AbstractIdentityGroupResolver {

    private static final Log log = LogFactory.getLog(SCIMGroupResolver.class);
    private static final String SQL_FILTERING_DELIMITER = "%";

    @Override
    public int getExecutionOrderId() {

        int orderId = super.getExecutionOrderId();
        if (orderId != IdentityCoreConstants.EVENT_LISTENER_ORDER_ID) {
            return orderId;
        }
        return 1;
    }

    @Override
    public boolean resolveGroupDomainByGroupId(Group group, int tenantId)
            throws UserStoreException {

        if (group == null || StringUtils.isBlank(group.getGroupID())) {
            return true;
        }
        String groupId = group.getGroupID();
        if (log.isDebugEnabled()) {
            log.debug(String.format("Retrieving group with id:%s from tenant: %s", groupId, tenantId));
        }
        GroupDAO groupDAO = new GroupDAO();
        String groupName;
        try {
            groupName = groupDAO.getGroupNameById(tenantId, groupId);
        } catch (IdentitySCIMException exception) {
            throw new UserStoreException(String.format("Error occurred while resolving the domain name for " +
                    "group with id: %s in tenant: %s", groupId, tenantId), exception);
        }
        if (StringUtils.isBlank(groupName)) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("No group found in IDN_SCIM_GROUP with group id: %s in tenant: %s", groupId,
                        tenantId));
            }
            return true;
        }
        String resolvedDomain = IdentityUtil.extractDomainFromName(groupName);
        if (log.isDebugEnabled()) {
            log.debug(String.format("Domain: %s resolved for group id: %s in tenant: %s", resolvedDomain, groupId,
                    tenantId));
        }
        group.setGroupName(groupName);
        group.setDisplayName(UserCoreUtil.removeDomainFromName(groupName));
        group.setUserStoreDomain(resolvedDomain);
        return true;
    }

    @Override
    public boolean getGroupsListOfUserByUserId(String userId, List<Group> groupList,
                                               UserStoreManager userStoreManager) throws UserStoreException {

        if (CollectionUtils.isEmpty(groupList)) {
            // To do filtering in IDN_SCIM_GROUP, we need group names. If the list is empty, we cannot do that.
            return true;
        }

        int tenantId = userStoreManager.getTenantId();
        AbstractUserStoreManager abstractUserStoreManager = ((AbstractUserStoreManager) userStoreManager);
        boolean isGroupIdEnabled = abstractUserStoreManager.isUniqueGroupIdEnabled();
        /*
         * isGroupIdEnabled equal to false indicates that the given userstore only support the legacy behaviour. In
         * that case we need to support getting group details from IDN_SCIM_GROUP table.
         */
        if (isGroupIdEnabled) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("SCIMGroupResolver will not be executed for userstore: %s in " +
                                "tenant %s since group id support is available in the userstore manager",
                        abstractUserStoreManager.getRealmConfiguration().getRealmProperty(PROPERTY_DOMAIN_NAME),
                        tenantId));
            }
            return true;
        }
        GroupDAO groupDAO = new GroupDAO();
        for (Group group : groupList) {
            // We need to only provide the group name and group id.
            try {
                group.setGroupID(groupDAO.getGroupIdByName(tenantId,
                        UserCoreUtil.addDomainToName(group.getGroupName(), group.getUserStoreDomain())));
            } catch (IdentitySCIMException e) {
                throw new UserStoreException(String.format("Error occurred while getting the group id of " +
                        "group: %s in tenant: %s", group.getGroupName(), tenantId), e);
            }
        }
        return true;
    }

    @Override
    public boolean getGroupIdByName(String groupName, Group group, UserStoreManager userStoreManager)
            throws UserStoreException {

        int tenantId = userStoreManager.getTenantId();
        AbstractUserStoreManager abstractUserStoreManager = ((AbstractUserStoreManager) userStoreManager);
        boolean isGroupIdEnabled = abstractUserStoreManager.isUniqueGroupIdEnabled();
        /*
         * isGroupIdEnabled equal to false indicates that the given userstore only support the legacy behaviour. In
         * that case we need to support getting group details from IDN_SCIM_GROUP table.
         */
        if (isGroupIdEnabled) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("SCIMGroupResolver will not be executed for userstore: %s in " +
                                "tenant %s since group id support is available in the userstore manager",
                        abstractUserStoreManager.getRealmConfiguration().getRealmProperty(PROPERTY_DOMAIN_NAME),
                        tenantId));
            }
            return true;
        }
        if (log.isDebugEnabled()) {
            log.debug(String.format("Retrieving group with name: %s from tenant: %s", groupName, tenantId));
        }
        String groupId;
        GroupDAO groupDAO = new GroupDAO();
        try {
            groupId = groupDAO.getGroupIdByName(tenantId,
                    UserCoreUtil.addDomainToName(group.getGroupName(), group.getUserStoreDomain()));
        } catch (IdentitySCIMException e) {
            throw new UserStoreException(String.format("Error occurred while getting the group id of " +
                    "group: %s in tenant: %s", groupName, tenantId), e);
        }
        if (StringUtils.isBlank(groupId)) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("No group found with the group name: %s in tenant: %s", groupName, tenantId));
            }
            return true;
        }
        String domainName = UserCoreUtil.extractDomainFromName(groupName);
        if (group == null) {
            group = new Group(groupId);
            group.setGroupName(resolveGroupName(groupName, domainName));
            group.setUserStoreDomain(domainName);
            group.setDisplayName(UserCoreUtil.removeDomainFromName(groupName));
        } else {
            group.setGroupID(groupId);
        }
        return true;
    }

    @Override
    public boolean getGroupNameById(String groupID, Group group, UserStoreManager userStoreManager)
            throws UserStoreException {

        int tenantId = userStoreManager.getTenantId();<commit_msg>Fix findbugs issues<commit_after>/*
 * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.com).
 *
 * WSO2 Inc. 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.wso2.carbon.identity.scim2.common.listener;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.identity.core.AbstractIdentityGroupResolver;
import org.wso2.carbon.identity.core.util.IdentityCoreConstants;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.scim2.common.DAO.GroupDAO;
import org.wso2.carbon.identity.scim2.common.exceptions.IdentitySCIMException;
import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonConstants;
import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils;
import org.wso2.carbon.user.core.UserCoreConstants;
import org.wso2.carbon.user.core.UserStoreConfigConstants;
import org.wso2.carbon.user.core.UserStoreException;
import org.wso2.carbon.user.core.UserStoreManager;
import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
import org.wso2.carbon.user.core.common.Group;
import org.wso2.carbon.user.core.model.Condition;
import org.wso2.carbon.user.core.model.ExpressionCondition;
import org.wso2.carbon.user.core.model.OperationalCondition;
import org.wso2.carbon.user.core.util.UserCoreUtil;
import org.wso2.charon3.core.schema.SCIMConstants;

import java.util.List;
import java.util.Map;

import static org.wso2.carbon.user.core.UserCoreConstants.RealmConfig.PROPERTY_DOMAIN_NAME;

/**
 * Implementation of group domain resolver.
 */
public class SCIMGroupResolver extends AbstractIdentityGroupResolver {

    private static final Log log = LogFactory.getLog(SCIMGroupResolver.class);
    private static final String SQL_FILTERING_DELIMITER = "%";

    @Override
    public int getExecutionOrderId() {

        int orderId = super.getExecutionOrderId();
        if (orderId != IdentityCoreConstants.EVENT_LISTENER_ORDER_ID) {
            return orderId;
        }
        return 1;
    }

    @Override
    public boolean resolveGroupDomainByGroupId(Group group, int tenantId)
            throws UserStoreException {

        if (group == null || StringUtils.isBlank(group.getGroupID())) {
            return true;
        }
        String groupId = group.getGroupID();
        if (log.isDebugEnabled()) {
            log.debug(String.format("Retrieving group with id:%s from tenant: %s", groupId, tenantId));
        }
        GroupDAO groupDAO = new GroupDAO();
        String groupName;
        try {
            groupName = groupDAO.getGroupNameById(tenantId, groupId);
        } catch (IdentitySCIMException exception) {
            throw new UserStoreException(String.format("Error occurred while resolving the domain name for " +
                    "group with id: %s in tenant: %s", groupId, tenantId), exception);
        }
        if (StringUtils.isBlank(groupName)) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("No group found in IDN_SCIM_GROUP with group id: %s in tenant: %s", groupId,
                        tenantId));
            }
            return true;
        }
        String resolvedDomain = IdentityUtil.extractDomainFromName(groupName);
        if (log.isDebugEnabled()) {
            log.debug(String.format("Domain: %s resolved for group id: %s in tenant: %s", resolvedDomain, groupId,
                    tenantId));
        }
        group.setGroupName(groupName);
        group.setDisplayName(UserCoreUtil.removeDomainFromName(groupName));
        group.setUserStoreDomain(resolvedDomain);
        return true;
    }

    @Override
    public boolean getGroupsListOfUserByUserId(String userId, List<Group> groupList,
                                               UserStoreManager userStoreManager) throws UserStoreException {

        if (CollectionUtils.isEmpty(groupList)) {
            // To do filtering in IDN_SCIM_GROUP, we need group names. If the list is empty, we cannot do that.
            return true;
        }

        int tenantId = userStoreManager.getTenantId();
        AbstractUserStoreManager abstractUserStoreManager = ((AbstractUserStoreManager) userStoreManager);
        boolean isGroupIdEnabled = abstractUserStoreManager.isUniqueGroupIdEnabled();
        /*
         * isGroupIdEnabled equal to false indicates that the given userstore only support the legacy behaviour. In
         * that case we need to support getting group details from IDN_SCIM_GROUP table.
         */
        if (isGroupIdEnabled) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("SCIMGroupResolver will not be executed for userstore: %s in " +
                                "tenant %s since group id support is available in the userstore manager",
                        abstractUserStoreManager.getRealmConfiguration().getRealmProperty(PROPERTY_DOMAIN_NAME),
                        tenantId));
            }
            return true;
        }
        GroupDAO groupDAO = new GroupDAO();
        for (Group group : groupList) {
            // We need to only provide the group name and group id.
            try {
                group.setGroupID(groupDAO.getGroupIdByName(tenantId,
                        UserCoreUtil.addDomainToName(group.getGroupName(), group.getUserStoreDomain())));
            } catch (IdentitySCIMException e) {
                throw new UserStoreException(String.format("Error occurred while getting the group id of " +
                        "group: %s in tenant: %s", group.getGroupName(), tenantId), e);
            }
        }
        return true;
    }

    @Override
    public boolean getGroupIdByName(String groupName, Group group, UserStoreManager userStoreManager)
            throws UserStoreException {

        int tenantId = userStoreManager.getTenantId();
        AbstractUserStoreManager abstractUserStoreManager = ((AbstractUserStoreManager) userStoreManager);
        boolean isGroupIdEnabled = abstractUserStoreManager.isUniqueGroupIdEnabled();
        /*
         * isGroupIdEnabled equal to false indicates that the given userstore only support the legacy behaviour. In
         * that case we need to support getting group details from IDN_SCIM_GROUP table.
         */
        if (isGroupIdEnabled) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("SCIMGroupResolver will not be executed for userstore: %s in " +
                                "tenant %s since group id support is available in the userstore manager",
                        abstractUserStoreManager.getRealmConfiguration().getRealmProperty(PROPERTY_DOMAIN_NAME),
                        tenantId));
            }
            return true;
        }

        if (group == null) {
            throw new IllegalArgumentException("Group object should be non-null for the id to be populated");
        }

        if (log.isDebugEnabled()) {
            log.debug(String.format("Retrieving group with name: %s from tenant: %s", groupName, tenantId));
        }
        String groupId;
        GroupDAO groupDAO = new GroupDAO();
        try {
            groupId = groupDAO.getGroupIdByName(tenantId,
                    UserCoreUtil.addDomainToName(group.getGroupName(), group.getUserStoreDomain()));
        } catch (IdentitySCIMException e) {
            throw new UserStoreException(String.format("Error occurred while getting the group id of " +
                    "group: %s in tenant: %s", groupName, tenantId), e);
        }
        if (StringUtils.isBlank(groupId)) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("No group found with the group name: %s in tenant: %s", groupName, tenantId));
            }
            return true;
        }
        group.setGroupID(groupId);
        return true;
    }

    @Override
    public boolean getGroupNameById(String groupID, Group group, UserStoreManager userStoreManager)
            throws UserStoreException {

        int tenantId = userStoreManager.getTenantId();
{'fraction_non_alphanumeric': 0.08730559766436471, 'fraction_numerical': 0.004379316152939195, 'mean_word_length': 2.6687950566426366, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6446372', 'n_tokens_mistral': 4792, 'n_tokens_neox': 4692, 'n_words': 1217}