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 )