001/* 002 * (C) Copyright 2006-2015 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 * Nuxeo - initial API and implementation 018 * 019 */ 020 021package org.nuxeo.usermapper.extension; 022 023import java.io.Serializable; 024import java.util.Collections; 025import java.util.HashMap; 026import java.util.Map; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.nuxeo.ecm.core.api.CoreInstance; 031import org.nuxeo.ecm.core.api.CoreSession; 032import org.nuxeo.ecm.core.api.DataModel; 033import org.nuxeo.ecm.core.api.DocumentModel; 034import org.nuxeo.ecm.core.api.DocumentModelList; 035import org.nuxeo.ecm.core.api.NuxeoPrincipal; 036import org.nuxeo.ecm.core.api.repository.RepositoryManager; 037import org.nuxeo.ecm.platform.usermanager.UserManager; 038import org.nuxeo.ecm.user.center.profile.UserProfileService; 039import org.nuxeo.runtime.api.Framework; 040import org.nuxeo.runtime.transaction.TransactionHelper; 041 042/** 043 * Provide default implementation for interaction with the {@link UserManager}. 044 * 045 * @author tiry 046 * @since 7.4 047 */ 048public abstract class AbstractUserMapper implements UserMapper { 049 050 protected static final Log log = LogFactory.getLog(AbstractUserMapper.class); 051 052 public AbstractUserMapper() { 053 } 054 055 @Override 056 public NuxeoPrincipal getOrCreateAndUpdateNuxeoPrincipal(Object userObject) { 057 return getOrCreateAndUpdateNuxeoPrincipal(userObject, true, true, null); 058 } 059 060 @Override 061 public NuxeoPrincipal getOrCreateAndUpdateNuxeoPrincipal(Object userObject, boolean createIfNeeded, boolean update, 062 Map<String, Serializable> params) { 063 064 DocumentModel userModel = null; 065 066 Map<String, Serializable> searchAttributes = new HashMap<>(); 067 Map<String, Serializable> userAttributes = new HashMap<>(); 068 final Map<String, Serializable> profileAttributes = new HashMap<>(); 069 070 if (params != null) { 071 searchAttributes.putAll(params); 072 } 073 074 resolveAttributes(userObject, searchAttributes, userAttributes, profileAttributes); 075 076 UserManager userManager = getUserManager(); 077 078 String userId = (String) searchAttributes.get(userManager.getUserIdField()); 079 080 if (userId != null) { 081 userModel = userManager.getUserModel(userId); 082 } 083 if (userModel == null) { 084 if (searchAttributes.size() > 0) { 085 DocumentModelList userDocs = userManager.searchUsers(searchAttributes, Collections.<String> emptySet()); 086 if (userDocs.size() > 1) { 087 log.warn("Can not map user with filter " + searchAttributes.toString() + " : too many results"); 088 } 089 if (userDocs.size() == 1) { 090 userModel = userDocs.get(0); 091 } 092 } 093 } 094 if (userModel != null) { 095 if (update) { 096 updatePrincipal(userAttributes, userModel); 097 } 098 } else { 099 if (!createIfNeeded) { 100 return null; 101 } 102 for (String k : searchAttributes.keySet()) { 103 if (!userAttributes.containsKey(k)) { 104 userAttributes.put(k, searchAttributes.get(k)); 105 } 106 } 107 userModel = createPrincipal(userAttributes); 108 } 109 110 if (userModel != null && profileAttributes.size() > 0 && update) { 111 UserProfileService UPS = Framework.getService(UserProfileService.class); 112 if (UPS != null) { 113 114 final String login = (String) userModel.getPropertyValue(userManager.getUserIdField()); 115 116 String repoName = Framework.getService(RepositoryManager.class).getDefaultRepositoryName(); 117 TransactionHelper.runInTransaction(() -> CoreInstance.doPrivileged(repoName, session -> { 118 DocumentModel profile = UPS.getUserProfileDocument(login, session); 119 updateProfile(session, profileAttributes, profile); 120 })); 121 } 122 } 123 124 if (userModel != null) { 125 userId = (String) userModel.getPropertyValue(userManager.getUserIdField()); 126 return userManager.getPrincipal(userId); 127 } 128 return null; 129 } 130 131 protected void updatePrincipal(Map<String, Serializable> attributes, DocumentModel userModel) { 132 UserManager userManager = getUserManager(); 133 DataModel dm = userModel.getDataModel(userManager.getUserSchemaName()); 134 for (String key : attributes.keySet()) { 135 dm.setValue(key, attributes.get(key)); 136 } 137 userManager.updateUser(userModel); 138 } 139 140 protected void updateProfile(CoreSession session, Map<String, Serializable> attributes, DocumentModel userProfile) { 141 for (String key : attributes.keySet()) { 142 userProfile.setPropertyValue(key, attributes.get(key)); 143 } 144 session.saveDocument(userProfile); 145 } 146 147 @SuppressWarnings({ "unchecked", "rawtypes" }) 148 protected DocumentModel createPrincipal(Map<String, Serializable> attributes) { 149 UserManager userManager = getUserManager(); 150 DocumentModel userModel = userManager.getBareUserModel(); 151 userModel.getDataModel(userManager.getUserSchemaName()).setMap((Map) attributes); 152 return userManager.createUser(userModel); 153 } 154 155 protected abstract void resolveAttributes(Object userObject, Map<String, Serializable> searchAttributes, 156 Map<String, Serializable> userAttributes, Map<String, Serializable> profileAttributes); 157 158 public UserManager getUserManager() { 159 return Framework.getService(UserManager.class); 160 } 161}