diff --git a/app/src/main/java/org/apache/roller/weblogger/business/BookmarkManager.java b/app/src/main/java/org/apache/roller/weblogger/business/BookmarkManager.java index e3cddf21bd..eef43d2c32 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/BookmarkManager.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/BookmarkManager.java @@ -63,8 +63,21 @@ public interface BookmarkManager { * @throws WebloggerException If there is a problem. */ WeblogBookmarkFolder getFolder(String id) throws WebloggerException; - - + + /** + * Get a folder by id, restricted to the given weblog. + * + *

Named differently from {@link #getFolder(Weblog, String)}, which + * looks a folder up by name, because the two would otherwise have the + * same erasure. + * + * @return the folder, or null if no folder with that id belongs to the + * given weblog. A folder that exists but belongs to another weblog + * is reported the same way as one that does not exist. + */ + WeblogBookmarkFolder getFolderById(Weblog weblog, String id) throws WebloggerException; + + /** * Get all folders for a weblog. * @@ -123,8 +136,18 @@ WeblogBookmarkFolder getFolder(Weblog weblog, String name) * @throws WebloggerException If there is a problem. */ WeblogBookmark getBookmark(String id) throws WebloggerException; - - + + /** + * Get a bookmark by id, restricted to the given weblog. + * + * @return the bookmark, or null if no bookmark with that id belongs to a + * folder of the given weblog. A bookmark that exists but belongs + * to another weblog is reported the same way as one that does not + * exist. + */ + WeblogBookmark getBookmark(Weblog weblog, String id) throws WebloggerException; + + /** * Lookup all Bookmarks in a folder, optionally search recursively. * diff --git a/app/src/main/java/org/apache/roller/weblogger/business/MediaFileManager.java b/app/src/main/java/org/apache/roller/weblogger/business/MediaFileManager.java index e345dddfad..f8a3611328 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/MediaFileManager.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/MediaFileManager.java @@ -76,6 +76,15 @@ void updateMediaFile(Weblog website, MediaFile mf, InputStream fis) */ MediaFile getMediaFile(String id) throws WebloggerException; + /** + * Get media file metadata by file id, restricted to the given weblog. + * + * @return the media file, or null if no media file with that id belongs to + * the given weblog. A media file that exists but belongs to another + * weblog is reported the same way as one that does not exist. + */ + MediaFile getMediaFile(Weblog weblog, String id) throws WebloggerException; + /** * Get media file metadata optionally including the actual content */ @@ -118,6 +127,16 @@ MediaFileDirectory createMediaFileDirectory(Weblog weblog, MediaFileDirectory getMediaFileDirectory(String id) throws WebloggerException; + /** + * Get media file directory by id, restricted to the given weblog. + * + * @return the directory, or null if no directory with that id belongs to + * the given weblog. A directory that exists but belongs to another + * weblog is reported the same way as one that does not exist. + */ + MediaFileDirectory getMediaFileDirectory(Weblog weblog, String id) + throws WebloggerException; + /** * Get media file directory by its path */ diff --git a/app/src/main/java/org/apache/roller/weblogger/business/WeblogEntryManager.java b/app/src/main/java/org/apache/roller/weblogger/business/WeblogEntryManager.java index ca95a0dc89..3ed56d16b6 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/WeblogEntryManager.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/WeblogEntryManager.java @@ -53,9 +53,18 @@ public interface WeblogEntryManager { * Get weblog entry by id. */ WeblogEntry getWeblogEntry(String id) throws WebloggerException; - - /** - * Get weblog entry by anchor. + + /** + * Get weblog entry by id, restricted to the given weblog. + * + * @return the entry, or null if no entry with that id belongs to the given + * weblog. An entry that exists but belongs to another weblog is + * reported the same way as one that does not exist. + */ + WeblogEntry getWeblogEntry(Weblog weblog, String id) throws WebloggerException; + + /** + * Get weblog entry by anchor. */ WeblogEntry getWeblogEntryByAnchor(Weblog website, String anchor) throws WebloggerException; @@ -154,8 +163,17 @@ void removeWeblogEntryAttribute(String name,WeblogEntry entry) * Get category by id. */ WeblogCategory getWeblogCategory(String id) throws WebloggerException; - - + + /** + * Get category by id, restricted to the given weblog. + * + * @return the category, or null if no category with that id belongs to the + * given weblog. A category that exists but belongs to another + * weblog is reported the same way as one that does not exist. + */ + WeblogCategory getWeblogCategory(Weblog weblog, String id) throws WebloggerException; + + /** * Recategorize all entries with one category to another. */ @@ -190,7 +208,18 @@ List getWeblogCategories(Weblog website) * Get comment by id. */ WeblogEntryComment getComment(String id) throws WebloggerException; - + + /** + * Get comment by id, restricted to the given weblog. + * + * @return the comment, or null if no comment with that id belongs to an + * entry of the given weblog. A comment that exists but belongs to + * another weblog is reported the same way as one that does not + * exist. + */ + WeblogEntryComment getComment(Weblog weblog, String id) throws WebloggerException; + + /** * Generic comments query method. * @param csc CommentSearchCriteria object with fields indicating search criteria diff --git a/app/src/main/java/org/apache/roller/weblogger/business/WeblogManager.java b/app/src/main/java/org/apache/roller/weblogger/business/WeblogManager.java index 1df391a7c6..2b65f371ba 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/WeblogManager.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/WeblogManager.java @@ -155,11 +155,28 @@ List getWeblogsByLetter(char letter, int offset, int length) /** - * Get a custom template by its id. + * Get a custom template by its id, without restricting the result to any + * weblog. + * + *

Callers that act on behalf of a single weblog must use + * {@link #getTemplate(Weblog, String)} instead, so that a template id + * belonging to another weblog cannot resolve. This unscoped form is for + * callers that legitimately have no weblog in context, such as the + * Velocity resource loader. */ WeblogTemplate getTemplate(String id) throws WebloggerException; - - + + + /** + * Get a custom template by its id, restricted to the given weblog. + * + * @return the template, or null if no template with that id belongs to + * the given weblog. A template that exists but belongs to another + * weblog is reported the same way as one that does not exist. + */ + WeblogTemplate getTemplate(Weblog weblog, String id) throws WebloggerException; + + /** * Get a custom template by the action it supports. */ diff --git a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPABookmarkManagerImpl.java b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPABookmarkManagerImpl.java index 5b4224e09c..6284302832 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPABookmarkManagerImpl.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPABookmarkManagerImpl.java @@ -88,6 +88,50 @@ public WeblogBookmark getBookmark(String id) throws WebloggerException { return (WeblogBookmark) strategy.load(WeblogBookmark.class, id); } + @Override + public WeblogBookmark getBookmark(Weblog weblog, String id) throws WebloggerException { + + if (weblog == null) { + throw new WebloggerException("weblog is null"); + } + + if (id == null) { + return null; + } + + TypedQuery q = strategy.getNamedQuery( + "WeblogBookmark.getByWebsite&Id", WeblogBookmark.class); + q.setParameter(1, weblog); + q.setParameter(2, id); + try { + return q.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + + @Override + public WeblogBookmarkFolder getFolderById(Weblog weblog, String id) throws WebloggerException { + + if (weblog == null) { + throw new WebloggerException("weblog is null"); + } + + if (id == null) { + return null; + } + + TypedQuery q = strategy.getNamedQuery( + "WeblogBookmarkFolder.getByWebsite&Id", WeblogBookmarkFolder.class); + q.setParameter(1, weblog); + q.setParameter(2, id); + try { + return q.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + @Override public void removeBookmark(WeblogBookmark bookmark) throws WebloggerException { Weblog weblog = bookmark.getWebsite(); diff --git a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAMediaFileManagerImpl.java b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAMediaFileManagerImpl.java index 2a4071cebd..85a19cd44f 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAMediaFileManagerImpl.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAMediaFileManagerImpl.java @@ -346,6 +346,51 @@ public MediaFile getMediaFile(String id) throws WebloggerException { return getMediaFile(id, false); } + @Override + public MediaFile getMediaFile(Weblog weblog, String id) throws WebloggerException { + + if (weblog == null) { + throw new WebloggerException("weblog is null"); + } + + if (id == null) { + return null; + } + + TypedQuery q = strategy.getNamedQuery( + "MediaFile.getByWeblogAndId", MediaFile.class); + q.setParameter(1, weblog); + q.setParameter(2, id); + try { + return q.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + + @Override + public MediaFileDirectory getMediaFileDirectory(Weblog weblog, String id) + throws WebloggerException { + + if (weblog == null) { + throw new WebloggerException("weblog is null"); + } + + if (id == null) { + return null; + } + + TypedQuery q = strategy.getNamedQuery( + "MediaFileDirectory.getByWeblogAndId", MediaFileDirectory.class); + q.setParameter(1, weblog); + q.setParameter(2, id); + try { + return q.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + /** * {@inheritDoc} */ diff --git a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogEntryManagerImpl.java b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogEntryManagerImpl.java index b9bdf1f106..7a84bb5d33 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogEntryManagerImpl.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogEntryManagerImpl.java @@ -762,7 +762,82 @@ public WeblogEntryComment getComment(String id) throws WebloggerException { public WeblogEntry getWeblogEntry(String id) throws WebloggerException { return (WeblogEntry)strategy.load(WeblogEntry.class, id); } - + + /** + * @inheritDoc + */ + @Override + public WeblogEntry getWeblogEntry(Weblog weblog, String id) throws WebloggerException { + + if (weblog == null) { + throw new WebloggerException("weblog is null"); + } + + if (id == null) { + return null; + } + + TypedQuery q = strategy.getNamedQuery( + "WeblogEntry.getByWebsite&Id", WeblogEntry.class); + q.setParameter(1, weblog); + q.setParameter(2, id); + try { + return q.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + + /** + * @inheritDoc + */ + @Override + public WeblogCategory getWeblogCategory(Weblog weblog, String id) throws WebloggerException { + + if (weblog == null) { + throw new WebloggerException("weblog is null"); + } + + if (id == null) { + return null; + } + + TypedQuery q = strategy.getNamedQuery( + "WeblogCategory.getByWeblog&Id", WeblogCategory.class); + q.setParameter(1, weblog); + q.setParameter(2, id); + try { + return q.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + + /** + * @inheritDoc + */ + @Override + public WeblogEntryComment getComment(Weblog weblog, String id) throws WebloggerException { + + if (weblog == null) { + throw new WebloggerException("weblog is null"); + } + + if (id == null) { + return null; + } + + TypedQuery q = strategy.getNamedQuery( + "WeblogEntryComment.getByWebsite&Id", WeblogEntryComment.class); + q.setParameter(1, weblog); + q.setParameter(2, id); + try { + return q.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + /** * @inheritDoc */ diff --git a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogManagerImpl.java b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogManagerImpl.java index 8cb1f96727..d4304b4587 100644 --- a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogManagerImpl.java +++ b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogManagerImpl.java @@ -514,9 +514,32 @@ public WeblogTemplate getTemplate(String id) throws WebloggerException { if (id != null && id.endsWith(".vm")) { return null; } - + return (WeblogTemplate)this.strategy.load(WeblogTemplate.class,id); } + + @Override + public WeblogTemplate getTemplate(Weblog weblog, String id) throws WebloggerException { + + if (weblog == null) { + throw new WebloggerException("weblog is null"); + } + + // Don't hit database for templates stored on disk + if (id == null || id.endsWith(".vm")) { + return null; + } + + TypedQuery query = strategy.getNamedQuery("WeblogTemplate.getByWeblog&Id", + WeblogTemplate.class); + query.setParameter(1, weblog); + query.setParameter(2, id); + try { + return query.getSingleResult(); + } catch (NoResultException e) { + return null; + } + } /** * Use JPA directly because Weblogger's Query API does too much allocation. diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarkEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarkEdit.java index ebb068c72b..0bc9387858 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarkEdit.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarkEdit.java @@ -65,7 +65,7 @@ public void myPrepare() { BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager(); try { if (!StringUtils.isEmpty(getFolderId())) { - bookmark.setFolder(bmgr.getFolder(getFolderId())); + bookmark.setFolder(bmgr.getFolderById(getActionWeblog(), getFolderId())); } } catch (WebloggerException ex) { addError("generic.error.check.logs"); @@ -75,7 +75,7 @@ public void myPrepare() { // existing bookmark, retrieve its info from DB try { BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager(); - bookmark = bmgr.getBookmark(getBean().getId()); + bookmark = bmgr.getBookmark(getActionWeblog(), getBean().getId()); } catch (WebloggerException ex) { addError("generic.error.check.logs"); log.error("Error looking up bookmark" + getBean().getId(), ex); @@ -88,6 +88,10 @@ public void myPrepare() { @Override public String execute() { if (!isAdd()) { + if (bookmark == null) { + addError("bookmarkForm.notFound"); + return ERROR; + } // load bean with database values during initial load getBean().copyFrom(getBookmark()); } @@ -96,6 +100,10 @@ public String execute() { public String save() { + if (bookmark == null || bookmark.getFolder() == null) { + addError("bookmarkForm.notFound"); + return ERROR; + } myValidate(); if (!hasActionErrors()) { @@ -118,6 +126,10 @@ public String save() { } public void myValidate() { + if (bookmark == null || bookmark.getFolder() == null) { + addError("bookmarkForm.notFound"); + return; + } // if name new or changed, check new name doesn't already exist if ((isAdd() || !getBean().getName().equals(bookmark.getName())) && bookmark.getFolder().hasBookmarkOfName(getBean().getName())) { diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Bookmarks.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Bookmarks.java index 60c8aa8fb0..df499162ee 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Bookmarks.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Bookmarks.java @@ -72,7 +72,7 @@ public void myPrepare() { try { BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager(); if (!StringUtils.isEmpty(getFolderId())) { - setFolder(bmgr.getFolder(getFolderId())); + setFolder(bmgr.getFolderById(getActionWeblog(), getFolderId())); } else { setFolder(bmgr.getDefaultFolder(getActionWeblog())); if (getFolder() != null) { @@ -134,7 +134,7 @@ public String delete() { if (log.isDebugEnabled()) { log.debug("Deleting bookmark - " + bookmarks[j]); } - bookmark = bmgr.getBookmark(bookmarks[j]); + bookmark = bmgr.getBookmark(getActionWeblog(), bookmarks[j]); if (bookmark != null) { bmgr.removeBookmark(bookmark); } @@ -160,7 +160,7 @@ public String deleteFolder() { try { BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager(); - WeblogBookmarkFolder fd = bmgr.getFolder(getFolderId()); + WeblogBookmarkFolder fd = bmgr.getFolderById(getActionWeblog(), getFolderId()); if (fd != null) { @@ -203,7 +203,7 @@ public String view() { try { BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager(); if (!StringUtils.isEmpty(viewFolderId)) { - setFolder(bmgr.getFolder(viewFolderId)); + setFolder(bmgr.getFolderById(getActionWeblog(), viewFolderId)); setFolderId(viewFolderId); } } catch (WebloggerException ex) { @@ -225,12 +225,25 @@ public String move() { } // Move bookmarks to new parent folder. - WeblogBookmarkFolder newFolder = bmgr.getFolder(getTargetFolderId()); + WeblogBookmarkFolder newFolder = bmgr.getFolderById(getActionWeblog(), getTargetFolderId()); String bookmarks[] = getSelectedBookmarks(); + if (newFolder == null) { + addError("bookmarksForm.error.move"); + return execute(); + } + if (null != bookmarks && bookmarks.length > 0) { - for (int j = 0; j < bookmarks.length; j++) { - WeblogBookmark bd = bmgr.getBookmark(bookmarks[j]); + List bookmarksToMove = new ArrayList<>(); + for (String bookmarkId : bookmarks) { + WeblogBookmark bd = bmgr.getBookmark(getActionWeblog(), bookmarkId); + if (bd == null) { + addError("bookmarksForm.error.move"); + return execute(); + } + bookmarksToMove.add(bd); + } + for (WeblogBookmark bd : bookmarksToMove) { newFolder.addBookmark(bd); bd.setFolder(newFolder); bmgr.saveBookmark(bd); diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/CategoryEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/CategoryEdit.java index a7cb24b8ce..f12f6abf68 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/CategoryEdit.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/CategoryEdit.java @@ -74,7 +74,7 @@ public void myPrepare() { } else { try { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); - category = wmgr.getWeblogCategory(getBean().getId()); + category = wmgr.getWeblogCategory(getActionWeblog(), getBean().getId()); } catch (WebloggerException ex) { log.error("Error looking up category", ex); } @@ -89,6 +89,10 @@ public void myPrepare() { @Override public String execute() { if (!isAdd()) { + if (category == null) { + addError("categoryForm.notFound"); + return ERROR; + } // make sure bean is properly loaded from pojo data getBean().copyFrom(category); } @@ -103,6 +107,10 @@ private boolean isAdd() { * Save new category. */ public String save() { + if (!isAdd() && category == null) { + addError("categoryForm.notFound"); + return ERROR; + } myValidate(); if(!hasActionErrors()) { @@ -138,6 +146,10 @@ public String save() { } public void myValidate() { + if (!isAdd() && category == null) { + addError("categoryForm.notFound"); + return; + } if (bean.getName() == null || !bean.getName().equals(StringEscapeUtils.escapeHtml4(bean.getName()))) { addError("categoryForm.error.invalidName"); } else if ( isAdd() ) { diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/CategoryRemove.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/CategoryRemove.java index 1c823b7ea1..0dbd8dc681 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/CategoryRemove.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/CategoryRemove.java @@ -73,7 +73,7 @@ public void myPrepare() { try { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); if(!StringUtils.isEmpty(getRemoveId())) { - setCategory(wmgr.getWeblogCategory(getRemoveId())); + setCategory(wmgr.getWeblogCategory(getActionWeblog(), getRemoveId())); } } catch (WebloggerException ex) { log.error("Error looking up category", ex); @@ -112,7 +112,11 @@ public String remove() { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); if (getTargetCategoryId() != null) { - WeblogCategory target = wmgr.getWeblogCategory(getTargetCategoryId()); + WeblogCategory target = wmgr.getWeblogCategory(getActionWeblog(), getTargetCategoryId()); + if (target == null) { + addError("categoryForm.notFound"); + return execute(); + } wmgr.moveWeblogCategoryContents(getCategory(), target); WebloggerFactory.getWeblogger().flush(); } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Comments.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Comments.java index 7ccd7d4a67..08699cd552 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Comments.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Comments.java @@ -77,6 +77,9 @@ public class Comments extends UIAction { // entry associated with comments or null if none private WeblogEntry queryEntry = null; + // distinguishes an unresolved submitted id from an intentionally empty filter + private boolean queryEntryMissing = false; + // indicates number of comments that would be deleted by bulk removal // a non-zero value here indicates bulk removal is a valid option private int bulkDeleteCount = 0; @@ -100,9 +103,10 @@ public void loadComments() { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger() .getWeblogEntryManager(); - // lookup weblog entry if necessary - if (!StringUtils.isEmpty(getBean().getEntryId())) { - setQueryEntry(wmgr.getWeblogEntry(getBean().getEntryId())); + if (!resolveQueryEntry(wmgr)) { + setPager(new CommentsPager(buildBaseUrl(), getBean().getPage(), + comments, false)); + return; } CommentSearchCriteria csc = getCommentSearchCriteria(); @@ -182,6 +186,10 @@ public String query() { // load bean data using comments list getBean().loadCheckboxes(getPager().getItems()); + if (queryEntryMissing) { + return LIST; + } + try { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); @@ -221,6 +229,10 @@ public String delete() { try { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + if (!resolveQueryEntry(wmgr)) { + return execute(); + } + // if search is enabled, we will need to re-index all entries with // comments that have been deleted, so build a list of those entries Set reindexEntries = new HashSet<>(); @@ -234,7 +246,7 @@ public String delete() { } } - int deleted = wmgr.removeMatchingComments(getActionWeblog(), null, + int deleted = wmgr.removeMatchingComments(getActionWeblog(), getQueryEntry(), getBean().getSearchString(), getBean().getStartDate(), getBean().getEndDate(), getBean().getStatus()); @@ -262,6 +274,28 @@ public String delete() { return LIST; } + private boolean resolveQueryEntry(WeblogEntryManager wmgr) + throws WebloggerException { + if (StringUtils.isEmpty(getBean().getEntryId())) { + queryEntryMissing = false; + setQueryEntry(null); + return true; + } + if (queryEntryMissing) { + return false; + } + if (getQueryEntry() == null) { + setQueryEntry(wmgr.getWeblogEntry( + getActionWeblog(), getBean().getEntryId())); + } + if (getQueryEntry() == null) { + queryEntryMissing = true; + addError("weblogEntry.notFound"); + return false; + } + return true; + } + /** * Update a list of comments. */ @@ -284,11 +318,11 @@ public String update() { WeblogEntryComment deleteComment = null; for (String deleteId : deletes) { - deleteComment = wmgr.getComment(deleteId); + deleteComment = wmgr.getComment(getActionWeblog(), deleteId); - // make sure comment is tied to action weblog - if (getActionWeblog().equals( - deleteComment.getWeblogEntry().getWebsite())) { + // scoped lookup yields null for ids that do not belong to + // the action weblog, and for ids that do not exist at all + if (deleteComment != null) { flushList.add(deleteComment); reindexList.add(deleteComment.getWeblogEntry()); wmgr.removeComment(deleteComment); @@ -315,11 +349,11 @@ public String update() { continue; } - WeblogEntryComment comment = wmgr.getComment(ids[i]); + WeblogEntryComment comment = wmgr.getComment(getActionWeblog(), ids[i]); - // make sure comment is tied to action weblog - if (getActionWeblog().equals( - comment.getWeblogEntry().getWebsite())) { + // scoped lookup yields null for ids that do not belong to the + // action weblog, and for ids that do not exist at all + if (comment != null) { // comment approvals and mark/unmark spam if (approvedIds.contains(ids[i])) { // if a comment was previously PENDING then this is diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryAddWithMediaFile.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryAddWithMediaFile.java index 40c67e39b5..600d6276d1 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryAddWithMediaFile.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryAddWithMediaFile.java @@ -70,9 +70,13 @@ public String execute() { StringBuilder sb = new StringBuilder(); if (selectedImages != null) { - for (String image : selectedImages) { - MediaFile mediaFile = manager.getMediaFile(image); - String link; + for (String image : selectedImages) { + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), image); + if (mediaFile == null) { + addError("MediaFile.error.view"); + return ERROR; + } + String link; if (mediaFile.isImageFile()) { link = "

" + mediaFile.getName() + "

"; @@ -104,10 +108,12 @@ public String execute() { bean.setText(sb.toString()); - } catch (Exception e) { - log.error("Error while constructing media file link for new entry", e); - } - return SUCCESS; + } catch (Exception e) { + log.error("Error while constructing media file link for new entry", e); + addError("MediaFile.error.view"); + return ERROR; + } + return SUCCESS; } public EntryBean getBean() { diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryEdit.java index a12dc18fff..21e5473611 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryEdit.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryEdit.java @@ -104,7 +104,7 @@ public void myPrepare() { // retrieve from DB WeblogEntry based on ID WeblogEntryManager wmgr = WebloggerFactory.getWeblogger() .getWeblogEntryManager(); - setEntry(wmgr.getWeblogEntry(getBean().getId())); + setEntry(wmgr.getWeblogEntry(getActionWeblog(), getBean().getId())); } catch (WebloggerException ex) { log.error( "Error looking up entry by id - " + getBean().getId(), @@ -122,6 +122,9 @@ public void myPrepare() { @Override public String execute() { if (getActionName().equals("entryEdit")) { + if (!requireEntry()) { + return ERROR; + } // load bean with pojo data getBean().copyFrom(getEntry(), getLocale()); } else { @@ -146,6 +149,9 @@ public String execute() { * @return String The result of the action. */ public String saveDraft() { + if (!requireEntry()) { + return INPUT; + } getBean().setStatus(PubStatus.DRAFT.name()); if (entry.isPublished()) { // entry reverted from published to non-viewable draft @@ -161,6 +167,9 @@ public String saveDraft() { * @return String The result of the action. */ public String publish() { + if (!requireEntry()) { + return INPUT; + } if (getActionWeblog().hasUserPermission( getAuthenticatedUser(), WeblogPermission.POST)) { Timestamp pubTime = getBean().getPubTime(getLocale(), @@ -191,6 +200,9 @@ public String publish() { * @return String The result of the action. */ private String save() { + if (!requireEntry()) { + return INPUT; + } if (!hasActionErrors()) { try { WeblogEntryManager weblogEntryManager = WebloggerFactory.getWeblogger() @@ -327,8 +339,19 @@ public void setEntry(WeblogEntry entry) { this.entry = entry; } + private boolean requireEntry() { + if (entry == null) { + addError("weblogEntry.notFound"); + return false; + } + return true; + } + @SkipValidation public String firstSave() { + if (!requireEntry()) { + return ERROR; + } addStatusMessage(getEntry().getStatus()); return execute(); } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryRemove.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryRemove.java index 5555f70423..0db70756e1 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryRemove.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/EntryRemove.java @@ -59,7 +59,7 @@ public void myPrepare() { try { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger() .getWeblogEntryManager(); - setRemoveEntry(wmgr.getWeblogEntry(getRemoveId())); + setRemoveEntry(wmgr.getWeblogEntry(getActionWeblog(), getRemoveId())); } catch (WebloggerException ex) { log.error("Error looking up entry by id - " + getRemoveId(), ex); } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/FolderEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/FolderEdit.java index 94de22d1fc..9df65972f1 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/FolderEdit.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/FolderEdit.java @@ -74,7 +74,7 @@ public void myPrepare() { // retrieve existing folder data from DB try { BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager(); - folder = bmgr.getFolder(getBean().getId()); + folder = bmgr.getFolderById(getActionWeblog(), getBean().getId()); } catch (WebloggerException ex) { log.error("Error looking up folder", ex); } @@ -93,6 +93,10 @@ public void setServletResponse(HttpServletResponse httpServletResponse) { @Override public String execute() { if (!isAdd()) { + if (folder == null) { + addError("folderForm.notFound"); + return ERROR; + } // load bean with database values during initial load getBean().copyFrom(folder); } @@ -103,6 +107,10 @@ public String execute() { * Save updated folder data. */ public String save() { + if (!isAdd() && folder == null) { + addError("folderForm.notFound"); + return ERROR; + } myValidate(); if(!hasActionErrors()) { @@ -144,6 +152,10 @@ public String save() { } public void myValidate() { + if (folder == null) { + addError("folderForm.notFound"); + return; + } // make sure new name is not a duplicate of an existing folder if ( isAdd() || !getBean().getName().equals(folder.getName()) ) { if (folder.getWeblog().hasBookmarkFolder(getBean().getName())) { diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java index 881dad7549..ca9aa66919 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java @@ -81,7 +81,7 @@ public void myPrepare() { MediaFileManager mgr = WebloggerFactory.getWeblogger() .getMediaFileManager(); if (!StringUtils.isEmpty(bean.getDirectoryId())) { - setDirectory(mgr.getMediaFileDirectory(bean.getDirectoryId())); + setDirectory(mgr.getMediaFileDirectory(getActionWeblog(), bean.getDirectoryId())); } else if (StringUtils.isNotEmpty(directoryName)) { setDirectory(mgr.getMediaFileDirectoryByName(getActionWeblog(), @@ -95,6 +95,10 @@ public void myPrepare() { } setDirectory(root); } + if (getDirectory() == null) { + addError("mediaFile.directory.notFound"); + return; + } directoryName = getDirectory().getName(); bean.setDirectoryId(getDirectory().getId()); diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileBase.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileBase.java index 38c4ef9edf..e48c50ec6b 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileBase.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileBase.java @@ -60,10 +60,14 @@ protected void doDeleteMediaFile() { try { log.debug("Processing delete of file id - " + this.mediaFileId); - MediaFileManager manager = WebloggerFactory.getWeblogger() - .getMediaFileManager(); - MediaFile mediaFile = manager.getMediaFile(this.mediaFileId); - manager.removeMediaFile(getActionWeblog(), mediaFile); + MediaFileManager manager = WebloggerFactory.getWeblogger() + .getMediaFileManager(); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), this.mediaFileId); + if (mediaFile == null) { + addError("mediaFile.delete.error", this.mediaFileId); + return; + } + manager.removeMediaFile(getActionWeblog(), mediaFile); // flush changes WebloggerFactory.getWeblogger().flush(); WebloggerFactory.getWeblogger().release(); @@ -82,10 +86,14 @@ protected void doIncludeMediaFileInGallery() { try { log.debug("Processing include-in-gallery of file id - " + this.mediaFileId); - MediaFileManager manager = WebloggerFactory.getWeblogger() - .getMediaFileManager(); - MediaFile mediaFile = manager.getMediaFile(this.mediaFileId); - mediaFile.setSharedForGallery(true); + MediaFileManager manager = WebloggerFactory.getWeblogger() + .getMediaFileManager(); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), this.mediaFileId); + if (mediaFile == null) { + addError("mediaFile.includeInGallery.error", this.mediaFileId); + return; + } + mediaFile.setSharedForGallery(true); manager.updateMediaFile(getActionWeblog(), mediaFile); // flush changes WebloggerFactory.getWeblogger().flush(); @@ -111,7 +119,7 @@ protected void doDeleteSelected() { + " media files."); for (String fileId : fileIds) { log.debug("Deleting media file - " + fileId); - MediaFile mediaFile = manager.getMediaFile(fileId); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), fileId); if (mediaFile != null) { manager.removeMediaFile(getActionWeblog(), mediaFile); } @@ -146,16 +154,28 @@ void doMoveSelected() { if (fileIds != null && fileIds.length > 0) { log.debug("Processing move of " + fileIds.length + " media files."); - MediaFileDirectory targetDirectory = manager - .getMediaFileDirectory(this.selectedDirectory); - for (String fileId : fileIds) { - log.debug("Moving media file - " + fileId - + " to directory - " + this.selectedDirectory); - MediaFile mediaFile = manager.getMediaFile(fileId); - if (mediaFile != null && !mediaFile.getDirectory().getId().equals(targetDirectory.getId())) { - manager.moveMediaFile(mediaFile, targetDirectory); - movedFiles++; - } + MediaFileDirectory targetDirectory = manager + .getMediaFileDirectory(getActionWeblog(), this.selectedDirectory); + if (targetDirectory == null) { + addError("mediaFile.move.errors"); + return; + } + List filesToMove = new ArrayList<>(); + for (String fileId : fileIds) { + log.debug("Moving media file - " + fileId + + " to directory - " + this.selectedDirectory); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), fileId); + if (mediaFile == null) { + addError("mediaFile.move.errors"); + return; + } + filesToMove.add(mediaFile); + } + for (MediaFile mediaFile : filesToMove) { + if (!mediaFile.getDirectory().getId().equals(targetDirectory.getId())) { + manager.moveMediaFile(mediaFile, targetDirectory); + movedFiles++; + } } } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileEdit.java index 76ff2dbb7c..885d8cd1ca 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileEdit.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileEdit.java @@ -67,7 +67,7 @@ public void myPrepare() { try { MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager(); if (!StringUtils.isEmpty(bean.getDirectoryId())) { - setDirectory(mgr.getMediaFileDirectory(bean.getDirectoryId())); + setDirectory(mgr.getMediaFileDirectory(getActionWeblog(), bean.getDirectoryId())); } } catch (WebloggerException ex) { log.error("Error looking up media file directory", ex); @@ -95,7 +95,7 @@ public void myValidate() { public String execute() { MediaFileManager manager = WebloggerFactory.getWeblogger().getMediaFileManager(); try { - MediaFile mediaFile = manager.getMediaFile(getMediaFileId()); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), getMediaFileId()); this.bean.copyFrom(mediaFile); } catch (FileIOException ex) { @@ -119,7 +119,7 @@ public String save() { if (!hasActionErrors()) { MediaFileManager manager = WebloggerFactory.getWeblogger().getMediaFileManager(); try { - MediaFile mediaFile = manager.getMediaFile(getMediaFileId()); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), getMediaFileId()); bean.copyTo(mediaFile); if (uploadedFile != null) { diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageChooser.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageChooser.java index 335255bd4b..c16f0a78eb 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageChooser.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageChooser.java @@ -83,7 +83,7 @@ public String execute() { MediaFileDirectory directory; if (this.directoryId != null) { - directory = manager.getMediaFileDirectory(this.directoryId); + directory = manager.getMediaFileDirectory(getActionWeblog(), this.directoryId); } else if (this.directoryName != null) { directory = manager.getMediaFileDirectoryByName(getActionWeblog(), this.directoryName); this.directoryId = directory.getId(); diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageDim.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageDim.java index 67b91e5b2e..8da76d487e 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageDim.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageDim.java @@ -50,7 +50,11 @@ public MediaFileImageDim() { public String execute() { try { MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager(); - MediaFile mediaFile = mgr.getMediaFile(getMediaFileId()); + MediaFile mediaFile = mgr.getMediaFile(getActionWeblog(), getMediaFileId()); + if (mediaFile == null) { + addError("MediaFile.error.view"); + return ERROR; + } bean.copyFrom(mediaFile); } catch (WebloggerException ex) { log.error("Error looking up media file directory", ex); diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileView.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileView.java index 79310ef539..32b83dc340 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileView.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileView.java @@ -199,7 +199,7 @@ public String execute() { try { MediaFileDirectory directory; if (StringUtils.isNotEmpty(this.directoryId)) { - directory = manager.getMediaFileDirectory(this.directoryId); + directory = manager.getMediaFileDirectory(getActionWeblog(), this.directoryId); } else if (StringUtils.isNotEmpty(this.directoryName)) { directory = manager.getMediaFileDirectoryByName( @@ -254,7 +254,7 @@ public String view() { .getMediaFileManager(); if (!StringUtils.isEmpty(viewDirectoryId)) { setDirectoryId(viewDirectoryId); - setCurrentDirectory(manager.getMediaFileDirectory(viewDirectoryId)); + setCurrentDirectory(manager.getMediaFileDirectory(getActionWeblog(), viewDirectoryId)); } } catch (WebloggerException ex) { log.error("Error looking up directory", ex); @@ -326,7 +326,7 @@ public String deleteFolder() { log.debug("Deleting media file folder - " + directoryId + " (" + directoryName + ")"); MediaFileDirectory mediaFileDir = manager - .getMediaFileDirectory(directoryId); + .getMediaFileDirectory(getActionWeblog(), directoryId); manager.removeMediaFileDirectory(mediaFileDir); refreshAllDirectories(); WebloggerFactory.getWeblogger().getWeblogManager() diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java index dd1261dc90..a1f95cebb0 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java @@ -58,7 +58,8 @@ public TemplateEdit() { @Override public void myPrepare() { try { - setTemplate(WebloggerFactory.getWeblogger().getWeblogManager().getTemplate(getBean().getId())); + setTemplate(WebloggerFactory.getWeblogger().getWeblogManager() + .getTemplate(getActionWeblog(), getBean().getId())); } catch (WebloggerException ex) { log.error("Error looking up template - " + getBean().getId(), ex); } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Templates.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Templates.java index 4cee7dae51..157e8f4092 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Templates.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Templates.java @@ -210,7 +210,7 @@ public String remove() { WeblogTemplate template = null; try { - template = WebloggerFactory.getWeblogger().getWeblogManager().getTemplate(getRemoveId()); + template = WebloggerFactory.getWeblogger().getWeblogManager().getTemplate(getActionWeblog(), getRemoveId()); } catch (WebloggerException e) { addError("Error deleting template - check Roller logs"); } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/WeblogConfig.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/WeblogConfig.java index 0cfe9a352b..03bbc1ba6e 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/WeblogConfig.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/WeblogConfig.java @@ -127,6 +127,20 @@ public String save() { Weblog weblog = getActionWeblog(); + WeblogCategory bloggerCategory = weblog.getBloggerCategory(); + String bloggerCategoryId = getBean().getBloggerCategoryId(); + boolean bloggerCategoryChanged = bloggerCategoryId != null + && (bloggerCategory == null + || !bloggerCategory.getId().equals(bloggerCategoryId)); + if (bloggerCategoryChanged) { + bloggerCategory = wmgr.getWeblogCategory( + getActionWeblog(), bloggerCategoryId); + if (bloggerCategory == null) { + addError("websiteSettings.error.invalidBloggerCategory"); + return INPUT; + } + } + if (getBean().getAnalyticsCode() != null) { getBean().setAnalyticsCode(getBean().getAnalyticsCode().trim()); } @@ -134,9 +148,8 @@ public String save() { getBean().copyTo(weblog); // if blogger category changed then lookup new cat and set it - if(getBean().getBloggerCategoryId() != null && - !weblog.getBloggerCategory().getId().equals(getBean().getBloggerCategoryId())) { - weblog.setBloggerCategory(wmgr.getWeblogCategory(getBean().getBloggerCategoryId())); + if (bloggerCategoryChanged) { + weblog.setBloggerCategory(bloggerCategory); } // ROL-485: comments not allowed on inactive weblogs diff --git a/app/src/main/resources/ApplicationResources.properties b/app/src/main/resources/ApplicationResources.properties index 66072c23f0..7f19282be8 100644 --- a/app/src/main/resources/ApplicationResources.properties +++ b/app/src/main/resources/ApplicationResources.properties @@ -105,6 +105,9 @@ bookmarksForm.visitLink=Visit bookmarksForm.visitLink.tip=Click to visit this site bookmarksForm.error.move=Error performing move, parent to child moves not allowed +bookmarkForm.notFound=The requested bookmark was not found +folderForm.notFound=The requested folder was not found +categoryForm.notFound=The requested category was not found bookmarksForm.importBookmarks=Import Blogroll via OPML bookmarksForm.noresults=There are currently no Blogroll links @@ -874,6 +877,7 @@ mediaFile.delete.confirm=Delete selected media files? mediaFile.move.confirm=Move selected media files? mediaFile.directoryCreate.success=New folder [{0}] successfully created. mediaFile.directoryCreate.error.exists=New folder [{0}] already exists. Please choose another name. +mediaFile.directory.notFound=The requested media directory was not found. mediaFile.includeInGallery.success=Media file(s) successfully included in gallery. mediaFile.includeInGallery.error=Error including media file {0} in gallery. mediaFile.delete.success=Media file(s) successfully deleted. @@ -1536,6 +1540,7 @@ Link to edit the pending post:\ <{2}> weblogEntry.notFound=Cannot find requested weblog entry +websiteSettings.error.invalidBloggerCategory=The selected blogger category was not found. weblogEdit.summary=Summary (optional) weblogEdit.summary.tooltip=If provided, replaces above content on weblog home page \ diff --git a/app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFile.orm.xml b/app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFile.orm.xml index 241c8a1641..f7b0113c71 100644 --- a/app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFile.orm.xml +++ b/app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFile.orm.xml @@ -9,6 +9,9 @@ SELECT f FROM MediaFile f WHERE f.weblog = ?1 AND f.originalPath = ?2 + + SELECT f FROM MediaFile f WHERE f.weblog = ?1 AND f.id = ?2 + diff --git a/app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml b/app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml index fcb24d2547..baea5b10f9 100644 --- a/app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml +++ b/app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml @@ -12,6 +12,9 @@ SELECT d FROM MediaFileDirectory d WHERE d.weblog = ?1 AND d.name = ?2 + + SELECT d FROM MediaFileDirectory d WHERE d.weblog = ?1 AND d.id = ?2 + diff --git a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmark.orm.xml b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmark.orm.xml index b04c6acaf9..dd9ccdc67a 100644 --- a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmark.orm.xml +++ b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmark.orm.xml @@ -9,6 +9,9 @@ SELECT b FROM WeblogBookmark b WHERE b.folder = ?1 order by b.priority + + SELECT b FROM WeblogBookmark b WHERE b.folder.weblog = ?1 AND b.id = ?2 + diff --git a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmarkFolder.orm.xml b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmarkFolder.orm.xml index a9cd414b29..ddee76952c 100644 --- a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmarkFolder.orm.xml +++ b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmarkFolder.orm.xml @@ -12,6 +12,9 @@ SELECT f FROM WeblogBookmarkFolder f WHERE f.weblog = ?1 AND f.name = ?2 + + SELECT f FROM WeblogBookmarkFolder f WHERE f.weblog = ?1 AND f.id = ?2 + diff --git a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogCategory.orm.xml b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogCategory.orm.xml index 23764dc18f..a5a0e76cbf 100644 --- a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogCategory.orm.xml +++ b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogCategory.orm.xml @@ -13,6 +13,9 @@ SELECT w FROM WeblogCategory w WHERE w.weblog = ?1 AND w.name = ?2 + + SELECT w FROM WeblogCategory w WHERE w.weblog = ?1 AND w.id = ?2 + DELETE FROM WeblogCategory w WHERE w.weblog = ?1 diff --git a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntry.orm.xml b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntry.orm.xml index 7c28c6e630..6f3c9178e4 100644 --- a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntry.orm.xml +++ b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntry.orm.xml @@ -18,6 +18,9 @@ SELECT w FROM WeblogEntry w WHERE w.website = ?1 AND w.anchor = ?2 + + SELECT w FROM WeblogEntry w WHERE w.website = ?1 AND w.id = ?2 + SELECT w FROM WeblogEntry w WHERE w.website = ?1 diff --git a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntryComment.orm.xml b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntryComment.orm.xml index 44607d7177..f1576b2ecb 100644 --- a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntryComment.orm.xml +++ b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntryComment.orm.xml @@ -11,6 +11,9 @@ SELECT COUNT(c) FROM WeblogEntryComment c where c.status = ?1 + + SELECT c FROM WeblogEntryComment c WHERE c.weblogEntry.website = ?1 AND c.id = ?2 + SELECT COUNT(c) FROM WeblogEntryComment c WHERE c.weblogEntry.website = ?1 AND c.status = ?2 diff --git a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogTemplate.orm.xml b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogTemplate.orm.xml index 0485071ade..e493537e5e 100644 --- a/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogTemplate.orm.xml +++ b/app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogTemplate.orm.xml @@ -22,6 +22,9 @@ SELECT w FROM WeblogTemplate w WHERE w.weblog = ?1 AND w.name= ?2 + + SELECT w FROM WeblogTemplate w WHERE w.weblog = ?1 AND w.id = ?2 + diff --git a/app/src/main/resources/struts.xml b/app/src/main/resources/struts.xml index cc94ba6588..7e56e55a44 100644 --- a/app/src/main/resources/struts.xml +++ b/app/src/main/resources/struts.xml @@ -340,12 +340,14 @@ .MediaFileImageDimension + mediaFileView execute entryAdd + mediaFileView execute diff --git a/app/src/test/java/org/apache/roller/weblogger/business/WeblogScopedLookupTest.java b/app/src/test/java/org/apache/roller/weblogger/business/WeblogScopedLookupTest.java new file mode 100644 index 0000000000..d0801b0072 --- /dev/null +++ b/app/src/test/java/org/apache/roller/weblogger/business/WeblogScopedLookupTest.java @@ -0,0 +1,413 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +package org.apache.roller.weblogger.business; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.roller.weblogger.TestUtils; +import org.apache.roller.weblogger.pojos.MediaFile; +import org.apache.roller.weblogger.pojos.MediaFileDirectory; +import org.apache.roller.weblogger.pojos.ThemeTemplate.ComponentType; +import org.apache.roller.weblogger.pojos.WeblogBookmark; +import org.apache.roller.weblogger.pojos.WeblogBookmarkFolder; +import org.apache.roller.weblogger.util.RollerMessages; +import org.apache.roller.weblogger.pojos.User; +import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogCategory; +import org.apache.roller.weblogger.pojos.WeblogEntry; +import org.apache.roller.weblogger.pojos.WeblogEntryComment; +import org.apache.roller.weblogger.pojos.WeblogTemplate; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * Tests that resource lookups performed on behalf of the authoring UI resolve + * only within the weblog they are scoped to. + * + * Each test sets up two independent weblogs owned by different users and + * verifies that a resource belonging to one is not reachable through a lookup + * scoped to the other. + */ +public class WeblogScopedLookupTest { + + public static Log log = LogFactory.getLog(WeblogScopedLookupTest.class); + + User userOne = null; + User userTwo = null; + Weblog weblogOne = null; + Weblog weblogTwo = null; + + @BeforeEach + public void setUp() throws Exception { + + TestUtils.setupWeblogger(); + + // media file creation is rejected outright unless uploads are enabled + WebloggerFactory.getWeblogger().getPropertiesManager().getProperties() + .get("uploads.enabled").setValue("true"); + + try { + userOne = TestUtils.setupUser("scopeTestUserOne"); + userTwo = TestUtils.setupUser("scopeTestUserTwo"); + weblogOne = TestUtils.setupWeblog("scopeTestWeblogOne", userOne); + weblogTwo = TestUtils.setupWeblog("scopeTestWeblogTwo", userTwo); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error(ex); + throw new Exception("Test setup failed", ex); + } + } + + @AfterEach + public void tearDown() throws Exception { + + try { + TestUtils.teardownWeblog(weblogOne.getId()); + TestUtils.teardownWeblog(weblogTwo.getId()); + TestUtils.teardownUser(userOne.getUserName()); + TestUtils.teardownUser(userTwo.getUserName()); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error(ex); + throw new Exception("Test teardown failed", ex); + } + } + + /** + * Creates a template owned by the given weblog and returns its id. + */ + private String createTemplate(Weblog weblog, String name) throws Exception { + WeblogTemplate template = new WeblogTemplate(); + template.setAction(ComponentType.WEBLOG); + template.setName(name); + template.setDescription("Test Weblog Template"); + template.setLink(name); + template.setLastModified(new java.util.Date()); + template.setWeblog(TestUtils.getManagedWebsite(weblog)); + + WebloggerFactory.getWeblogger().getWeblogManager().saveTemplate(template); + TestUtils.endSession(true); + + return template.getId(); + } + + @Test + public void testGetTemplateReturnsNullForTemplateOwnedByAnotherWeblog() throws Exception { + + WeblogManager mgr = WebloggerFactory.getWeblogger().getWeblogManager(); + + String foreignTemplateId = createTemplate(weblogTwo, "scopeTestForeignTemplate"); + + WeblogTemplate found = mgr.getTemplate( + TestUtils.getManagedWebsite(weblogOne), foreignTemplateId); + + assertNull(found, "template owned by another weblog must not be returned"); + } + + @Test + public void testGetTemplateReturnsTemplateOwnedByTheGivenWeblog() throws Exception { + + WeblogManager mgr = WebloggerFactory.getWeblogger().getWeblogManager(); + + String ownTemplateId = createTemplate(weblogOne, "scopeTestOwnTemplate"); + + WeblogTemplate found = mgr.getTemplate( + TestUtils.getManagedWebsite(weblogOne), ownTemplateId); + + assertNotNull(found, "template owned by the given weblog must be returned"); + assertEquals(ownTemplateId, found.getId()); + } + + @Test + public void testGetWeblogEntryReturnsNullForEntryOwnedByAnotherWeblog() throws Exception { + + WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + WeblogEntry foreign = TestUtils.setupWeblogEntry( + "scopeTestForeignEntry", weblogTwo, userTwo); + TestUtils.endSession(true); + + WeblogEntry found = mgr.getWeblogEntry( + TestUtils.getManagedWebsite(weblogOne), foreign.getId()); + + assertNull(found, "entry owned by another weblog must not be returned"); + } + + @Test + public void testGetWeblogEntryReturnsEntryOwnedByTheGivenWeblog() throws Exception { + + WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + WeblogEntry own = TestUtils.setupWeblogEntry( + "scopeTestOwnEntry", weblogOne, userOne); + TestUtils.endSession(true); + + WeblogEntry found = mgr.getWeblogEntry( + TestUtils.getManagedWebsite(weblogOne), own.getId()); + + assertNotNull(found, "entry owned by the given weblog must be returned"); + assertEquals(own.getId(), found.getId()); + } + + @Test + public void testGetWeblogCategoryReturnsNullForCategoryOwnedByAnotherWeblog() throws Exception { + + WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + WeblogCategory foreign = TestUtils.setupWeblogCategory( + TestUtils.getManagedWebsite(weblogTwo), "scopeTestForeignCategory"); + TestUtils.endSession(true); + + WeblogCategory found = mgr.getWeblogCategory( + TestUtils.getManagedWebsite(weblogOne), foreign.getId()); + + assertNull(found, "category owned by another weblog must not be returned"); + } + + @Test + public void testGetWeblogCategoryReturnsCategoryOwnedByTheGivenWeblog() throws Exception { + + WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + WeblogCategory own = TestUtils.setupWeblogCategory( + TestUtils.getManagedWebsite(weblogOne), "scopeTestOwnCategory"); + TestUtils.endSession(true); + + WeblogCategory found = mgr.getWeblogCategory( + TestUtils.getManagedWebsite(weblogOne), own.getId()); + + assertNotNull(found, "category owned by the given weblog must be returned"); + assertEquals(own.getId(), found.getId()); + } + + @Test + public void testGetCommentReturnsNullForCommentOwnedByAnotherWeblog() throws Exception { + + WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + WeblogEntry foreignEntry = TestUtils.setupWeblogEntry( + "scopeTestForeignCommentEntry", weblogTwo, userTwo); + WeblogEntryComment foreign = TestUtils.setupComment( + "scopeTestForeignComment", foreignEntry); + TestUtils.endSession(true); + + WeblogEntryComment found = mgr.getComment( + TestUtils.getManagedWebsite(weblogOne), foreign.getId()); + + assertNull(found, "comment owned by another weblog must not be returned"); + } + + @Test + public void testGetCommentReturnsCommentOwnedByTheGivenWeblog() throws Exception { + + WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + + WeblogEntry ownEntry = TestUtils.setupWeblogEntry( + "scopeTestOwnCommentEntry", weblogOne, userOne); + WeblogEntryComment own = TestUtils.setupComment( + "scopeTestOwnComment", ownEntry); + TestUtils.endSession(true); + + WeblogEntryComment found = mgr.getComment( + TestUtils.getManagedWebsite(weblogOne), own.getId()); + + assertNotNull(found, "comment owned by the given weblog must be returned"); + assertEquals(own.getId(), found.getId()); + } + + /** + * Creates a bookmark in a new folder owned by the given weblog. + */ + private WeblogBookmark createBookmark(Weblog weblog, String name) throws Exception { + + BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager(); + + WeblogBookmarkFolder folder = TestUtils.setupFolder( + TestUtils.getManagedWebsite(weblog), name + "Folder"); + TestUtils.endSession(true); + + WeblogBookmark bookmark = new WeblogBookmark( + bmgr.getFolder(folder.getId()), name, "desc", + "http://example.com/", "http://example.com/feed", "image"); + bmgr.saveBookmark(bookmark); + TestUtils.endSession(true); + + return bookmark; + } + + @Test + public void testGetFolderReturnsNullForFolderOwnedByAnotherWeblog() throws Exception { + + BookmarkManager mgr = WebloggerFactory.getWeblogger().getBookmarkManager(); + + WeblogBookmarkFolder foreign = TestUtils.setupFolder( + TestUtils.getManagedWebsite(weblogTwo), "scopeTestForeignFolder"); + TestUtils.endSession(true); + + WeblogBookmarkFolder found = mgr.getFolderById( + TestUtils.getManagedWebsite(weblogOne), foreign.getId()); + + assertNull(found, "folder owned by another weblog must not be returned"); + } + + @Test + public void testGetFolderReturnsFolderOwnedByTheGivenWeblog() throws Exception { + + BookmarkManager mgr = WebloggerFactory.getWeblogger().getBookmarkManager(); + + WeblogBookmarkFolder own = TestUtils.setupFolder( + TestUtils.getManagedWebsite(weblogOne), "scopeTestOwnFolder"); + TestUtils.endSession(true); + + WeblogBookmarkFolder found = mgr.getFolderById( + TestUtils.getManagedWebsite(weblogOne), own.getId()); + + assertNotNull(found, "folder owned by the given weblog must be returned"); + assertEquals(own.getId(), found.getId()); + } + + @Test + public void testGetBookmarkReturnsNullForBookmarkOwnedByAnotherWeblog() throws Exception { + + BookmarkManager mgr = WebloggerFactory.getWeblogger().getBookmarkManager(); + + WeblogBookmark foreign = createBookmark(weblogTwo, "scopeTestForeignBookmark"); + + WeblogBookmark found = mgr.getBookmark( + TestUtils.getManagedWebsite(weblogOne), foreign.getId()); + + assertNull(found, "bookmark owned by another weblog must not be returned"); + } + + @Test + public void testGetBookmarkReturnsBookmarkOwnedByTheGivenWeblog() throws Exception { + + BookmarkManager mgr = WebloggerFactory.getWeblogger().getBookmarkManager(); + + WeblogBookmark own = createBookmark(weblogOne, "scopeTestOwnBookmark"); + + WeblogBookmark found = mgr.getBookmark( + TestUtils.getManagedWebsite(weblogOne), own.getId()); + + assertNotNull(found, "bookmark owned by the given weblog must be returned"); + assertEquals(own.getId(), found.getId()); + } + + /** + * Creates a media file in the given weblog's default directory. + */ + private MediaFile createMediaFile(Weblog weblog, String name) throws Exception { + + MediaFileManager mmgr = WebloggerFactory.getWeblogger().getMediaFileManager(); + + Weblog managed = TestUtils.getManagedWebsite(weblog); + MediaFileDirectory directory = mmgr.getDefaultMediaFileDirectory(managed); + if (directory == null) { + directory = mmgr.createMediaFileDirectory(managed, "default"); + TestUtils.endSession(true); + managed = TestUtils.getManagedWebsite(weblog); + directory = mmgr.getMediaFileDirectory(directory.getId()); + } + + MediaFile mediaFile = new MediaFile(); + mediaFile.setName(name); + mediaFile.setDescription("scoped lookup test file"); + mediaFile.setCopyrightText("none"); + mediaFile.setSharedForGallery(false); + mediaFile.setLength(3000); + mediaFile.setDirectory(directory); + mediaFile.setWeblog(managed); + mediaFile.setContentType("image/jpeg"); + mediaFile.setInputStream(getClass().getResourceAsStream("/hawk.jpg")); + + RollerMessages messages = new RollerMessages(); + mmgr.createMediaFile(managed, mediaFile, messages); + // createMediaFile reports rejection through messages rather than + // throwing, so a silent failure here would leave the test asserting + // against a file that was never stored + assertEquals(0, messages.getErrorCount(), + "media file fixture was rejected: " + messages); + TestUtils.endSession(true); + + return mediaFile; + } + + @Test + public void testGetMediaFileReturnsNullForFileOwnedByAnotherWeblog() throws Exception { + + MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager(); + + MediaFile foreign = createMediaFile(weblogTwo, "scopeTestForeignFile.jpg"); + + MediaFile found = mgr.getMediaFile( + TestUtils.getManagedWebsite(weblogOne), foreign.getId()); + + assertNull(found, "media file owned by another weblog must not be returned"); + } + + @Test + public void testGetMediaFileReturnsFileOwnedByTheGivenWeblog() throws Exception { + + MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager(); + + MediaFile own = createMediaFile(weblogOne, "scopeTestOwnFile.jpg"); + + MediaFile found = mgr.getMediaFile( + TestUtils.getManagedWebsite(weblogOne), own.getId()); + + assertNotNull(found, "media file owned by the given weblog must be returned"); + assertEquals(own.getId(), found.getId()); + } + + @Test + public void testGetMediaFileDirectoryReturnsNullForDirectoryOwnedByAnotherWeblog() throws Exception { + + MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager(); + + MediaFileDirectory foreign = mgr.createMediaFileDirectory( + TestUtils.getManagedWebsite(weblogTwo), "scopeTestForeignDir"); + TestUtils.endSession(true); + + MediaFileDirectory found = mgr.getMediaFileDirectory( + TestUtils.getManagedWebsite(weblogOne), foreign.getId()); + + assertNull(found, "directory owned by another weblog must not be returned"); + } + + @Test + public void testGetMediaFileDirectoryReturnsDirectoryOwnedByTheGivenWeblog() throws Exception { + + MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager(); + + MediaFileDirectory own = mgr.createMediaFileDirectory( + TestUtils.getManagedWebsite(weblogOne), "scopeTestOwnDir"); + TestUtils.endSession(true); + + MediaFileDirectory found = mgr.getMediaFileDirectory( + TestUtils.getManagedWebsite(weblogOne), own.getId()); + + assertNotNull(found, "directory owned by the given weblog must be returned"); + assertEquals(own.getId(), found.getId()); + } +} diff --git a/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/AuthoringActionScopingTest.java b/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/AuthoringActionScopingTest.java new file mode 100644 index 0000000000..f03a484542 --- /dev/null +++ b/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/AuthoringActionScopingTest.java @@ -0,0 +1,451 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +package org.apache.roller.weblogger.ui.struts2.editor; + +import com.opensymphony.xwork2.DefaultTextProvider; +import com.opensymphony.xwork2.TextProvider; +import com.opensymphony.xwork2.TextProviderFactory; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Scope; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.roller.weblogger.TestUtils; +import org.apache.roller.weblogger.business.BookmarkManager; +import org.apache.roller.weblogger.business.WebloggerFactory; +import org.apache.roller.weblogger.pojos.User; +import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogBookmark; +import org.apache.roller.weblogger.pojos.WeblogBookmarkFolder; +import org.apache.roller.weblogger.pojos.WeblogCategory; +import org.apache.roller.weblogger.pojos.WeblogEntry; +import org.apache.roller.weblogger.ui.struts2.util.UIAction; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; +import java.util.ResourceBundle; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verifies that authoring actions resolve the resource named by a request + * parameter within the weblog the request is acting on, rather than by id + * alone. + * + * The interceptor stack resolves and authorizes the action weblog before + * myPrepare() runs, so these tests set the action weblog directly and then + * ask each action to prepare against an id owned by a different weblog. + */ +public class AuthoringActionScopingTest { + + public static Log log = LogFactory.getLog(AuthoringActionScopingTest.class); + + User userOne = null; + User userTwo = null; + Weblog weblogOne = null; + Weblog weblogTwo = null; + + @BeforeEach + public void setUp() throws Exception { + + TestUtils.setupWeblogger(); + + try { + userOne = TestUtils.setupUser("actScopeUserOne"); + userTwo = TestUtils.setupUser("actScopeUserTwo"); + weblogOne = TestUtils.setupWeblog("actScopeWeblogOne", userOne); + weblogTwo = TestUtils.setupWeblog("actScopeWeblogTwo", userTwo); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error(ex); + throw new Exception("Test setup failed", ex); + } + } + + @AfterEach + public void tearDown() throws Exception { + + try { + TestUtils.teardownWeblog(weblogOne.getId()); + TestUtils.teardownWeblog(weblogTwo.getId()); + TestUtils.teardownUser(userOne.getUserName()); + TestUtils.teardownUser(userTwo.getUserName()); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error(ex); + throw new Exception("Test teardown failed", ex); + } + } + + // ----------------------------------------------------- entry removal + + @Test + public void testEntryRemoveDoesNotLoadEntryOwnedByAnotherWeblog() throws Exception { + + WeblogEntry foreign = TestUtils.setupWeblogEntry( + "actScopeForeignEntry", weblogTwo, userTwo); + TestUtils.endSession(true); + + EntryRemove action = new EntryRemove(); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.setRemoveId(foreign.getId()); + action.myPrepare(); + + assertNull(action.getRemoveEntry(), + "remove must not load an entry owned by another weblog"); + } + + @Test + public void testEntryRemoveLoadsEntryOwnedByTheActionWeblog() throws Exception { + + WeblogEntry own = TestUtils.setupWeblogEntry( + "actScopeOwnEntry", weblogOne, userOne); + TestUtils.endSession(true); + + EntryRemove action = new EntryRemove(); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.setRemoveId(own.getId()); + action.myPrepare(); + + assertNotNull(action.getRemoveEntry(), + "remove must load an entry owned by the action weblog"); + assertEquals(own.getId(), action.getRemoveEntry().getId()); + } + + // ----------------------------------------------------- entry editing + + @Test + public void testEntryEditDoesNotLoadEntryOwnedByAnotherWeblog() throws Exception { + + WeblogEntry foreign = TestUtils.setupWeblogEntry( + "actScopeForeignEditEntry", weblogTwo, userTwo); + TestUtils.endSession(true); + + EntryEdit action = new EntryEdit(); + prepareText(action); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.getBean().setId(foreign.getId()); + action.myPrepare(); + + assertNull(action.getEntry(), + "editor must not load an entry owned by another weblog"); + } + + @Test + public void testEntryEditReportsMissingEntry() throws Exception { + EntryEdit action = new EntryEdit(); + prepareText(action); + action.setActionName("entryEdit"); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.getBean().setId("missing-entry"); + action.myPrepare(); + + assertEquals(EntryEdit.ERROR, action.execute()); + assertTrue(action.hasActionErrors()); + } + + // -------------------------------------------------- category removal + + @Test + public void testCategoryRemoveDoesNotLoadCategoryOwnedByAnotherWeblog() throws Exception { + + WeblogCategory foreign = TestUtils.setupWeblogCategory( + TestUtils.getManagedWebsite(weblogTwo), "actScopeForeignCat"); + TestUtils.endSession(true); + + CategoryRemove action = new CategoryRemove(); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.setRemoveId(foreign.getId()); + action.myPrepare(); + + assertNull(action.getCategory(), + "remove must not load a category owned by another weblog"); + } + + @Test + public void testCategoryRemoveLoadsCategoryOwnedByTheActionWeblog() throws Exception { + + WeblogCategory own = TestUtils.setupWeblogCategory( + TestUtils.getManagedWebsite(weblogOne), "actScopeOwnCat"); + TestUtils.endSession(true); + + CategoryRemove action = new CategoryRemove(); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.setRemoveId(own.getId()); + action.myPrepare(); + + assertNotNull(action.getCategory(), + "remove must load a category owned by the action weblog"); + assertEquals(own.getId(), action.getCategory().getId()); + } + + @Test + public void testCategoryEditReportsMissingCategory() throws Exception { + CategoryEdit action = new CategoryEdit(); + prepareText(action); + action.setActionName("categoryEdit"); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.getBean().setId("missing-category"); + action.myPrepare(); + + assertEquals(CategoryEdit.ERROR, action.execute()); + assertTrue(action.hasActionErrors()); + } + + @Test + public void testCategoryRemoveRejectsMissingTarget() throws Exception { + WeblogCategory own = TestUtils.setupWeblogCategory( + TestUtils.getManagedWebsite(weblogOne), "actScopeRemoveCat"); + TestUtils.endSession(true); + + CategoryRemove action = new CategoryRemove(); + prepareText(action); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.setRemoveId(own.getId()); + action.setTargetCategoryId("missing-target-category"); + action.myPrepare(); + + assertEquals(CategoryRemove.INPUT, action.remove()); + assertTrue(action.hasActionErrors()); + assertNotNull(WebloggerFactory.getWeblogger().getWeblogEntryManager() + .getWeblogCategory(TestUtils.getManagedWebsite(weblogOne), own.getId())); + } + + @Test + public void testWeblogConfigPreservesCategoryWhenSelectionIsMissing() + throws Exception { + Weblog managed = TestUtils.getManagedWebsite(weblogOne); + String originalCategoryId = managed.getBloggerCategory().getId(); + WeblogConfig action = new WeblogConfig(); + prepareText(action); + action.setActionWeblog(managed); + action.getBean().copyFrom(managed); + action.getBean().setBloggerCategoryId("missing-blogger-category"); + + assertEquals(WeblogConfig.INPUT, action.save()); + assertTrue(action.hasActionErrors()); + assertEquals(originalCategoryId, + managed.getBloggerCategory().getId()); + } + + // -------------------------------------------------- bookmark editing + + @Test + public void testBookmarkEditDoesNotLoadBookmarkOwnedByAnotherWeblog() throws Exception { + + BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager(); + + WeblogBookmarkFolder folder = TestUtils.setupFolder( + TestUtils.getManagedWebsite(weblogTwo), "actScopeForeignBmFolder"); + TestUtils.endSession(true); + + WeblogBookmark foreign = new WeblogBookmark( + bmgr.getFolder(folder.getId()), "actScopeForeignBm", "desc", + "http://example.com/", "http://example.com/feed", "image"); + bmgr.saveBookmark(foreign); + TestUtils.endSession(true); + + BookmarkEdit action = new BookmarkEdit(); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.getBean().setId(foreign.getId()); + action.myPrepare(); + + assertNull(action.getBookmark(), + "editor must not load a bookmark owned by another weblog"); + } + + @Test + public void testBookmarkAndFolderEditorsReportMissingResources() throws Exception { + BookmarkEdit bookmark = new BookmarkEdit(); + prepareText(bookmark); + bookmark.setActionName("bookmarkEdit"); + bookmark.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + bookmark.getBean().setId("missing-bookmark"); + bookmark.myPrepare(); + + assertEquals(BookmarkEdit.ERROR, bookmark.execute()); + assertTrue(bookmark.hasActionErrors()); + + FolderEdit folder = new FolderEdit(); + prepareText(folder); + folder.setActionName("folderEdit"); + folder.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + folder.getBean().setId("missing-folder"); + folder.myPrepare(); + + assertEquals(FolderEdit.ERROR, folder.execute()); + assertTrue(folder.hasActionErrors()); + } + + @Test + public void testBookmarkMoveRejectsMissingTarget() throws Exception { + Bookmarks action = new Bookmarks(); + prepareText(action); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.setTargetFolderId("missing-target-folder"); + action.setSelectedBookmarks(new String[0]); + + assertEquals(Bookmarks.LIST, action.move()); + assertTrue(action.hasActionErrors()); + } + + @Test + public void testMissingCommentFilterReturnsNoComments() throws Exception { + Comments action = new Comments(); + prepareText(action); + action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + action.getBean().setEntryId("missing-comment-entry"); + + assertEquals(Comments.LIST, action.execute()); + assertTrue(action.hasActionErrors()); + assertTrue(action.getPager().getItems().isEmpty()); + } + + @Test + public void testMediaActionsReportMissingResources() throws Exception { + MediaFileImageDim dimensions = new MediaFileImageDim(); + prepareText(dimensions); + dimensions.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + dimensions.setMediaFileId("missing-media-file"); + + assertEquals(MediaFileImageDim.ERROR, dimensions.execute()); + assertTrue(dimensions.hasActionErrors()); + + EntryAddWithMediaFile entry = new EntryAddWithMediaFile(); + prepareText(entry); + entry.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + entry.setSelectedImages(new String[] {"missing-media-file"}); + + assertEquals(EntryAddWithMediaFile.ERROR, entry.execute()); + assertTrue(entry.hasActionErrors()); + + TestMediaFileAction media = new TestMediaFileAction(); + prepareText(media); + media.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + media.setMediaFileId("missing-media-file"); + media.deleteMissing(); + assertTrue(media.hasActionErrors()); + } + + @Test + public void testMediaMoveRejectsMissingDirectory() throws Exception { + TestMediaFileAction media = new TestMediaFileAction(); + prepareText(media); + media.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); + media.setSelectedMediaFiles(new String[] {"missing-media-file"}); + media.setSelectedDirectory("missing-media-directory"); + + media.moveMissing(); + + assertTrue(media.hasActionErrors()); + } + + private static class TestMediaFileAction extends MediaFileBase { + private static final long serialVersionUID = 1L; + + void deleteMissing() { + doDeleteMediaFile(); + } + + void moveMissing() { + doMoveSelected(); + } + } + + private static void prepareText(UIAction action) { + action.setContainer(TEST_CONTAINER); + } + + private static final TextProvider TEST_TEXT_PROVIDER = new DefaultTextProvider() { + @Override + public String getText(String key) { + return key; + } + + @Override + public String getText(String key, List args) { + return key; + } + + @Override + public String getText(String key, String defaultValue, String value) { + return key; + } + }; + + private static final TextProviderFactory TEST_TEXT_PROVIDER_FACTORY = + new TextProviderFactory() { + @Override + @SuppressWarnings("rawtypes") + public TextProvider createInstance(Class type) { + return TEST_TEXT_PROVIDER; + } + + @Override + public TextProvider createInstance(ResourceBundle bundle) { + return TEST_TEXT_PROVIDER; + } + }; + + private static final Container TEST_CONTAINER = new Container() { + @Override + public void inject(Object object) { + } + + @Override + public T inject(Class implementation) { + return null; + } + + @Override + public T getInstance(Class type, String name) { + return getInstance(type); + } + + @Override + public T getInstance(Class type) { + if (type == TextProviderFactory.class) { + return type.cast(TEST_TEXT_PROVIDER_FACTORY); + } + if (type == String.class) { + return type.cast("false"); + } + return null; + } + + @Override + public Set getInstanceNames(Class type) { + return Collections.emptySet(); + } + + @Override + public void setScopeStrategy(Scope.Strategy strategy) { + } + + @Override + public void removeScopeStrategy() { + } + }; +} diff --git a/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditScopingTest.java b/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditScopingTest.java new file mode 100644 index 0000000000..e4285ea89a --- /dev/null +++ b/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditScopingTest.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +package org.apache.roller.weblogger.ui.struts2.editor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.roller.weblogger.TestUtils; +import org.apache.roller.weblogger.business.WebloggerFactory; +import org.apache.roller.weblogger.pojos.ThemeTemplate.ComponentType; +import org.apache.roller.weblogger.pojos.User; +import org.apache.roller.weblogger.pojos.Weblog; +import org.apache.roller.weblogger.pojos.WeblogTemplate; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * Verifies that the template editor resolves the template it is asked to edit + * within the weblog the request is acting on, rather than by id alone. + */ +public class TemplateEditScopingTest { + + public static Log log = LogFactory.getLog(TemplateEditScopingTest.class); + + User userOne = null; + User userTwo = null; + Weblog weblogOne = null; + Weblog weblogTwo = null; + + @BeforeEach + public void setUp() throws Exception { + + TestUtils.setupWeblogger(); + + try { + userOne = TestUtils.setupUser("tmplEditUserOne"); + userTwo = TestUtils.setupUser("tmplEditUserTwo"); + weblogOne = TestUtils.setupWeblog("tmplEditWeblogOne", userOne); + weblogTwo = TestUtils.setupWeblog("tmplEditWeblogTwo", userTwo); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error(ex); + throw new Exception("Test setup failed", ex); + } + } + + @AfterEach + public void tearDown() throws Exception { + + try { + TestUtils.teardownWeblog(weblogOne.getId()); + TestUtils.teardownWeblog(weblogTwo.getId()); + TestUtils.teardownUser(userOne.getUserName()); + TestUtils.teardownUser(userTwo.getUserName()); + TestUtils.endSession(true); + } catch (Exception ex) { + log.error(ex); + throw new Exception("Test teardown failed", ex); + } + } + + private String createTemplate(Weblog weblog, String name) throws Exception { + WeblogTemplate template = new WeblogTemplate(); + template.setAction(ComponentType.WEBLOG); + template.setName(name); + template.setDescription("Test Weblog Template"); + template.setLink(name); + template.setLastModified(new java.util.Date()); + template.setWeblog(TestUtils.getManagedWebsite(weblog)); + + WebloggerFactory.getWeblogger().getWeblogManager().saveTemplate(template); + TestUtils.endSession(true); + + return template.getId(); + } + + /** + * Builds the action as the interceptor stack would: the action weblog is + * already resolved and authorized before myPrepare() runs. + */ + private TemplateEdit actionFor(Weblog actionWeblog, String requestedTemplateId) + throws Exception { + TemplateEdit action = new TemplateEdit(); + action.setActionWeblog(TestUtils.getManagedWebsite(actionWeblog)); + action.getBean().setId(requestedTemplateId); + return action; + } + + @Test + public void testDoesNotLoadTemplateBelongingToAnotherWeblog() throws Exception { + + String foreignTemplateId = createTemplate(weblogTwo, "tmplEditForeign"); + + TemplateEdit action = actionFor(weblogOne, foreignTemplateId); + action.myPrepare(); + + assertNull(action.getTemplate(), + "editor must not load a template owned by another weblog"); + } + + @Test + public void testLoadsTemplateBelongingToTheActionWeblog() throws Exception { + + String ownTemplateId = createTemplate(weblogOne, "tmplEditOwn"); + + TemplateEdit action = actionFor(weblogOne, ownTemplateId); + action.myPrepare(); + + assertNotNull(action.getTemplate(), + "editor must load a template owned by the action weblog"); + assertEquals(ownTemplateId, action.getTemplate().getId()); + } +}