+package Apache2::AuthzCaps 0.001;
+
+use 5.014000;
+use strict;
+use warnings;
+
+use Apache2::Access;
+use Apache2::Const qw/OK DECLINED/;
+use Apache2::RequestRec;
+use YAML::Any qw/LoadFile DumpFile/;
+
+use parent qw/Exporter/;
+
+our @EXPORT_OK = qw/setcap hascaps/;
+
+##################################################
+
+our $rootdir;
+
+sub setcap{
+ my ($user, $cap, $value) = @_;
+ my $config = eval { LoadFile "$rootdir/$user.yml" } // {};
+ $config->{caps}//={};
+ my $caps=$config->{caps};
+
+ delete $caps->{$cap} unless $value;
+ $caps->{$cap} = 1 if $value;
+ DumpFile "$rootdir/$user.yml", $config
+}
+
+sub hascaps{
+ my ($user, @caps) = @_;
+ my $config = LoadFile "$rootdir/$user.yml";
+ my $caps = $config->{caps};
+ for (@caps) {
+ return 0 unless $caps->{$_}
+ }
+ 1
+}
+
+sub handler{
+ my $r=shift;
+ my $user = $r->user;
+ local $rootdir = $r->dir_config('AuthzCapsRootdir');
+
+ if ($user) {
+ LOOP: for my $requirement (map { $_->{requirement} } @{$r->requires}) {
+ my ($command, @args) = split ' ', $requirement;
+
+ given ($command){
+ when('cap'){
+ return OK if hascaps $user, @args
+ }
+
+ }
+ }
+ }
+
+ DECLINED
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Apache2::AuthzCaps - mod_perl2 capability authorization
+
+=head1 SYNOPSIS
+
+ use Apache2::AuthzCaps qw/setcap hascaps/;
+ $Apache2::AuthzCaps::rootdir = "/path/to/user/directory"
+ setcap marius => deleteusers => 1; # Grant marius the deleteusers capability
+ setcap marius => createusers => 0;
+ hascaps marius => qw/deleteusers/; # returns 1, since marius can delete users
+ hascaps marius => qw/deleteusers createusers/; # returns 0, since marius can delete users but cannot create users
+
+ # In Apache2 config
+ <Location /protected>
+ # Insert authentication here
+ PerlAuthzHandler Apache2::AuthzCaps
+ PerlSetVar AuthzCapsRootdir /path/to/user/directory
+ Require cap staff important
+ Require cap admin
+ </Location>
+ # This will:
+ # 1) Let important staff members access /protected
+ # 2) Let admins access /protected
+ # 3) Not let anyone else (such as an important non-staff member or an non-important staff member) access /protected
+
+=head1 DESCRIPTION
+
+Apache2::AuthzCaps is a perl module which provides simple Apache2 capability-based authorization. It contains a PerlAuthzHandler and some utility functions.
+
+The user data is stored in YAML files in a user-set directory. Set this directory using:
+
+ $Apache2::AuthzCaps::rootdir = "/path/to/directory"; # From perl
+ PerlSetVar AuthzCapsRootdir /path/to/directory # From Apache2 config
+
+=head1 FUNCTIONS
+
+=over
+
+=item B<setcap>(I<$username>, I<$capability>, I<$value>)
+
+If I<$value> is true, grants I<$username> the I<$capability> capability. Otherwise denies I<$username> that capability.
+
+=item B<hascaps>(I<$username>, I<$cap>, ...)
+
+Returns true if and only of I<$username> has ALL of the listed capabilities. Dies if I<$username> does not exist.
+
+=item B<handler>
+
+The PerlAuthzHandler for use in apache2.
+
+=back
+
+=head1 AUTHOR
+
+Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2013 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.14.2 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut