use Storable qw(freeze thaw);
use Date::Parse;
use Email::Valid;
+use LWP::UserAgent;
+use Net::OpenID::Consumer;
#
# Набор поддерживаемых действий. Хэш вида
# "имя поля в запросе" => "функция обработчик"
# Запрос к скрипту методом GET. Надо показать форму, если только это не
# редирект от OpenId-сервера
if ($cgi->param('openidvfy')) {
- openid_verify($cgi);
+ openid_verify($cgi,$forum);
} elsif ($cgi->param("logout")) {
logout('logout',$cgi,$forum);
} else {
sub authenticate {
my ($cgi,$forum) = @_;
if ($cgi->param("openidsite")) {
- my $openid_url = sprintf($cgi->param("openidsite",$cgi->param("user")));
- openidstart($cgi,$openid_url);
+ my $openid_url = sprintf($cgi->param("openidsite"),$cgi->param("user"));
+ openidstart($cgi,$forum,$openid_url);
}
my %userbase;
dbmopen %userbase,datafile($forum,"passwd"),0644;
my ($cgi,$forum,$url) = @_;
if (!defined $url) {
$url = $cgi->param("returnto");
- $url = $cgi->url(-base=>1).$cgi->path_info() if (!$url);
+ $url =
+ $cgi->url(-base=>1).($cgi->path_info()||$forum->{forumtop}) if !$url ;
}
print $cgi->redirect(-url=>$url,
($forum->{cookies}?(-cookie=>$forum->{cookies}):()));
close $f;
return sprintf ("%08s",$id);
}
+#
+# ----------------- OpenID registration -----------------------------
+#
+sub create_openid_consumer {
+ my ($cgi,$forum) = @_;
+ return Net::OpenID::Consumer ->new(
+ ua => LWP::UserAgent->new(),
+ args => $cgi,
+ consumer_secret=>"X9RWPo0rBE7yLja6VB3d",
+ required_root => $cgi->url(-base=>1));
+}
+# openidstart - вызывается когда обнаружено что текущее имя
+# пользователя, пытающегося аутентифицироваться, содержит http://
+#
+#
+
+sub openidstart {
+ my ($cgi,$forum,$openidurl) = @_;
+ #
+ # Fix duplicated http:// which can be produced by our sprintf based
+ # login system
+ #
+ $openidurl=~s!^http://http://!http://!;
+ my $csr = create_openid_consumer($cgi,$forum);
+ my $claimed_identity=$csr->claimed_identity($openidurl);
+ if (!defined $claimed_identity) {
+ show_error($forum,"Указанная URL $openidurl не является OpenId");
+ exit;
+ }
+ $cgi->param("openidvfy",1);
+ $cgi->delete("user");
+ $cgi->delete("openidsite");
+ $cgi->delete("password");
+ my $check_url = $claimed_identity->check_url(
+ return_to=> $cgi->url(-full=>1,-path_info=>1,-query=>1),
+ trust_root=> $cgi->url(-base=>1));
+ print $cgi->redirect(-location=>$check_url);
+ exit;
+}
+#
+# Вызывается при редиректе от openid producer-а. Проверяет, что
+# удаленный сервер подтвердил openid и вызывает операцию для которой
+# (либо возврат на исходную страницу при операции login, либо постинг
+# реплики)
+#
+sub openid_verify {
+ my ($cgi,$forum) = @_;
+ my $csr = create_openid_consumer($cgi,$forum);
+ if (my $setup_url = $csr->user_setup_url) {
+ print $cgi->redirect(-location=>$setup_url);
+ exit;
+ } elsif ($csr->user_cancel) {
+ show_error($forum,"Ваш openid-сервер отказался подтвержать вашу
+ идентичность");
+ exit;
+ } elsif (my $vident = $csr->verified_identity) {
+ #Успешная аутентификация.
+ #Создаем сессию
+ my $user = $vident->url;
+ my %userbase;
+ dbmopen %userbase,datafile($forum,"passwd"),0664;
+ if (!$userbase{$user}) {
+ $userbase{$user} = $forum->{authenticated}={};
+ } else {
+ $forum->{authenticated} = thaw ($userbase{$user});
+ }
+ dbmclose %userbase;
+ $forum->{"authenticated"}{"user"} = $user;
+ newsession(undef,$forum,$user);
+ # Если указан параметр reply, вызываем обработку реплики
+ if ($cgi->param("reply")) {
+ reply("reply",$cgi,$forum);
+ exit;
+ }
+ #Иначе, возвращаемся на исходную страницу
+ forum_redirect($cgi,$forum,undef);
+ } else {
+ show_error($forum,"Ошибка OpenId аутентификации");
+ exit;
+ }
+}