svn: /pear/pearweb/trunk/ include/pear-database-channel.php public_html/channels/add.php

[email protected] ("Daniel O'Connor") Sat, 09 Apr 2011 14:25:07 +0000
Newsgroups php.pear.cvs,php.pear.core
Message-ID <[email protected]>
clockwerx                                Sat, 09 Apr 2011 14:25:07 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=310093

Log:
Cleanup of validation/error behaviour.

Changed paths:
    U   pear/pearweb/trunk/include/pear-database-channel.php
    U   pear/pearweb/trunk/public_html/channels/add.php
svn-diffs-310093.txt (text/x-diff, 10.9 KB)
Modified: pear/pearweb/trunk/include/pear-database-channel.php
===================================================================
--- pear/pearweb/trunk/include/pear-database-channel.php	2011-04-09 14:03:31 UTC (rev 310092)
+++ pear/pearweb/trunk/include/pear-database-channel.php	2011-04-09 14:25:07 UTC (rev 310093)
@@ -67,6 +67,18 @@
         }
     }

+    static function exists($name)
+    {
+        global $dbh;
+        $query = "SELECT * FROM channels WHERE name = ?";
+        $err = $dbh->query($query, array($name));
+        if (DB::isError($err)) {
+            return $err;
+        }
+
+        return $err->numRows();
+    }
+
     /**
      * List all registered channels
      * @return array Format: array(array(channel server), array(channel server),... )
@@ -100,4 +112,37 @@
         $query = 'SELECT name, project_label, project_link, contact_name, contact_email FROM channels WHERE is_active = 0';
         return $dbh->getAll($query, null, DB_FETCHMODE_ASSOC);
     }
+
+    /** A method to validate a channel */
+    static function validate(HTTP_Request2 $req, PEAR_ChannelFile $chan)
+    {
+        $response = $req->send();
+        if ($response->getStatus() != 200) {
+            throw new Exception("Invalid channel site");
+        }
+
+        if (!$response->getBody()) {
+            throw new Exception("Empty channel.xml");
+        }
+
+
+        if (strlen($response->getBody()) > 100000) {
+            throw new Exception("Channel.xml too large");
+        }
+
+        if (!$chan->fromXmlString($response->getBody())) {
+            throw new Exception("Invalid xml");
+        }
+
+        if (!$chan->validate()) {
+            throw new Exception("Invalid channel file");
+        }
+
+        if ($url->getHost() != $chan->getServer()) {
+            throw new Exception("Channel server for wrong host");
+        }
+
+
+        return true;
+    }
 }

Modified: pear/pearweb/trunk/public_html/channels/add.php
===================================================================
--- pear/pearweb/trunk/public_html/channels/add.php	2011-04-09 14:03:31 UTC (rev 310092)
+++ pear/pearweb/trunk/public_html/channels/add.php	2011-04-09 14:25:07 UTC (rev 310093)
@@ -27,6 +27,7 @@
 require_once 'pear-database-channel.php';
 require_once 'HTML/QuickForm2/Renderer.php';
 require_once 'HTML/QuickForm2/Element/Input.php';
+require_once 'PEAR/ChannelFile.php';

 /** @todo Shift ! */
 if (!class_exists('HTML_QuickForm2_Element_InputUrl')) {
@@ -49,6 +50,8 @@
     HTML_QuickForm2_Factory::registerElement('email', 'HTML_QuickForm2_Element_InputEmail');
 }

