New page when viewing a protected entry: if logged in, just present an 
informative error message. If logged out, show forms to log in via either a 
Dreamwidth account, or an OpenID account.

        Patch by allen. 

diffs (300 lines):

diff -r d98d283c7fbe -r f4fd12b8dc1e cgi-bin/Apache/LiveJournal.pm
--- a/cgi-bin/Apache/LiveJournal.pm     Tue Jul 06 23:05:04 2010 +0800
+++ b/cgi-bin/Apache/LiveJournal.pm     Wed Jul 07 12:51:39 2010 +0800
@@ -1397,6 +1397,15 @@ sub journal_content
     # Allow to add extra http-header or even modify html
     LJ::Hooks::run_hooks("after_journal_content_created", $opts, \$html) 
unless $handle_with_siteviews;
 
+    # check for redirects
+    if ( $opts->{internal_redir} ) {
+        my $int_redir = DW::Routing->call( uri => $opts->{internal_redir} );
+        if ( defined $int_redir ) {
+            # we got a match; clear the request cache and return DECLINED.
+            LJ::start_request();
+            return DECLINED;
+        }
+    }
     return redir($r, $opts->{'redir'}) if $opts->{'redir'};
     return $opts->{'handler_return'} if defined $opts->{'handler_return'};
 
diff -r d98d283c7fbe -r f4fd12b8dc1e cgi-bin/DW/Controller.pm
--- a/cgi-bin/DW/Controller.pm  Tue Jul 06 23:05:04 2010 +0800
+++ b/cgi-bin/DW/Controller.pm  Wed Jul 07 12:51:39 2010 +0800
@@ -21,6 +21,8 @@ use Exporter;
 use Exporter;
 use DW::Routing;
 use DW::Template;
+use URI;
+
 
 our ( @ISA, @EXPORT );
 @ISA = qw/ Exporter /;
@@ -140,4 +142,23 @@ sub controller {
     return $ok->();
 }
 
+# checks a URL to make sure it's ok to redirect to it.
+#
+# note that this checks on the host name of the given URL, so it's important
+# to make sure to pass in a full, absolute URL rather than a relative URI.
+sub validate_redirect_url {
+    my $url = $_[0];
+
+    return 0 unless $url;
+
+    # Redirect to offsite uri if allowed, and not an internal LJ redirect.
+    my $parsed_uri = URI->new($url);
+    
+    # if the given URI isn't valid, the URI module doesn't even give the 
+    # returned object a host method
+    my $redir_host = eval { $parsed_uri->host } || "";
+        
+    return $LJ::REDIRECT_ALLOWED{$redir_host} || $redir_host =~ 
m#${LJ::DOMAIN}$#i;
+}
+
 1;
diff -r d98d283c7fbe -r f4fd12b8dc1e cgi-bin/DW/Routing.pm
--- a/cgi-bin/DW/Routing.pm     Tue Jul 06 23:05:04 2010 +0800
+++ b/cgi-bin/DW/Routing.pm     Wed Jul 07 12:51:39 2010 +0800
@@ -52,6 +52,7 @@ Valid options:
 
 =over
 
+=item uri - explicitly override the uri
 =item role - explicitly define the role
 =item username - define the username, implies username role
 =item ssl - this is a SSL page, implies the ssl role
@@ -76,6 +77,7 @@ Valid options:
 
 =over
 
+=item uri - explicitly override the uri
 =item role - explicitly define the role
 =item username - define the username, implies username role
 =item ssl - this is a SSL page, implies the ssl role
