changeset 330:fe725fad2d90

Added access checking to web resources
author sergey
date Tue, 04 Jun 2013 19:25:54 +0400
parents 50ff1595bd62
children 2ff1726c066c
files Lib/IMPL/Security/AbstractContext.pm Lib/IMPL/Web/Application/CustomResource.pm Lib/IMPL/Web/Application/CustomResourceContract.pm Lib/IMPL/Web/Application/Resource.pm Lib/IMPL/Web/Application/ResourceContract.pm
diffstat 5 files changed, 43 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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) = @_;
     
--- 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 {
     
 }
--- 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) = @_;
                
--- 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);
--- 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 {