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, 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.gwt.shared; 029 030import org.opencms.file.CmsResource; 031import org.opencms.util.CmsStringUtil; 032 033import java.util.ArrayList; 034import java.util.Collections; 035import java.util.HashMap; 036import java.util.HashSet; 037import java.util.List; 038import java.util.Map; 039import java.util.Set; 040 041import com.google.common.base.Joiner; 042import com.google.gwt.user.client.rpc.IsSerializable; 043 044/** 045 * Contains information about which folders should restrict uploads. 046 */ 047public class CmsUploadRestrictionInfo implements IsSerializable { 048 049 /** 050 * Helper class for building a new CmsUploadRestrictionInfo object. 051 */ 052 public static class Builder { 053 054 /** 'Enabled' status. */ 055 private Map<String, Boolean> m_tempUploadEnabledMap = new HashMap<>(); 056 057 /** 'Types' status. */ 058 private Map<String, Set<String>> uploadTypesMap = new HashMap<>(); 059 060 /** 061 * Adds a new entry. 062 * 063 * <p>The info string has the format 'key1:value1|key2:value2|....'. Currently the keys 'types' and 'enabled' are supported; 064 * 'enabled' (format: 'enabled:true') enables/disables uploads, and 'types' (format: 'types:jpg,png' sets the allowed file extensions. 065 * 066 * @param path the path 067 * @param info the upload info entry 068 * @return the builder instance 069 */ 070 public Builder add(String path, String info) { 071 072 Map<String, String> parsedInfo = CmsStringUtil.splitAsMap(info, "|", ":"); 073 path = normalizePath(path); 074 String enabledStr = parsedInfo.get(KEY_ENABLED); 075 if (enabledStr != null) { 076 m_tempUploadEnabledMap.put(path, Boolean.valueOf(enabledStr)); 077 } 078 String typesStr = parsedInfo.get(KEY_TYPES); 079 if (typesStr != null) { 080 Set<String> types = new HashSet<>(); 081 for (String type : typesStr.split(",")) { 082 type = type.trim().toLowerCase(); 083 if (type.startsWith(".")) { 084 type = type.substring(1); 085 } 086 if (type.length() > 0) { 087 types.add(type); 088 } 089 } 090 uploadTypesMap.put(path, types); 091 } 092 return this; 093 094 } 095 096 /** 097 * Creates a new upload restriction info object. 098 * 099 * @return the new object 100 */ 101 @SuppressWarnings("synthetic-access") 102 public CmsUploadRestrictionInfo build() { 103 104 CmsUploadRestrictionInfo result = new CmsUploadRestrictionInfo(); 105 result.m_uploadEnabledMap = m_tempUploadEnabledMap; 106 result.m_uploadTypesMap = uploadTypesMap; 107 return result; 108 } 109 110 } 111 112 /** The 'enabled' key. */ 113 public static final String KEY_ENABLED = "enabled"; 114 115 /** The 'types' key. */ 116 public static final String KEY_TYPES = "types"; 117 118 /** The default upload restriction that allows everything. */ 119 public static final String UNRESTRICTED_UPLOADS = "enabled:true|types:*"; 120 121 /** Map to keep track of enabled/disabled status. */ 122 private Map<String, Boolean> m_uploadEnabledMap = new HashMap<>(); 123 124 /** Map to keep track of allowed file extensions. */ 125 private Map<String, Set<String>> m_uploadTypesMap = new HashMap<>(); 126 127 /** 128 * Creates a new instance. 129 */ 130 protected CmsUploadRestrictionInfo() {} 131 132 /** 133 * Normalizes a path. 134 * 135 * @param path the path 136 * @return the normalized path 137 */ 138 static String normalizePath(String path) { 139 140 if (!path.endsWith("/")) { 141 path = path + "/"; 142 } 143 return path; 144 } 145 146 /** 147 * Check if a given file extension is allowed for the given upload path. 148 * 149 * @param path the root path of the upload folder 150 * @param extension the file extension to check 151 * @return true if the file extension is valid for uploads to the folder 152 */ 153 public boolean checkTypeAllowed(String path, String extension) { 154 155 Set<String> types = getTypes(path); 156 if (extension.startsWith(".")) { 157 extension = extension.substring(1); 158 } 159 extension = extension.toLowerCase(); 160 boolean result = types.contains(extension) || types.contains("*"); 161 return result; 162 } 163 164 /** 165 * Gets the 'accept' attribute to use for the file input element for the given upload folder. 166 * 167 * @param path the upload folder root path 168 * @return the 'accept' attribute that should be used for the file input 169 */ 170 public String getAcceptAttribute(String path) { 171 172 Set<String> types = getTypes(path); 173 List<String> suffixes = new ArrayList<>(); 174 for (String type : types) { 175 if ("*".equals(type)) { 176 return ""; 177 } else { 178 suffixes.add("." + type); 179 } 180 } 181 return Joiner.on(",").join(suffixes); 182 } 183 184 /** 185 * Checks if the upload should be enabled for the given upload path. 186 * 187 * @param originalPath the upload root path 188 * @return true if the upload is enabled 189 */ 190 public boolean isUploadEnabled(String originalPath) { 191 192 String path = originalPath; 193 194 while (path != null) { 195 path = normalizePath(path); 196 Boolean value = m_uploadEnabledMap.get(path); 197 if (value != null) { 198 return value.booleanValue(); 199 } 200 path = CmsResource.getParentFolder(path); 201 } 202 return true; 203 } 204 205 /** 206 * Gets the valid extensions for uploads to a given upload folder 207 * 208 * @param path the upload folder root path 209 * @return the valid extensions 210 */ 211 protected Set<String> getTypes(String path) { 212 213 while (path != null) { 214 path = normalizePath(path); 215 Set<String> value = m_uploadTypesMap.get(path); 216 if (value != null) { 217 return value; 218 219 } 220 path = CmsResource.getParentFolder(path); 221 } 222 return Collections.emptySet(); 223 } 224 225}