#!/usr/bin/perl use strict; use warnings; use lib (qw(lib)); use CGI (':cgi'); use CGI::Carp (qw(fatalsToBrowser)); use URI::Escape; use Data::Dumper; use Person; our $Debug = 0; our %Config = (); our @MultiFields = (qw(address homephone cellphone officephone fax mail uri group)); our $MySelf = $ENV{'SCRIPT_NAME'}; our $Action = param ('action'); $Action ||= 'default'; our %Actions = ( default => \&action_default, edit => \&action_edit, save => \&action_save, search => \&action_search ); read_config (); # make sure AuthLDAPRemoteUserIsDN is enabled. die unless ($ENV{'REMOTE_USER'}); $Config{'base_dn'} = $ENV{'REMOTE_USER'}; Person->connect ( uri => $Config{'uri'}, base_dn => $Config{'base_dn'}, bind_dn => $Config{'bind_dn'}, password => $Config{'password'} ) or die; our ($UserCN, $UserID) = Person->get_user ($Config{'base_dn'}); if (!$UserID and $Action ne 'save') { $Action = 'edit'; } print <(); print qq#
Authenticated as ($UserCN, $UserID, #, $Config{'base_dn'}, qq#)
\n#; print_html_end (); Person->disconnect (); exit (0); ### sub action_default { print "action_default\n"; } sub action_search { print "action_search\n"; } sub action_edit { my %opts = @_; my $cn = param ('cn'); $cn = $opts{'cn'} if (defined ($opts{'cn'})); $cn ||= ''; if (!$UserID) { $cn = $UserCN; } my $person; my $lastname; my $firstname; my $contacts = {}; $contacts->{$_} = [] for (@MultiFields); if ($cn) { $person = Person->load ($cn); if (!$person) { print qq(\t
Unable to load CN "$cn". Sorry.
\n); return; } $lastname = $person->lastname (); $firstname = $person->firstname (); $contacts->{'address'} = $person->address (); $contacts->{'homephone'} = $person->homephone (); $contacts->{'cellphone'} = $person->cellphone (); $contacts->{'officephone'} = $person->officephone (); $contacts->{'fax'} = $person->fax (); $contacts->{'mail'} = $person->mail (); $contacts->{'uri'} = $person->uri (); $contacts->{'group'} = $person->group (); } $lastname = param ('lastname') if (param ('lastname') and $UserID); $firstname = param ('firstname') if (param ('firstname') and $UserID); get_contacts ($contacts); $lastname = $opts{'lastname'} if (defined ($opts{'lastname'})); $firstname = $opts{'firstname'} if (defined ($opts{'firstname'})); for (@MultiFields) { my $field = $_; @{$contacts->{$field}} = @{$opts{$field}} if (defined ($opts{$field})); } if ($cn) { print "

Edit contact $cn

\n"; } else { print "

Create new contact

\n"; } my $selector = sub { my $selected = @_ ? shift : ''; my @options = ( [none => '-- Contact --'], [address => 'Address'], [homephone => 'Home Phone'], [cellphone => 'Cellphone'], [officephone => 'Office Phone'], [fax => 'FAX'], [mail => 'E-Mail'], [uri => 'URI (Homepage)'], [group => 'Group'] ); print qq(); }; print < EOF if ($UserID) { print qq(\t\t\t\n); } else { print qq(\t\t\t\n); } print < EOF if ($UserID) { print qq(\t\t\t\n); } else { print qq(\t\t\t\n); } print "\t\t\n"; for (@MultiFields) { my $field = $_; my @values = @{$contacts->{$field}}; @values = ('') unless (@values); for (@values) { my $value = $_; print "\t\t\n", "\t\t\t\n", < EOF } } print "\t\t\n", "\t\t\t\n", <
Lastname$lastname
Firstname$firstname
"; $selector->($field); print "
"; $selector->(); print "
EOF } sub action_save { my $cn = $UserID ? param ('cn') : $UserCN; if ($cn) { action_update (); return; } die unless ($UserID); if (!param ('lastname') or !param ('firstname')) { print qq(\t
You have to give both, first and lastname, to identify this record.
\n); action_edit (cn => ''); return; } my $lastname = param ('lastname'); my $firstname = param ('firstname'); my $contacts = get_contacts (); my $person = Person->create (lastname => $lastname, firstname => $firstname, %$contacts); if (!$person) { print qq(\t
Unable to save entry. Sorry.
\n); return; } $cn = $person->name (); action_edit (cn => $cn); } sub action_update { my $cn = $UserID ? param ('cn') : $UserCN; my $person = Person->load ($cn); die unless ($person); if ($UserID) { my $lastname = param ('lastname'); my $firstname = param ('firstname'); $person->lastname ($lastname) if ($lastname); $person->firstname ($firstname) if ($firstname); $cn = $person->name (); } my $contacts = get_contacts (); for (@MultiFields) { my $field = $_; if (defined ($contacts->{$field})) { my $values = $contacts->{$field}; $person->set ($field, $values); } else { $person->set ($field, []); } } action_edit (cn => $cn); } sub print_html_start { my $title = shift; $title = 'Search for names' unless ($title); print < $title EOF if ($UserID) { my $search = param ('search') || ''; print <

EOF } print "\t

octo's lightweight address book

\n"; } sub print_html_end { print <octo's Address Book <octo at verplant.org> EOF } sub read_config { my $file = '/var/www/html/cgi.verplant.org/address/book.conf'; my $fh; open ($fh, "< $file") or die ("open ($file): $!"); for (<$fh>) { chomp; my $line = $_; if ($line =~ m/^(\w+):\s*"(.+)"\s*$/) { my $key = lc ($1); my $val = $2; $Config{$key} = $val; } } close ($fh); for (qw(uri bind_dn password)) { die ("Not defined: $_") unless (defined ($Config{$_})); } } sub get_contacts { my $contacts = @_ ? shift : {}; if (param ('c_value')) { my @c_values = param ('c_value'); my @c_types = param ('c_type'); my %cts = (); die if (scalar (@c_values) != scalar (@c_types)); for (my $i = 0; $i < scalar (@c_values); $i++) { my $type = $c_types[$i]; my $value = $c_values[$i]; $cts{$type} = [] unless (defined ($cts{$type})); push (@{$cts{$type}}, $value) if ($value); } for (@MultiFields) { my $type = $_; @{$contacts->{$type}} = @{$cts{$type}} if (defined ($cts{$type})); } } return ($contacts); }