diff options
| author | Robert Haas | 2009-05-22 14:41:10 +0000 |
|---|---|---|
| committer | Robert Haas | 2009-05-22 14:41:10 +0000 |
| commit | 5bc9ab5aee7ff20941e0ea6a42aa9c80e5f8f946 (patch) | |
| tree | 061857ffc98835b2151dec00f713b16aa6c43200 /perl-lib/PgCommitFest/Handler.pm | |
First attempt.
Diffstat (limited to 'perl-lib/PgCommitFest/Handler.pm')
| -rw-r--r-- | perl-lib/PgCommitFest/Handler.pm | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/perl-lib/PgCommitFest/Handler.pm b/perl-lib/PgCommitFest/Handler.pm new file mode 100644 index 0000000..72b0c4f --- /dev/null +++ b/perl-lib/PgCommitFest/Handler.pm @@ -0,0 +1,128 @@ +package PgCommitFest::Handler; +require Digest::SHA; +require PgCommitFest::CommitFest; +require PgCommitFest::CommitFestTopic; +require PgCommitFest::Patch; +require PgCommitFest::PatchComment; +require PgCommitFest::Request; +use strict; +use warnings; +use FCGI; +use Template; + +our %ACTION = ( + 'login' => \&PgCommitFest::Handler::login, + 'logout' => \&PgCommitFest::Handler::logout, + 'commitfest_delete' => \&PgCommitFest::CommitFest::delete, + 'commitfest_form' => \&PgCommitFest::CommitFest::form, + 'commitfest_search' => \&PgCommitFest::CommitFest::search, + 'commitfest_view' => \&PgCommitFest::CommitFest::view, + 'commitfest_topic_delete' => \&PgCommitFest::CommitFestTopic::delete, + 'commitfest_topic_form' => \&PgCommitFest::CommitFestTopic::form, + 'commitfest_topic_search' => \&PgCommitFest::CommitFestTopic::search, + 'patch_form' => \&PgCommitFest::Patch::form, + 'patch_delete' => \&PgCommitFest::Patch::delete, + 'patch_view' => \&PgCommitFest::Patch::view, + 'patch_comment_form' => \&PgCommitFest::PatchComment::form, + 'patch_comment_delete' => \&PgCommitFest::PatchComment::delete +); + +our $PG = 'dbi:Pg:dbname=commitfest'; +our $PGUSERNAME = 'rhaas'; +our $PGPASSWORD = ''; + +sub main_loop { + $SIG{'PIPE'} = sub { die "SIGPIPE\n"; }; + while (1) { + # Invoke main request handler and save any resulting error message. + my $db = PgCommitFest::DB->connect($PG, $PGUSERNAME, $PGPASSWORD); + my $r = PgCommitFest::Request->new($db); + last if !defined $r; + eval { + handler($r); + if (! $r->response_sent) { + $r->error_exit('No response was generated.'); + } + }; + my $err = $@; + + # Roll back any uncommited database work. + $db->tidy; + + # Print errors to system log. + if ($err && $err ne "SIGPIPE\n" && $err ne "DONE\n") { + print STDERR $err; + if (defined $r && ! $r->response_sent) { + $r->set_title('Internal Server Error'); + $r->render_template('error', { 'error_list' => [ $err ] }); + } + } + $db->disconnect; + } +} + +sub handler { + my ($r) = @_; + my ($action, $extrapath); + my $url = $ENV{'SCRIPT_URL'}; + if ($url eq '/') { + $action = 'commitfest_search'; + } + elsif ($url =~ /^\/action\/([^\/]*)(\/(.*))?$/) { + $action = $1; + $extrapath = $3; + } + if (defined $action && exists $ACTION{$action}) { + $ACTION{$action}->($r, $extrapath); + } + else { + $r->header('Status', '404 Not Found'); + $r->set_title('Page Not Found'); + $r->render_template('404'); + } + return; +} + +sub login { + my ($r) = @_; + + # Prompt for username and password. + $r->set_title('Log in'); + $r->add_control('username', 'text', 'Username', 'required' => 1); + $r->add_control('password', 'password', 'Password', 'required' => 1); + $r->add_control('uri', 'hidden', 'URI'); + my %value = $r->initialize_controls(); + + # Handle cancellation. + $r->redirect('/') if $r->cgi('cancel'); + + # Attempt to validate login. + if ($r->cgi('go') && ! $r->is_error) { + my $u = $r->db->select_one(<<EOM, +SELECT username FROM person WHERE username = ? AND sha512password = ? +EOM + $value{'username'}, + Digest::SHA::sha512_base64($value{'password'})); + if (defined $u) { + my $random_bits; + open(RANDOM_BITS, '</dev/urandom') || die "/dev/urandom: $!"; + sysread(RANDOM_BITS, $random_bits, 16); + close(RANDOM_BITS); + my $session_cookie = unpack("H*", $random_bits); + $r->db->{'trace'} = 1; + $r->db->insert('session', { 'id' => $session_cookie, + 'username' => $u->{'username'} }); + $r->db->commit; + $r->header('Set-Cookie', "session=$session_cookie"); + $r->redirect($value{'uri'} ne '' ? $value{'uri'} : '/'); + } + else { + $r->error('Invalid username or password.'); + } + } + + # Display template. + $r->render_template('login'); +} + +1; |
