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