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.ecm.core.api.DocumentModel; 030import org.nuxeo.ecm.core.api.DocumentModelList; 031import org.nuxeo.ecm.core.api.NuxeoGroup; 032import org.nuxeo.ecm.core.api.NuxeoPrincipal; 033import org.nuxeo.ecm.directory.BaseSession; 034import org.nuxeo.ecm.platform.usermanager.NuxeoPrincipalImpl; 035import org.nuxeo.ecm.platform.usermanager.UserManager; 036import org.nuxeo.ecm.platform.usermanager.UserManagerImpl; 037import org.nuxeo.runtime.api.Framework; 038 039/** 040 * {@link UserManager} implementation that is aware of {@link ComputedGroup}. 041 * 042 * @author Thierry Delprat 043 */ 044public class UserManagerWithComputedGroups extends UserManagerImpl { 045 046 private static final long serialVersionUID = 1L; 047 048 protected static ComputedGroupsService cgs; 049 050 protected static Boolean useComputedGroup; 051 052 public static final String VIRTUAL_GROUP_MARKER = "__virtualGroup"; 053 054 protected ComputedGroupsService getService() { 055 if (cgs == null) { 056 cgs = Framework.getLocalService(ComputedGroupsService.class); 057 } 058 return cgs; 059 } 060 061 protected boolean activateComputedGroup() { 062 // NXP-8133: recompute during tests, need to find a cleaner fix 063 if (useComputedGroup == null || Framework.isTestModeSet()) { 064 useComputedGroup = getService().activateComputedGroups(); 065 } 066 return useComputedGroup; 067 } 068 069 @Override 070 protected NuxeoPrincipal makePrincipal(DocumentModel userEntry, boolean anonymous, List<String> groups) 071 { 072 073 NuxeoPrincipal principal = super.makePrincipal(userEntry, anonymous, groups); 074 if (activateComputedGroup() && principal instanceof NuxeoPrincipalImpl) { 075 NuxeoPrincipalImpl nuxPrincipal = (NuxeoPrincipalImpl) principal; 076 077 List<String> vGroups = getService().computeGroupsForUser(nuxPrincipal); 078 079 if (vGroups == null) { 080 vGroups = new ArrayList<String>(); 081 } 082 083 List<String> origVGroups = nuxPrincipal.getVirtualGroups(); 084 if (origVGroups == null) { 085 origVGroups = new ArrayList<String>(); 086 } 087 088 // MERGE! 089 origVGroups.addAll(vGroups); 090 091 nuxPrincipal.setVirtualGroups(origVGroups); 092 093 // This a hack to work around the problem of running tests 094 if (!Framework.isTestModeSet()) { 095 nuxPrincipal.updateAllGroups(); 096 } else { 097 List<String> allGroups = nuxPrincipal.getGroups(); 098 for (String vGroup : vGroups) { 099 if (!allGroups.contains(vGroup)) { 100 allGroups.add(vGroup); 101 } 102 } 103 nuxPrincipal.setGroups(allGroups); 104 } 105 } 106 return principal; 107 } 108 109 @Override 110 public NuxeoGroup getGroup(String groupName) { 111 NuxeoGroup grp = super.getGroup(groupName); 112 if (activateComputedGroup() && (grp == null || getService().allowGroupOverride())) { 113 NuxeoGroup computed = getService().getComputedGroup(groupName); 114 if (computed != null) { 115 grp = computed; 116 } 117 } 118 return grp; 119 } 120 121 @Override 122 public NuxeoGroup getGroup(String groupName, DocumentModel context) { 123 NuxeoGroup grp = super.getGroup(groupName, context); 124 if (activateComputedGroup() && (grp == null || getService().allowGroupOverride())) { 125 NuxeoGroup computed = getService().getComputedGroup(groupName); 126 if (computed != null) { 127 grp = computed; 128 } 129 } 130 return grp; 131 } 132 133 @Override 134 public List<String> getGroupIds() { 135 List<String> ids = super.getGroupIds(); 136 if (activateComputedGroup()) { 137 List<String> vGroups = getService().computeGroupIds(); 138 for (String vGroup : vGroups) { 139 if (!ids.contains(vGroup)) { 140 ids.add(vGroup); 141 } 142 } 143 } 144 return ids; 145 } 146 147 @Override 148 public DocumentModel getGroupModel(String groupName) { 149 DocumentModel grpDoc = super.getGroupModel(groupName); 150 if (activateComputedGroup() && grpDoc == null) { 151 return getComputedGroupAsDocumentModel(groupName); 152 } 153 return grpDoc; 154 } 155 156 @Override 157 public DocumentModelList searchGroups(Map<String, Serializable> filter, Set<String> fulltext) 158 { 159 return searchGroups(filter, fulltext, null); 160 } 161 162 @Override 163 public DocumentModelList searchGroups(Map<String, Serializable> filter, Set<String> fulltext, DocumentModel context) 164 { 165 166 boolean searchInVirtualGroups = activateComputedGroup(); 167 if (Boolean.FALSE.equals(filter.get(VIRTUAL_GROUP_MARKER))) { 168 searchInVirtualGroups = false; 169 } 170 171 removeVirtualFilters(filter); 172 DocumentModelList groups = super.searchGroups(filter, fulltext, context); 173 174 if (searchInVirtualGroups) { 175 for (String vGroupName : getService().searchComputedGroups(filter, fulltext)) { 176 DocumentModel vGroup = getComputedGroupAsDocumentModel(vGroupName); 177 if (vGroup != null) { 178 if (!groups.contains(vGroup)) { 179 groups.add(vGroup); 180 } 181 } 182 } 183 } 184 return groups; 185 } 186 187 protected DocumentModel getComputedGroupAsDocumentModel(String grpName) { 188 NuxeoGroup grp = getService().getComputedGroup(grpName); 189 if (grp == null) { 190 return null; 191 } 192 193 String schemaName = getGroupSchemaName(); 194 String id = getGroupIdField(); 195 DocumentModel groupDoc = BaseSession.createEntryModel(null, schemaName, grpName, null); 196 197 groupDoc.setProperty(schemaName, getGroupMembersField(), grp.getMemberUsers()); 198 groupDoc.setProperty(schemaName, id, grp.getName()); 199 groupDoc.setProperty(schemaName, getGroupIdField(), grp.getName()); 200 201 groupDoc.putContextData("virtual", Boolean.TRUE); 202 203 return groupDoc; 204 } 205 206}