App-Phoebe
view release on metacpan or search on metacpan
lib/App/Phoebe/RegisteredEditorsOnly.pm view on Meta::CPAN
above. Add it, and restart Phoebe.
If a visitor uses a fingerprint that Phoebe doesnât know, the fingerprint is
printed in the log (if your log level is set to âinfoâ or more), so you can get
it from there in case the user canât send you their client certificate, or tell
you what the fingerprint is.
You should also have a login link somewhere such that people can login
immediately. If they donât, and they try to save, their client is going to ask
them for a certificate and their edits may or may not be lost. It depends. ð
=> /login Login
This code works by intercepting all C<titan:> links, and all web edit requests.
If you allow editing via the web using L<App::Phoebe::WebEdit>, then those also
require a valid client certificate â and setting these up in a web browser are
not easy. Be prepared to explain how to do this to your users!
This code does I<not> prevent simple comments using L<App::Phoebe::Comments> or
L<App::Phoebe::WebComments>. People can still leave comments, if you use these
modules. This can be a problem: if only registered users can edit the site, you
probably donât want a token; if anonymous users can comment, you probably want a
token. There is currently no solution for this. Choose one or the other. If you
choose both, registered users might have to provide a token, which might annoy
them.
Hereâs an example config that allows reading and editing via the web, but only
for users with known fingerprints, with no comments and no tokens:
# tested by t/example-registered-editors-only.t
package App::Phoebe;
use App::Phoebe::Web;
use App::Phoebe::WebEdit;
use App::Phoebe::RegisteredEditorsOnly;
our @known_fingerprints = qw(
sha256$0ba6ba61da1385890f611439590f2f0758760708d1375859b2184dcd8f855a00);
our $server->{wiki_token} = []; # no tokens
1;
At the time of this writing, hereâs a way to do provide a client certificate for
Firefox users. First, we need a file in the C<PKCS12> format. On the command
line, create this file from the F<cert.pem> and F<key.pem> files you have.
Provide no password when you run the command.
openssl pkcs12 -export -inkey key.pem -in cert.pem -out cert.p12
In Firefox, go to âPreferencesâ â âPrivacy & Securityâ â âCertificatesâ; under
âWhen a server requests your personal certificateâ check the option âSelect one
automaticallyâ; click on the âView Certificatesâ button, switch to the âYour
Certificatesâ tab, click on âImportâ¦â and pick the F<cert.p12> file you just
created.
Once you have done this and you visit the Phoebe site, itâll use the client
certificate you provided or itâll ask you what client certificate to use.
=cut
package App::Phoebe::RegisteredEditorsOnly;
use App::Phoebe qw(@request_handlers @extensions @known_fingerprints $log
port host_regex space_regex handle_titan result);
use Modern::Perl;
unshift(@request_handlers, '^titan://' => \&protected_titan);
sub protected_titan {
my $stream = shift;
my $data = shift;
my $hosts = host_regex();
my $spaces = space_regex();
my $port = port($stream);
my $fingerprint = $stream->handle->get_fingerprint();
if ($fingerprint and grep { $_ eq $fingerprint} @known_fingerprints) {
$log->info("Successfully identified client certificate");
return handle_titan($stream, $data);
} elsif ($fingerprint) {
$log->info("Unknown client certificate $fingerprint");
result($stream, "61", "Your client certificate is not authorized for editing");
} else {
$log->info("Requested client certificate");
result($stream, "60", "You need a client certificate to edit this wiki");
}
$stream->close_gracefully();
}
# for App::Phoebe::WebEdit
unshift(@extensions, \&protect_edit_requests);
sub protect_edit_requests {
my ($stream, $request, $headers, $buffer) = @_;
my $host_regex = host_regex();
my $spaces = space_regex();
my $port = port($stream);
if ($request =~ m!^GET (?:/($spaces))?/do/edit/([^/#?]+) HTTP/1\.[01]$!
or $request =~ m!^POST (?:/($spaces))?/do/edit/([^/#?]+) HTTP/1\.[01]$!) {
# we donât check $space and $host like we do in App::Phoebe::WebEdit!
my $fingerprint = $stream->handle->get_fingerprint();
if ($fingerprint and grep { $_ eq $fingerprint} @known_fingerprints) {
$log->info("Successfully identified client certificate via the web");
return 0; # let it be handled by process_edit_request in App::Phoebe::WebEdit!
} elsif ($fingerprint) {
$log->info("Unknown client certificate $fingerprint via the web");
$stream->write("HTTP/1.1 403 Not authorized\r\n");
$stream->write("Content-Type: text/plain\r\n");
$stream->write("\r\n");
$stream->write("Your client certificate is not authorized for editing\n");
return 1; # we handled it, no further action required
} else {
$log->info("Requested client certificate via the web");
$stream->write("HTTP/1.1 403 Not authorized\r\n");
$stream->write("Content-Type: text/plain\r\n");
$stream->write("\r\n");
$stream->write("You need a client certificate to edit this wiki");
return 1; # we handled it, no further action required
}
}
return 0;
}
push(@extensions, \®istered_editor_login);
sub registered_editor_login {
( run in 0.637 second using v1.01-cache-2.11-cpan-a1f116cd669 )