bugzilla-4intranet/globalauth.cgi

143 lines
5.1 KiB
Plaintext
Raw Normal View History

#!/usr/bin/perl -wT
# CustIS Bug 63447 - Сервер глобальной авторизации
use utf8;
use strict;
use lib qw(. lib);
use Bugzilla;
use Bugzilla::User;
use Bugzilla::Util;
use Bugzilla::Constants;
use Encode;
use HTTP::Request::Common;
use LWP::Simple qw($ua);
use URI;
use URI::QueryParam;
use URI::Escape;
use JSON;
my $gc_prob = 0.01;
my $args = Bugzilla->input_params;
my $check = $args->{ga_check} ? 1 : 0; # если 1 и пользователь не вошёл, входа не требовать
# требуем входа, если пришёл пользователь (в запросе нет ключа) и в запросе не сказано "не требовать входа"
my $user = Bugzilla->login(!$args->{ga_key} && !$check ? LOGIN_REQUIRED : !LOGIN_REQUIRED);
my $dbh = Bugzilla->dbh;
my $expire = Bugzilla->params->{globalauth_expire} || 86400;
my $id;
# только серверная сторона
if (($id = $args->{ga_id}) && !$args->{ga_client})
{
if (rand() < $gc_prob)
{
$dbh->do("DELETE FROM globalauth WHERE expire < UNIX_TIMESTAMP()");
}
trick_taint($id);
# приём ID и ключа от клиента
my $key = $args->{ga_key};
if ($key)
{
trick_taint($key);
$dbh->do("REPLACE INTO globalauth SET id=?, secret=?, expire=?", undef, $id, $key, time+$expire);
Bugzilla->cgi->send_header;
print "1"; # потенциально здесь любой JSON
exit;
}
# передача данных авторизации клиенту
else
{
my $tm;
($key, $tm) = $dbh->selectrow_array("SELECT secret, expire FROM globalauth WHERE id=?", undef, $id);
if ($key && time > $tm)
{
$key = undef;
$dbh->do("DELETE FROM globalauth WHERE id=?", undef, $id);
die "GlobalAuth key expired";
}
if ($key)
{
my $url = $args->{ga_url};
if (!$url)
{
# ошибко :(
Bugzilla->cgi->send_header;
print "Global Auth: No ga_url in request for ID=$id";
warn "Global Auth: No ga_url in request for ID=$id";
exit;
}
$url = URI->new($url);
my $authdata;
if ($user && $user->id)
{
# почтовые алиасы
my $rows = $dbh->selectall_arrayref("SELECT * FROM emailin_aliases WHERE userid=?", {Slice=>{}}, $user->id);
my $aliases = {};
my $primary_email;
for (@$rows)
{
if ($_->{isprimary})
{
$primary_email = $_->{address};
}
$aliases->{$_->{address}} = 1;
}
$aliases->{$user->email} = 1;
$primary_email ||= $user->email;
# собираем данные
$authdata = {
user_email => $primary_email,
user_real_name => $user->name,
user_name => $user->login,
user_email_aliases => [ sort keys %$aliases ],
# включаем также информацию о правах пользователя
user_groups => [ map { $_->name } @{ $user->groups } ],
#selectable_products => [ map { $_->name } @{ $user->get_selectable_products } ], # пока не нужно
#editable_products => [ map { $_->name } @{ $user->get_editable_products } ], # пока не нужно
# информация об источнике данных
auth_source => 'Bugzilla',
auth_server => correct_urlbase().'/globalauth.cgi',
auth_site => correct_urlbase(),
};
# кодируем данные в JSON
$authdata = { ga_data => encode_json($authdata) };
}
else
{
$authdata = { ga_nologin => 1 };
}
$authdata->{ga_id} = $id;
$authdata->{ga_key} = $key;
# TODO LWPx::ParanoidAgent
$ua->timeout(Bugzilla->params->{globalauth_timeout} || 30);
# отправляем запрос серверу клиента
my $res = $ua->request(POST "$url", Content => $authdata);
# и делаем перенаправление в браузере
{
no utf8;
# URI::QueryParam имеет проблемы с утф'ом...
$url->query_param(ga_id => $id);
$url->query_param(ga_res => $res->code);
}
$dbh->do("DELETE FROM globalauth WHERE id=?", undef, $id);
print Bugzilla->cgi->redirect(-location => "$url");
exit;
}
else
{
die "Global Auth key not found";
}
}
}
else
{
die("Global Auth client mode disabled in Bugzilla");
}
1;
__END__