001    /**
002     * Copyright (c) 2000-2013 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.exception.SystemException;
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            public static final int DELETE_INTERVAL = 100;
046    
047            @Override
048            public void checkMembership(
049                            long[] userIds, long[] addGroupIds, long[] removeGroupIds)
050                    throws PortalException, SystemException {
051    
052                    if (addGroupIds != null) {
053                            checkAddUsersLimitedGroup(userIds, addGroupIds);
054                    }
055            }
056    
057            @Override
058            public boolean isMembershipAllowed(long userId, long groupId) {
059                    try {
060                            Group group = GroupLocalServiceUtil.getGroup(groupId);
061    
062                            if (group.isLimitedToParentSiteMembers()) {
063                                    if (!GroupLocalServiceUtil.hasUserGroup(
064                                                    userId, group.getParentGroupId(), false)) {
065    
066                                            return false;
067                                    }
068                            }
069                    }
070                    catch (Exception e) {
071                            _log.error(e, e);
072                    }
073    
074                    return true;
075            }
076    
077            @Override
078            public void propagateMembership(
079                            long[] userIds, long[] addGroupIds, long[] removeGroupIds)
080                    throws PortalException, SystemException {
081    
082                    if (removeGroupIds != null) {
083                            for (long removeGroupId : removeGroupIds) {
084                                    removeUsersFromLimitedChildrenGroups(userIds, removeGroupId);
085                            }
086                    }
087            }
088    
089            @Override
090            public void verifyPolicy(Group group)
091                    throws PortalException, SystemException {
092    
093                    if (group.isLimitedToParentSiteMembers()) {
094                            verifyLimitedParentMembership(group);
095                    }
096            }
097    
098            @Override
099            public void verifyPolicy(
100                            Group group, Group oldGroup, List<AssetCategory> oldAssetCategories,
101                            List<AssetTag> oldAssetTags,
102                            Map<String, Serializable> oldExpandoAttributes,
103                            UnicodeProperties oldTypeSettingsProperties)
104                    throws PortalException, SystemException {
105    
106                    if (group.isLimitedToParentSiteMembers()) {
107                            if ((group.getParentGroupId() == oldGroup.getParentGroupId()) &&
108                                    oldGroup.isLimitedToParentSiteMembers()) {
109    
110                                    verifyPolicy(group);
111                            }
112                            else {
113                                    List<Group> childrenGroups = getLimitedChildrenGroups(group);
114    
115                                    for (Group childrenGroup : childrenGroups) {
116                                            verifyPolicy(childrenGroup);
117                                    }
118                            }
119                    }
120            }
121    
122            protected void checkAddUsersLimitedGroup(long[] userIds, long[] groupIds)
123                    throws PortalException, SystemException {
124    
125                    MembershipPolicyException membershipPolicyException = null;
126    
127                    for (long groupId : groupIds) {
128                            Group group = GroupLocalServiceUtil.getGroup(groupId);
129    
130                            if (!group.isLimitedToParentSiteMembers()) {
131                                    continue;
132                            }
133    
134                            for (long userId : userIds) {
135                                    if (!GroupLocalServiceUtil.hasUserGroup(
136                                                    userId, group.getParentGroupId(), false)) {
137    
138                                            if (membershipPolicyException == null) {
139                                                    membershipPolicyException =
140                                                            new MembershipPolicyException(
141                                                                    MembershipPolicyException.
142                                                                            SITE_MEMBERSHIP_NOT_ALLOWED);
143                                            }
144    
145                                            User user = UserLocalServiceUtil.getUser(userId);
146    
147                                            membershipPolicyException.addUser(user);
148                                    }
149                            }
150    
151                            if (membershipPolicyException != null) {
152                                    membershipPolicyException.addGroup(group);
153                            }
154                    }
155    
156                    if (membershipPolicyException != null) {
157                            throw membershipPolicyException;
158                    }
159            }
160    
161            protected List<Group> getLimitedChildrenGroups(Group group)
162                    throws PortalException, SystemException {
163    
164                    List<Group> parentGroups = new ArrayList<Group>();
165    
166                    parentGroups.add(group);
167    
168                    LinkedHashMap<String, Object> groupParams =
169                            new LinkedHashMap<String, Object>();
170    
171                    groupParams.put("groupsTree", parentGroups);
172                    groupParams.put(
173                            "membershipRestriction",
174                            GroupConstants.MEMBERSHIP_RESTRICTION_TO_PARENT_SITE_MEMBERS);
175                    groupParams.put("site", Boolean.TRUE);
176    
177                    List<Group> childrenGroups = GroupLocalServiceUtil.search(
178                            group.getCompanyId(), null, StringPool.BLANK, groupParams,
179                            QueryUtil.ALL_POS, QueryUtil.ALL_POS);
180    
181                    List<Group> filteredChildrenGroups = ListUtil.copy(childrenGroups);
182    
183                    for (Group childrenGroup : childrenGroups) {
184                            for (Group ancestorGroup : childrenGroup.getAncestors()) {
185                                    if ((ancestorGroup.getGroupId() != group.getGroupId()) &&
186                                            !ancestorGroup.isLimitedToParentSiteMembers()) {
187    
188                                            filteredChildrenGroups.remove(childrenGroup);
189    
190                                            break;
191                                    }
192                            }
193                    }
194    
195                    return filteredChildrenGroups;
196            }
197    
198            protected void removeUsersFromLimitedChildrenGroups(
199                            long[] userIds, long groupId)
200                    throws PortalException, SystemException {
201    
202                    Group group = GroupLocalServiceUtil.getGroup(groupId);
203    
204                    List<Group> childrenGroups = getLimitedChildrenGroups(group);
205    
206                    for (Group childrenGroup : childrenGroups) {
207                            if (!childrenGroup.isLimitedToParentSiteMembers()) {
208                                    continue;
209                            }
210    
211                            for (long userId : userIds) {
212                                    UserLocalServiceUtil.unsetGroupUsers(
213                                            childrenGroup.getGroupId(), new long[] {userId}, null);
214                            }
215                    }
216            }
217    
218            protected void verifyLimitedParentMembership(final Group group)
219                    throws PortalException, SystemException {
220    
221                    int count = UserLocalServiceUtil.getGroupUsersCount(group.getGroupId());
222    
223                    int pages = count / DELETE_INTERVAL;
224    
225                    int start = 0;
226    
227                    for (int i = 0; i <= pages; i++) {
228                            int end = start + DELETE_INTERVAL;
229    
230                            List<User> users = UserLocalServiceUtil.getGroupUsers(
231                                    group.getGroupId(), start, end);
232    
233                            for (User user : users) {
234                                    if (!UserLocalServiceUtil.hasGroupUser(
235                                                    group.getParentGroupId(), user.getUserId())) {
236    
237                                            UserLocalServiceUtil.unsetGroupUsers(
238                                                    group.getGroupId(), new long[] {user.getUserId()},
239                                                    null);
240                                    }
241                                    else {
242                                            start++;
243                                    }
244                            }
245                    }
246            }
247    
248            private static Log _log = LogFactoryUtil.getLog(
249                    DefaultSiteMembershipPolicy.class);
250    
251    }