001/* 002 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thierry Delprat 018 * 019 */ 020 021package org.nuxeo.ecm.platform.computedgroups; 022 023import java.io.Serializable; 024import java.util.ArrayList; 025import java.util.List; 026import java.util.Map; 027import java.util.Set; 028 029import org.nuxeo.common.collections.ScopedMap; 030import org.nuxeo.ecm.core.api.DocumentModel; 031import org.nuxeo.ecm.core.api.DocumentModelList; 032import org.nuxeo.ecm.core.api.NuxeoGroup; 033import org.nuxeo.ecm.core.api.NuxeoPrincipal; 034import org.nuxeo.ecm.directory.BaseSession; 035import org.nuxeo.ecm.platform.usermanager.NuxeoPrincipalImpl; 036import org.nuxeo.ecm.platform.usermanager.UserManager; 037import org.nuxeo.ecm.platform.usermanager.UserManagerImpl; 038import org.nuxeo.runtime.api.Framework; 039 040/** 041 * {@link UserManager} implementation that is aware of {@link ComputedGroup}. 042 * 043 * @author Thierry Delprat 044 */ 045public class UserManagerWithComputedGroups extends UserManagerImpl { 046 047 private static final long serialVersionUID = 1L; 048 049 protected static ComputedGroupsService cgs; 050 051 protected static Boolean useComputedGroup; 052 053 public static final String VIRTUAL_GROUP_MARKER = "__virtualGroup"; 054 055 protected ComputedGroupsService getService() { 056 if (cgs == null) { 057 cgs = Framework.getLocalService(ComputedGroupsService.class); 058 } 059 return cgs; 060 } 061 062 protected boolean activateComputedGroup() { 063 // NXP-8133: recompute during tests, need to find a cleaner fix 064 if (useComputedGroup == null || Framework.isTestModeSet()) { 065 useComputedGroup = getService().activateComputedGroups(); 066 } 067 return useComputedGroup; 068 } 069 070 @Override 071 protected NuxeoPrincipal makePrincipal(DocumentModel userEntry, boolean anonymous, List<String> groups) 072 { 073 074 NuxeoPrincipal principal = super.makePrincipal(userEntry, anonymous, groups); 075 if (activateComputedGroup() && principal instanceof NuxeoPrincipalImpl) { 076 NuxeoPrincipalImpl nuxPrincipal = (NuxeoPrincipalImpl) principal; 077 078 List<String> vGroups = getService().computeGroupsForUser(nuxPrincipal); 079 080 if (vGroups == null) { 081 vGroups = new ArrayList<String>(); 082 } 083 084 List<String> origVGroups = nuxPrincipal.getVirtualGroups(); 085 if (origVGroups == null) { 086 origVGroups = new ArrayList<String>(); 087 } 088 089 // MERGE! 090 origVGroups.addAll(vGroups); 091 092 nuxPrincipal.setVirtualGroups(origVGroups); 093 094 // This a hack to work around the problem of running tests 095 if (!Framework.isTestModeSet()) { 096 nuxPrincipal.updateAllGroups(); 097 } else { 098 List<String> allGroups = nuxPrincipal.getGroups(); 099 for (String vGroup : vGroups) { 100 if (!allGroups.contains(vGroup)) { 101 allGroups.add(vGroup); 102 } 103 } 104 nuxPrincipal.setGroups(allGroups); 105 } 106 } 107 return principal; 108 } 109 110 @Override 111 public NuxeoGroup getGroup(String groupName) { 112 NuxeoGroup grp = super.getGroup(groupName); 113 if (activateComputedGroup() && (grp == null || getService().allowGroupOverride())) { 114 NuxeoGroup computed = getService().getComputedGroup(groupName); 115 if (computed != null) { 116 grp = computed; 117 } 118 } 119 return grp; 120 } 121 122 @Override 123 public List<String> getGroupIds() { 124 List<String> ids = super.getGroupIds(); 125 if (activateComputedGroup()) { 126 List<String> vGroups = getService().computeGroupIds(); 127 for (String vGroup : vGroups) { 128 if (!ids.contains(vGroup)) { 129 ids.add(vGroup); 130 } 131 } 132 } 133 return ids; 134 } 135 136 @Override 137 public DocumentModel getGroupModel(String groupName) { 138 DocumentModel grpDoc = super.getGroupModel(groupName); 139 if (activateComputedGroup() && grpDoc == null) { 140 return getComputedGroupAsDocumentModel(groupName); 141 } 142 return grpDoc; 143 } 144 145 @Override 146 public DocumentModelList searchGroups(Map<String, Serializable> filter, Set<String> fulltext) 147 { 148 return searchGroups(filter, fulltext, null); 149 } 150 151 @Override 152 public DocumentModelList searchGroups(Map<String, Serializable> filter, Set<String> fulltext, DocumentModel context) 153 { 154 155 boolean searchInVirtualGroups = activateComputedGroup(); 156 if (Boolean.FALSE.equals(filter.get(VIRTUAL_GROUP_MARKER))) { 157 searchInVirtualGroups = false; 158 } 159 160 removeVirtualFilters(filter); 161 DocumentModelList groups = super.searchGroups(filter, fulltext, context); 162 163 if (searchInVirtualGroups) { 164 for (String vGroupName : getService().searchComputedGroups(filter, fulltext)) { 165 DocumentModel vGroup = getComputedGroupAsDocumentModel(vGroupName); 166 if (vGroup != null) { 167 if (!groups.contains(vGroup)) { 168 groups.add(vGroup); 169 } 170 } 171 } 172 } 173 return groups; 174 } 175 176 protected DocumentModel getComputedGroupAsDocumentModel(String grpName) { 177 NuxeoGroup grp = getService().getComputedGroup(grpName); 178 if (grp == null) { 179 return null; 180 } 181 182 String schemaName = getGroupSchemaName(); 183 String id = getGroupIdField(); 184 DocumentModel groupDoc = BaseSession.createEntryModel(null, schemaName, grpName, null); 185 186 groupDoc.setProperty(schemaName, getGroupMembersField(), grp.getMemberUsers()); 187 groupDoc.setProperty(schemaName, id, grp.getName()); 188 groupDoc.setProperty(schemaName, getGroupIdField(), grp.getName()); 189 190 final ScopedMap contextData = groupDoc.getContextData(); 191 contextData.putScopedValue("virtual", Boolean.TRUE); 192 193 return groupDoc; 194 } 195 196}