From 7442fd06706749adbd1e9e371c4cc9d23fe2ecc1 Mon Sep 17 00:00:00 2001 From: Marius Gavrilescu Date: Mon, 5 Aug 2013 11:25:15 +0300 Subject: [PATCH 1/1] Initial commit --- Changes | 4 ++ MANIFEST | 6 ++ Makefile.PL | 16 +++++ README | 30 +++++++++ lib/Apache2/AuthzCaps.pm | 131 +++++++++++++++++++++++++++++++++++++++ t/Apache2-AuthzCaps.t | 28 +++++++++ 6 files changed, 215 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 README create mode 100644 lib/Apache2/AuthzCaps.pm create mode 100644 t/Apache2-AuthzCaps.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..de358a3 --- /dev/null +++ b/Changes @@ -0,0 +1,4 @@ +Revision history for Perl extension Apache2::AuthzCaps. + +0.001 Mon 5 Aug 11:22:54 EEST 2013 + - Initial release diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..f231dcc --- /dev/null +++ b/MANIFEST @@ -0,0 +1,6 @@ +Changes +Makefile.PL +MANIFEST +README +t/Apache2-AuthzCaps.t +lib/Apache2/AuthzCaps.pm diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..c3bab38 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,16 @@ +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'Apache2::AuthzCaps', + VERSION_FROM => 'lib/Apache2/AuthzCaps.pm', + ABSTRACT_FROM => 'lib/Apache2/AuthzCaps.pm', + AUTHOR => 'Marius Gavrilescu ', + MIN_PERL_VERSION => '5.14.0', + LICENSE => 'perl', + PREREQ_PM => { + Apache2::Access => 0, + Apache2::Const => 0, + Apache2::RequestRec => 0, + YAML::Any => 0, + }, +); diff --git a/README b/README new file mode 100644 index 0000000..5c6ff6b --- /dev/null +++ b/README @@ -0,0 +1,30 @@ +Apache2-AuthzCaps version 0.001 +=============================== + +Apache2::AuthzCaps is a perl module which provides simple Apache2 capability-based authorization. It contains a PerlAuthzHandler and some utility functions. + +Please read the Apache2::AuthzCaps POD for detailed information. + +INSTALLATION + +To install this module type the following: + + perl Makefile.PL + make + make test + make install + +DEPENDENCIES + +This module requires these other modules and libraries: + +- mod_perl2 +- YAML::Any + +COPYRIGHT AND LICENCE + +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. diff --git a/lib/Apache2/AuthzCaps.pm b/lib/Apache2/AuthzCaps.pm new file mode 100644 index 0000000..ac16d17 --- /dev/null +++ b/lib/Apache2/AuthzCaps.pm @@ -0,0 +1,131 @@ +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 + + # Insert authentication here + PerlAuthzHandler Apache2::AuthzCaps + PerlSetVar AuthzCapsRootdir /path/to/user/directory + Require cap staff important + Require cap admin + + # 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(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(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 + +The PerlAuthzHandler for use in apache2. + +=back + +=head1 AUTHOR + +Marius Gavrilescu, Emarius@ieval.roE + +=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 diff --git a/t/Apache2-AuthzCaps.t b/t/Apache2-AuthzCaps.t new file mode 100644 index 0000000..b018dd5 --- /dev/null +++ b/t/Apache2-AuthzCaps.t @@ -0,0 +1,28 @@ +use v5.14; +use strict; +use warnings; + +use File::Temp qw/tempdir/; +use Test::More tests => 5; +BEGIN { use_ok('Apache2::AuthzCaps', qw/setcap hascaps/) }; + +$Apache2::AuthzCaps::rootdir = tempdir CLEANUP => 1; + +sub checkcaps{ + my ($user, $testname, @caps) = @_; + ok hascaps ($user, @caps), $testname +} + +sub checknocaps{ + my ($user, $testname, @caps) = @_; + ok !(hascaps $user, @caps), $testname +} + +setcap marius => dostuff => 1; +checkcaps marius => 'Set cap and check it', qw/dostuff/; +checknocaps marius => 'Check an inexistent cap', qw/dootherstuff/; + +setcap marius => goaway => 1; +checkcaps marius => 'Check multiple caps', qw/dostuff goaway/; +setcap marius => goaway => 0; +checknocaps marius => 'Remove cap', qw/dostuff goaway/; -- 2.39.2