Subject: | Permissions error when calling :Restricted method in an adjacent parent class |
First, thank you for all your work on this amazing module. Having this
at my disposal makes refactoring old code and building new libraries a
pleasure.
Please see the attached test.pl and test.error files, as those describe
the issue better than I am about to.
In short, I am unable to call a :Restricted method from an adjacent
parent class. For example, in the following layout...
package Baz;
{ use Object::InsideOut; }
package Bar;
{ use Object::InsideOut; }
package Foo;
{ use Object::InsideOut qw| Bar Baz |; }
..all three objects would report themselves as belonging to Foo, Bar
and Baz via "->isa()" or "->meta()->get_classes()". I would therefore
expect to be able to call :Restricted methods in Baz from Bar, and vice-
versa, since they are now in the hierarchy chain thanks to Foo.
However, attempts to call a :Restricted method in Baz from Bar results
in a permissions failure. Looking at the Object::InsideOut closure
that performs the permission checks...
# Returns a 'wrapper' closure back to initialize() that restricts a
method
# to being only callable from within its class hierarchy
sub wrap_RESTRICTED :Sub(Private)
{
my ($pkg, $method, $code, $except) = @_;
return sub {
# Caller must be in class hierarchy, or be specified as an
exception
my $caller = caller();
if (! ((grep { $_ eq $caller } @$except) ||
$GBL{'isa'}->($caller, $pkg) ||
$GBL{'isa'}->($pkg, $caller)))
{
OIO::Method->die('message' => "Can't call restricted method
'$pkg->$method' from class '$caller'");
}
goto $code;
};
}
...I see that it is using the original UNIVERSAL::isa directly instead
of passing it through the overloaded one, which returns false in this
case and prevents the call to the :Restricted method. If I make it
public or add an exemption, it of course works fine.
It is entirely possible that I am grossly misunderstanding the
hierarchy coupling, so if this is the case please let me know.
Given my ignorance of the underlying mechanisms, though, it seems to me
like if I get a thumbs up from $self->isa() in my app code, I should be
able to call :Restricted methods therein.
Thanks in advance for looking at this!
Subject: | perl.version |
Message body not shown because it is not plain text.
Subject: | test.pl |
package Derp;
{
use Object::InsideOut;
sub say_derp
{
my ( $self ) = @_;
print
"Derp isa: "
. ( join q{ }, $self->isa() )
. "\n"
;
return;
}
}
package Baz;
{
use Object::InsideOut;
sub say_baz :Restricted
{
my ( $self ) = @_;
print
"Baz isa: "
. ( join q{ }, $self->isa() )
. "\n"
;
return;
}
}
package Bar;
{
use Object::InsideOut;
sub say_bar :Restricted
{
my ( $self ) = @_;
print
"Bar isa: "
. ( join q{ }, $self->isa() )
. "\n"
;
# THIS WORKS
# Say hello from a public method in one of the other parents
# in the hierarchy
$self->say_derp();
# THIS FAILS
# Say hello from a restricted method in one of the other parents
# in the hierarchy
$self->say_baz();
}
}
package Foo;
{
use Object::InsideOut qw|
Bar
Baz
Derp
|;
sub say_foo
{
my ( $self ) = @_;
print
"Foo isa: "
. ( join q{ }, $self->isa() )
. "\n"
;
# Say hello from a restricted method in one of our parents, Bar
$self->say_bar();
return;
}
}
package main;
my $foo = Foo->new();
$foo->say_foo();
Subject: | test.error |
Message body not shown because it is not plain text.
Subject: | os.version |
Message body not shown because it is not plain text.