001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.membershippolicy;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.interval.IntervalActionProcessor;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.ListUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.UnicodeProperties;
025    import com.liferay.portal.model.Group;
026    import com.liferay.portal.model.GroupConstants;
027    import com.liferay.portal.model.User;
028    import com.liferay.portal.service.GroupLocalServiceUtil;
029    import com.liferay.portal.service.UserLocalServiceUtil;
030    import com.liferay.portlet.asset.model.AssetCategory;
031    import com.liferay.portlet.asset.model.AssetTag;
032    
033    import java.io.Serializable;
034    
035    import java.util.ArrayList;
036    import java.util.LinkedHashMap;
037    import java.util.List;
038    import java.util.Map;
039    
040    /**
041     * @author Sergio Gonz??lez
042     */
043    public class DefaultSiteMembershipPolicy extends BaseSiteMembershipPolicy {
044    
045            @Override
046            public void checkMembership(
047                            long[] userIds, long[] addGroupIds, long[] removeGroupIds)
048                    throws PortalException {
049    
050                    if (addGroupIds != null) {
051                            checkAddUsersLimitedGroup(userIds, addGroupIds);
052                    }
053            }
054    
055            @Override
056            public boolean isMembershipAllowed(long userId, long groupId) {
057                    try {
058                            Group group = GroupLocalServiceUtil.getGroup(groupId);
059    
060                            if (group.isLimitedToParentSiteMembers()) {
061                                    if (!GroupLocalServiceUtil.hasUserGroup(
062                                                    userId, group.getParentGroupId(), false)) {
063    
064                                            return false;
065                                    }
066                            }
067                    }
068                    catch (Exception e) {
069                            _log.error(e, e);
070                    }
071    
072                    return true;
073            }
074    
075            @Override
076            public void propagateMembership(
077                            long[] userIds, long[] addGroupIds, long[] removeGroupIds)
078                    throws PortalException {
079    
080                    if (removeGroupIds != null) {
081                            for (long removeGroupId : removeGroupIds) {
082                                    removeUsersFromLimitedChildrenGroups(userIds, removeGroupId);
083                            }
084                    }
085            }
086    
087            @Override
088            public void verifyPolicy(Group group) throws PortalException {
089                    if (group.isLimitedToParentSiteMembers()) {
090                            verifyLimitedParentMembership(group);
091                    }
092            }
093    
094            @Override
095            public void verifyPolicy(
096                            Group group, Group oldGroup, List<AssetCategory> oldAssetCategories,
097                            List<AssetTag> oldAssetTags,
098                            Map<String, Serializable> oldExpandoAttributes,
099                            UnicodeProperties oldTypeSettingsProperties)
100                    throws PortalException {
101    
102                    if (group.isLimitedToParentSiteMembers()) {
103                            if ((group.getParentGroupId() == oldGroup.getParentGroupId()) &&
104                                    oldGroup.isLimitedToParentSiteMembers()) {
105    
106                                    verifyPolicy(group);
107                            }
108                            else {
109                                    List<Group> childrenGroups = getLimitedChildrenGroups(group);
110    
111                                    for (Group childrenGroup : childrenGroups) {
112                                            verifyPolicy(childrenGroup);
113                                    }
114                            }
115                    }
116            }
117    
118            protected void checkAddUsersLimitedGroup(long[] userIds, long[] groupIds)
119                    throws PortalException {
120    
121                    MembershipPolicyException membershipPolicyException = null;
122    
123                    for (long groupId : groupIds) {
124                            Group group = GroupLocalServiceUtil.getGroup(groupId);
125    
126                            if (!group.isLimitedToParentSiteMembers()) {
127                                    continue;
128                            }
129    
130                            for (long userId : userIds) {
131                                    if (!GroupLocalServiceUtil.hasUserGroup(
132                                                    userId, group.getParentGroupId(), false)) {
133    
134                                            if (membershipPolicyException == null) {
135                                                    membershipPolicyException =
136                                                            new MembershipPolicyException(
137                                                                    MembershipPolicyException.
138                                                                            SITE_MEMBERSHIP_NOT_ALLOWED);
139                                            }
140    
141                                            User user = UserLocalServiceUtil.getUser(userId);
142    
143                                            membershipPolicyException.addUser(user);
144                                    }
145                            }
146    
147                            if (membershipPolicyException != null) {
148                                    membershipPolicyException.addGroup(group);
149                            }
150                    }
151    
152                    if (membershipPolicyException != null) {
153                            throw membershipPolicyException;
154                    }
155            }
156    
157            protected List<Group> getLimitedChildrenGroups(Group group)
158                    throws PortalException {
159    
160                    List<Group> parentGroups = new ArrayList<>();
161    
162                    parentGroups.add(group);
163    
164                    LinkedHashMap<String, Object> groupParams = new LinkedHashMap<>();
165    
166                    groupParams.put("groupsTree", parentGroups);
167                    groupParams.put(
168                            "membershipRestriction",
169                            GroupConstants.MEMBERSHIP_RESTRICTION_TO_PARENT_SITE_MEMBERS);
170                    groupParams.put("site", Boolean.TRUE);
171    
172                    List<Group> childrenGroups = GroupLocalServiceUtil.search(
173                            group.getCompanyId(), null, StringPool.BLANK, groupParams,
174                            QueryUtil.ALL_POS, QueryUtil.ALL_POS);
175    
176                    List<Group> filteredChildrenGroups = ListUtil.copy(childrenGroups);
177    
178                    for (Group childrenGroup : childrenGroups) {
179                            for (Group ancestorGroup : childrenGroup.getAncestors()) {
180                                    if ((ancestorGroup.getGroupId() != group.getGroupId()) &&
181                                            !ancestorGroup.isLimitedToParentSiteMembers()) {
182    
183                                            filteredChildrenGroups.remove(childrenGroup);
184    
185                                            break;
186                                    }
187                            }
188                    }
189    
190                    return filteredChildrenGroups;
191            }
192    
193            protected void removeUsersFromLimitedChildrenGroups(
194                            long[] userIds, long groupId)
195                    throws PortalException {
196    
197                    Group group = GroupLocalServiceUtil.getGroup(groupId);
198    
199                    List<Group> childrenGroups = getLimitedChildrenGroups(group);
200    
201                    for (Group childrenGroup : childrenGroups) {
202                            if (!childrenGroup.isLimitedToParentSiteMembers()) {
203                                    continue;
204                            }
205    
206                            for (long userId : userIds) {
207                                    UserLocalServiceUtil.unsetGroupUsers(
208                                            childrenGroup.getGroupId(), new long[] {userId}, null);
209                            }
210                    }
211            }
212    
213            protected void verifyLimitedParentMembership(final Group group)
214                    throws PortalException {
215    
216                    int total = UserLocalServiceUtil.getGroupUsersCount(group.getGroupId());
217    
218                    final IntervalActionProcessor<Void> intervalActionProcessor =
219                            new IntervalActionProcessor<>(total);
220    
221                    intervalActionProcessor.setPerformIntervalActionMethod(
222                            new IntervalActionProcessor.PerformIntervalActionMethod<Void>() {
223    
224                                    @Override
225                                    public Void performIntervalAction(int start, int end)
226                                            throws PortalException {
227    
228                                            List<User> users = UserLocalServiceUtil.getGroupUsers(
229                                                    group.getGroupId(), start, end);
230    
231                                            for (User user : users) {
232                                                    if (!UserLocalServiceUtil.hasGroupUser(
233                                                                    group.getParentGroupId(), user.getUserId())) {
234    
235                                                            UserLocalServiceUtil.unsetGroupUsers(
236                                                                    group.getGroupId(),
237                                                                    new long[] {user.getUserId()}, null);
238                                                    }
239                                                    else {
240                                                            intervalActionProcessor.incrementStart();
241                                                    }
242                                            }
243    
244                                            return null;
245                                    }
246    
247                            });
248    
249                    intervalActionProcessor.performIntervalActions();
250            }
251    
252            private static final Log _log = LogFactoryUtil.getLog(
253                    DefaultSiteMembershipPolicy.class);
254    
255    }