001/* 002 * (C) Copyright 2006-2016 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 * Bogdan Stefanescu 018 * Florent Guillaume 019 */ 020package org.nuxeo.ecm.core.api; 021 022import java.security.Principal; 023import java.util.ArrayList; 024import java.util.function.Consumer; 025import java.util.function.Function; 026 027import org.apache.commons.lang3.mutable.MutableObject; 028import org.nuxeo.ecm.core.api.impl.UserPrincipal; 029import org.nuxeo.ecm.core.api.local.ClientLoginModule; 030import org.nuxeo.ecm.core.api.local.LoginStack; 031import org.nuxeo.ecm.core.api.repository.RepositoryManager; 032import org.nuxeo.runtime.api.Framework; 033import org.nuxeo.runtime.api.login.LoginComponent; 034 035/** 036 * The CoreInstance is the main access point to a CoreSession. 037 */ 038public class CoreInstance { 039 040 private CoreInstance() { 041 } 042 043 /** 044 * Opens a {@link CoreSession} for the currently logged-in user. 045 * <p> 046 * The session must be closed using {@link CloseableCoreSession#close}. 047 * 048 * @param repositoryName the repository name, or {@code null} for the default repository 049 * @return the session 050 * @since 5.9.3 051 */ 052 public static CloseableCoreSession openCoreSession(String repositoryName) { 053 return openCoreSession(repositoryName, getPrincipal(null)); 054 } 055 056 /** 057 * MUST ONLY BE USED IN UNIT TESTS to open a {@link CoreSession} for the given user. 058 * <p> 059 * The session must be closed using {@link CloseableCoreSession#close}. 060 * 061 * @param repositoryName the repository name, or {@code null} for the default repository 062 * @param username the user name 063 * @return the session 064 * @since 5.9.3 065 */ 066 public static CloseableCoreSession openCoreSession(String repositoryName, String username) { 067 return openCoreSession(repositoryName, getPrincipal(username)); 068 } 069 070 /** 071 * Opens a {@link CoreSession} for a system user. 072 * <p> 073 * The session must be closed using {@link CloseableCoreSession#close}. 074 * 075 * @param repositoryName the repository name, or {@code null} for the default repository 076 * @return the session 077 * @since 5.9.3 078 */ 079 public static CloseableCoreSession openCoreSessionSystem(String repositoryName) { 080 return openCoreSession(repositoryName, new SystemPrincipal(null)); 081 } 082 083 /** 084 * Opens a {@link CoreSession} for a system user with an optional originating username. 085 * <p> 086 * The session must be closed using {@link CloseableCoreSession#close}. 087 * 088 * @param repositoryName the repository name, or {@code null} for the default repository 089 * @param originatingUsername the originating username to set on the SystemPrincipal 090 * @return the session 091 * @since 8.1 092 */ 093 public static CloseableCoreSession openCoreSessionSystem(String repositoryName, String originatingUsername) { 094 return openCoreSession(repositoryName, new SystemPrincipal(originatingUsername)); 095 } 096 097 /** 098 * Opens a {@link CoreSession} for the given principal. 099 * <p> 100 * The session must be closed using {@link CloseableCoreSession#close}. 101 * 102 * @param repositoryName the repository name, or {@code null} for the default repository 103 * @param principal the principal 104 * @return the session 105 * @since 5.9.3 106 */ 107 public static CloseableCoreSession openCoreSession(String repositoryName, NuxeoPrincipal principal) { 108 if (repositoryName == null) { 109 RepositoryManager repositoryManager = Framework.getService(RepositoryManager.class); 110 repositoryName = repositoryManager.getDefaultRepositoryName(); 111 } 112 return Framework.getService(CoreSessionService.class).createCoreSession(repositoryName, principal); 113 } 114 115 /** 116 * Gets an existing open session for the given session id. 117 * <p> 118 * The returned CoreSession must not be closed, as it is owned by someone else. 119 * 120 * @param sessionId the session id 121 * @return the session, which must not be closed 122 */ 123 public CoreSession getSession(String sessionId) { 124 return Framework.getService(CoreSessionService.class).getCoreSession(sessionId); 125 } 126 127 /** 128 * Use {@link CloseableCoreSession#close} instead. 129 * 130 * @since 5.9.3 131 */ 132 public static void closeCoreSession(CloseableCoreSession session) { 133 Framework.getService(CoreSessionService.class).releaseCoreSession(session); 134 } 135 136 protected static NuxeoPrincipal getPrincipal(String username) { 137 if (username != null) { 138 return new UserPrincipal(username, new ArrayList<>(), false, false); 139 } else { 140 LoginStack.Entry entry = ClientLoginModule.getCurrentLogin(); 141 if (entry != null) { 142 Principal p = entry.getPrincipal(); 143 if (p instanceof NuxeoPrincipal) { 144 return (NuxeoPrincipal) p; 145 } else if (LoginComponent.isSystemLogin(p)) { 146 return new SystemPrincipal(p.getName()); 147 } else { 148 throw new RuntimeException("Unsupported principal: " + p.getClass()); 149 } 150 } else { 151 if (Framework.isTestModeSet()) { 152 return new SystemPrincipal(null); 153 } else { 154 throw new NuxeoException( 155 "Cannot create a CoreSession outside a security context, " + " login() missing."); 156 } 157 } 158 } 159 } 160 161 /** 162 * Gets the name of the currently logged-in principal. 163 * 164 * @return the principal name, or {@code null} if there was no login 165 * @since 8.4 166 */ 167 protected static String getCurrentPrincipalName() { 168 NuxeoPrincipal p = ClientLoginModule.getCurrentPrincipal(); 169 return p == null ? null : p.getName(); 170 } 171 172 /** 173 * Runs the given {@link Function} with a system {@link CoreSession} while logged in as a system user. 174 * 175 * @param repositoryName the repository name for the {@link CoreSession} 176 * @param function the function taking a system {@link CoreSession} and returning a result of type {@code <R>} 177 * @param <R> the function return type 178 * @return the result of the function 179 * @since 8.4 180 */ 181 public static <R> R doPrivileged(String repositoryName, Function<CoreSession, R> function) { 182 MutableObject<R> result = new MutableObject<>(); 183 new UnrestrictedSessionRunner(repositoryName, getCurrentPrincipalName()) { 184 @Override 185 public void run() { 186 result.setValue(function.apply(session)); 187 } 188 }.runUnrestricted(); 189 return result.getValue(); 190 } 191 192 /** 193 * Runs the given {@link Function} with a system {@link CoreSession} while logged in as a system user. 194 * 195 * @param session an existing session 196 * @param function the function taking a system {@link CoreSession} and returning a result of type {@code <R>} 197 * @param <R> the function return type 198 * @return the result of the function 199 * @since 8.4 200 */ 201 public static <R> R doPrivileged(CoreSession session, Function<CoreSession, R> function) { 202 MutableObject<R> result = new MutableObject<>(); 203 new UnrestrictedSessionRunner(session) { 204 @Override 205 public void run() { 206 result.setValue(function.apply(session)); 207 } 208 }.runUnrestricted(); 209 return result.getValue(); 210 } 211 212 /** 213 * Runs the given {@link Consumer} with a system {@link CoreSession} while logged in as a system user. 214 * 215 * @param repositoryName the repository name for the {@link CoreSession} 216 * @param consumer the consumer taking a system {@link CoreSession} 217 * @since 8.4 218 */ 219 public static void doPrivileged(String repositoryName, Consumer<CoreSession> consumer) { 220 new UnrestrictedSessionRunner(repositoryName, getCurrentPrincipalName()) { 221 @Override 222 public void run() { 223 consumer.accept(session); 224 } 225 }.runUnrestricted(); 226 } 227 228 /** 229 * Runs the given {@link Consumer} with a system {@link CoreSession} while logged in as a system user. 230 * 231 * @param session an existing session 232 * @param consumer the consumer taking a system {@link CoreSession} 233 * @since 8.4 234 */ 235 public static void doPrivileged(CoreSession session, Consumer<CoreSession> consumer) { 236 new UnrestrictedSessionRunner(session) { 237 @Override 238 public void run() { 239 consumer.accept(session); 240 } 241 }.runUnrestricted(); 242 } 243 244}