001/* 002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * <a href="mailto:grenard@nuxeo.com">Guillaume</a> 016 */ 017package org.nuxeo.ecm.platform.ui.select2.automation; 018 019import java.io.Serializable; 020import java.util.List; 021import java.util.Locale; 022 023import net.sf.json.JSONArray; 024import net.sf.json.JSONObject; 025 026import org.apache.commons.lang.StringUtils; 027import org.apache.commons.logging.Log; 028import org.apache.commons.logging.LogFactory; 029import org.nuxeo.common.utils.i18n.I18NUtils; 030import org.nuxeo.ecm.automation.OperationContext; 031import org.nuxeo.ecm.automation.core.Constants; 032import org.nuxeo.ecm.automation.core.annotations.Context; 033import org.nuxeo.ecm.automation.core.annotations.Operation; 034import org.nuxeo.ecm.automation.core.annotations.OperationMethod; 035import org.nuxeo.ecm.automation.core.annotations.Param; 036import org.nuxeo.ecm.core.api.Blob; 037import org.nuxeo.ecm.core.api.Blobs; 038import org.nuxeo.ecm.core.api.DocumentModel; 039import org.nuxeo.ecm.core.api.DocumentModelList; 040import org.nuxeo.ecm.core.api.NuxeoGroup; 041import org.nuxeo.ecm.core.api.NuxeoPrincipal; 042import org.nuxeo.ecm.core.schema.SchemaManager; 043import org.nuxeo.ecm.core.schema.types.Field; 044import org.nuxeo.ecm.core.schema.types.QName; 045import org.nuxeo.ecm.core.schema.types.Schema; 046import org.nuxeo.ecm.directory.Directory; 047import org.nuxeo.ecm.directory.SizeLimitExceededException; 048import org.nuxeo.ecm.directory.api.DirectoryService; 049import org.nuxeo.ecm.platform.ui.select2.common.Select2Common; 050import org.nuxeo.ecm.platform.usermanager.UserAdapter; 051import org.nuxeo.ecm.platform.usermanager.UserManager; 052 053/** 054 * SuggestUser Operation. 055 * 056 * @since 5.7.3 057 */ 058@Operation(id = SuggestUserEntries.ID, category = Constants.CAT_SERVICES, label = "Get user/group suggestion", description = "Get the user/group list of the running instance. This is returning a blob containing a serialized JSON array..", addToStudio = false) 059public class SuggestUserEntries { 060 061 @SuppressWarnings("unused") 062 private static final Log log = LogFactory.getLog(SuggestUserEntries.class); 063 064 public static final String ID = "UserGroup.Suggestion"; 065 066 @Context 067 protected OperationContext ctx; 068 069 @Context 070 protected SchemaManager schemaManager; 071 072 @Param(name = "searchTerm", alias = "prefix", required = false) 073 protected String prefix; 074 075 @Param(name = "searchType", required = false) 076 protected String searchType; 077 078 @Param(name = "groupRestriction", required = false) 079 protected String groupRestriction; 080 081 @Param(name = "userSuggestionMaxSearchResults", required = false) 082 protected Integer userSuggestionMaxSearchResults; 083 084 @Param(name = "firstLabelField", required = false) 085 protected String firstLabelField; 086 087 @Param(name = "secondLabelField", required = false) 088 protected String secondLabelField; 089 090 @Param(name = "thirdLabelField", required = false) 091 protected String thirdLabelField; 092 093 @Param(name = "hideFirstLabel", required = false) 094 protected boolean hideFirstLabel = false; 095 096 @Param(name = "hideSecondLabel", required = false) 097 protected boolean hideSecondLabel = false; 098 099 @Param(name = "hideThirdLabel", required = false) 100 protected boolean hideThirdLabel; 101 102 @Param(name = "displayEmailInSuggestion", required = false) 103 protected boolean displayEmailInSuggestion; 104 105 @Param(name = "hideIcon", required = false) 106 protected boolean hideIcon; 107 108 @Context 109 protected UserManager userManager; 110 111 @Context 112 protected DirectoryService directoryService; 113 114 @Param(name = "lang", required = false) 115 protected String lang; 116 117 @OperationMethod 118 public Blob run() { 119 JSONArray result = new JSONArray(); 120 boolean isGroupRestriction = !StringUtils.isBlank(groupRestriction); 121 boolean groupOnly = false; 122 boolean userOnly = isGroupRestriction; 123 124 if (!isGroupRestriction && searchType != null && !searchType.isEmpty()) { 125 if (searchType.equals(Select2Common.USER_TYPE)) { 126 userOnly = true; 127 } else if (searchType.equals(Select2Common.GROUP_TYPE)) { 128 groupOnly = true; 129 } 130 } 131 try { 132 DocumentModelList userList = null; 133 DocumentModelList groupList = null; 134 if (!groupOnly) { 135 Schema schema = schemaManager.getSchema(userManager.getUserSchemaName()); 136 userList = userManager.searchUsers(prefix); 137 Directory userDir = directoryService.getDirectory(userManager.getUserDirectoryName()); 138 for (DocumentModel user : userList) { 139 JSONObject obj = new JSONObject(); 140 for (Field field : schema.getFields()) { 141 QName fieldName = field.getName(); 142 String key = fieldName.getLocalName(); 143 Serializable value = user.getPropertyValue(fieldName.getPrefixedName()); 144 if (key.equals(userDir.getPasswordField())) { 145 continue; 146 } 147 obj.element(key, value); 148 } 149 String userId = user.getId(); 150 obj.put(Select2Common.ID, userId); 151 obj.put(Select2Common.TYPE_KEY_NAME, Select2Common.USER_TYPE); 152 obj.put(Select2Common.PREFIXED_ID_KEY_NAME, NuxeoPrincipal.PREFIX + userId); 153 Select2Common.computeUserLabel(obj, firstLabelField, secondLabelField, thirdLabelField, 154 hideFirstLabel, hideSecondLabel, hideThirdLabel, displayEmailInSuggestion, userId); 155 Select2Common.computeUserGroupIcon(obj, hideIcon); 156 if (isGroupRestriction) { 157 // We need to load all data about the user particularly 158 // its 159 // groups. 160 user = userManager.getUserModel(userId); 161 UserAdapter userAdapter = user.getAdapter(UserAdapter.class); 162 List<String> groups = userAdapter.getGroups(); 163 if (groups != null && groups.contains(groupRestriction)) { 164 result.add(obj); 165 } 166 } else { 167 result.add(obj); 168 } 169 } 170 } 171 if (!userOnly) { 172 Schema schema = schemaManager.getSchema(userManager.getGroupSchemaName()); 173 groupList = userManager.searchGroups(prefix); 174 for (DocumentModel group : groupList) { 175 JSONObject obj = new JSONObject(); 176 for (Field field : schema.getFields()) { 177 QName fieldName = field.getName(); 178 String key = fieldName.getLocalName(); 179 Serializable value = group.getPropertyValue(fieldName.getPrefixedName()); 180 obj.element(key, value); 181 } 182 String groupId = group.getId(); 183 obj.put(Select2Common.ID, groupId); 184 // If the group hasn't an label, let's put the groupid 185 Select2Common.computeGroupLabel(obj, groupId, userManager.getGroupLabelField(), hideFirstLabel); 186 obj.put(Select2Common.TYPE_KEY_NAME, Select2Common.GROUP_TYPE); 187 obj.put(Select2Common.PREFIXED_ID_KEY_NAME, NuxeoGroup.PREFIX + groupId); 188 Select2Common.computeUserGroupIcon(obj, hideIcon); 189 result.add(obj); 190 } 191 } 192 193 // Limit size results. 194 int userSize = userList != null ? userList.size() : 0; 195 int groupSize = groupList != null ? groupList.size() : 0; 196 int totalSize = userSize + groupSize; 197 if (userSuggestionMaxSearchResults != null && userSuggestionMaxSearchResults > 0) { 198 if (userSize > userSuggestionMaxSearchResults || groupSize > userSuggestionMaxSearchResults 199 || totalSize > userSuggestionMaxSearchResults) { 200 throw new SizeLimitExceededException(); 201 } 202 } 203 204 } catch (SizeLimitExceededException e) { 205 return searchOverflowMessage(); 206 } 207 208 return Blobs.createBlob(result.toString(), "application/json"); 209 } 210 211 /** 212 * @return searchOverflowMessage 213 * @since 5.7.3 214 */ 215 private Blob searchOverflowMessage() { 216 JSONArray result = new JSONArray(); 217 JSONObject obj = new JSONObject(); 218 obj.put(Select2Common.LABEL, 219 I18NUtils.getMessageString("messages", "label.security.searchOverFlow", new Object[0], getLocale())); 220 result.add(obj); 221 return Blobs.createBlob(result.toString(), "application/json"); 222 } 223 224 protected String getLang() { 225 if (lang == null) { 226 lang = (String) ctx.get("lang"); 227 if (lang == null) { 228 lang = Select2Common.DEFAULT_LANG; 229 } 230 } 231 return lang; 232 } 233 234 protected Locale getLocale() { 235 return new Locale(getLang()); 236 } 237 238}