1 31 package org.blojsom.plugin.admin; 32 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 import org.blojsom.blog.Blog; 36 import org.blojsom.blog.Entry; 37 import org.blojsom.plugin.PluginException; 38 import org.blojsom.util.BlojsomConstants; 39 import org.blojsom.util.BlojsomUtils; 40 41 import javax.servlet.http.HttpServletRequest ; 42 import javax.servlet.http.HttpServletResponse ; 43 import java.io.*; 44 import java.util.*; 45 46 53 public class EditBlogTemplatesPlugin extends BaseAdminPlugin { 54 55 private Log _logger = LogFactory.getLog(EditBlogTemplatesPlugin.class); 56 57 private static final String DEFAULT_ACCEPTED_TEMPLATE_EXTENSIONS = "vm"; 58 private static final String ACCEPTED_TEMPLATE_EXTENSIONS_INIT_PARAM = "accepted-template-extensions"; 59 60 private static final String EDIT_BLOG_TEMPLATES_PAGE = "/org/blojsom/plugin/admin/templates/admin-edit-blog-templates"; 62 private static final String EDIT_BLOG_TEMPLATE_PAGE = "/org/blojsom/plugin/admin/templates/admin-edit-blog-template"; 63 64 private static final String BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE_FILES = "BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE_FILES"; 66 private static final String BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE_FILE = "BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE_FILE"; 67 private static final String BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE = "BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE"; 68 private static final String BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_DIRECTORIES = "BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_DIRECTORIES"; 69 70 private static final String FAILED_EDIT_TEMPLATES_PERMISSION_KEY = "failed.edit.templates.permission.text"; 72 private static final String INVALID_TEMPLATE_PATH_KEY = "invalid.template.path.text"; 73 private static final String UNABLE_TO_LOAD_TEMPLATE_KEY = "unable.to.load.template.text"; 74 private static final String UNABLE_TO_DELETE_TEMPLATE_KEY = "unable.to.delete.template.text"; 75 private static final String UPDATED_TEMPLATE_KEY = "updated.template.text"; 76 private static final String NO_TEMPLATE_NAME_KEY = "no.template.name.text"; 77 private static final String INVALID_TEMPLATE_EXTENSION_KEY = "invalid.template.extension.text"; 78 private static final String TEMPLATE_DIRECTORY_NONEXISTENT_KEY = "template.directory.nonexistent.text"; 79 private static final String TEMPLATE_DIRECTORY_NOTSPECIFIED_KEY = "template.directory.notspecified.text"; 80 private static final String UNABLE_TO_ADD_TEMPLATE_DIRECTORY_KEY = "unable.to.add.template.directory.text"; 81 private static final String ADDED_TEMPLATE_DIRECTORY_KEY = "added.template.directory.text"; 82 private static final String CANNOT_REMOVE_TOP_TEMPLATE_DIRECTORY_KEY = "cannot.remove.top.template.directory.text"; 83 private static final String UNABLE_TO_DELETE_TEMPLATE_DIRECTORY_KEY = "unable.to.delete.template.directory.text"; 84 private static final String REMOVED_TEMPLATE_DIRECTORY_KEY = "removed.template.directory.text"; 85 private static final String DELETED_TEMPLATE_KEY = "deleted.template.text"; 86 87 private static final String ADD_BLOG_TEMPLATE_ACTION = "add-blog-template"; 89 private static final String DELETE_BLOG_TEMPLATE_ACTION = "delete-blog-template"; 90 private static final String EDIT_BLOG_TEMPLATES_ACTION = "edit-blog-template"; 91 private static final String UPDATE_BLOG_TEMPLATE_ACTION = "update-blog-template"; 92 private static final String ADD_TEMPLATE_DIRECTORY_ACTION = "add-template-directory"; 93 private static final String DELETE_TEMPLATE_DIRECTORY_ACTION = "delete-template-directory"; 94 95 private static final String BLOG_TEMPLATE = "blog-template"; 97 private static final String BLOG_TEMPLATE_DATA = "blog-template-data"; 98 private static final String BLOG_TEMPLATE_DIRECTORY = "blog-template-directory"; 99 private static final String TEMPLATE_DIRECTORY_TO_ADD = "template-directory-to-add"; 100 101 private static final String EDIT_BLOG_TEMPLATES_PERMISSION = "edit_blog_templates_permission"; 103 104 private Map _acceptedTemplateExtensions; 105 private Properties _templateEditProperties; 106 private Properties _blojsomProperties; 107 private String _templatesDirectory; 108 private String _blogsDirectory; 109 110 113 public EditBlogTemplatesPlugin() { 114 } 115 116 121 public void setTemplateEditProperties(Properties templateEditProperties) { 122 _templateEditProperties = templateEditProperties; 123 } 124 125 130 public void setBlojsomProperties(Properties blojsomProperties) { 131 _blojsomProperties = blojsomProperties; 132 } 133 134 140 public void init() throws PluginException { 141 super.init(); 142 143 String acceptedTemplateExtensions = _templateEditProperties.getProperty(ACCEPTED_TEMPLATE_EXTENSIONS_INIT_PARAM); 144 if (BlojsomUtils.checkNullOrBlank(acceptedTemplateExtensions)) { 145 acceptedTemplateExtensions = DEFAULT_ACCEPTED_TEMPLATE_EXTENSIONS; 146 } 147 148 _acceptedTemplateExtensions = new HashMap(); 149 String [] templateExtensions = BlojsomUtils.parseCommaList(acceptedTemplateExtensions); 150 for (int i = 0; i < templateExtensions.length; i++) { 151 String templateExtension = templateExtensions[i]; 152 _acceptedTemplateExtensions.put(templateExtension, templateExtension); 153 } 154 155 _templatesDirectory = _blojsomProperties.getProperty(BlojsomConstants.TEMPLATES_DIRECTORY_IP, BlojsomConstants.DEFAULT_TEMPLATES_DIRECTORY); 156 _blogsDirectory = _blojsomProperties.getProperty(BlojsomConstants.BLOGS_DIRECTORY_IP, BlojsomConstants.DEFAULT_BLOGS_DIRECTORY); 157 } 158 159 165 protected String sanitizeFilename(String blogTemplate) { 166 String templateFilename = new File(blogTemplate).getName(); 167 int lastSeparator; 168 blogTemplate = BlojsomUtils.normalize(blogTemplate); 169 lastSeparator = blogTemplate.lastIndexOf(File.separator); 170 if (lastSeparator == -1) { 171 if (templateFilename != null) { 172 return templateFilename; 173 } else { 174 return null; 175 } 176 } else { 177 blogTemplate = blogTemplate.substring(0, lastSeparator + 1) + templateFilename; 178 } 179 180 return blogTemplate; 181 } 182 183 189 protected void putTemplatesInContext(File templatesDirectory, Map context) { 190 List templateFiles = new ArrayList(); 191 BlojsomUtils.listFilesInSubdirectories(templatesDirectory, templatesDirectory.getAbsolutePath(), templateFiles); 192 File[] templates = (File[]) templateFiles.toArray(new File[templateFiles.size()]); 193 Arrays.sort(templates); 194 195 context.put(BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE_FILES, templates); 196 } 197 198 204 protected void putTemplateDirectoriesInContext(File templatesDirectory, Map context) { 205 List templateDirectories = new ArrayList(); 206 BlojsomUtils.listDirectoriesInSubdirectories(templatesDirectory, templatesDirectory.getAbsolutePath(), templateDirectories); 207 File[] directories = (File[]) templateDirectories.toArray(new File[templateDirectories.size()]); 208 Arrays.sort(directories); 209 210 context.put(BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_DIRECTORIES, directories); 211 } 212 213 224 public Entry[] process(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Blog blog, Map context, Entry[] entries) throws PluginException { 225 if (!authenticateUser(httpServletRequest, httpServletResponse, context, blog)) { 226 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, ADMIN_LOGIN_PAGE); 227 228 return entries; 229 } 230 231 String username = getUsernameFromSession(httpServletRequest, blog); 232 if (!checkPermission(blog, null, username, EDIT_BLOG_TEMPLATES_PERMISSION)) { 233 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, ADMIN_ADMINISTRATION_PAGE); 234 addOperationResultMessage(context, getAdminResource(FAILED_EDIT_TEMPLATES_PERMISSION_KEY, FAILED_EDIT_TEMPLATES_PERMISSION_KEY, blog.getBlogAdministrationLocale())); 235 236 return entries; 237 } 238 239 File templatesDirectory = new File(_servletConfig.getServletContext().getRealPath("/") + BlojsomConstants.DEFAULT_CONFIGURATION_BASE_DIRECTORY + _blogsDirectory + blog.getBlogId() + _templatesDirectory); 241 _logger.debug("Looking for templates in directory: " + templatesDirectory.toString()); 242 243 putTemplatesInContext(templatesDirectory, context); 244 putTemplateDirectoriesInContext(templatesDirectory, context); 245 246 String action = BlojsomUtils.getRequestValue(ACTION_PARAM, httpServletRequest); 247 if (BlojsomUtils.checkNullOrBlank(action)) { 248 _logger.debug("User did not request edit action"); 249 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, ADMIN_ADMINISTRATION_PAGE); 250 } else if (PAGE_ACTION.equals(action)) { 251 _logger.debug("User requested edit blog templates page"); 252 253 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 254 } else if (EDIT_BLOG_TEMPLATES_ACTION.equals(action)) { 255 _logger.debug("User requested edit blog templates action"); 256 257 String blogTemplate = BlojsomUtils.getRequestValue(BLOG_TEMPLATE, httpServletRequest); 258 if (BlojsomUtils.checkNullOrBlank(blogTemplate)) { 259 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 260 261 return entries; 262 } 263 264 blogTemplate = sanitizeFilename(blogTemplate); 265 if (blogTemplate == null) { 266 addOperationResultMessage(context, getAdminResource(INVALID_TEMPLATE_PATH_KEY, INVALID_TEMPLATE_PATH_KEY, blog.getBlogAdministrationLocale())); 267 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 268 269 return entries; 270 } 271 272 File blogTemplateFile = new File(_servletConfig.getServletContext().getRealPath("/") + BlojsomConstants.DEFAULT_CONFIGURATION_BASE_DIRECTORY + _blogsDirectory + blog.getBlogId() + _templatesDirectory + blogTemplate); 273 _logger.debug("Reading template file: " + blogTemplateFile.toString()); 274 275 try { 276 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(blogTemplateFile), BlojsomConstants.UTF8)); 277 String input; 278 StringBuffer template = new StringBuffer (); 279 280 while ((input = br.readLine()) != null) { 281 template.append(input); 282 template.append(BlojsomConstants.LINE_SEPARATOR); 283 } 284 285 br.close(); 286 287 context.put(BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE_FILE, blogTemplate); 288 context.put(BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE, BlojsomUtils.escapeString(template.toString())); 289 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATE_PAGE); 290 } catch (UnsupportedEncodingException e) { 291 _logger.error(e); 292 addOperationResultMessage(context, formatAdminResource(UNABLE_TO_LOAD_TEMPLATE_KEY, UNABLE_TO_LOAD_TEMPLATE_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplate})); 293 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 294 } catch (IOException e) { 295 _logger.error(e); 296 addOperationResultMessage(context, formatAdminResource(UNABLE_TO_LOAD_TEMPLATE_KEY, UNABLE_TO_LOAD_TEMPLATE_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplate})); 297 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 298 } 299 } else if (UPDATE_BLOG_TEMPLATE_ACTION.equals(action)) { 300 _logger.debug("User requested update blog template action"); 301 302 String blogTemplate = BlojsomUtils.getRequestValue(BLOG_TEMPLATE, httpServletRequest); 303 if (BlojsomUtils.checkNullOrBlank(blogTemplate)) { 304 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 305 306 return entries; 307 } 308 309 blogTemplate = sanitizeFilename(blogTemplate); 310 if (blogTemplate == null) { 311 addOperationResultMessage(context, getAdminResource(INVALID_TEMPLATE_PATH_KEY, INVALID_TEMPLATE_PATH_KEY, blog.getBlogAdministrationLocale())); 312 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 313 314 return entries; 315 } 316 317 String blogTemplateData = BlojsomUtils.getRequestValue(BLOG_TEMPLATE_DATA, httpServletRequest); 318 File blogTemplateFile = new File(_servletConfig.getServletContext().getRealPath("/") + BlojsomConstants.DEFAULT_CONFIGURATION_BASE_DIRECTORY + _blogsDirectory + blog.getBlogId() + _templatesDirectory + blogTemplate); 319 320 _logger.debug("Writing template file: " + blogTemplateFile.toString()); 321 322 try { 323 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(blogTemplateFile), BlojsomConstants.UTF8)); 324 bw.write(blogTemplateData); 325 bw.close(); 326 } catch (UnsupportedEncodingException e) { 327 _logger.error(e); 328 addOperationResultMessage(context, formatAdminResource(UNABLE_TO_DELETE_TEMPLATE_KEY, UNABLE_TO_DELETE_TEMPLATE_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplate})); 329 } catch (IOException e) { 330 _logger.error(e); 331 addOperationResultMessage(context, formatAdminResource(UNABLE_TO_DELETE_TEMPLATE_KEY, UNABLE_TO_DELETE_TEMPLATE_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplate})); 332 } 333 334 addOperationResultMessage(context, formatAdminResource(UPDATED_TEMPLATE_KEY, UPDATED_TEMPLATE_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplate})); 335 336 context.put(BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE_FILE, blogTemplate); 337 context.put(BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE, BlojsomUtils.escapeString(blogTemplateData)); 338 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATE_PAGE); 339 } else if (ADD_BLOG_TEMPLATE_ACTION.equals(action)) { 340 _logger.debug("User requested add blog template action"); 341 342 String blogTemplate = BlojsomUtils.getRequestValue(BLOG_TEMPLATE, httpServletRequest); 343 String blogTemplateDirectory = BlojsomUtils.getRequestValue(BLOG_TEMPLATE_DIRECTORY, httpServletRequest); 344 345 if (BlojsomUtils.checkNullOrBlank(blogTemplate)) { 346 addOperationResultMessage(context, getAdminResource(NO_TEMPLATE_NAME_KEY, NO_TEMPLATE_NAME_KEY, blog.getBlogAdministrationLocale())); 347 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 348 349 return entries; 350 } 351 352 String templateName = BlojsomUtils.getFilenameFromPath(blogTemplate); 353 String templateExtension = BlojsomUtils.getFileExtension(templateName); 354 355 if (!_acceptedTemplateExtensions.containsKey(templateExtension)) { 356 addOperationResultMessage(context, formatAdminResource(INVALID_TEMPLATE_EXTENSION_KEY, INVALID_TEMPLATE_EXTENSION_KEY, blog.getBlogAdministrationLocale(), new Object []{templateExtension})); 357 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 358 359 return entries; 360 } else { 361 blogTemplateDirectory = BlojsomUtils.normalize(blogTemplateDirectory); 362 File addedTemplateDirectory = new File(templatesDirectory, blogTemplateDirectory); 363 if (addedTemplateDirectory.exists()) { 364 context.put(BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE_FILE, blogTemplateDirectory + File.separator + templateName); 365 context.put(BLOJSOM_PLUGIN_EDIT_BLOG_TEMPLATES_TEMPLATE, ""); 366 367 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATE_PAGE); 368 } else { 369 addOperationResultMessage(context, getAdminResource(TEMPLATE_DIRECTORY_NONEXISTENT_KEY, TEMPLATE_DIRECTORY_NONEXISTENT_KEY, blog.getBlogAdministrationLocale())); 370 } 371 } 372 } else if (ADD_TEMPLATE_DIRECTORY_ACTION.equals(action)) { 373 _logger.debug("User requested add blog template directory action"); 374 375 String templateDirectoryToAdd = BlojsomUtils.getRequestValue(TEMPLATE_DIRECTORY_TO_ADD, httpServletRequest); 376 String blogTemplateDirectory = BlojsomUtils.getRequestValue(BLOG_TEMPLATE_DIRECTORY, httpServletRequest); 377 if (BlojsomUtils.checkNullOrBlank(templateDirectoryToAdd)) { 378 addOperationResultMessage(context, getAdminResource(TEMPLATE_DIRECTORY_NOTSPECIFIED_KEY, TEMPLATE_DIRECTORY_NOTSPECIFIED_KEY, blog.getBlogAdministrationLocale())); 379 } else { 380 blogTemplateDirectory = BlojsomUtils.normalize(blogTemplateDirectory); 381 templateDirectoryToAdd = BlojsomUtils.normalize(templateDirectoryToAdd); 382 383 File newTemplateDirectory = new File(templatesDirectory, blogTemplateDirectory + File.separator + templateDirectoryToAdd); 384 _logger.debug("Adding blog template directory: " + newTemplateDirectory.toString()); 385 386 if (!newTemplateDirectory.mkdir()) { 387 addOperationResultMessage(context, formatAdminResource(UNABLE_TO_ADD_TEMPLATE_DIRECTORY_KEY, UNABLE_TO_ADD_TEMPLATE_DIRECTORY_KEY, blog.getBlogAdministrationLocale(), new Object []{templateDirectoryToAdd})); 388 } else { 389 addOperationResultMessage(context, formatAdminResource(ADDED_TEMPLATE_DIRECTORY_KEY, ADDED_TEMPLATE_DIRECTORY_KEY, blog.getBlogAdministrationLocale(), new Object []{templateDirectoryToAdd})); 390 391 putTemplateDirectoriesInContext(templatesDirectory, context); 392 } 393 } 394 395 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 396 } else if (DELETE_TEMPLATE_DIRECTORY_ACTION.equals(action)) { 397 _logger.debug("User requested delete blog template directory action"); 398 399 String blogTemplateDirectory = BlojsomUtils.getRequestValue(BLOG_TEMPLATE_DIRECTORY, httpServletRequest); 400 if (BlojsomUtils.checkNullOrBlank(blogTemplateDirectory)) { 401 addOperationResultMessage(context, getAdminResource(CANNOT_REMOVE_TOP_TEMPLATE_DIRECTORY_KEY, CANNOT_REMOVE_TOP_TEMPLATE_DIRECTORY_KEY, blog.getBlogAdministrationLocale())); 402 } else { 403 blogTemplateDirectory = BlojsomUtils.normalize(blogTemplateDirectory); 404 _logger.debug("Sanitized template directory: " + blogTemplateDirectory); 405 File templateDirectoryToDelete = new File(templatesDirectory, blogTemplateDirectory); 406 _logger.debug("Removing blog template directory: " + templateDirectoryToDelete); 407 408 if (!BlojsomUtils.deleteDirectory(templateDirectoryToDelete, true)) { 409 addOperationResultMessage(context, formatAdminResource(UNABLE_TO_DELETE_TEMPLATE_DIRECTORY_KEY, UNABLE_TO_DELETE_TEMPLATE_DIRECTORY_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplateDirectory})); 410 } else { 411 addOperationResultMessage(context, formatAdminResource(REMOVED_TEMPLATE_DIRECTORY_KEY, REMOVED_TEMPLATE_DIRECTORY_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplateDirectory})); 412 413 putTemplateDirectoriesInContext(templatesDirectory, context); 414 } 415 } 416 417 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 418 } else if (DELETE_BLOG_TEMPLATE_ACTION.equals(action)) { 419 _logger.debug("User requested delete blog template directory action"); 420 421 String blogTemplate = BlojsomUtils.getRequestValue(BLOG_TEMPLATE, httpServletRequest); 422 if (BlojsomUtils.checkNullOrBlank(blogTemplate)) { 423 addOperationResultMessage(context, getAdminResource(NO_TEMPLATE_NAME_KEY, NO_TEMPLATE_NAME_KEY, blog.getBlogAdministrationLocale())); 424 } 425 426 blogTemplate = sanitizeFilename(blogTemplate); 427 File templateToDelete = new File(templatesDirectory, blogTemplate); 428 _logger.debug("Deleting blog template: " + templateToDelete.toString()); 429 430 if (!templateToDelete.delete()) { 431 addOperationResultMessage(context, formatAdminResource(UNABLE_TO_DELETE_TEMPLATE_KEY, UNABLE_TO_DELETE_TEMPLATE_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplate})); 432 } else { 433 addOperationResultMessage(context, formatAdminResource(DELETED_TEMPLATE_KEY, DELETED_TEMPLATE_KEY, blog.getBlogAdministrationLocale(), new Object []{blogTemplate})); 434 435 putTemplatesInContext(templatesDirectory, context); 436 } 437 438 httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, EDIT_BLOG_TEMPLATES_PAGE); 439 } 440 441 return entries; 442 } 443 } 444 | Popular Tags |