1 41 package com.mvnforum.user; 42 43 import java.io.*; 44 import java.sql.Timestamp ; 45 import java.util.*; 46 47 import javax.servlet.http.HttpServletRequest ; 48 import javax.servlet.http.HttpServletResponse ; 49 50 import com.mvnforum.*; 51 import com.mvnforum.auth.*; 52 import com.mvnforum.common.AttachmentUtil; 53 import com.mvnforum.db.*; 54 import com.mvnforum.search.post.PostIndexer; 55 import net.myvietnam.mvncore.exception.*; 56 import net.myvietnam.mvncore.filter.DisableHtmlTagFilter; 57 import net.myvietnam.mvncore.interceptor.InterceptorService; 58 import net.myvietnam.mvncore.service.BinaryStorage; 59 import net.myvietnam.mvncore.util.*; 60 import net.myvietnam.mvncore.web.*; 61 import net.myvietnam.mvncore.web.fileupload.FileItem; 62 import net.myvietnam.mvncore.web.fileupload.FileUploadException; 63 import org.apache.commons.io.IOUtils; 64 import org.apache.commons.logging.Log; 65 import org.apache.commons.logging.LogFactory; 66 67 public class AttachmentWebHandler { 68 69 private static Log log = LogFactory.getLog(AttachmentWebHandler.class); 70 71 private OnlineUserManager userManager = OnlineUserManager.getInstance(); 72 73 public AttachmentWebHandler() { 74 } 75 76 public void prepareAdd(GenericRequest request) 77 throws BadInputException, DatabaseException, ObjectNotFoundException, 78 AuthenticationException, AssertionException { 79 80 Locale locale = I18nUtil.getLocaleInRequest(request); 81 if (MVNForumConfig.getEnableAttachment() == false) { 82 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.AssertionException.attachment_is_disabled"); 83 throw new AssertionException(localizedMessage); 84 } 86 87 OnlineUser onlineUser = userManager.getOnlineUser(request); 88 MVNForumPermission permission = onlineUser.getPermission(); 89 96 97 int postID = GenericParamUtil.getParameterInt(request, "post"); 99 100 PostBean postBean = null; 101 try { 102 postBean = DAOFactory.getPostDAO().getPost(postID); } catch (ObjectNotFoundException ex) { 104 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.postid_not_exists", new Object [] {new Integer (postID)}); 105 throw new ObjectNotFoundException(localizedMessage); 106 } 107 108 int forumID = postBean.getForumID(); 109 permission.ensureCanAddAttachment(forumID); 110 111 ForumCache.getInstance().getBean(forumID).ensureNotDisabledForum(); 112 ForumCache.getInstance().getBean(forumID).ensureNotLockedForum(); 113 ForumCache.getInstance().getBean(forumID).ensureNotClosedForum(); 114 115 int logonMemberID = onlineUser.getMemberID(); 116 int authorID = postBean.getMemberID(); 117 118 if (permission.canEditPost(forumID)) { } else if ( (logonMemberID==authorID) && onlineUser.isMember() ) { 122 Timestamp now = DateUtil.getCurrentGMTTimestamp(); 124 Timestamp postDate = postBean.getPostCreationDate(); 126 int maxDays = MVNForumConfig.getMaxAttachDays(); 127 if ( (now.getTime() - postDate.getTime()) > (DateUtil.DAY * maxDays) ) { 128 129 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.BadInputException.attach_into_old_post", new Object [] {new Integer (maxDays)}); 130 throw new BadInputException(localizedMessage); 131 } 133 134 if (postBean.getPostStatus() == PostBean.POST_STATUS_DISABLED) { 135 throw new BadInputException("Cannot attach a file to disabled post."); 137 } 138 } else { permission.ensureCanEditPost(forumID); } 142 143 request.setAttribute("PostBean", postBean); 144 } 145 146 public void processAdd(GenericRequest request, GenericResponse response) 147 throws BadInputException, CreateException, DatabaseException, IOException, ForeignKeyNotFoundException, 148 AuthenticationException, AssertionException, ObjectNotFoundException, InterceptorException { 149 150 Locale locale = I18nUtil.getLocaleInRequest(request); 151 152 if (MVNForumConfig.getEnableAttachment() == false) { 153 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.AssertionException.attachment_is_disabled"); 154 throw new AssertionException(localizedMessage); 155 } 157 158 OnlineUser onlineUser = userManager.getOnlineUser(request); 159 MVNForumPermission permission = onlineUser.getPermission(); 160 163 164 MyUtil.saveVNTyperMode(request, response); 165 166 String tempDir = MVNForumConfig.getTempDir(); 167 log.debug("AttachmentWebHandler : process upload with temp dir = " + tempDir); 168 169 final int UNLIMITED = -1; 170 int sizeMax = permission.canAdminSystem() ? UNLIMITED : MVNForumConfig.getMaxAttachmentSize() ; 171 int sizeThreshold = 100000; 172 173 List fileItems; 174 try { 175 FileUploadParser uploadParser = FileUploadParserFactory.getFileUploadParser(); 176 fileItems = uploadParser.parseRequest(request, sizeMax, sizeThreshold, tempDir, "UTF-8"); 177 } catch (FileUploadException ex) { 178 log.error("Cannot upload", ex); 179 String localizedMessage = MVNForumResourceBundle.getString(locale, "java.io.IOException.cannot_upload", new Object [] {ex.getMessage()}); 180 throw new IOException(localizedMessage); 181 } 183 184 int offset = 0; 186 int postID = 0; 187 String attachFilename = null; 188 int attachFileSize = 0; 189 String attachMimeType = null; 190 String attachDesc = null; 191 192 FileItem attachFileItem = null; 193 boolean attachMore = false; 194 for (int i = 0; i < fileItems.size(); i++ ) { 195 FileItem currentFileItem = (FileItem)fileItems.get(i); 196 String fieldName = currentFileItem.getFieldName(); 197 if (fieldName.equals("offset")) { 198 String content = currentFileItem.getString("utf-8"); 199 offset = Integer.parseInt(content); 200 log.debug("offset = " + offset); 201 } else if (fieldName.equals("AttachMore")) { 202 String content = currentFileItem.getString("utf-8"); 203 attachMore = (content.length() > 0); 204 log.debug("attachMore = " + attachMore); 205 } else if (fieldName.equals("PostID")) { 206 String content = currentFileItem.getString("utf-8"); 207 postID = Integer.parseInt(content); 208 log.debug("postID = " + postID); 209 } else if (fieldName.equals("AttachDesc")) { 210 String content = currentFileItem.getString("utf-8"); 211 attachDesc = DisableHtmlTagFilter.filter(content); 212 log.debug("attachDesc = " + attachDesc); 213 attachDesc = InterceptorService.getInstance().validateContent(attachDesc); 214 } else if (fieldName.equals("vnselector")) { 215 } else if (fieldName.equals(URLResolverFactory.getURLResolver().getActionParam())) { 217 } else if (fieldName.equals("AttachFilename")) { 219 if (currentFileItem.isFormField() == true) { 220 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.AssertionException.cannot_process_uploaded_attach_file_with_form_field"); 221 throw new AssertionException(localizedMessage); 222 } 224 attachMimeType = currentFileItem.getContentType(); 225 attachMimeType = DisableHtmlTagFilter.filter(attachMimeType); 226 attachFileSize = (int)currentFileItem.getSize(); 227 if (attachFileSize == 0) { 228 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.BadInputException.cannot_process_upload_with_file_size_is_zero"); 229 throw new BadInputException(localizedMessage); 230 } 232 String fullFilePath = currentFileItem.getName(); 233 attachFilename = FileUtil.getFileName(fullFilePath); 234 attachFilename = DisableHtmlTagFilter.filter(attachFilename); 235 log.debug("attachFilename = " + attachFilename); 236 237 attachFileItem = currentFileItem; 239 } else { 240 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.AssertionException.cannot_process_field_name", new Object [] {fieldName}); 243 throw new AssertionException(localizedMessage); 244 } 246 } 247 Timestamp now = DateUtil.getCurrentGMTTimestamp(); 248 249 PostBean postBean = null; 251 try { 252 postBean = DAOFactory.getPostDAO().getPost(postID); } catch (ObjectNotFoundException ex) { 254 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.postid_not_exists", new Object [] {new Integer (postID)}); 255 throw new ObjectNotFoundException(localizedMessage); 256 } 257 int forumID = postBean.getForumID(); 258 permission.ensureCanAddAttachment(forumID); 259 260 ForumCache.getInstance().getBean(forumID).ensureNotDisabledForum(); 261 ForumCache.getInstance().getBean(forumID).ensureNotLockedForum(); 262 ForumCache.getInstance().getBean(forumID).ensureNotClosedForum(); 263 264 int logonMemberID = onlineUser.getMemberID(); 265 int authorID = postBean.getMemberID(); 267 268 if (permission.canEditPost(forumID)) { } else if ( (logonMemberID==authorID) && onlineUser.isMember() ) { 272 Timestamp postDate = postBean.getPostCreationDate(); 275 int maxDays = MVNForumConfig.getMaxAttachDays(); 276 if ( (now.getTime() - postDate.getTime()) > (DateUtil.DAY * maxDays) ) { 277 278 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.BadInputException.attach_into_old_post", new Object [] {new Integer (maxDays)}); 279 throw new BadInputException(localizedMessage); 280 } 282 283 if (postBean.getPostStatus() == PostBean.POST_STATUS_DISABLED) { 284 throw new BadInputException("Cannot attach a file to disabled post."); 286 } 287 } else { permission.ensureCanEditPost(forumID); } 291 292 String attachCreationIP = request.getRemoteAddr(); 295 Timestamp attachCreationDate= now; 296 Timestamp attachModifiedDate= now; 297 int attachDownloadCount = 0; 298 int attachOption = 0; int attachStatus = 0; 301 int attachID = DAOFactory.getAttachmentDAO().createAttachment(postID, logonMemberID, attachFilename, 302 attachFileSize, attachMimeType, attachDesc, 303 attachCreationIP, attachCreationDate, attachModifiedDate, 304 attachDownloadCount, attachOption, attachStatus); 305 306 try { 307 BinaryStorage binaryStorage = ManagerFactory.getBinaryStorage(); 311 binaryStorage.storeData(BinaryStorage.CATEGORY_POST_ATTACHMENT, String.valueOf(attachID), attachFilename, 312 attachFileItem.getInputStream(), attachFileSize, 0, 0, attachMimeType, attachCreationIP); 313 } catch (Exception ex) { 314 log.error("Cannot save the attachment file", ex); 315 DAOFactory.getAttachmentDAO().delete(attachID); 316 String localizedMessage = MVNForumResourceBundle.getString(locale, "java.io.IOException.cannot_save_attach_file"); 317 throw new IOException(localizedMessage); 318 } 320 321 int threadID = postBean.getThreadID(); 323 int attachCount = DAOFactory.getAttachmentDAO().getNumberOfAttachments_inPost(postID); 324 DAOFactory.getPostDAO().updateAttachCount(postID, attachCount); 325 326 postBean.setPostAttachCount(attachCount); 328 PostIndexer.scheduleUpdatePostTask(postBean); 329 330 int attachCountInThread = DAOFactory.getAttachmentDAO().getNumberOfAttachments_inThread(threadID); 331 DAOFactory.getThreadDAO().updateThreadAttachCount(threadID, attachCountInThread); 332 333 PostCache.getInstance().clear(); 335 336 request.setAttribute("ForumID", String.valueOf(forumID)); 337 request.setAttribute("ThreadID", String.valueOf(threadID)); 338 request.setAttribute("PostID", String.valueOf(postID)); 339 request.setAttribute("offset", String.valueOf(offset)); 340 request.setAttribute("AttachMore", new Boolean (attachMore)); 341 } 342 343 public void prepareEdit(GenericRequest request) 344 throws ObjectNotFoundException, BadInputException, DatabaseException, AuthenticationException, AssertionException { 345 346 OnlineUser onlineUser = userManager.getOnlineUser(request); 347 MVNForumPermission permission = onlineUser.getPermission(); 348 349 Locale locale = I18nUtil.getLocaleInRequest(request); 350 351 int attachID = GenericParamUtil.getParameterInt(request, "attach"); 353 AttachmentBean attachmentBean = null; 354 try { 355 attachmentBean = DAOFactory.getAttachmentDAO().getAttachment(attachID); 356 } catch (ObjectNotFoundException e) { 357 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.attachmentid_not_exists", new Object [] {new Integer (attachID)}); 358 throw new ObjectNotFoundException(localizedMessage); 359 } 360 361 int postID = attachmentBean.getPostID(); 362 PostBean postBean = null; 363 try { 364 postBean = DAOFactory.getPostDAO().getPost(postID); } catch (ObjectNotFoundException ex) { 366 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.postid_not_exists", new Object [] {new Integer (postID)}); 367 throw new ObjectNotFoundException(localizedMessage); 368 } 369 370 permission.ensureCanEditPost(postBean.getForumID()); 372 373 ForumCache.getInstance().getBean(postBean.getForumID()).ensureNotDisabledForum(); 374 ForumCache.getInstance().getBean(postBean.getForumID()).ensureNotLockedForum(); 375 376 request.setAttribute("AttachmentBean", attachmentBean); 377 request.setAttribute("PostBean", postBean); 378 } 379 380 public void processEdit(GenericRequest request) 381 throws BadInputException, DatabaseException, AuthenticationException, AssertionException, ObjectNotFoundException { 382 383 OnlineUser onlineUser = userManager.getOnlineUser(request); 384 MVNForumPermission permission = onlineUser.getPermission(); 385 Locale locale = I18nUtil.getLocaleInRequest(request); 386 permission.ensureIsAuthenticated(); 388 389 int attachID = GenericParamUtil.getParameterInt(request, "attach"); 391 392 AttachmentBean attachmentBean = DAOFactory.getAttachmentDAO().getAttachment(attachID); 393 int postID = attachmentBean.getPostID(); 394 395 PostBean postBean = null; 396 try { 397 postBean = DAOFactory.getPostDAO().getPost(postID); } catch (ObjectNotFoundException ex) { 399 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.postid_not_exists", new Object [] {new Integer (postID)}); 400 throw new ObjectNotFoundException(localizedMessage); 401 } 402 403 ForumCache.getInstance().getBean(postBean.getForumID()).ensureNotDisabledForum(); 404 ForumCache.getInstance().getBean(postBean.getForumID()).ensureNotLockedForum(); 405 406 permission.ensureCanEditPost(postBean.getForumID()); 408 409 MyUtil.ensureCorrectCurrentPassword(request); 411 int threadID = postBean.getThreadID(); 412 413 String newDesc = GenericParamUtil.getParameter(request, "newdesc"); 415 DAOFactory.getAttachmentDAO().updateAttachDesc(attachID, newDesc); 416 417 request.setAttribute("ThreadID", String.valueOf(threadID)); 418 } 419 420 public void prepareDelete(GenericRequest request) 421 throws ObjectNotFoundException, BadInputException, DatabaseException, AuthenticationException, AssertionException { 422 423 OnlineUser onlineUser = userManager.getOnlineUser(request); 424 MVNForumPermission permission = onlineUser.getPermission(); 425 426 Locale locale = I18nUtil.getLocaleInRequest(request); 427 428 int attachID = GenericParamUtil.getParameterInt(request, "attach"); 430 AttachmentBean attachmentBean = null; 431 try { 432 attachmentBean = DAOFactory.getAttachmentDAO().getAttachment(attachID); 433 } catch (ObjectNotFoundException e) { 434 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.attachmentid_not_exists", new Object [] {new Integer (attachID)}); 435 throw new ObjectNotFoundException(localizedMessage); 436 } 437 438 int postID = attachmentBean.getPostID(); 439 PostBean postBean = null; 440 try { 441 postBean = DAOFactory.getPostDAO().getPost(postID); } catch (ObjectNotFoundException ex) { 443 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.postid_not_exists", new Object [] {new Integer (postID)}); 444 throw new ObjectNotFoundException(localizedMessage); 445 } 446 447 permission.ensureCanDeletePost(postBean.getForumID()); 449 450 ForumCache.getInstance().getBean(postBean.getForumID()).ensureNotDisabledForum(); 451 ForumCache.getInstance().getBean(postBean.getForumID()).ensureNotLockedForum(); 452 453 request.setAttribute("AttachmentBean", attachmentBean); 454 request.setAttribute("PostBean", postBean); 455 } 456 457 public void processDelete(GenericRequest request) 458 throws BadInputException, DatabaseException, AuthenticationException, AssertionException, ObjectNotFoundException { 459 460 OnlineUser onlineUser = userManager.getOnlineUser(request); 461 MVNForumPermission permission = onlineUser.getPermission(); 462 Locale locale = I18nUtil.getLocaleInRequest(request); 463 permission.ensureIsAuthenticated(); 465 466 int attachID = GenericParamUtil.getParameterInt(request, "attach"); 468 469 AttachmentBean attachmentBean = DAOFactory.getAttachmentDAO().getAttachment(attachID); 470 int postID = attachmentBean.getPostID(); 471 472 PostBean postBean = null; 473 try { 474 postBean = DAOFactory.getPostDAO().getPost(postID); } catch (ObjectNotFoundException ex) { 476 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.postid_not_exists", new Object [] {new Integer (postID)}); 477 throw new ObjectNotFoundException(localizedMessage); 478 } 479 480 ForumCache.getInstance().getBean(postBean.getForumID()).ensureNotDisabledForum(); 481 ForumCache.getInstance().getBean(postBean.getForumID()).ensureNotLockedForum(); 482 483 permission.ensureCanDeletePost(postBean.getForumID()); 485 486 MyUtil.ensureCorrectCurrentPassword(request); 488 489 BinaryStorage binaryStorage = ManagerFactory.getBinaryStorage(); 492 try { 493 binaryStorage.deleteData(BinaryStorage.CATEGORY_POST_ATTACHMENT, String.valueOf(attachID), null); 494 } catch (IOException ex) { 495 log.error("Cannot delete file", ex); 496 } 498 499 DAOFactory.getAttachmentDAO().delete(attachID); 501 502 int attachCount = DAOFactory.getAttachmentDAO().getNumberOfAttachments_inPost(postID); 504 DAOFactory.getPostDAO().updateAttachCount(postID, attachCount); 505 506 postBean.setPostAttachCount(attachCount); 508 PostIndexer.scheduleUpdatePostTask(postBean); 509 510 int threadID = postBean.getThreadID(); 511 int attachCountInThread = DAOFactory.getAttachmentDAO().getNumberOfAttachments_inThread(threadID); 512 DAOFactory.getThreadDAO().updateThreadAttachCount(threadID, attachCountInThread); 513 514 PostCache.getInstance().clear(); 516 517 request.setAttribute("ThreadID", String.valueOf(threadID)); 518 } 519 520 524 public void downloadAttachment(HttpServletRequest request, HttpServletResponse response) 525 throws BadInputException, DatabaseException, ObjectNotFoundException, IOException, 526 AuthenticationException, AssertionException { 527 528 Locale locale = I18nUtil.getLocaleInRequest(request); 529 OnlineUser onlineUser = userManager.getOnlineUser(request); 530 MVNForumPermission permission = onlineUser.getPermission(); 531 532 int attachID = ParamUtil.getParameterInt(request, "attach"); 533 AttachmentBean attachBean = null; 534 try { 535 attachBean = DAOFactory.getAttachmentDAO().getAttachment(attachID); 536 } catch (ObjectNotFoundException e) { 537 String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.ObjectNotFoundException.attachmentid_not_exists", new Object [] {new Integer (attachID)}); 538 throw new ObjectNotFoundException(localizedMessage); 539 } 540 541 int postID = attachBean.getPostID(); 542 543 PostBean postBean = DAOFactory.getPostDAO().getPost(postID); 544 int forumID = postBean.getForumID(); 545 ForumCache.getInstance().getBean(forumID).ensureNotDisabledForum(); 546 548 if (MVNForumConfig.getEnableGuestViewImageAttachment() && 549 attachBean.getAttachMimeType().startsWith("image/")) { 550 permission.ensureCanReadPost(forumID); 553 } else { 554 permission.ensureCanGetAttachment(forumID); 556 } 557 558 BinaryStorage binaryStorage = ManagerFactory.getBinaryStorage(); 559 InputStream inputStream = binaryStorage.getInputStream(BinaryStorage.CATEGORY_POST_ATTACHMENT, String.valueOf(attachID), null); 560 561 571 572 DAOFactory.getAttachmentDAO().increaseDownloadCount(attachID); 575 576 OutputStream outputStream = null; 577 try { 578 response.setContentType(attachBean.getAttachMimeType()); 579 response.setHeader("Location", attachBean.getAttachFilename()); 580 581 if (attachBean.getAttachMimeType().startsWith("image/")) { 583 long cacheTime = DateUtil.DAY * 30 / 1000; response.setHeader("Cache-Control", "max-age=" + cacheTime); 585 } 586 response.setHeader("Content-Disposition", "attachment; filename=" + attachBean.getAttachFilename()); 588 589 outputStream = response.getOutputStream(); 591 try { 593 IOUtils.copy(inputStream, outputStream); 595 } catch (IOException ex) { 596 log.error("Error while trying to send attachment file from server: attachID = " + attachID + ".", ex); 598 } 599 601 outputStream.flush(); 602 outputStream.close(); 603 outputStream = null; } catch (IOException ex) { 605 throw ex; 606 } finally { 607 if (inputStream != null) { 608 try { 609 inputStream.close(); 610 } catch (IOException ex) { } 611 } 612 if (outputStream != null) { 613 try { 614 outputStream.close(); 615 } catch (IOException ex) { } 616 } 617 } 618 } 619 620 625 static void deleteAttachments_inPost(int postID) throws DatabaseException { 626 627 BinaryStorage binaryStorage = ManagerFactory.getBinaryStorage(); 628 629 Collection attachmentBeans = DAOFactory.getAttachmentDAO().getAttachments_inPost(postID); 631 DAOFactory.getAttachmentDAO().delete_inPost(postID); 632 633 for (Iterator iter = attachmentBeans.iterator(); iter.hasNext(); ) { 635 AttachmentBean attachmentBean = (AttachmentBean)iter.next(); 636 int attachID = attachmentBean.getAttachID(); 637 try { 639 binaryStorage.deleteData(BinaryStorage.CATEGORY_POST_ATTACHMENT, String.valueOf(attachID), null); 640 } catch (IOException ex) { 641 log.error("Cannot delete file", ex); 642 } 644 } 645 } 646 647 652 static void deleteAttachments_inThread(int threadID) throws DatabaseException { 653 654 BinaryStorage binaryStorage = ManagerFactory.getBinaryStorage(); 655 656 Collection attachmentBeans = DAOFactory.getAttachmentDAO().getAttachments_inThread(threadID); 658 659 for (Iterator iter = attachmentBeans.iterator(); iter.hasNext(); ) { 661 AttachmentBean attachmentBean = (AttachmentBean)iter.next(); 662 int attachID = attachmentBean.getAttachID(); 663 try { 665 binaryStorage.deleteData(BinaryStorage.CATEGORY_POST_ATTACHMENT, String.valueOf(attachID), null); 666 } catch (IOException ex) { 667 log.error("Cannot delete file", ex); 668 } 670 try { 671 DAOFactory.getAttachmentDAO().delete(attachID); 672 } catch (Exception ex) { 673 log.warn("Cannot delete attachment (id = " + attachID + ") in database", ex); 674 } 675 } 676 } 677 678 } 679 | Popular Tags |