From 1513bafe7a5b32602ed93e3503cf36b0180b3837 Mon Sep 17 00:00:00 2001 From: "David M. Johnson" Date: Sat, 15 Aug 2026 13:35:38 -0400 Subject: [PATCH 1/2] Scope authoring resource lookups to the action weblog Authoring actions resolve the resource named by a request parameter by id alone, independently of the weblog the action is operating on. Add weblog-scoped lookups beside the existing unscoped ones, modelled on getTemplateByLink(Weblog, String), and point the authoring actions at them: WeblogManager getTemplate(Weblog, String) WeblogEntryManager getWeblogEntry / getWeblogCategory / getComment BookmarkManager getBookmark, getFolderById MediaFileManager getMediaFile, getMediaFileDirectory Each is backed by a named query filtering on the owning weblog, and returns null when the id does not belong to that weblog, the same as for an id that does not exist. The bookmark folder lookup is named getFolderById because getFolder(Weblog, String) already exists as the by-name lookup and the two would otherwise share an erasure. Call sites updated across templates, entries, categories, comments, bookmarks, folders and media files. The two comment loops in Comments already compared the weblog after loading; they now use the scoped lookup instead, which also removes an NPE on ids that do not exist. Left unchanged, having been verified to resolve correctly by other means: EntryBean, StylesheetEdit, CommentDataServlet, and the XML-RPC and Atom handlers, which derive the weblog from the entity itself. Tests: WeblogScopedLookupTest (manager layer), TemplateEditScopingTest and AuthoringActionScopingTest (action layer). Full suite 182 run, 0 failures. --- .../weblogger/business/BookmarkManager.java | 31 +- .../weblogger/business/MediaFileManager.java | 19 + .../business/WeblogEntryManager.java | 41 +- .../weblogger/business/WeblogManager.java | 23 +- .../business/jpa/JPABookmarkManagerImpl.java | 44 ++ .../business/jpa/JPAMediaFileManagerImpl.java | 45 ++ .../jpa/JPAWeblogEntryManagerImpl.java | 77 +++- .../business/jpa/JPAWeblogManagerImpl.java | 25 +- .../ui/struts2/editor/BookmarkEdit.java | 4 +- .../ui/struts2/editor/Bookmarks.java | 12 +- .../ui/struts2/editor/CategoryEdit.java | 2 +- .../ui/struts2/editor/CategoryRemove.java | 4 +- .../weblogger/ui/struts2/editor/Comments.java | 18 +- .../struts2/editor/EntryAddWithMediaFile.java | 2 +- .../ui/struts2/editor/EntryEdit.java | 2 +- .../ui/struts2/editor/EntryRemove.java | 2 +- .../ui/struts2/editor/FolderEdit.java | 2 +- .../ui/struts2/editor/MediaFileAdd.java | 2 +- .../ui/struts2/editor/MediaFileBase.java | 10 +- .../ui/struts2/editor/MediaFileEdit.java | 6 +- .../struts2/editor/MediaFileImageChooser.java | 2 +- .../ui/struts2/editor/MediaFileImageDim.java | 2 +- .../ui/struts2/editor/MediaFileView.java | 6 +- .../ui/struts2/editor/TemplateEdit.java | 3 +- .../ui/struts2/editor/Templates.java | 2 +- .../ui/struts2/editor/WeblogConfig.java | 2 +- .../roller/weblogger/pojos/MediaFile.orm.xml | 3 + .../pojos/MediaFileDirectory.orm.xml | 3 + .../weblogger/pojos/WeblogBookmark.orm.xml | 3 + .../pojos/WeblogBookmarkFolder.orm.xml | 3 + .../weblogger/pojos/WeblogCategory.orm.xml | 3 + .../weblogger/pojos/WeblogEntry.orm.xml | 3 + .../pojos/WeblogEntryComment.orm.xml | 3 + .../weblogger/pojos/WeblogTemplate.orm.xml | 3 + .../business/WeblogScopedLookupTest.java | 413 ++++++++++++++++++ .../editor/AuthoringActionScopingTest.java | 203 +++++++++ .../editor/TemplateEditScopingTest.java | 133 ++++++ 37 files changed, 1105 insertions(+), 56 deletions(-) create mode 100644 app/src/test/java/org/apache/roller/weblogger/business/WeblogScopedLookupTest.java create mode 100644 app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/AuthoringActionScopingTest.java create mode 100644 app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditScopingTest.java 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..f9c12d31ad 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); 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..1aa8b4c1b2 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,12 @@ public String move() { } // Move bookmarks to new parent folder. - WeblogBookmarkFolder newFolder = bmgr.getFolder(getTargetFolderId()); + WeblogBookmarkFolder newFolder = bmgr.getFolderById(getActionWeblog(), getTargetFolderId()); String bookmarks[] = getSelectedBookmarks(); if (null != bookmarks && bookmarks.length > 0) { for (int j = 0; j < bookmarks.length; j++) { - WeblogBookmark bd = bmgr.getBookmark(bookmarks[j]); + WeblogBookmark bd = bmgr.getBookmark(getActionWeblog(), bookmarks[j]); 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..c2968797d3 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); } 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..e6f6444899 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,7 @@ public String remove() { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); if (getTargetCategoryId() != null) { - WeblogCategory target = wmgr.getWeblogCategory(getTargetCategoryId()); + WeblogCategory target = wmgr.getWeblogCategory(getActionWeblog(), getTargetCategoryId()); 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..fba790eee8 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 @@ -102,7 +102,7 @@ public void loadComments() { // lookup weblog entry if necessary if (!StringUtils.isEmpty(getBean().getEntryId())) { - setQueryEntry(wmgr.getWeblogEntry(getBean().getEntryId())); + setQueryEntry(wmgr.getWeblogEntry(getActionWeblog(), getBean().getEntryId())); } CommentSearchCriteria csc = getCommentSearchCriteria(); @@ -284,11 +284,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 +315,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..4f7d11f4d9 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 @@ -71,7 +71,7 @@ public String execute() { if (selectedImages != null) { for (String image : selectedImages) { - MediaFile mediaFile = manager.getMediaFile(image); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), image); String link; if (mediaFile.isImageFile()) { 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..5ef718505c 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(), 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..613e4bd0a7 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); } 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..356e498e62 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(), 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..13c301f020 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 @@ -62,7 +62,7 @@ protected void doDeleteMediaFile() { log.debug("Processing delete of file id - " + this.mediaFileId); MediaFileManager manager = WebloggerFactory.getWeblogger() .getMediaFileManager(); - MediaFile mediaFile = manager.getMediaFile(this.mediaFileId); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), this.mediaFileId); manager.removeMediaFile(getActionWeblog(), mediaFile); // flush changes WebloggerFactory.getWeblogger().flush(); @@ -84,7 +84,7 @@ protected void doIncludeMediaFileInGallery() { + this.mediaFileId); MediaFileManager manager = WebloggerFactory.getWeblogger() .getMediaFileManager(); - MediaFile mediaFile = manager.getMediaFile(this.mediaFileId); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), this.mediaFileId); mediaFile.setSharedForGallery(true); manager.updateMediaFile(getActionWeblog(), mediaFile); // flush changes @@ -111,7 +111,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); } @@ -147,11 +147,11 @@ void doMoveSelected() { log.debug("Processing move of " + fileIds.length + " media files."); MediaFileDirectory targetDirectory = manager - .getMediaFileDirectory(this.selectedDirectory); + .getMediaFileDirectory(getActionWeblog(), this.selectedDirectory); for (String fileId : fileIds) { log.debug("Moving media file - " + fileId + " to directory - " + this.selectedDirectory); - MediaFile mediaFile = manager.getMediaFile(fileId); + MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), fileId); if (mediaFile != null && !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..5796ece72d 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,7 @@ public MediaFileImageDim() { public String execute() { try { MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager(); - MediaFile mediaFile = mgr.getMediaFile(getMediaFileId()); + MediaFile mediaFile = mgr.getMediaFile(getActionWeblog(), getMediaFileId()); 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..45e4ed5848 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 @@ -136,7 +136,7 @@ public String save() { // 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())); + weblog.setBloggerCategory(wmgr.getWeblogCategory(getActionWeblog(), getBean().getBloggerCategoryId())); } // ROL-485: comments not allowed on inactive weblogs 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/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..17572463df --- /dev/null +++ b/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/AuthoringActionScopingTest.java @@ -0,0 +1,203 @@ +/* + * 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.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.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 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(); + 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"); + } + + // -------------------------------------------------- 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()); + } + + // -------------------------------------------------- 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"); + } +} 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()); + } +} From c42d0e309261b8b6aac56838f8e8787931cad22a Mon Sep 17 00:00:00 2001 From: "David M. Johnson" Date: Tue, 1 Sep 2026 16:59:11 -0400 Subject: [PATCH 2/2] Handle missing scoped authoring resources --- .../ui/struts2/editor/BookmarkEdit.java | 12 + .../ui/struts2/editor/Bookmarks.java | 17 +- .../ui/struts2/editor/CategoryEdit.java | 12 + .../ui/struts2/editor/CategoryRemove.java | 4 + .../weblogger/ui/struts2/editor/Comments.java | 42 ++- .../struts2/editor/EntryAddWithMediaFile.java | 20 +- .../ui/struts2/editor/EntryEdit.java | 23 ++ .../ui/struts2/editor/FolderEdit.java | 12 + .../ui/struts2/editor/MediaFileAdd.java | 4 + .../ui/struts2/editor/MediaFileBase.java | 56 ++-- .../ui/struts2/editor/MediaFileImageDim.java | 4 + .../ui/struts2/editor/WeblogConfig.java | 19 +- .../resources/ApplicationResources.properties | 5 + app/src/main/resources/struts.xml | 2 + .../editor/AuthoringActionScopingTest.java | 248 ++++++++++++++++++ 15 files changed, 446 insertions(+), 34 deletions(-) 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 f9c12d31ad..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 @@ -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 1aa8b4c1b2..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 @@ -228,9 +228,22 @@ public String move() { 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(getActionWeblog(), 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 c2968797d3..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 @@ -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 e6f6444899..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 @@ -113,6 +113,10 @@ public String remove() { if (getTargetCategoryId() != null) { 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 fba790eee8..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(getActionWeblog(), 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. */ 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 4f7d11f4d9..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(getActionWeblog(), 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 5ef718505c..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 @@ -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/FolderEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/FolderEdit.java index 613e4bd0a7..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 @@ -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 356e498e62..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 @@ -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 13c301f020..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(getActionWeblog(), 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(getActionWeblog(), 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(); @@ -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(getActionWeblog(), this.selectedDirectory); - for (String fileId : fileIds) { - log.debug("Moving media file - " + fileId - + " to directory - " + this.selectedDirectory); - MediaFile mediaFile = manager.getMediaFile(getActionWeblog(), 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/MediaFileImageDim.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageDim.java index 5796ece72d..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 @@ -51,6 +51,10 @@ public String execute() { try { MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager(); 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/WeblogConfig.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/WeblogConfig.java index 45e4ed5848..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(getActionWeblog(), 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/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/ui/struts2/editor/AuthoringActionScopingTest.java b/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/AuthoringActionScopingTest.java index 17572463df..f03a484542 100644 --- 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 @@ -18,6 +18,11 @@ 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; @@ -29,13 +34,20 @@ 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 @@ -132,6 +144,7 @@ public void testEntryEditDoesNotLoadEntryOwnedByAnotherWeblog() throws Exception TestUtils.endSession(true); EntryEdit action = new EntryEdit(); + prepareText(action); action.setActionWeblog(TestUtils.getManagedWebsite(weblogOne)); action.getBean().setId(foreign.getId()); action.myPrepare(); @@ -140,6 +153,19 @@ public void testEntryEditDoesNotLoadEntryOwnedByAnotherWeblog() throws Exception "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 @@ -175,6 +201,55 @@ public void testCategoryRemoveLoadsCategoryOwnedByTheActionWeblog() throws Excep 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 @@ -200,4 +275,177 @@ public void testBookmarkEditDoesNotLoadBookmarkOwnedByAnotherWeblog() throws Exc 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() { + } + }; }