summaryrefslogtreecommitdiff
path: root/perl-lib/PgCommitFest/Handler.pm
diff options
context:
space:
mode:
authorRobert Haas2009-05-22 14:41:10 +0000
committerRobert Haas2009-05-22 14:41:10 +0000
commit5bc9ab5aee7ff20941e0ea6a42aa9c80e5f8f946 (patch)
tree061857ffc98835b2151dec00f713b16aa6c43200 /perl-lib/PgCommitFest/Handler.pm
First attempt.
Diffstat (limited to 'perl-lib/PgCommitFest/Handler.pm')
-rw-r--r--perl-lib/PgCommitFest/Handler.pm128
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;