package com.constellio.app.api.cmis.binding.global; import static com.constellio.model.entities.CorePermissions.USE_EXTERNAL_APIS_FOR_COLLECTION; import java.math.BigInteger; import java.util.Map; import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException; import org.apache.chemistry.opencmis.commons.impl.server.AbstractServiceFactory; import org.apache.chemistry.opencmis.commons.server.CallContext; import org.apache.chemistry.opencmis.commons.server.CmisService; import org.apache.chemistry.opencmis.commons.server.MutableCallContext; import org.apache.chemistry.opencmis.server.support.wrapper.CallContextAwareCmisService; import org.apache.chemistry.opencmis.server.support.wrapper.CmisServiceWrapperManager; import org.apache.chemistry.opencmis.server.support.wrapper.ConformanceCmisServiceWrapper; import com.constellio.app.api.cmis.CmisExceptions.CmisExceptions_InvalidLogin; import com.constellio.app.services.factories.AppLayerFactory; import com.constellio.app.services.factories.ConstellioFactories; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.security.global.UserCredential; import com.constellio.model.services.factories.ModelLayerFactory; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.security.AuthorizationsServices; import com.constellio.model.services.security.authentification.AuthenticationService; import com.constellio.model.services.users.UserServices; import com.constellio.model.services.users.UserServicesRuntimeException; public class ConstellioCmisRequestFactory extends AbstractServiceFactory { /** Default maxItems value for getTypeChildren()}. */ private static final BigInteger DEFAULT_MAX_ITEMS_TYPES = BigInteger.valueOf(50); /** Default depth value for getTypeDescendants(). */ private static final BigInteger DEFAULT_DEPTH_TYPES = BigInteger.valueOf(-1); /** * Default maxItems value for getChildren() and other methods returning lists of objects. */ private static final BigInteger DEFAULT_MAX_ITEMS_OBJECTS = BigInteger.valueOf(200); /** Default depth value for getDescendants(). */ private static final BigInteger DEFAULT_DEPTH_OBJECTS = BigInteger.valueOf(10); private CmisServiceWrapperManager wrapperManager; @Override public void init(Map<String, String> parameters) { configureWrappers(parameters); } private void configureWrappers(Map<String, String> parameters) { wrapperManager = new CmisServiceWrapperManager(); wrapperManager.addWrappersFromServiceFactoryParameters(parameters); wrapperManager.addOuterWrapper(ConformanceCmisServiceWrapper.class, DEFAULT_MAX_ITEMS_TYPES, DEFAULT_DEPTH_TYPES, DEFAULT_MAX_ITEMS_OBJECTS, DEFAULT_DEPTH_OBJECTS); } @Override public void destroy() { } @Override public CmisService getService(CallContext context) { authenticate(context); CallContextAwareCmisService service = getCurrentThreadCmisService(); addConstellioParameters(context); service.setCallContext(context); return service; } private void addConstellioParameters(CallContext context) { String collection = context.getRepositoryId(); User currentUser = getCurrentUser(context, collection); MutableCallContext mcc = (MutableCallContext) context; mcc.put(ConstellioCmisContextParameters.COLLECTION, collection); mcc.put(ConstellioCmisContextParameters.USER, currentUser); } public static UserCredential authenticateUserFromContext(CallContext callContext, UserServices userServices) { String collection = callContext.getRepositoryId(); String serviceKey = callContext.getUsername(); String token = callContext.getPassword(); try { String username = userServices.getTokenUser(serviceKey, token); UserCredential userCredential = userServices.getUser(username); if (collection != null) { User user = userServices.getUserInCollection(username, collection); if (!userCredential.isSystemAdmin() && !user.has(USE_EXTERNAL_APIS_FOR_COLLECTION).globally()) { throw new CmisPermissionDeniedException( "User does not have permission to use CMIS in collection '" + collection + "'"); } } else { if (!userServices.has(userCredential).globalPermissionInAnyCollection(USE_EXTERNAL_APIS_FOR_COLLECTION)) { throw new CmisPermissionDeniedException( "User must have the permission to use CMIS in at least one collection"); } } return userCredential; } catch (UserServicesRuntimeException e) { throw new CmisExceptions_InvalidLogin(); } } private void authenticate(CallContext context) { UserServices userServices = getUserServices(); authenticateUserFromContext(context, userServices); } private User getCurrentUser(CallContext context, String collection) { User currentUser = null; String serviceKey = context.getUsername(); if (collection != null) { // if (username.contains("=>")) { // username = username.split("=>")[1]; // } UserServices userServices = getUserServices(); String username = userServices.getUserCredentialByServiceKey(serviceKey); currentUser = userServices.getUserInCollection(username, collection); } return currentUser; } private CallContextAwareCmisService getCurrentThreadCmisService() { ThreadLocal<CallContextAwareCmisService> threadLocalService = getConstellioCmisRepositoriesManager() .getCallContextAwareCmisServiceThreadLocal(); CallContextAwareCmisService service = threadLocalService.get(); if (service == null) { ConstellioCmisRequests constellioCmisService = new ConstellioCmisRequests(getAppLayerFactory(), getConstellioCmisRepositoriesManager()); service = (CallContextAwareCmisService) wrapperManager.wrap(constellioCmisService); threadLocalService.set(service); } return service; } public UserServices getUserServices() { return getModelLayerFactory().newUserServices(); } public RecordServices getRecordServices() { return getModelLayerFactory().newRecordServices(); } public AuthorizationsServices getAuthorizationsServices() { return getModelLayerFactory().newAuthorizationsServices(); } public AuthenticationService getAuthenticationService() { return getModelLayerFactory().newAuthenticationService(); } public ModelLayerFactory getModelLayerFactory() { ConstellioFactories constellioFactories = ConstellioFactories.getInstance(); return constellioFactories.getModelLayerFactory(); } public AppLayerFactory getAppLayerFactory() { ConstellioFactories constellioFactories = ConstellioFactories.getInstance(); return constellioFactories.getAppLayerFactory(); } public CmisCacheManager getConstellioCmisRepositoriesManager() { ConstellioFactories constellioFactories = ConstellioFactories.getInstance(); return constellioFactories.getAppLayerFactory().getConstellioCmisRepositoriesManager(); } }