fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-12-01 08:36 am

[dw-free] Crosspost set-up error unhelpful

[commit: http://hg.dwscoalition.org/dw-free/rev/ed1682f8a46e]

http://bugs.dwscoalition.org/show_bug.cgi?id=2445

Fix the URL if we have other lj-type site + only provided the domain.

Patch by [personal profile] fu.

Files modified:
  • cgi-bin/DW/External/XPostProtocol.pm
  • cgi-bin/DW/External/XPostProtocol/LJXMLRPC.pm
  • htdocs/manage/externalaccount.bml
--------------------------------------------------------------------------------
diff -r f8dbf3b0a52e -r ed1682f8a46e cgi-bin/DW/External/XPostProtocol.pm
--- a/cgi-bin/DW/External/XPostProtocol.pm	Thu Dec 01 16:16:05 2011 +0800
+++ b/cgi-bin/DW/External/XPostProtocol.pm	Thu Dec 01 16:36:48 2011 +0800
@@ -141,8 +141,8 @@
 }
 
 # validates that the given server is running the appropriate protocol.
-# must be run in an eval block.  returns 1 on success, 0 on failure
-sub validate_server { 1 }
+# must be run in an eval block.  returns ( 1, $validurl ) on success, 0 on failure
+sub validate_server { return ( 1, $_[0] ); }
 
 # hash the password in a protocol-specific manner
 sub encrypt_password {
diff -r f8dbf3b0a52e -r ed1682f8a46e cgi-bin/DW/External/XPostProtocol/LJXMLRPC.pm
--- a/cgi-bin/DW/External/XPostProtocol/LJXMLRPC.pm	Thu Dec 01 16:16:05 2011 +0800
+++ b/cgi-bin/DW/External/XPostProtocol/LJXMLRPC.pm	Thu Dec 01 16:36:48 2011 +0800
@@ -245,25 +245,44 @@
 # must be run in an eval block.  returns 1 on success, dies with an error
 # message on failure.
 sub validate_server {
-    my ($self, $proxyurl) = @_;
+    my ($self, $proxyurl, $depth) = @_;
+    $depth ||= 1;
 
     # get the xml-rpc proxy and start the connection.
     my $xmlrpc = eval { XMLRPC::Lite->proxy($proxyurl); };
+
     # fail if no proxy
     return 0 unless $xmlrpc;
 
     # assume if we respond to LJ.XMLRPC.getchallenge, then we're good
     # on the server.
     # note:  this will die on a failed connection with an error.
-    my $challengecall = $xmlrpc->call("LJ.XMLRPC.getchallenge");
-    if ($challengecall->fault) {
+    my $challengecall = eval{ $xmlrpc->call("LJ.XMLRPC.getchallenge"); };
+    if ($challengecall && $challengecall->fault) {
         # error from the server
         #die($challengecall->faultstring);
         return 0;
     }
 
-    # otherwise success.
-    return 1;
+    # error; URL probably wrong. Guess and try again
+    if ( $@ ) {
+        return 0 if $depth > 2;
+        eval "use URI;";
+        return 0 if $@;
+
+        my $uri = URI->new( $proxyurl );
+
+        my $path = $uri->path;
+        # don't try to guess further if user actually gave us a path
+        return 0 if $path && $path ne "/";
+
+        # user didn't provide us a path, so let's guess
+        $uri->path( "/interface/xmlrpc" );
+        return $self->validate_server( $uri->as_string, $depth+1 );
+    }
+
+    # otherwise success. (proxyurl has possibly been updated)
+    return ( 1, $proxyurl );
 }
 
 # translates at Entry object into a request for crossposting
diff -r f8dbf3b0a52e -r ed1682f8a46e htdocs/manage/externalaccount.bml
--- a/htdocs/manage/externalaccount.bml	Thu Dec 01 16:16:05 2011 +0800
+++ b/htdocs/manage/externalaccount.bml	Thu Dec 01 16:36:48 2011 +0800
@@ -309,7 +309,9 @@
         $errs->{username} = BML::ml('.settings.xpost.error.username.required');
         $ok = 0;
     }
-    
+
+    my $extacct_info = +{ map { $_ => $POST{$_}  } keys %POST };
+
     # check if it's a default site or a custom site
     if ($POST->{"site"} ne -1) {
         # default site; just use the siteid
@@ -335,8 +337,11 @@
                 $errs->{servicetype} = BML::ml('.settings.xpost.error.servicetype', { servicetype => $opts{servicetype} });
                 $ok = 0;
             } else {
-                my $valid = $protocol->validate_server($opts{serviceurl});
-                if (! $valid) {
+                my ( $valid, $serviceurl ) = $protocol->validate_server( $opts{serviceurl} );
+                if ( $valid ) {
+                    # update in case it's been canonicalized
+                    $extacct_info->{serviceurl} = $opts{serviceurl} = $serviceurl;
+                } else {
                     $errs->{serviceurl} = BML::ml('.settings.xpost.error.url', { url => $opts{serviceurl} });
                     $ok = 0;
                 }
@@ -346,7 +351,8 @@
 
     # verification of account info - only do this if $ok isn't already set to 0, so we have username/password and valid site info
     if ( $ok ) {
-        my $account_valid = account_isvalid( $u, \%POST );
+        my $account_valid = account_isvalid( $u, $extacct_info );
+
         if ( $account_valid != 1 ) {
             $ok = 0;
             #create different error messages for different server errors. If we get some other error message, show the one we get from the server
@@ -371,8 +377,7 @@
         } else { 
             $protocol = DW::External::XPostProtocol->get_protocol( $opts{servicetype} );
         }
-        my $options = parse_options( $protocol, $POST );
-
+        my $options = parse_options( $protocol, $extacct_info );
         $opts{options} = $options;
 
         # if the user requested that we don't save their password, then
--------------------------------------------------------------------------------