# HG changeset patch # User sergey # Date 1350404051 -14400 # Node ID 23daf2fae33a9dbd6c9c2c4c3b1b048ad16fb8de # Parent b8c724f6de3646d3a2db8888fbda02a17d4c963b *security subsytem bugfixes *HttpResponse: cookies which values are set to undefined will be deleted from browser diff -r b8c724f6de36 -r 23daf2fae33a Lib/IMPL/Security/Auth/Simple.pm --- a/Lib/IMPL/Security/Auth/Simple.pm Tue Oct 16 01:33:06 2012 +0400 +++ b/Lib/IMPL/Security/Auth/Simple.pm Tue Oct 16 20:14:11 2012 +0400 @@ -62,7 +62,7 @@ $this->_stage(STAGE_DONE); } return (AUTH_SUCCESS, undef); - } elsee { + } else { return (AUTH_FAIL, undef); } } diff -r b8c724f6de36 -r 23daf2fae33a Lib/IMPL/Web/Handler/SecureCookie.pm --- a/Lib/IMPL/Web/Handler/SecureCookie.pm Tue Oct 16 01:33:06 2012 +0400 +++ b/Lib/IMPL/Web/Handler/SecureCookie.pm Tue Oct 16 20:14:11 2012 +0400 @@ -43,7 +43,7 @@ my $sid = $action->cookie('sid',qr/(\w+)/); my $cookie = $action->cookie('sdata',qr/(\w+)/); - my $sign = $action->cookie('sign',qw/(\w+)/); + my $sign = $action->cookie('sign',qw/(\w+)/); if ( $sid and @@ -58,15 +58,16 @@ ) { # TODO: add a DefferedProxy to deffer a request to a data source if ( $context = $this->_manager->GetSession($sid) ) { - if ( eval { $context->auth->isa(AuthSimple) } ) { my ($result,$challenge) = $context->auth->DoAuth($cookie); - - $action->_manager->SaveSession($context); - + + $context->authority($this); + if ($result == AUTH_FAIL) { $context = undef; } + } else { + undef $context; } } @@ -83,27 +84,46 @@ } sub InitSession { - my ($this,$user,$auth,$roles) = @_; + my ($this,$user,$roles,$auth,$challenge) = @_; - my $sid = GenSSID(); - my $cookie = GenSSID(); + my ($status,$answer) = $auth->DoAuth($challenge); + + die OperationException->new("This provider doesn't support multiround auth") + if ($status == AUTH_INCOMPLETE || $answer); - $this->_cookies({ - sid => $sid, - sdata => $cookie - }); + if ($status == AUTH_SUCCESS) { + my $sid = GenSSID(); + my $cookie = GenSSID(); + + $this->_cookies({ + sid => $sid, + sdata => $cookie + }); + + my $context = $this->_manager->CreateSession( + sessionId => $sid, + principal => $user, + auth => AuthSimple->Create(password => $cookie), + authority => $this, + rolesAssigned => $roles + ); + + $context->Apply(); + + $this->_manager->SaveSession($context); + } + + return $status; +} - my $context = $this->_manager->CreateSession( - sessionId => $sid, - principal => $user, - auth => AuthSimple->Create(password => $cookie), - authority => $this, - assignedRoles => $roles - ); - - $context->Apply(); - - return $context; +sub CloseSession { + my ($this) = @_; + if(my $session = SecurityContext->current) { + $this->_cookies({ + sid => undef, + sdata => undef + }) + } } sub WriteResponse { @@ -111,7 +131,7 @@ if (my $data = $this->_cookies) { - my $sign = md5_hex( + my $sign = $data->{sid} && md5_hex( $this->salt, $data->{sid}, $data->{sdata}, diff -r b8c724f6de36 -r 23daf2fae33a Lib/IMPL/Web/HttpResponse.pm --- a/Lib/IMPL/Web/HttpResponse.pm Tue Oct 16 01:33:06 2012 +0400 +++ b/Lib/IMPL/Web/HttpResponse.pm Tue Oct 16 20:14:11 2012 +0400 @@ -61,7 +61,12 @@ #used to map a pair name valie to a valid cookie object sub _createCookie { - return UNIVERSAL::isa($_[1], 'CGI::Cookie') ? $_[1] : CGI::Cookie->new(-name => $_[0], -value => $_[1] ); + return UNIVERSAL::isa($_[1], 'CGI::Cookie') + ? $_[1] + : ( defined $_[1] + ? CGI::Cookie->new(-name => $_[0], -value => $_[1] ) + : CGI::Cookie->new(-name => $_[0], -expires => '-1d', -value => '') + ); } sub InternalError { diff -r b8c724f6de36 -r 23daf2fae33a Lib/IMPL/Web/Security.pm --- a/Lib/IMPL/Web/Security.pm Tue Oct 16 01:33:06 2012 +0400 +++ b/Lib/IMPL/Web/Security.pm Tue Oct 16 20:14:11 2012 +0400 @@ -13,7 +13,9 @@ use constant { ERR_NO_SUCH_USER => -1, ERR_NO_SEC_DATA => -2, - ERR_AUTH_FAIL => -3 + ERR_NO_AUTHORITY => -3, + ERR_NO_SEC_CONTEXT => -4, + ERR_AUTH_FAIL => -5 }; sub AuthUser { @@ -24,7 +26,7 @@ status => AUTH_FAIL, code => ERR_NO_SUCH_USER }; - + my $auth; if ( my $secData = $user->GetSecData($package) ) { $auth = $package->new($secData); @@ -36,10 +38,21 @@ }; } + return { + status => AUTH_FAIL, + code => ERR_NO_SEC_CONTEXT + } unless SecurityContext->current; + + return { + status => AUTH_FAIL, + code => ERR_NO_AUTHORITY + } unless SecurityContext->current->authority; + my $status = SecurityContext->current->authority->InitSession( $user, + [$user->roles], $auth, - [$user->roles] + $challenge ); return { @@ -49,6 +62,17 @@ }; } +sub Logout { + my ($this) = @_; + + my $session = SecurityContext->current; + if($session && $session->authority) { + $session->authority->CloseSession($session); + + $this->CloseSession($session); + } +} + sub FindUserByName { die NotImplementedException->new(); } @@ -65,6 +89,10 @@ die NotImplementedException->new(); } +sub CloseSession { + die NotImplementedException->new(); +} + 1; __END__