8 use CGI::Carp (qw(fatalsToBrowser));
17 our @MultiFields = (qw(address homephone cellphone officephone fax mail uri group));
22 homephone => 'Home Phone',
23 cellphone => 'Cellphone',
24 officephone => 'Office Phone',
27 uri => 'URI (Homepage)',
31 our $MySelf = $ENV{'SCRIPT_NAME'};
33 our $Action = param ('action');
34 $Action ||= 'default';
38 default => \&action_default,
39 detail => \&action_detail,
40 edit => \&action_edit,
41 save => \&action_save,
42 search => \&action_search
47 # make sure AuthLDAPRemoteUserIsDN is enabled.
48 die unless ($ENV{'REMOTE_USER'});
49 $Config{'base_dn'} = $ENV{'REMOTE_USER'};
53 uri => $Config{'uri'},
54 base_dn => $Config{'base_dn'},
55 bind_dn => $Config{'bind_dn'},
56 password => $Config{'password'}
59 our ($UserCN, $UserID) = Person->get_user ($Config{'base_dn'});
61 if (!$UserID and $Action ne 'save')
67 Content-Type: text/html; charset=UTF-8
71 print_html_start ("octo's Address Book");
78 if (!defined ($Actions{$Action}))
83 $Actions{$Action}->();
85 #print qq#<div>Authenticated as ($UserCN, $UserID, #, $Config{'base_dn'}, qq#)</div>\n#;
89 Person->disconnect ();
97 print "<code>action_default</code>\n";
102 my $cn = param ('cn');
105 my $person = Person->load ($cn);
108 print qq(\t<div>Entry "$cn" could not be loaded from DB.</div>\n);
112 my $cn_esc = uri_escape ($cn);
115 <table class="detail">
124 my $values = $person->get ($field);
125 my $num = scalar (@$values);
126 my $print = defined ($FieldNames{$field}) ? $FieldNames{$field} : $field;
133 print qq(\t\t\t<th rowspan="$num">$print</th>\n);
137 print qq(\t\t\t<th>$print</th>\n);
140 for (my $i = 0; $i < $num; $i++)
142 my $val = $values->[$i];
143 print "\t\t<tr>\n" if ($i);
144 print "\t\t\t<td>$val</td>\n",
150 <div class="detail menu">
151 [<a href="$MySelf?action=edit&cn=$cn_esc">edit</a>]
158 my $search = param ('search');
161 $search =~ s/[^\s\w]//g;
165 print qq(\t<div class="error">Sorry, the empty search is not allowed.</div>\n);
170 my @patterns = split (m/\s+/, $search);
176 push (@filter, [[lastname => $pattern], [firstname => $pattern]]);
179 my @matches = Person->search (@filter);
183 print qq(\t<div>No entries matched your search.</div>\n);
187 print qq(\t<ul class="result">\n);
191 my $cn = $person->name ();
192 my $cn_esc = uri_escape ($cn);
194 print qq(\t\t<li><a href="$MySelf?action=detail&cn=$cn_esc">$cn</a></li>\n);
203 my $cn = param ('cn');
205 $cn = $opts{'cn'} if (defined ($opts{'cn'}));
219 $contacts->{$_} = [] for (@MultiFields);
223 $person = Person->load ($cn);
227 print qq(\t<div class="error">Unable to load CN "$cn". Sorry.</div>\n);
231 $lastname = $person->lastname ();
232 $firstname = $person->firstname ();
233 $contacts->{'address'} = $person->address ();
234 $contacts->{'homephone'} = $person->homephone ();
235 $contacts->{'cellphone'} = $person->cellphone ();
236 $contacts->{'officephone'} = $person->officephone ();
237 $contacts->{'fax'} = $person->fax ();
238 $contacts->{'mail'} = $person->mail ();
239 $contacts->{'uri'} = $person->uri ();
240 $contacts->{'group'} = $person->group ();
243 $lastname = param ('lastname') if (param ('lastname') and $UserID);
244 $firstname = param ('firstname') if (param ('firstname') and $UserID);
246 get_contacts ($contacts);
248 $lastname = $opts{'lastname'} if (defined ($opts{'lastname'}));
249 $firstname = $opts{'firstname'} if (defined ($opts{'firstname'}));
253 @{$contacts->{$field}} = @{$opts{$field}} if (defined ($opts{$field}));
258 print "<h2>Edit contact $cn</h2>\n";
262 print "<h2>Create new contact</h2>\n";
267 my $selected = @_ ? shift : '';
271 [none => '-- Contact --'],
272 [address => 'Address'],
273 [homephone => 'Home Phone'],
274 [cellphone => 'Cellphone'],
275 [officephone => 'Office Phone'],
278 [uri => 'URI (Homepage)'],
282 print qq(<select name="c_type">\n);
285 my ($field, $print) = @$_;
286 my $sel = $field eq $selected ? ' selected="selected"' : '';
287 print qq(\t\t\t\t<option value="$field"$sel>$print</option>\n);
289 print qq(\t\t\t</select>);
293 <form action="$MySelf" method="post">
294 <input type="hidden" name="action" value="save" />
295 <input type="hidden" name="cn" value="$cn" />
302 print qq(\t\t\t<td><input type="text" name="lastname" value="$lastname" /></td>\n);
306 print qq(\t\t\t<td>$lastname</td>\n);
315 print qq(\t\t\t<td><input type="text" name="firstname" value="$firstname" /></td>\n);
319 print qq(\t\t\t<td>$firstname</td>\n);
327 my @values = @{$contacts->{$field}};
329 @values = ('') unless (@values);
337 print "</td>\n", <<EOF;
338 <td><input type="text" name="c_value" value="$value" /></td>
347 print "</td>\n", <<EOF;
348 <td><input type="text" name="c_value" value="" /></td>
351 <td colspan="2"><input type="submit" name="button" value="Save" /></td>
360 my $cn = $UserID ? param ('cn') : $UserCN;
368 die unless ($UserID);
370 if (!param ('lastname') or !param ('firstname'))
372 print qq(\t<div class="error">You have to give both, first and lastname, to identify this record.</div>\n);
373 action_edit (cn => '');
377 my $lastname = param ('lastname');
378 my $firstname = param ('firstname');
380 my $contacts = get_contacts ();
382 my $person = Person->create (lastname => $lastname, firstname => $firstname, %$contacts);
386 print qq(\t<div class="error">Unable to save entry. Sorry.</div>\n);
390 $cn = $person->name ();
392 action_edit (cn => $cn);
397 my $cn = $UserID ? param ('cn') : $UserCN;
398 my $person = Person->load ($cn);
400 die unless ($person);
404 my $lastname = param ('lastname');
405 my $firstname = param ('firstname');
407 $person->lastname ($lastname) if ($lastname);
408 $person->firstname ($firstname) if ($firstname);
410 $cn = $person->name ();
413 my $contacts = get_contacts ();
419 if (defined ($contacts->{$field}))
421 my $values = $contacts->{$field};
422 $person->set ($field, $values);
426 $person->set ($field, []);
430 action_edit (cn => $cn);
436 $title = 'Search for names' unless ($title);
441 <title>$title</title>
442 <style type="text/css">
447 background-color: white;
453 background-color: yellow;
457 border: 2px solid red;
463 background-color: white;
473 border-top: 1px solid black;
491 background-color: #cccccc;
497 background-color: #999999;
510 my $search = param ('search') || '';
513 <form action="$MySelf" method="post">
514 <input type="hidden" name="action" value="search" />
515 <input type="text" name="search" value="$search" />
516 <input type="submit" name="button" value="Search" />
518 <form action="$MySelf" method="post">
519 <input type="hidden" name="action" value="edit" />
520 <input type="hidden" name="dn" value="" />
521 <input type="submit" name="button" value="Add New" />
527 print "\t<h1>octo's Lightweight Address Book</h1>\n";
533 <div class="foot">octo's Lightweight Address Book <octo at verplant.org></div>
541 my $file = '/var/www/html/cgi.verplant.org/address/book.conf';
544 open ($fh, "< $file") or die ("open ($file): $!");
550 if ($line =~ m/^(\w+):\s*"(.+)"\s*$/)
555 $Config{$key} = $val;
561 for (qw(uri bind_dn password))
563 die ("Not defined: $_") unless (defined ($Config{$_}));
569 my $contacts = @_ ? shift : {};
571 if (param ('c_value'))
573 my @c_values = param ('c_value');
574 my @c_types = param ('c_type');
578 die if (scalar (@c_values) != scalar (@c_types));
580 for (my $i = 0; $i < scalar (@c_values); $i++)
582 my $type = $c_types[$i];
583 my $value = $c_values[$i];
585 $cts{$type} = [] unless (defined ($cts{$type}));
586 push (@{$cts{$type}}, $value) if ($value);
592 @{$contacts->{$type}} = @{$cts{$type}} if (defined ($cts{$type}));