App-CamelPKI
view release on metacpan or search on metacpan
lib/App/CamelPKI/RestrictedClassMethod.pm view on Meta::CPAN
#!perl -w
package App::CamelPKI::RestrictedClassMethod;
use strict;
use warnings;
=head1 NAME
B<App::CamelPKI::RestrictedClassMethod> - Application of the "brand"
capability discipline pattern to sensitive constructors and classes.
=head1 SYNOPSIS
=for My::Tests::Below "synopsis" begin
package App::CamelPKI::Foo;
use App::CamelPKI::RestrictedClassMethod ":Restricted";
sub new : Restricted {
my ($class) = @_;
# ...
}
App::CamelPKI::RestrictedClassMethod->lockdown(__PACKAGE__);
# Meanwhile, in a nearby piece of privileged code...
my $brand = grab App::CamelPKI::RestrictedClassMethod("App::CamelPKI::Foo");
my $object = $brand->invoke("new", @args);
=for My::Tests::Below "synopsis" end
=head1 DESCRIPTION
B<App::CamelPKI::RestrictedClassMethod> is an implementation of the "brand"
pattern, which is of general use in capability discipline (see
L<App::CamelPKI::CodingStyle/Capability discipline>). It is used to
ascertain that the security-sensitive class methods, especially the
construction of objects that use the ambiant autority of the process,
are kept secure in capability discipline style.
=head1 CAPABILITY DISCIPLINE
An instance of I<App::CamelPKI::RestrictedClassMethod> represents the right
to invoke methods marked as C<Restricted> in an given Perl class.
=cut
use Class::Inspector;
use App::CamelPKI::Error;
=head1 "use" form
The L</SYNOPSIS> formula
use App::CamelPKI::RestrictedClassMethod ":Restricted";
indicates that the calling package wants to use the C<Restricted>
attribute for its methods. When affixed the C<Restricted> on a method
class (again as shown in the synopsis) prevents the execution of this
method to all excepted to holder of the corresponding
I<App::CamelPKI::RestrictedClassMethod> object (see L</METHODS>).
=cut
sub import {
my ($class, @args) = @_;
return if ! @args;
die "unsupported import form" unless (@args == 1 &&
$args[0] eq ":Restricted");
my ($caller) = caller;
no strict "refs";
*{$caller . "::MODIFY_CODE_ATTRIBUTES"} = sub {
my ($package, $coderef, @attrs) = @_;
return @attrs unless (@attrs == 1 && $attrs[0] eq "Restricted");
__PACKAGE__->_create($package)->
_register_restricted_constructor($coderef);
return;
};
}
=head1 CONSTRUCTORS
=head2 grab($classname)
Commences an hostile takeover on $classname. I<grab> will only succeed
once on any given $classname during the lifetime of the Perl
interpreter; when it succeeds, it returns an instance of the
I<App::CamelPKI::RestrictedClassMethod> class which represents the right to
invoke methods marked as C<Restricted> in $classname.
=cut
sub grab {
my ($class, $wantclass) = @_;
# Can also be invoked as an instance method from inside this
# package:
my $self = ref($class) ? $class : $class->_get($wantclass);
throw App::CamelPKI::Error::Privilege("$wantclass is not loaded yet")
if (! defined $self);
throw App::CamelPKI::Error::Privilege("$wantclass is already taken")
if ($self->{grabbed});
$self->lockdown();
$self->{grabbed}++;
return $self;
}
=head2 fake_grab($classname)
Returns an object of class
L</App::CamelPKI::RestrictedClassMethod::FakeBrand>. Unlike the real
L</grab>, a C<fake_grab()> has no security consequences: restricted
methods are not locked down (see L</lockdown>), and C<fake_grab()> may
succeed several times for the same $classname.
( run in 0.784 second using v1.01-cache-2.11-cpan-99c4e6809bf )