+$chan = new PEAR_ChannelFile;
+
 $tabs = array("List" => array("url" => "/channels/index.php",
                               "title" => "List Sites."),
               "Add Site" => array("url" => "/channels/add.php",
@@ -114,114 +117,69 @@
         $req = new HTTP_Request2;

         $req->setURL($url->getScheme() . "://" . $url->getHost() . ":" . $url->getPort() . "/channel.xml");
-        $response = $req->send();
-        if ($response->getStatus() != 200) {
-            echo "<div class=\"errors\">The submitted URL does not ";
-            echo "appear to point to a valid channel site.  You will ";
-            echo "have to make sure that <tt>/channel.xml</tt> at least ";
-            echo "exists and is valid.  If you think that this mechanism does not work ";
-            echo "properly, please drop a mail to the ";
-            echo '<a href="mailto:' . PEAR_WEBMASTER_EMAIL . '">webmasters</a>.';
-            echo "</div>";
+        channel::validate($request, $chan, $project_name);

-            echo $form;
-        } elseif (!$response->getBody()) {
-            // channel.xml is empty - spam spam spam
-            echo "<div class=\"errors\">The submitted URL does not ";
-            echo "appear to point to a valid channel site.  You will ";
-            echo "have to make sure that <tt>/channel.xml</tt> at least ";
-            echo "exists and is valid.  If you think that this mechanism does not work ";
-            echo "properly, please drop a mail to the ";
-            echo '<a href="mailto:' . PEAR_WEBMASTER_EMAIL . '">webmasters</a>.';
-            echo "</div>";
+        if (channel::exists($project_name)) {
+            throw new Exception("Already exists");
+        }

-            echo $form;
-        } elseif (strlen($response->getBody()) > 100000) {
-            // channel.xml is huge - possible DoS attack
-            echo "<div class=\"errors\">The submitted URL does not ";
-            echo "appear to point to a valid channel site.  You will ";
-            echo "have to make sure that <tt>/channel.xml</tt> at least ";
-            echo "exists and is not huge.  If you think that this mechanism does not work ";
-            echo "properly, please drop a mail to the ";
-            echo '<a href="mailto:' . PEAR_WEBMASTER_EMAIL . '">webmasters</a>.';
-            echo "</div>";
+        $text = sprintf("[Channels] Please activate %s (%s) on the channel index.",
+                        $project_name->getValue(),
+                        $project_link->getValue());
+        $from = sprintf('"%s" <%s>',
+                        $name->getValue(),
+                        $email->getValue());

-            echo $form;
-        } else {
-            do {
-                // poor man's try/catch
-                require_once 'PEAR/ChannelFile.php';
-                $chan = new PEAR_ChannelFile;
-                if (!$chan->fromXmlString($response->getBody())) {
-                    // channel.xml is invalid xml - spam spam spam
-                    echo "<div class=\"errors\">The submitted URL does not ";
-                    echo "appear to point to a valid channel site.  You will ";
-                    echo "have to make sure that <tt>/channel.xml</tt> at least ";
-                    echo "exists and is valid.  If you think that this mechanism does not work ";
-                    echo "properly, please drop a mail to the ";
-                    echo '<a href="mailto:' . PEAR_WEBMASTER_EMAIL . '">webmasters</a>.';
-                    echo "</div>";
+        $logger = new Damblan_Log;

-                    echo $form;
-                    break;
-                }
-                if (!$chan->validate()) {
-                    // channel.xml is invalid channelfile xml - spam spam spam
-                    echo "<div class=\"errors\">The submitted URL does not ";
-                    echo "appear to point to a valid channel site.  You will ";
-                    echo "have to make sure that <tt>/channel.xml</tt> at least ";
-                    echo "exists and is valid.  If you think that this mechanism does not work ";
-                    echo "properly, please drop a mail to the ";
-                    echo '<a href="mailto:' . PEAR_WEBMASTER_EMAIL . '">webmasters</a>.';
-                    echo "</div>";
+        $observer = new Damblan_Log_Mail;
+        $observer->setRecipients(PEAR_WEBMASTER_EMAIL);
+        $observer->setHeader("From", $from);
+        $observer->setHeader("Subject", "Channel link submission");
+        $logger->attach($observer);

-                    echo $form;
-                    break;
-                }
-                if ($url->getHost() != $chan->getServer()) {
-                    // channel.xml refers to different site - spam spam spam
-                    echo "<div class=\"errors\">The submitted URL does not ";
-                    echo "appear to point to a valid channel site.  You will ";
-                    echo "have to make sure that <tt>/channel.xml</tt> at least ";
-                    echo "exists and is valid.  In addition, it must refer to ";
-                    echo "your channel.  If you think that this mechanism does not work ";
-                    echo "properly, please drop a mail to the ";
-                    echo '<a href="mailto:' . PEAR_WEBMASTER_EMAIL . '">webmasters</a>.';
-                    echo "</div>";
+        $logger->log($text);

-                    echo $form;
-                    break;
-                }
-                $text = sprintf("[Channels] Please activate %s (%s) on the channel index.",
-                                $project_name->getValue(),
-                                $project_link->getValue());
-                $from = sprintf('"%s" <%s>',
-                                $name->getValue(),
-                                $email->getValue());
+        // Add the channel to the DB, but not yet activated
+        channel::add($project_name);
+        channel::edit($project_name, $project_label, $project_link, $name, $email);

-                $logger = new Damblan_Log;

-                $observer = new Damblan_Log_Mail;
-                $observer->setRecipients(PEAR_WEBMASTER_EMAIL);
-                $observer->setHeader("From", $from);
-                $observer->setHeader("Subject", "Channel link submission");
-                $logger->attach($observer);
+        echo "<div class=\"success\">Thanks for your submission.  It will ";
+        echo "be reviewed as soon as possible.</div>\n";
+    } catch (Exception $exception) {
+        echo '<div class="errors">';

-                $logger->log($text);
+        switch ($exception->getMessage()) {
+            case "Invalid channel site":
+                echo "The submitted URL does not ";
+                echo "appear to point to a valid channel site.  You will ";
+                echo "have to make sure that <tt>/channel.xml</tt> at least ";
+                echo "exists and is valid.";
+            break;

-                // Add the channel to the DB, but not yet activated
-                channel::add($project_name);
-                channel::edit($project_name, $project_label, $project_link, $name, $email);
+            case "Empty channel.xml":
+                echo "The submitted URL does not ";
+                echo "appear to point to a valid channel site.  You will ";
+                echo "have to make sure that <tt>/channel.xml</tt> at least ";
+                echo "exists and is valid.";
+            break;

-                echo "<div class=\"success\">Thanks for your submission.  It will ";
-                echo "be reviewed as soon as possible.</div>\n";
-            } while (false);
+            case "Channel.xml too large":
+                echo "The submitted URL does not ";
+                echo "appear to point to a valid channel site.  You will ";
+                echo "have to make sure that <tt>/channel.xml</tt> at least ";
+                echo "exists and is not huge.";
+            break;
+            default:
+                echo $exception->getMessage();
+            break;
         }
-    } catch (HTTP_Request2_Exception $exception) {
-        echo '<div class="errors">';
-        echo $exception->getMessage();
-        echo "</div>";

+        echo "If you think that this mechanism does not work ";
+        echo "properly, please drop a mail to the ";
+        echo '<a href="mailto:' . PEAR_WEBMASTER_EMAIL . '">webmasters</a>.';
+
         echo $form;
     }
 } else {