001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.repository; 029 030import org.opencms.configuration.CmsConfigurationException; 031import org.opencms.configuration.CmsParameterConfiguration; 032import org.opencms.db.CmsUserSettings; 033import org.opencms.file.CmsObject; 034import org.opencms.file.wrapper.CmsObjectWrapper; 035import org.opencms.file.wrapper.I_CmsResourceWrapper; 036import org.opencms.main.CmsException; 037import org.opencms.main.CmsLog; 038import org.opencms.main.OpenCms; 039import org.opencms.security.CmsRole; 040import org.opencms.workplace.CmsWorkplace; 041 042import java.security.MessageDigest; 043import java.util.ArrayList; 044import java.util.Collections; 045import java.util.List; 046import java.util.Map; 047import java.util.concurrent.TimeUnit; 048 049import org.apache.commons.codec.binary.Hex; 050import org.apache.commons.lang3.RandomStringUtils; 051import org.apache.commons.logging.Log; 052 053import com.google.common.cache.CacheBuilder; 054 055/** 056 * Creates a repository session to access OpenCms.<p> 057 * 058 * The configuration of the used {@link I_CmsResourceWrapper} is done here. 059 * This is the main class to get access to the resources in the VFS of 060 * OpenCms. The method {@link #login(String, String)} logs in to OpenCms 061 * and returns a {@link CmsRepositorySession} to use for basic file and 062 * folder operations.<p> 063 * 064 * The project and the site to use for the access to OpenCms is read out 065 * of the user settings.<p> 066 * 067 * @see CmsObjectWrapper 068 * 069 * @since 6.5.6 070 */ 071public class CmsRepository extends A_CmsRepository { 072 073 /** The log object for this class. */ 074 private static final Log LOG = CmsLog.getLog(CmsRepository.class); 075 076 /** Random value used for hashing login credentials for the CmsObject cache. */ 077 private static String m_passwordSalt = RandomStringUtils.randomAlphanumeric(10); 078 079 /** The name of the parameter of the configuration. */ 080 private static final String PARAM_WRAPPER = "wrapper"; 081 082 /** Timed cache for CmsObjects. */ 083 private Map<String, CmsObject> m_cmsObjectCache; 084 085 /** The list of configured wrappers of the repository. */ 086 private List<I_CmsResourceWrapper> m_wrappers; 087 088 /** 089 * Empty default constructor.<p> 090 */ 091 public CmsRepository() { 092 093 super(); 094 m_wrappers = new ArrayList<I_CmsResourceWrapper>(); 095 CacheBuilder<?, ?> builder = CacheBuilder.newBuilder().concurrencyLevel(4).expireAfterWrite( 096 30, 097 TimeUnit.SECONDS); 098 m_cmsObjectCache = (Map<String, CmsObject>)(builder.build().asMap()); 099 } 100 101 /** 102 * Gets the cache key for a username/password pair. 103 * 104 * @param user the user name 105 * @param password the password 106 * @return the cache key to use 107 */ 108 private static String getLoginKey(String user, String password) { 109 110 try { 111 MessageDigest md5 = MessageDigest.getInstance("MD5"); 112 md5.update(user.getBytes("UTF-8")); 113 md5.update(new byte[] {0}); 114 md5.update(password.getBytes("UTF-8")); 115 md5.update(new byte[] {0}); 116 md5.update(m_passwordSalt.getBytes("UTF-8")); 117 return Hex.encodeHexString(md5.digest()); 118 } catch (Exception e) { 119 return null; 120 } 121 122 } 123 124 /** 125 * @see org.opencms.repository.A_CmsRepository#initConfiguration() 126 */ 127 @Override 128 public void initConfiguration() throws CmsConfigurationException { 129 130 CmsParameterConfiguration config = getConfiguration(); 131 List<I_CmsResourceWrapper> wrapperObjects = CmsRepositoryManager.createResourceWrappersFromConfiguration( 132 config, 133 PARAM_WRAPPER, 134 LOG); 135 m_wrappers = Collections.unmodifiableList(wrapperObjects); 136 super.initConfiguration(); 137 } 138 139 /** 140 * @see org.opencms.repository.I_CmsRepository#initializeCms(org.opencms.file.CmsObject) 141 */ 142 public void initializeCms(CmsObject cms) { 143 144 // do nothing 145 } 146 147 /** 148 * @see org.opencms.repository.A_CmsRepository#login(java.lang.String, java.lang.String) 149 */ 150 @Override 151 public I_CmsRepositorySession login(String userName, String password) throws CmsException { 152 153 CmsObject cms; 154 // Cache CmsObjects for 30 seconds to avoid expensive password checks 155 // (We always copy the cached values, so it's safe for multithreading) 156 String cacheKey = getLoginKey(userName, password); 157 CmsObject origCms = m_cmsObjectCache.get(cacheKey); 158 String configuredProject = getConfiguration().getString("project", null); 159 String configuredSite = getConfiguration().getString("root", null); 160 String roleStr = getConfiguration().getString("role", CmsRole.WORKPLACE_USER.getRoleName()); 161 CmsRole requiredRole = null; 162 if (!"any".equals(roleStr)) { 163 if (roleStr.indexOf("/") == -1) { 164 requiredRole = CmsRole.valueOfRoleName(roleStr).forOrgUnit(null); 165 } else { 166 requiredRole = CmsRole.valueOfRoleName(roleStr); 167 } 168 } 169 String project = configuredProject; 170 String site = configuredSite; 171 if (origCms != null) { 172 cms = OpenCms.initCmsObject(origCms); 173 } else { 174 cms = OpenCms.initCmsObject(OpenCms.getDefaultUsers().getUserGuest()); 175 cms.loginUser(userName, password); 176 if (requiredRole != null) { 177 OpenCms.getRoleManager().checkRole(cms, requiredRole); 178 } 179 if ((site == null) || (project == null)) { 180 CmsUserSettings settings = new CmsUserSettings(cms); 181 if (site == null) { 182 site = CmsWorkplace.getStartSiteRoot(cms, settings); 183 } 184 if (project == null) { 185 project = settings.getStartProject(); 186 } 187 } 188 cms.getRequestContext().setSiteRoot(site); 189 cms.getRequestContext().setCurrentProject(cms.readProject(project)); 190 m_cmsObjectCache.put(cacheKey, OpenCms.initCmsObject(cms)); 191 } 192 193 // set the object wrapper as an attribute in the request context, so that it can be 194 // used everywhere a CmsObject is accessible. 195 CmsObjectWrapper objWrapper = new CmsObjectWrapper(cms, m_wrappers); 196 boolean addBOM = getConfiguration().getBoolean("addBOM", true); 197 objWrapper.setAddByteOrderMark(addBOM); 198 cms.getRequestContext().setAttribute(CmsObjectWrapper.ATTRIBUTE_NAME, objWrapper); 199 200 return new CmsRepositorySession(objWrapper, getFilter(), isTranslationEnabled() ? getTranslation() : null); 201 } 202 203}