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"));
+    }
+}