From e43cd269d2b492da6fc4bfdc3d6930e88f1dfa0c Mon Sep 17 00:00:00 2001 From: joey Date: Mon, 20 Nov 2006 09:40:09 +0000 Subject: [PATCH] * Add openidsignup config option. * Make the openid plugin support the callbacks from myopenid.com via its affiliate program. * Change how post signin actions are propigated through the signin process; they're now stored in the session. --- IkiWiki/CGI.pm | 82 +++++++++++++++++++++++--------------- IkiWiki/Plugin/httpauth.pm | 2 +- IkiWiki/Plugin/openid.pm | 42 ++++++++++++------- debian/changelog | 5 +++ doc/ikiwiki.setup | 4 ++ doc/plugins/openid.mdwn | 13 ++++++ 6 files changed, 100 insertions(+), 48 deletions(-) diff --git a/IkiWiki/CGI.pm b/IkiWiki/CGI.pm index c399ad8a6..65e6a2ae9 100644 --- a/IkiWiki/CGI.pm +++ b/IkiWiki/CGI.pm @@ -129,7 +129,7 @@ sub cgi_signin ($$) { #{{{ error($@) if $@; my $form = CGI::FormBuilder->new( title => "signin", - fields => [qw(do title page subpage from name password openid_url)], + fields => [qw(do name password openid_url)], header => 1, charset => "utf-8", method => 'POST', @@ -153,14 +153,13 @@ sub cgi_signin ($$) { #{{{ $form->field(name => "name", required => 0); $form->field(name => "do", type => "hidden"); - $form->field(name => "page", type => "hidden"); - $form->field(name => "title", type => "hidden"); - $form->field(name => "from", type => "hidden"); - $form->field(name => "subpage", type => "hidden"); $form->field(name => "password", type => "password", required => 0); if ($config{openid}) { $form->field(name => "openid_url", label => "OpenID", - comment => '('.htmllink("", "", "OpenID", 1, 0, "What's this?").')'); + comment => '('. + htmllink("", "", "OpenID", 1, 0, "What's this?") + .($config{openidsignup} ? " | Get an OpenID" : "") + .')'); } else { $form->field(name => "openid_url", type => "hidden"); @@ -168,7 +167,7 @@ sub cgi_signin ($$) { #{{{ if ($form->submitted eq "Register" || $form->submitted eq "Create Account") { $form->title("register"); $form->text(""); - $form->fields(qw(do title page subpage from name password confirm_password email)); + $form->fields(qw(do name password confirm_password email)); $form->field(name => "confirm_password", type => "password"); $form->field(name => "email", type => "text"); $form->field(name => "openid_url", type => "hidden"); @@ -189,7 +188,7 @@ sub cgi_signin ($$) { #{{{ name => "openid_url", validate => sub { # FIXME: ugh - IkiWiki::Plugin::openid::validate($q, $session, $form, shift); + IkiWiki::Plugin::openid::validate($q, $session, shift, $form); }, ); } @@ -257,19 +256,7 @@ sub cgi_signin ($$) { #{{{ if ($form->submitted && $form->validate) { if ($form->submitted eq 'Login') { $session->param("name", $form->field("name")); - if (defined $form->field("do") && - $form->field("do") ne 'signin') { - redirect($q, cgiurl( - do => $form->field("do"), - page => $form->field("page"), - title => $form->field("title"), - from => $form->field("from"), - subpage => $form->field("subpage"), - )); - } - else { - redirect($q, $config{url}); - } + cgi_postsignin($q, $session); } elsif ($form->submitted eq 'Create Account') { my $user_name=$form->field('name'); @@ -328,6 +315,23 @@ sub cgi_signin ($$) { #{{{ } } #}}} +sub cgi_postsignin ($$) { #{{{ + my $q=shift; + my $session=shift; + + # Continue with whatever was being done before the signin process. + if (defined $q->param("do") && $q->param("do") ne "signin" && + defined $session->param("postsignin")) { + my $postsignin=CGI->new($session->param("postsignin")); + $session->clear("postsignin"); + cgi($postsignin, $session); + exit; + } + else { + redirect($q, $config{url}); + } +} #}}} + sub cgi_prefs ($$) { #{{{ my $q=shift; my $session=shift; @@ -679,14 +683,19 @@ sub cgi_editpage ($$) { #{{{ } } #}}} -sub cgi () { #{{{ - eval q{use CGI; use CGI::Session}; - error($@) if $@; +sub cgi (;$$) { #{{{ + my $q=shift; + my $session=shift; + + if (! $q) { + eval q{use CGI; use CGI::Session}; + error($@) if $@; - my $q=CGI->new; - - run_hooks(cgi => sub { shift->($q) }); + $q=CGI->new; + run_hooks(cgi => sub { shift->($q) }); + } + my $do=$q->param('do'); if (! defined $do || ! length $do) { my $error = $q->cgi_error; @@ -707,12 +716,14 @@ sub cgi () { #{{{ cgi_hyperestraier(); } - CGI::Session->name("ikiwiki_session_".encode_utf8($config{wikiname})); + if (! $session) { + CGI::Session->name("ikiwiki_session_".encode_utf8($config{wikiname})); - my $oldmask=umask(077); - my $session = CGI::Session->new("driver:DB_File", $q, - { FileName => "$config{wikistatedir}/sessions.db" }); - umask($oldmask); + my $oldmask=umask(077); + $session = CGI::Session->new("driver:DB_File", $q, + { FileName => "$config{wikistatedir}/sessions.db" }); + umask($oldmask); + } # Auth hooks can sign a user in. if ($do ne 'signin' && ! defined $session->param("name")) { @@ -734,10 +745,12 @@ sub cgi () { #{{{ # Everything below this point needs the user to be signed in. if (((! $config{anonok} || $do eq 'prefs') && - (! $config{httpauth}) && (! defined $session->param("name") || ! userinfo_get($session->param("name"), "regdate"))) || $do eq 'signin') { + if ($do ne 'signin' && ! defined $session->param("postsignin")) { + $session->param(postsignin => $ENV{QUERY_STRING}); + } cgi_signin($q, $session); # Force session flush with safe umask. @@ -747,6 +760,9 @@ sub cgi () { #{{{ return; } + elsif (defined $session->param("postsignin")) { + cgi_postsignin($q, $session); + } if (defined $session->param("name") && userinfo_get($session->param("name"), "banned")) { print $q->header(-status => "403 Forbidden"); diff --git a/IkiWiki/Plugin/httpauth.pm b/IkiWiki/Plugin/httpauth.pm index 336eb793a..786bcba3b 100644 --- a/IkiWiki/Plugin/httpauth.pm +++ b/IkiWiki/Plugin/httpauth.pm @@ -7,7 +7,7 @@ use strict; use IkiWiki; sub import { #{{{ - hook(type => "auth", id => "skeleton", call => \&auth); + hook(type => "auth", id => "httpauth", call => \&auth); } # }}} sub auth ($$) { #{{{ diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm index 55b1c4b17..43ce8fd31 100644 --- a/IkiWiki/Plugin/openid.pm +++ b/IkiWiki/Plugin/openid.pm @@ -7,10 +7,18 @@ use strict; use IkiWiki; sub import { #{{{ - hook(type => "checkconfig", id => "smiley", call => \&checkconfig); - hook(type => "auth", id => "skeleton", call => \&auth); + hook(type => "getopt", id => "openid", call => \&getopt); + hook(type => "checkconfig", id => "openid", call => \&checkconfig); + hook(type => "auth", id => "openid", call => \&auth); } # }}} +sub getopt () { #{{{ + eval q{use Getopt::Long}; + error($@) if $@; + Getopt::Long::Configure('pass_through'); + GetOptions("openidsignup=s" => \$config{openidsignup}); +} #}}} + sub checkconfig () { #{{{ # Currently part of the OpenID code is in CGI.pm, and is enabled by # this setting. @@ -34,31 +42,37 @@ sub auth ($$) { #{{{ elsif (my $vident = $csr->verified_identity) { $session->param(name => $vident->url); } + else { + error("OpenID failure: ".$csr->err); + } + } + elsif (defined $q->param('openid_identifier')) { + validate($q, $session, $q->param('openid_identifier')); } } #}}} -sub validate ($$$$) { #{{{ +sub validate ($$$;$) { #{{{ my $q=shift; my $session=shift; - my $form=shift; my $openid_url=shift; + my $form=shift; my $csr=getobj($q, $session); my $claimed_identity = $csr->claimed_identity($openid_url); if (! $claimed_identity) { - # Put the error in the form and fail validation. - $form->field(name => "openid_url", comment => $csr->err); - return 0; + if ($form) { + # Put the error in the form and fail validation. + $form->field(name => "openid_url", comment => $csr->err); + return 0; + } + else { + error($csr->err); + } } + my $check_url = $claimed_identity->check_url( - return_to => IkiWiki::cgiurl( - do => $form->field("do"), - page => $form->field("page"), - title => $form->field("title"), - from => $form->field("from"), - subpage => $form->field("subpage") - ), + return_to => IkiWiki::cgiurl(do => "postsignin"), trust_root => $config{cgiurl}, delayed_return => 1, ); diff --git a/debian/changelog b/debian/changelog index 26778719d..5317c4755 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,11 @@ ikiwiki (1.34) UNRELEASED; urgency=low form+link. * Modified svn, git, tla backends to recognise such web commits. * Move httpauth support to a plugin. + * Add openidsignup config option. + * Make the openid plugin support the callbacks from myopenid.com via its + affiliate program. + * Change how post signin actions are propigated through the signin process; + they're now stored in the session. -- Joey Hess Sun, 19 Nov 2006 16:40:26 -0500 diff --git a/doc/ikiwiki.setup b/doc/ikiwiki.setup index 6eb6446e0..7d0eb71fe 100644 --- a/doc/ikiwiki.setup +++ b/doc/ikiwiki.setup @@ -106,4 +106,8 @@ use IkiWiki::Setup::Standard { # For use with the search plugin if your estseek.cgi is located # somewhere else. #estseek => "/usr/lib/estraier/estseek.cgi", + + # For use with the openid plugin, to give an url to a page users + # can use to signup for an OpenID. + #openidsignup => "http://myopenid.com/", } diff --git a/doc/plugins/openid.mdwn b/doc/plugins/openid.mdwn index 344be7de3..2bd686d44 100644 --- a/doc/plugins/openid.mdwn +++ b/doc/plugins/openid.mdwn @@ -9,4 +9,17 @@ The plugin needs the `Net::OpenID::Consumer` perl module. The security. Finally, the `Crypt::SSLeay` perl module is needed to support users entering "https" OpenID urls. +This plugin supports the +[myopenid.com affiliate program](http://myopenid.com/affiliate_welcome), +which can be used to help users sign up for an OpenID and log into your +site in a single, unified process. When you create the affiliate, specify a +login url like `http://example.com/ikiwiki.cgi?do=postsignin`. Users who +create an OpenID will then be logged in and sent on their way in the wiki. + +This plugin has a configuration option. You can set `--openidsignup` +to the url of a third-party site where users can sign up for an OpenID. If +it's set, the signin page will link to that page. To make the wiki's signin +page direct users to the affiliate signup page, set the `openidsignup` +configuration parameter to the URL of the signup page. + This plugin is included in ikiwiki, but is not enabled by default.