diff Lib/IMPL/Web/Handler/SecureCookie.pm @ 230:6d8092d8ce1b

*reworked IMPL::Security *reworked IMPL::Web::Security *refactoring
author sergey
date Mon, 08 Oct 2012 03:37:37 +0400
parents a705e848dcc7
children ff1e8fa932f2
line wrap: on
line diff
--- a/Lib/IMPL/Web/Handler/SecureCookie.pm	Sat Sep 29 02:34:47 2012 +0400
+++ b/Lib/IMPL/Web/Handler/SecureCookie.pm	Mon Oct 08 03:37:37 2012 +0400
@@ -1,16 +1,27 @@
-package IMPL::Web::QueryHandler::SecureCookie;
+package IMPL::Web::Handler::SecureCookie;
 use strict;
 
-use parent qw(IMPL::Web::QueryHandler);
+
 use Digest::MD5 qw(md5_hex);
-
-use IMPL::Class::Property;
-use IMPL::Security::Auth qw(:Const);
-use IMPL::Security;
-
-BEGIN {
-    public property salt => prop_all;
-}
+use IMPL::Const qw(:prop);
+use IMPL::Security::Auth qw(:Const GenSSID);
+use IMPL::declare {
+    require => {
+        SecurityContext => 'IMPL::Security::Context',
+        User => 'IMPL::Security::User',
+        AuthSimple => 'IMPL::Security::Auth::Simple',
+    },
+    base => {
+        'IMPL::Object' => undef,
+        'IMPL::Object::Autofill' => '@_',
+        'IMPL::Object::Serializable' => undef
+    },
+    props => [  
+        salt => PROP_RO,
+        manager => PROP_RO,
+        _cookies => PROP_RW
+    ]
+};
 
 sub CTOR {
     my ($this) = @_;
@@ -18,67 +29,93 @@
     $this->salt('DeadBeef') unless $this->salt;
 }
 
-sub Process {
+sub Invoke {
     my ($this,$action,$nextHandler) = @_;
     
-    return undef unless $nextHandler;
+    return unless $nextHandler;
+    
+    my $context;
     
-    local $IMPL::Security::authority = $this;
-    
-    my $method = $action->query->cookie('method') || 'simple';
+        
+    my $sid = $action->cookie('sid',qr/(\w+)/); 
+    my $cookie = $action->cookie('sdata',qr/(\w+)/);
+    my $sign = $action->cookie('sign',qw/(\w+)/); 
     
-    if ($method eq 'simple') {
-        
-        my $sid = $action->query->cookie('sid'); 
-        my $cookie = $action->query->cookie('sdata');
-        my $sign = $action->query->cookie('sign'); 
+    if (
+        $sid and
+        $cookie and
+        $sign and
+        $sign eq md5_hex(
+            $this->salt,
+            $sid,
+            $cookie,
+            $this->salt
+        )
+    ) {
+        # TODO: add a DefferedProxy to deffer a request to a data source
+        if ( $context = $this->manager->GetSession($sid) ) {
         
-        if (
-            $sid and
-            $cookie and
-            $sign and
-            $sign eq md5_hex(
-                $this->salt,
-                $sid,
-                $cookie,
-                $this->salt
-            )
-        ) {
-            # TODO: add a DefferedProxy to deffer a request to a data source
-            my $context = $action->application->security->sourceSession->find(
-                { id => $sid }
-            ) or return $nextHandler->();
-            
-            my ($result,$challenge) = $context->auth->ValidateSession($cookie);
-            
-            if ($result == AUTH_SUCCESS) {
-                $context->authority($this);
-                return $context->Impersonate($nextHandler);                
-            } else {
-                return $nextHandler->();
+            if ( eval { $context->auth->isa(AuthSimple) } ) {
+                my ($result,$challenge) = $context->auth->DoAuth($cookie);
+                
+                $action->manager->SaveSession($context);
+                
+                if ($result == AUTH_FAIL) {
+                    $context = undef;
+                }
             }
-        } else {
-            return $nextHandler->();
         }
-    } else {
-        return $nextHandler->();
+        
     }
+    
+    $context = SecurityContext->new(principal => User->nobody, authority => $this);
+    
+    my $httpResponse = $context->Impersonate($nextHandler);
+    
+    $this->WriteResponse($httpResponse);
+    
+}
+
+sub CreateContext {
+    my ($this,$user,$auth,$roles) = @_;
+    
+    my $sid = GenSSID();
+    my $cookie = GenSSID();
+    
+    $this->_cookies({
+        sid => $sid,
+        sdata => $cookie
+    })
+
+    my $context = $this->$manager->CreateSession(
+        sessionId => $sid,
+        principal => $user,
+        auth => AuthSimple->(password => $cookie),
+        authority => $this,
+        assignedRoles => $roles
+    );
+    
+    $context->Apply();
+    
+    return $context;
 }
 
 sub WriteResponse {
-    my ($this,$response,$sid,$cookie,$method) = @_;
+    my ($this,$response) = @_;
+    
+    if (my $data $this->_cookies) {
 
-    my $sign = md5_hex(
-        $this->salt,
-        $sid,
-        $cookie,
-        $this->salt
-    );
-    
-    $response->setCookie(sid => $sid);
-    $response->setCookie(sdata => $cookie);
-    $response->setCookie(sign => $sign);
-    $response->setCookie(method => $method) if $method;
+        my $sign = md5_hex(
+            $this->salt,
+            $data->{sid},
+            $data->{sdata},
+            $this->salt
+        );
+        
+        $response->cookies->{sid} = $data->{sid};
+        $response->cookies->{sdata} = $data->{sdata};
+        $response->cookies->{sign} = $sign;
+    }
 }
 
 1;
@@ -89,12 +126,10 @@
 
 =head1 NAME
 
-C<IMPL::Web::QueryHandler::SecureCookie>
+C<IMPL::Web::Handler::SecureCookie>
 
 =head1 DESCRIPTION
 
-C<use parent qw(IMPL::Web::QueryHandler)>
-
 Возобновляет сессию пользователя на основе информации переданной через Cookie.
 
 Использует механизм подписи информации для проверки верности входных данных перед
@@ -102,6 +137,8 @@
 
 Данный обработчик возвращает результат выполнения следдующего обработчика.
 
+
+
 =head1 MEMBERS
 
 =over