You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2026/08/15 19:52:03 UTC
(roller) 01/01: Remove legacy outbound trackback action
This is an automated email from the ASF dual-hosted git repository.
snoopdave pushed a commit to branch entry-trackback-cleanup
in repository https://gitbox.apache.org/repos/asf/roller.git
commit 59348eb3d790ff0772104e12bbfea46acd573aac
Author: David M. Johnson <sn...@apache.org>
AuthorDate: Sat Aug 15 15:49:40 2026 -0400
Remove legacy outbound trackback action
---
.../weblogger/ui/struts2/editor/EntryEdit.java | 73 --------
.../apache/roller/weblogger/util/Trackback.java | 201 ---------------------
.../util/TrackbackNotAllowedException.java | 34 ----
.../roller/weblogger/config/roller.properties | 6 -
app/src/main/resources/struts.xml | 4 +-
.../main/webapp/WEB-INF/jsps/editor/EntryEdit.jsp | 13 --
.../struts2/editor/EntryTrackbackRemovalTest.java | 76 ++++++++
7 files changed, 78 insertions(+), 329 deletions(-)
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 a12dc18ff..58dd32064 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
@@ -20,10 +20,8 @@ package org.apache.roller.weblogger.ui.struts2.editor;
import java.sql.Timestamp;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -53,10 +51,6 @@ import org.apache.roller.weblogger.util.MailUtil;
import org.apache.roller.weblogger.util.MediacastException;
import org.apache.roller.weblogger.util.MediacastResource;
import org.apache.roller.weblogger.util.MediacastUtil;
-import org.apache.roller.weblogger.util.RollerMessages;
-import org.apache.roller.weblogger.util.RollerMessages.RollerMessage;
-import org.apache.roller.weblogger.util.Trackback;
-import org.apache.roller.weblogger.util.TrackbackNotAllowedException;
import org.apache.struts2.convention.annotation.AllowedMethods;
import org.apache.struts2.interceptor.validation.SkipValidation;
@@ -74,9 +68,6 @@ public final class EntryEdit extends UIAction {
// the entry we are adding or editing
private WeblogEntry entry = null;
- // url to send trackback to
- private String trackbackUrl = null;
-
public EntryEdit() {
this.desiredMenu = "editor";
}
@@ -359,70 +350,6 @@ public final class EntryEdit extends UIAction {
getEntry().getAnchor(), true);
}
- public String getTrackbackUrl() {
- return trackbackUrl;
- }
-
- public void setTrackbackUrl(String trackbackUrl) {
- this.trackbackUrl = trackbackUrl;
- }
-
- /**
- * Send trackback to a specific url.
- */
- @SkipValidation
- public String trackback() {
-
- // make sure we have an entry to edit and it belongs to the action
- // weblog
- if (getEntry() == null) {
- return ERROR;
- } else if (!getEntry().getWebsite().equals(getActionWeblog())) {
- return DENIED;
- }
-
- if (!StringUtils.isEmpty(getTrackbackUrl())) {
- RollerMessages results = null;
- try {
- Trackback trackback = new Trackback(getEntry(),
- getTrackbackUrl());
- results = trackback.send();
- } catch (TrackbackNotAllowedException ex) {
- addError("error.trackbackNotAllowed");
- } catch (Exception e) {
- log.error("Error sending trackback", e);
- // TODO: error handling
- addError("error.general", e.getMessage());
- }
-
- if (results != null) {
- for (Iterator<RollerMessage> mit = results.getMessages(); mit.hasNext();) {
- RollerMessage msg = mit.next();
- if (msg.getArgs() == null) {
- addMessage(msg.getKey());
- } else {
- addMessage(msg.getKey(), Arrays.asList(msg.getArgs()));
- }
- }
-
- for (Iterator<RollerMessage> eit = results.getErrors(); eit.hasNext();) {
- RollerMessage err = eit.next();
- if (err.getArgs() == null) {
- addError(err.getKey());
- } else {
- addError(err.getKey(), Arrays.asList(err.getArgs()));
- }
- }
- }
-
- // reset trackback url
- setTrackbackUrl(null);
-
- }
-
- return INPUT;
- }
-
/**
* Get the list of all categories for the action weblog
*/
diff --git a/app/src/main/java/org/apache/roller/weblogger/util/Trackback.java b/app/src/main/java/org/apache/roller/weblogger/util/Trackback.java
deleted file mode 100644
index 88753a501..000000000
--- a/app/src/main/java/org/apache/roller/weblogger/util/Trackback.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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.util;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.HttpStatus;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.text.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.roller.util.RollerConstants;
-import org.apache.roller.weblogger.WebloggerException;
-import org.apache.roller.weblogger.config.WebloggerConfig;
-import org.apache.roller.weblogger.pojos.WeblogEntry;
-import org.jdom2.Document;
-import org.jdom2.Element;
-import org.jdom2.JDOMException;
-import org.jdom2.input.SAXBuilder;
-
-
-/**
- * Represents a trackback request.
- */
-public class Trackback {
-
- private static final Log LOG = LogFactory.getLog(Trackback.class);
-
- private final WeblogEntry entry;
- private final String trackbackURL;
-
-
- public Trackback(WeblogEntry tEntry, String tURL)
- throws TrackbackNotAllowedException {
-
- // Make sure trackback to URL is allowed
- boolean allowTrackback = true;
- String allowedURLs = WebloggerConfig.getProperty("trackback.allowedURLs");
- if (!StringUtils.isEmpty(allowedURLs)) {
- // in the case that the administrator has enabled trackbacks
- // for only specific URLs, set it to false by default
- allowTrackback = false;
- String[] splitURLs = allowedURLs.split("\\|\\|");
- for (int i=0; i < splitURLs.length; i++) {
- Matcher m = Pattern.compile(splitURLs[i]).matcher(tURL);
- if (m.matches()) {
- allowTrackback = true;
- break;
- }
- }
- }
-
- if(!allowTrackback) {
- throw new TrackbackNotAllowedException(tURL);
- } else {
- // test url
- try {
- new URL(tURL);
- } catch(MalformedURLException ex) {
- // bad url
- throw new IllegalArgumentException("bad url: "+tURL);
- }
-
- entry = tEntry;
- trackbackURL = tURL;
- }
-
- }
-
-
- /**
- * Sends trackback from entry to remote URL.
- * See Trackback spec for details: http://www.sixapart.com/pronet/docs/trackback_spec
- */
- public RollerMessages send() throws WebloggerException {
-
- RollerMessages messages = new RollerMessages();
-
- LOG.debug("Sending trackback to url - " + trackbackURL);
-
- // Construct data
- String title = entry.getTitle();
- String excerpt = StringUtils.left( Utilities.removeHTML(entry.getDisplayContent()),
- RollerConstants.TEXTWIDTH_255);
- String url = entry.getPermalink();
- String blog_name = entry.getWebsite().getName();
-
- // build trackback post parameters as query string
- Map<String, String> params = Map.of("title", URLUtilities.encode(title),
- "excerpt", URLUtilities.encode(excerpt),
- "url", URLUtilities.encode(url),
- "blog_name", URLUtilities.encode(blog_name));
- String queryString = URLUtilities.getQueryString(params);
-
- LOG.debug("query string - " + queryString);
-
- // prepare http request
- HttpClient client = new HttpClient();
- client.setConnectionTimeout(45 * RollerConstants.SEC_IN_MS);
- HttpMethod method = new PostMethod(trackbackURL);
- method.setQueryString(queryString);
-
- try {
- // execute trackback
- int statusCode = client.executeMethod(method);
-
- // read response
- byte[] response = method.getResponseBody();
- String responseString = Utilities.escapeHTML(new String(response, StandardCharsets.UTF_8));
-
- LOG.debug("result = " + statusCode + " " + method.getStatusText());
- LOG.debug("response:\n" + responseString);
-
- if(statusCode == HttpStatus.SC_OK) {
- // trackback request succeeded, message will give details
- try {
- messages = parseTrackbackResponse(new String(response, StandardCharsets.UTF_8), messages);
- } catch (Exception e) {
- // Cannot parse response, indicates failure
- messages.addError("weblogEdit.trackbackErrorParsing", responseString);
- }
- } else if(statusCode == HttpStatus.SC_NOT_FOUND) {
- // 404, invalid trackback url
- messages.addError("weblogEdit.trackbackError404");
- } else {
- // some other kind of error with url, like 500, 403, etc
- // just provide a generic error message and give the http response text
- messages.addError("weblogEdit.trackbackErrorResponse",
- new String[] {""+statusCode, method.getStatusText()});
- }
-
- } catch (IOException e) {
- // some kind of transport error sending trackback post
- LOG.debug("Error sending trackback", e);
- messages.addError("weblogEdit.trackbackErrorTransport");
- } finally {
- // release used connection
- method.releaseConnection();
- }
-
- return messages;
- }
-
-
- /**
- * Parse XML returned from trackback POST, returns error or success message
- * in RollerMessages object.
- */
- private RollerMessages parseTrackbackResponse(String response, RollerMessages messages)
- throws JDOMException, IOException {
-
- SAXBuilder builder = new SAXBuilder();
- Document doc = builder.build(
- new StringReader(StringEscapeUtils.unescapeHtml4(response)));
- Element root = doc.getRootElement();
-
- if ("response".equals(root.getName())) {
- int code = -99;
- try {
- code = Integer.parseInt(root.getChildText("error"));
- } catch (NumberFormatException ignoredByDesign) {}
-
- String message = root.getChildText("message");
- if (code != 0) {
- messages.addError("weblogEdit.trackbackFailure", Utilities.removeHTML(message));
- } else {
- messages.addMessage("weblogEdit.trackbackSuccess");
- }
- } else {
- messages.addError("weblogEdit.trackbackErrorParsing", Utilities.removeHTML(response));
- }
-
- return messages;
- }
-
-}
diff --git a/app/src/main/java/org/apache/roller/weblogger/util/TrackbackNotAllowedException.java b/app/src/main/java/org/apache/roller/weblogger/util/TrackbackNotAllowedException.java
deleted file mode 100644
index f5056f693..000000000
--- a/app/src/main/java/org/apache/roller/weblogger/util/TrackbackNotAllowedException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.util;
-
-import org.apache.roller.weblogger.WebloggerException;
-
-
-/**
- * An exception thrown when a Trackback is formed for a url which is disallowed
- * by the system administrator.
- */
-public class TrackbackNotAllowedException extends WebloggerException {
-
- public TrackbackNotAllowedException(String url) {
- super(url);
- }
-
-}
diff --git a/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties b/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
index d73e7f9ca..8fba94217 100644
--- a/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
+++ b/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
@@ -198,12 +198,6 @@ site.bannedwordslist.enable.trackbacks=true
# enables partial bannedwordslist check (not including bannedwordslist.txt) for each incoming referrer
site.bannedwordslist.enable.referrers=false
-# Trackback protection. Set this only if you need to limit the URLs to
-# which users may send trackbacks. Regex expressions are allowed, for example:
-# trackback.allowedURLs=http://w3.ibm.com/.*||http://another.example.com/.*
-trackback.allowedURLs=
-
-
#----------------------------------
# Planet Aggregator settings
diff --git a/app/src/main/resources/struts.xml b/app/src/main/resources/struts.xml
index cc94ba658..e3bab427c 100644
--- a/app/src/main/resources/struts.xml
+++ b/app/src/main/resources/struts.xml
@@ -359,7 +359,7 @@
<param name="weblog">${weblog}</param>
<param name="bean.id">${bean.id}</param>
</result>
- <allowed-methods>execute,firstSave,publish,saveDraft,trackback</allowed-methods>
+ <allowed-methods>execute,firstSave,publish,saveDraft</allowed-methods>
</action>
<action name="entryEdit"
@@ -371,7 +371,7 @@
<param name="actionName">menu</param>
<param name="namespace">/roller-ui</param>
</result>
- <allowed-methods>execute,firstSave,publish,saveDraft,trackback</allowed-methods>
+ <allowed-methods>execute,firstSave,publish,saveDraft</allowed-methods>
</action>
<action name="entryRemove"
diff --git a/app/src/main/webapp/WEB-INF/jsps/editor/EntryEdit.jsp b/app/src/main/webapp/WEB-INF/jsps/editor/EntryEdit.jsp
index 61995356a..7677d2489 100644
--- a/app/src/main/webapp/WEB-INF/jsps/editor/EntryEdit.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/editor/EntryEdit.jsp
@@ -297,19 +297,6 @@
</span>
</s:if>
-
- <%-- Trackback control
- <s:if test="actionName == 'entryEdit' && userAnAuthor">
- <br/>
- <h2><s:text name="weblogEdit.trackback"/></h2>
- <s:text name="weblogEdit.trackbackUrl"/>
- <br/>
- <s:textfield name="trackbackUrl" size="80" maxlength="255" style="width:35%"/>
-
- <s:submit value="%{getText('weblogEdit.sendTrackback')}" action="entryEdit!trackback"/>
- </s:if>
- --%>
-
</s:form>
diff --git a/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/EntryTrackbackRemovalTest.java b/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/EntryTrackbackRemovalTest.java
new file mode 100644
index 000000000..961593458
--- /dev/null
+++ b/app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/EntryTrackbackRemovalTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ */
+package org.apache.roller.weblogger.ui.struts2.editor;
+
+import java.io.InputStream;
+import java.util.Set;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.junit.jupiter.api.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class EntryTrackbackRemovalTest {
+
+ @Test
+ void entryActionsDoNotAllowTrackbackMethod() throws Exception {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+ factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+ factory.setXIncludeAware(false);
+ factory.setExpandEntityReferences(false);
+
+ try (InputStream input = getClass().getClassLoader().getResourceAsStream("struts.xml")) {
+ assertNotNull(input);
+ Document config = factory.newDocumentBuilder().parse(input);
+ NodeList actions = config.getElementsByTagName("action");
+ Set<String> expectedActions = Set.of("entryAdd", "entryEdit");
+ int actionsChecked = 0;
+
+ for (int i = 0; i < actions.getLength(); i++) {
+ Element action = (Element) actions.item(i);
+ if (expectedActions.contains(action.getAttribute("name"))) {
+ NodeList allowedMethods = action.getElementsByTagName("allowed-methods");
+ assertEquals(1, allowedMethods.getLength());
+ String methods = allowedMethods.item(0).getTextContent();
+ assertFalse(Set.of(methods.trim().split("\\s*,\\s*")).contains("trackback"));
+ actionsChecked++;
+ }
+ }
+
+ assertEquals(expectedActions.size(), actionsChecked);
+ }
+ }
+
+ @Test
+ void outboundTrackbackImplementationIsRemoved() {
+ assertThrows(NoSuchMethodException.class,
+ () -> EntryEdit.class.getMethod("trackback"));
+ assertThrows(ClassNotFoundException.class,
+ () -> Class.forName("org.apache.roller.weblogger.util.Trackback"));
+ assertThrows(ClassNotFoundException.class,
+ () -> Class.forName(
+ "org.apache.roller.weblogger.util.TrackbackNotAllowedException"));
+ }
+}