# HG changeset patch # User sergey # Date 1370359554 -14400 # Node ID fe725fad2d90e8ef66713ae7eefafd2a7872b299 # Parent 50ff1595bd626fa3021dfeaaa58439d897d6e33f Added access checking to web resources diff -r 50ff1595bd62 -r fe725fad2d90 Lib/IMPL/Security/AbstractContext.pm --- a/Lib/IMPL/Security/AbstractContext.pm Mon Jun 03 18:03:54 2013 +0400 +++ b/Lib/IMPL/Security/AbstractContext.pm Tue Jun 04 19:25:54 2013 +0400 @@ -6,6 +6,7 @@ use IMPL::require { Role => 'IMPL::Security::Role', + Principal => 'IMPL::Security::Principal', Exception => 'IMPL::Exception', NotImplementedException => '-IMPL::NotImplementedException' }; @@ -60,6 +61,10 @@ } } +sub isNobody { + return (shift->principal == Principal->nobody ? 1 : 0); +} + sub Satisfy { my ($this,@roles) = @_; diff -r 50ff1595bd62 -r fe725fad2d90 Lib/IMPL/Web/Application/CustomResource.pm --- a/Lib/IMPL/Web/Application/CustomResource.pm Mon Jun 03 18:03:54 2013 +0400 +++ b/Lib/IMPL/Web/Application/CustomResource.pm Tue Jun 04 19:25:54 2013 +0400 @@ -10,12 +10,22 @@ }, base => [ 'IMPL::Web::Application::Resource' => '@_' + ], + props => [ + accessCheck => PROP_RW ] }; __PACKAGE__->static_accessor(contractFactory => CustomResourceContract ); __PACKAGE__->static_accessor_own(_contractInstance => undef); +sub CTOR { + my ($this,%args) = @_; + + $this->accessCheck($args{accessCheck}) + if $args{accessCheck}; +} + sub contractInstance { my ($self) = @_; @@ -51,6 +61,16 @@ $self->CreateContract()->CreateResource(%args); } +sub AccessCheck { + my ($this,$verb) = @_; + + my $handler = $this->accessCheck; + + if(ref($handler) eq 'CODE') { + &$handler($this,$verb); + } +} + sub GetChildResources { } diff -r 50ff1595bd62 -r fe725fad2d90 Lib/IMPL/Web/Application/CustomResourceContract.pm --- a/Lib/IMPL/Web/Application/CustomResourceContract.pm Mon Jun 03 18:03:54 2013 +0400 +++ b/Lib/IMPL/Web/Application/CustomResourceContract.pm Tue Jun 04 19:25:54 2013 +0400 @@ -23,10 +23,10 @@ sub CTOR { my ($this) = @_; - $this->verbs->{options} = OperationContract->new( binding => \&_HttpOptionsBinding ); + $this->verbs->{options} ||= OperationContract->new( binding => \&_HttpOptionsBinding ); while(my ($verb,$methodName) = each %RESOURCE_BINDINGS) { - $this->verbs->{lc($verb)} = OperationContract->new ( + $this->verbs->{lc($verb)} ||= OperationContract->new ( binding => sub { my ($resource,$action) = @_; diff -r 50ff1595bd62 -r fe725fad2d90 Lib/IMPL/Web/Application/Resource.pm --- a/Lib/IMPL/Web/Application/Resource.pm Mon Jun 03 18:03:54 2013 +0400 +++ b/Lib/IMPL/Web/Application/Resource.pm Tue Jun 04 19:25:54 2013 +0400 @@ -54,6 +54,8 @@ die NotAllowedException->new( allow => join( ',', map( uc, keys %{ $this->contract->verbs } ) ) ) unless $operation; + + $this->AccessCheck($verb); # в случае, когда один ресурс вызывает HTTP метод другого ресурса, нужно # сохранить оригинальный resourceLocation @@ -70,6 +72,10 @@ return _InvokeDelegate($operation, $this, $action ); } +sub AccessCheck { + +} + sub PrepareEnvironment { my ($this) = @_; @@ -89,6 +95,8 @@ # в контракте. sub FetchChildResource { my ( $this, $childId ) = @_; + + $this->AccessCheck('FETCH'); my ( $info, $childIdParts ) = $this->contract->FindChildResourceInfo($childId); diff -r 50ff1595bd62 -r fe725fad2d90 Lib/IMPL/Web/Application/ResourceContract.pm --- a/Lib/IMPL/Web/Application/ResourceContract.pm Mon Jun 03 18:03:54 2013 +0400 +++ b/Lib/IMPL/Web/Application/ResourceContract.pm Tue Jun 04 19:25:54 2013 +0400 @@ -8,7 +8,9 @@ Exception => 'IMPL::Exception', ArgumentException => '-IMPL::ArgumentException', KeyNotFoundException => '-IMPL::KeyNotFoundException', - ResourceClass => 'IMPL::Web::Application::Resource' + ResourceClass => 'IMPL::Web::Application::CustomResource', + CustomContract => 'IMPL::Web::Application::CustomResourceContract', + Factory => 'IMPL::Object::Factory' }, base => [ 'IMPL::Object' => undef ], props => [ @@ -23,10 +25,9 @@ my $this = shift; my %args = @_; - $this->resourceFactory( $args{resourceFactory} || ResourceClass ); - - my $resources = $args{resources} || []; - my $verbs = $args{verbs} || {}; + my $factory = delete $args{resourceFactory} || ResourceClass; + my $resources = delete $args{resources} || []; + my $verbs = delete $args{verbs} || {}; die ArgumentException->new( resources => 'resources parameter must be a reference to an array' ) @@ -57,6 +58,8 @@ } $this->_namedResources( \%nameMap ); + + $this->resourceFactory( %args ? Factory->new($factory,\%args) : $factory ); } sub AddChildResourceContract {