Apache-OneTimeURL
view release on metacpan or search on metacpan
lib/Apache/OneTimeURL.pm view on Meta::CPAN
my ($class, $r) = @_;
die "No OneTimeDoc specified!" unless my $file = $r->dir_config("OneTimeDoc");
my $subr = $r->lookup_file($file);
return $subr->run;
}
sub authorize {
my ($class, $db, $comments) = @_;
my $key = md5_hex(time().{}.rand().$$);
my %o;
tie %o, "MLDBM", $db or die "Couldn't open database: $!";
$o{$key} = {
comments => $comments,
count => 0,
created => time
};
untie %o;
return $key;
}
sub intruder {
my ($class, $r, $hash) = @_;
my $sendcount = $r->dir_config("OneTimeMailCount") || 5;
if ($hash->{count} < $sendcount) {
$class->send_mail($r, $hash);
}
$r->send_http_header("text/html");
print "<HTML><HEAD><title>Unauthorized access</title></HEAD>
<BODY>
You are not authorized to access this resource. This attempt has been
recorded.
</BODY>
<HTML>";
return OK; # Can't return forbidden, since that calls other handlers.
}
sub send_mail {
my ($class, $r, $hash) = @_;
my $email = $r->dir_config("OneTimeEmail") || $r->server_admin();
my $referrer = $r->header_in( 'Referer' );
my $msg = new Mail::Send To => $email,
Subject => 'One-time URL reused';
my $fh = $msg->open;
print $fh <<EOF;
Key issued at @{[ scalar localtime $hash->{created} ]}
with comments @{[ $hash->{comments} ]}
Reused at @{[ scalar localtime ]}
by @{[ $r->get_remote_host ]} ( @{[ $r->get_remote_logname ]} )
EOF
if ($referrer) { print $fh "Accessed via $referrer\n\n" }
$fh->close;
}
1;
__END__
# Below is stub documentation for your module. You better edit it!
=head1 NAME
Apache::OneTimeURL - One-time use URLs for sensitive data
=head1 SYNOPSIS
PerlModule Apache::OneTimeURL
<Location /secret>
PerlHandle Apache:OneTimeURL
SetHandler perl-script
PerlSetVar OneTimeDb /opt/secret/access.db
PerlSetVar OneTimeDoc /opt/secret/realfile.html
PerlSetVar OneTimeEmail intruder@simon-cozens.org
</Location>
F<authorize.pl>:
#!/usr/bin/perl
use Apache::OneTimeURL;
my $comments = join " ", @ARGV;
my $db = "/opt/secret/access.db";
print "http://www.my.server.int/secret/",
Apache::OneTimeURL->authorize($db, $comments),
"\n";
Now:
% authorize.pl Given to Simon C on IRC
http://www.my.server.int/secret/2c61de78edd612cf79c0d73a3c7c94fb
This URL will only be viewable once, and will then return an error. For
the first five times that the URL is accessed in error, a mail will be sent
to the email address given in the config. The number of times can be
configured with the C<OneTimeMailCount> variable; if you don't want any
mail, set this to minus one.
=head1 DESCRIPTION
The synopsis pretty much wraps it up. I'm paranoid about giving out
certain information, and although I can't really control what people do
with the HTML when they download it, I can damned well ensure that URLs
in mail I send don't end up on the web and being a liability. Hence the
desire for a URL that's only valid once. You may have your own
interesting uses for such a set-up.
I've hopefully designed the module so that if there's some aspect of its
behaviour you don't like, you can switch to the "method handler" style
(ie. C<PerlHandler Apache::OneTime::URL-E<gt>handler> and subclass to
override the bits you're unhappy about. This may be easier than convincing
me to make changes to the module.
=head1 THANKS
Peter Sergeant offered several useful ideas which contributed to the 1.1
and 1.2. releases of this module.
=head1 REPOSITORY
L<https://github.com/cpan-janitor/Apache-OneTimeURL>
( run in 0.958 second using v1.01-cache-2.11-cpan-39bf76dae61 )