/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.security.membershippolicy; import com.liferay.asset.kernel.model.AssetCategory; import com.liferay.asset.kernel.model.AssetTag; import com.liferay.portal.kernel.dao.orm.QueryUtil; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.interval.IntervalActionProcessor; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.model.GroupConstants; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.security.membershippolicy.BaseSiteMembershipPolicy; import com.liferay.portal.kernel.security.membershippolicy.MembershipPolicyException; import com.liferay.portal.kernel.service.GroupLocalServiceUtil; import com.liferay.portal.kernel.service.UserLocalServiceUtil; import com.liferay.portal.kernel.util.ListUtil; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.UnicodeProperties; import java.io.Serializable; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * @author Sergio González */ public class DefaultSiteMembershipPolicy extends BaseSiteMembershipPolicy { @Override public void checkMembership( long[] userIds, long[] addGroupIds, long[] removeGroupIds) throws PortalException { if (addGroupIds != null) { checkAddUsersLimitedGroup(userIds, addGroupIds); } } @Override public boolean isMembershipAllowed(long userId, long groupId) { try { Group group = GroupLocalServiceUtil.getGroup(groupId); if (group.isLimitedToParentSiteMembers()) { if (!GroupLocalServiceUtil.hasUserGroup( userId, group.getParentGroupId(), false)) { return false; } } } catch (Exception e) { _log.error(e, e); } return true; } @Override public void propagateMembership( long[] userIds, long[] addGroupIds, long[] removeGroupIds) throws PortalException { if (removeGroupIds != null) { for (long removeGroupId : removeGroupIds) { removeUsersFromLimitedChildrenGroups(userIds, removeGroupId); } } } @Override public void verifyPolicy(Group group) throws PortalException { if (group.isLimitedToParentSiteMembers()) { verifyLimitedParentMembership(group); } } @Override public void verifyPolicy( Group group, Group oldGroup, List<AssetCategory> oldAssetCategories, List<AssetTag> oldAssetTags, Map<String, Serializable> oldExpandoAttributes, UnicodeProperties oldTypeSettingsProperties) throws PortalException { if (group.isLimitedToParentSiteMembers()) { if ((group.getParentGroupId() == oldGroup.getParentGroupId()) && oldGroup.isLimitedToParentSiteMembers()) { verifyPolicy(group); } else { List<Group> childrenGroups = getLimitedChildrenGroups(group); for (Group childrenGroup : childrenGroups) { verifyPolicy(childrenGroup); } } } } protected void checkAddUsersLimitedGroup(long[] userIds, long[] groupIds) throws PortalException { MembershipPolicyException membershipPolicyException = null; for (long groupId : groupIds) { Group group = GroupLocalServiceUtil.getGroup(groupId); if (!group.isLimitedToParentSiteMembers()) { continue; } for (long userId : userIds) { if (!GroupLocalServiceUtil.hasUserGroup( userId, group.getParentGroupId(), false)) { if (membershipPolicyException == null) { membershipPolicyException = new MembershipPolicyException( MembershipPolicyException. SITE_MEMBERSHIP_NOT_ALLOWED); } User user = UserLocalServiceUtil.getUser(userId); membershipPolicyException.addUser(user); } } if (membershipPolicyException != null) { membershipPolicyException.addGroup(group); } } if (membershipPolicyException != null) { throw membershipPolicyException; } } protected List<Group> getLimitedChildrenGroups(Group group) throws PortalException { List<Group> parentGroups = new ArrayList<>(); parentGroups.add(group); LinkedHashMap<String, Object> groupParams = new LinkedHashMap<>(); groupParams.put("groupsTree", parentGroups); groupParams.put( "membershipRestriction", GroupConstants.MEMBERSHIP_RESTRICTION_TO_PARENT_SITE_MEMBERS); groupParams.put("site", Boolean.TRUE); List<Group> childrenGroups = GroupLocalServiceUtil.search( group.getCompanyId(), null, StringPool.BLANK, groupParams, QueryUtil.ALL_POS, QueryUtil.ALL_POS); List<Group> filteredChildrenGroups = ListUtil.copy(childrenGroups); for (Group childrenGroup : childrenGroups) { for (Group ancestorGroup : childrenGroup.getAncestors()) { if ((ancestorGroup.getGroupId() != group.getGroupId()) && !ancestorGroup.isLimitedToParentSiteMembers()) { filteredChildrenGroups.remove(childrenGroup); break; } } } return filteredChildrenGroups; } protected void removeUsersFromLimitedChildrenGroups( long[] userIds, long groupId) throws PortalException { Group group = GroupLocalServiceUtil.getGroup(groupId); List<Group> childrenGroups = getLimitedChildrenGroups(group); for (Group childrenGroup : childrenGroups) { if (!childrenGroup.isLimitedToParentSiteMembers()) { continue; } for (long userId : userIds) { UserLocalServiceUtil.unsetGroupUsers( childrenGroup.getGroupId(), new long[] {userId}, null); } } } protected void verifyLimitedParentMembership(final Group group) throws PortalException { int total = UserLocalServiceUtil.getGroupUsersCount(group.getGroupId()); final IntervalActionProcessor<Void> intervalActionProcessor = new IntervalActionProcessor<>(total); intervalActionProcessor.setPerformIntervalActionMethod( new IntervalActionProcessor.PerformIntervalActionMethod<Void>() { @Override public Void performIntervalAction(int start, int end) throws PortalException { List<User> users = UserLocalServiceUtil.getGroupUsers( group.getGroupId(), start, end); for (User user : users) { if (!UserLocalServiceUtil.hasGroupUser( group.getParentGroupId(), user.getUserId())) { UserLocalServiceUtil.unsetGroupUsers( group.getGroupId(), new long[] {user.getUserId()}, null); } else { intervalActionProcessor.incrementStart(); } } return null; } }); intervalActionProcessor.performIntervalActions(); } private static final Log _log = LogFactoryUtil.getLog( DefaultSiteMembershipPolicy.class); }