summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/openid.pm
blob: 43ce8fd31e8e6bbb950b10b367cf6bc4242b3614 (plain)
  1. #!/usr/bin/perl
  2. # OpenID support.
  3. package IkiWiki::Plugin::openid;
  4. use warnings;
  5. use strict;
  6. use IkiWiki;
  7. sub import { #{{{
  8. hook(type => "getopt", id => "openid", call => \&getopt);
  9. hook(type => "checkconfig", id => "openid", call => \&checkconfig);
  10. hook(type => "auth", id => "openid", call => \&auth);
  11. } # }}}
  12. sub getopt () { #{{{
  13. eval q{use Getopt::Long};
  14. error($@) if $@;
  15. Getopt::Long::Configure('pass_through');
  16. GetOptions("openidsignup=s" => \$config{openidsignup});
  17. } #}}}
  18. sub checkconfig () { #{{{
  19. # Currently part of the OpenID code is in CGI.pm, and is enabled by
  20. # this setting.
  21. # TODO: modularise it all out into this plugin..
  22. $config{openid}=1;
  23. } #}}}
  24. sub auth ($$) { #{{{
  25. my $q=shift;
  26. my $session=shift;
  27. if (defined $q->param('openid.mode')) {
  28. my $csr=getobj($q, $session);
  29. if (my $setup_url = $csr->user_setup_url) {
  30. IkiWiki::redirect($q, $setup_url);
  31. }
  32. elsif ($csr->user_cancel) {
  33. IkiWiki::redirect($q, $config{url});
  34. }
  35. elsif (my $vident = $csr->verified_identity) {
  36. $session->param(name => $vident->url);
  37. }
  38. else {
  39. error("OpenID failure: ".$csr->err);
  40. }
  41. }
  42. elsif (defined $q->param('openid_identifier')) {
  43. validate($q, $session, $q->param('openid_identifier'));
  44. }
  45. } #}}}
  46. sub validate ($$$;$) { #{{{
  47. my $q=shift;
  48. my $session=shift;
  49. my $openid_url=shift;
  50. my $form=shift;
  51. my $csr=getobj($q, $session);
  52. my $claimed_identity = $csr->claimed_identity($openid_url);
  53. if (! $claimed_identity) {
  54. if ($form) {
  55. # Put the error in the form and fail validation.
  56. $form->field(name => "openid_url", comment => $csr->err);
  57. return 0;
  58. }
  59. else {
  60. error($csr->err);
  61. }
  62. }
  63. my $check_url = $claimed_identity->check_url(
  64. return_to => IkiWiki::cgiurl(do => "postsignin"),
  65. trust_root => $config{cgiurl},
  66. delayed_return => 1,
  67. );
  68. # Redirect the user to the OpenID server, which will
  69. # eventually bounce them back to auth() above.
  70. IkiWiki::redirect($q, $check_url);
  71. exit 0;
  72. } #}}}
  73. sub getobj ($$) { #{{{
  74. my $q=shift;
  75. my $session=shift;
  76. eval q{use Net::OpenID::Consumer};
  77. error($@) if $@;
  78. my $ua;
  79. eval q{use LWPx::ParanoidAgent};
  80. if (! $@) {
  81. $ua=LWPx::ParanoidAgent->new;
  82. }
  83. else {
  84. $ua=LWP::UserAgent->new;
  85. }
  86. # Store the secret in the session.
  87. my $secret=$session->param("openid_secret");
  88. if (! defined $secret) {
  89. $secret=$session->param(openid_secret => time);
  90. }
  91. return Net::OpenID::Consumer->new(
  92. ua => $ua,
  93. args => $q,
  94. consumer_secret => $secret,
  95. required_root => $config{cgiurl},
  96. );
  97. } #}}}
  98. 1