@@ -90,7 +92,8 @@ sub get_call_opts {
     my ( $class, %opts ) = @_;
     my $r = DW::Request->get;
 
-    my ( $uri, $format ) = ( $r->uri, undef );
+    my $uri = $opts{uri} ||  $r->uri;
+    my $format = undef;
     ( $uri, $format ) = ( $1, $2 )
         if $uri =~ m/^(.+?)\.([a-z]+)$/;
 
diff -r d98d283c7fbe -r f4fd12b8dc1e cgi-bin/DW/Template.pm
--- a/cgi-bin/DW/Template.pm    Tue Jul 06 23:05:04 2010 +0800
+++ b/cgi-bin/DW/Template.pm    Wed Jul 07 12:51:39 2010 +0800
@@ -43,6 +43,7 @@ my $roots_constants = Template::Namespac
 my $roots_constants = Template::Namespace::Constants->new({
     site => $LJ::SITEROOT,
     img => $LJ::IMGPREFIX,
+    ssl => $LJ::SSLROOT,
 });
 
 # precreating this
diff -r d98d283c7fbe -r f4fd12b8dc1e cgi-bin/LJ/S2/EntryPage.pm
--- a/cgi-bin/LJ/S2/EntryPage.pm        Tue Jul 06 23:05:04 2010 +0800
+++ b/cgi-bin/LJ/S2/EntryPage.pm        Wed Jul 07 12:51:39 2010 +0800
@@ -54,6 +54,7 @@ sub EntryPage
     return if $opts->{'readonlyjournal'};
     return if $opts->{'handler_return'};
     return if $opts->{'redir'};
+    return if $opts->{'internal_redir'};
 
     $p->{'multiform_on'} = $entry->comments_manageable_by($remote);
 
@@ -463,17 +464,28 @@ sub EntryPage_entry
 
     # check using normal rules
     unless ($entry->visible_to($remote, $canview)) {
-        if ($remote) {
-            $opts->{'handler_return'} = 403;
-            return;
-        } else {
-            my $host = $r->headers_in->{Host};
-            my $args = scalar $r->args;
-            my $querysep = $args ? "?" : "";
-            my $redir = LJ::eurl("http://$host$uri$querysep$args";);
-            $opts->{'redir'} = 
"$LJ::SITEROOT/?returnto=$redir&errmsg=notloggedin";
-            return;
+        # this checks to see why the logged-in user is not allowed to see
+        # the given content.
+        if (defined $remote) {
+            my $journal = $entry->journal;
+
+            if ( $journal->is_community && ! $journal->is_closed_membership && 
$remote && $entry->security ne "private" ) {
+                $r->notes->{error_key} = ".comm.open";
+                $r->notes->{journalname} = $journal->name_raw;
+            } elsif ( $journal->is_community && $journal->is_closed_membership 
) {
+                $r->notes->{error_key} = ".comm.closed";
+                $r->notes->{journalname} = $journal->name_raw;
+            }
         }
+
+        my $host = $r->headers_in->{Host};
+        my $args = scalar $r->args;
+        my $querysep = $args ? "?" : "";
+        my $redir = "http://$host$uri$querysep$args";;
+        $opts->{internal_redir} = "/protected";
+        $r->notes->{journalid} = $entry->journalid;
+        $r->notes->{returnto} = $redir;
+        return;
     }
 
     if ( $pu && $pu->is_suspended && ! $viewsome ) {
diff -r d98d283c7fbe -r f4fd12b8dc1e cgi-bin/LJ/Talk.pm
--- a/cgi-bin/LJ/Talk.pm        Tue Jul 06 23:05:04 2010 +0800
+++ b/cgi-bin/LJ/Talk.pm        Wed Jul 07 12:51:39 2010 +0800
@@ -271,28 +271,31 @@ sub check_viewable
         or die "Unable to construct entry object.\n";
     return 1 if $ent->visible_to( $remote );
 
-    my $journal = LJ::load_userid( $item->{ownerid} );
-    my $journalname = $journal->username;
+    my $r = BML::get_request();
 
+    # this checks to see why the logged-in user is not allowed to see
+    # the given content.
     if (defined $remote) {
+        my $journal = LJ::load_userid( $item->{ownerid} );
+        my $journalname = $journal->username;
+
         if ( $journal->is_community && ! $journal->is_closed_membership && 
$remote && $item->{security} ne "private" ) {
-            return $err->( BML::ml( 'talk.error.notauthorised.comm.open', { 
aopts => "href='$LJ::SITEROOT/community/join?comm=$journalname'" } ) );
+            $r->notes->{error_key} = ".comm.open";
+            $r->notes->{journalname} = $journalname;
         } elsif ( $journal->is_community && $journal->is_closed_membership ) {
-            return $err->( BML::ml( 'talk.error.notauthorised.comm.closed' ) );
-        } else {
-            return $err->( BML::ml( 'talk.error.notauthorised' ) );
+            $r->notes->{error_key} = ".comm.closed";
+            $r->notes->{journalname} = $journalname;
         }
-    } else {
-        my $r = BML::get_request();
-        my $host = $r->headers_in->{Host};
-        my $args = scalar $r->args;
-        my $querysep = $args ? "?" : "";
-        my $redir = LJ::eurl("http://"; . $host . $r->uri . $querysep . $args);
-
-        return 
$err->(BML::redirect("$LJ::SITEROOT/?returnto=$redir&errmsg=notloggedin"));
     }
 
-    return 1;
+    my $host = $r->headers_in->{Host};
+    my $args = scalar $r->args;
+    my $querysep = $args ? "?" : "";
+    my $returnto = "http://"; . $host . $r->uri . $querysep . $args;
+    $r->notes->{internal_redir} = "/protected";
+    $r->notes->{returnto} = $returnto;
+    return 0;
+
 }
 
 # <LJFUNC>
diff -r d98d283c7fbe -r f4fd12b8dc1e htdocs/login.bml
--- a/htdocs/login.bml  Tue Jul 06 23:05:04 2010 +0800
+++ b/htdocs/login.bml  Wed Jul 07 12:51:39 2010 +0800
@@ -62,27 +62,21 @@ _c?>
     # we may want to redirect later in successfull cases, based on this ugly 
blob of logic
     # return 1 if $want_success_redirect is handling the request, otherwise 0 
and the caller should handle
     my $want_success_redirect = sub {
-        if ($POST{returnto}) {
+        my $redirect_url;
+        if ( $POST{returnto} ) {
             # this passes in the URI of the page to redirect to on success, eg:
             # /manage/profile/index?authas=test or whatever
-            my $uri = $POST{returnto};
-            if ($uri =~ /^\//) {
-                $uri = $LJ::SITEROOT . $uri;
+            $redirect_url = $POST{returnto};
+            if ($redirect_url =~ /^\//) {
+                $redirect_url = $LJ::SITEROOT . $redirect_url;
             }
-            BML::redirect($uri);
+        } elsif ( $POST{ret} && $POST{ret} != 1 ) {
+            $redirect_url = $POST{ret};
+        }
+        if ( $redirect_url && DW::Controller::validate_redirect_url( 
$redirect_url ) ) {
+            LJ::Hooks::run_hook( 'login_redirect_extra', $redirect_url );
+            BML::redirect( $redirect_url );
             return 1;
-        }
-
-        # Redirect to offsite uri if allowed, and not an internal LJ redirect. 
('ret' == 1)
-        if ($POST{ret} && $POST{ret} != 1) {
-            my $redir_host;
-            $redir_host = $1 if $POST{ret} =~ m#^http://([\.:\w-]+)#i;
-        
-            if ($LJ::REDIRECT_ALLOWED{$redir_host} || $redir_host eq 
$LJ::DOMAIN_WEB) {
-                LJ::Hooks::run_hook('login_redirect_extra', $redir_host);
-                BML::redirect($POST{ret});
-                return 1;
-            }
         }
 
         return 0;
@@ -129,6 +123,14 @@ _c?>
                 $body .= "<?warningbar " . BML::ml('.loggedin.openidemail', { 
aopts1 => "href='$LJ::SITEROOT/changeemail'", aopts2 => 
"href='$LJ::SITEROOT/register'" }) . " warningbar?>";
             }
             $body .= "<br />\n";
+
+            if ( $GET{'continue_to'} ) {
+                $body .= "<div style='margin-left: 36px'>";
+                $body .= "<?h2 <a href=\"" . LJ::ehtml( $GET{'continue_to'} ) 
. "\">";
+                $body .= BML::ml( '.loggedin.continueto', { 'continue_url' => 
LJ::ehtml ( $GET{'continue_to'} ) } ) . "</a> h2?>\n";
+                $body .= "</div>\n";
+                $body .= "<br />\n";
+            }
 
             unless ( $remote->is_identity ) {
                 $body .= "<div style='float: left; padding: 5px 10px 0px 
10px;'>";
diff -r d98d283c7fbe -r f4fd12b8dc1e htdocs/login.bml.text
--- a/htdocs/login.bml.text     Tue Jul 06 23:05:04 2010 +0800
+++ b/htdocs/login.bml.text     Wed Jul 07 12:51:39 2010 +0800
@@ -14,6 +14,8 @@
 .createaccount.whylogin.benefit5=Access features that are only visible when 
you're logged in.
 
 .error.notuser=Username not found.  Would you like to <a [[aopts]]>create an 
account</a> using this username?
+
+.loggedin.continueto=Continue to [[continue_url]]
 
 .loggedin.head2=Welcome back to [[sitename]]!
 
diff -r d98d283c7fbe -r f4fd12b8dc1e htdocs/openid/login.bml
--- a/htdocs/openid/login.bml   Tue Jul 06 23:05:04 2010 +0800
+++ b/htdocs/openid/login.bml   Wed Jul 07 12:51:39 2010 +0800
@@ -31,7 +31,9 @@ _c?>
     return $err->($ML{'.error.no_support'})
         unless LJ::OpenID::consumer_enabled();
 
-    my $return_to = "$LJ::SITEROOT/openid/login";
+    my $query_args = $POST{'continue_to'} ? "?continue_to=" .  LJ::eurl( 
$POST{'continue_to'} ) : "";
+    
+    my $return_to = "$LJ::SITEROOT/openid/login" . $query_args;
 
     my $remote = LJ::get_remote();
     if ($remote) {
@@ -77,9 +79,19 @@ _c?>
         $u->make_login_session($sess_opts->{'exptype'}, 
$sess_opts->{'ipfixed'});
         LJ::set_remote($u);
 
-        return BML::redirect("$LJ::SITEROOT/login");
+        my $redirect = "$LJ::SITEROOT/login";
+        # handle the continue_to url, if it's a valid URL to redirect to.
+        my $continue_to = $GET{'continue_to'};
+        if ( $continue_to && DW::Controller::validate_redirect_url( 
$continue_to ) ) {
+            # if the account is validated, then go ahead and redirct
+            if ( $u->is_validated ) {
+                $redirect = $continue_to;
+            } else {
+                $redirect .= "?continue_to=" . LJ::eurl( $continue_to );
+            }
+        }
+        return BML::redirect( $redirect );
     }
-
 
     if (LJ::did_post()) {
         my $csr = LJ::OpenID::consumer();
_______________________________________________
dw-changelog mailing list
[email protected]
http://lists.dwscoalition.org/mailman/listinfo/dw-changelog

Reply via email to