diff Lib/IMPL/Security/AbstractContext.pm @ 230:6d8092d8ce1b

*reworked IMPL::Security *reworked IMPL::Web::Security *refactoring
author sergey
date Mon, 08 Oct 2012 03:37:37 +0400
parents Lib/IMPL/Security/Context.pm@4d0e1962161c
children b8c724f6de36
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/IMPL/Security/AbstractContext.pm	Mon Oct 08 03:37:37 2012 +0400
@@ -0,0 +1,152 @@
+package IMPL::Security::AbstractContext;
+use strict;
+use warnings;
+
+use IMPL::Const qw(:prop);
+use IMPL::require {
+    Role => 'IMPL::Security::Role'
+};
+
+use parent qw(IMPL::Class::Meta);
+
+__PACKAGE__->static_accessor_clone(abstractProps => [
+    principal => PROP_RW,
+    rolesAssigned => PROP_RW | PROP_LIST,
+    auth => PROP_RW,
+    authority => PROP_RW
+]);
+
+my $current; # current session if any
+
+sub Impersonate {
+    my ($this,$code) = @_;
+    
+    my $old = $current;
+    $current = $this;
+    my $result;
+    my $e;
+    
+    {
+        local $@;
+        eval {
+            $result = $code->();
+        };
+        $e = $@;
+    }
+    $current = $old;
+    if($e) {
+        die $e;
+    } else {
+        return $result;
+    }
+}
+
+sub Apply {
+    my ($this) = @_;
+    
+    $current = $this;
+}
+
+sub isTrusted {
+    my ($this) = @_;
+    
+    if (my $auth = $this->auth) {
+        return $auth->isTrusted;
+    } else {
+        return 0;
+    }
+}
+
+sub Satisfy {
+    my ($this,@roles) = @_;
+    
+    my $roleEffective = Role->new ( _effective => scalar $this->rolesAssigned );
+    
+    return $roleEffective->Satisfy(@roles);
+}
+
+sub current {
+    $current;
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+C<abstract IMPL::Security::Context> - контекст безопасности.
+
+=head1 SINOPSYS
+
+=begin code
+
+package MyApp::Model::Session;
+use strict;
+
+use IMPL::delare {
+    base => [
+        'MyApp::Model::BaseDBO' => '@_',
+        'IMPL::Security::AbstractContext' => undef
+    ],
+    props {
+        IMPL::Security::AbstractContext->abstractProps,
+        qouta => PROP_GET
+    }
+}
+
+package main;
+
+$app->model->GetSession('546a54df4')->Impersonate(sub{
+    # do something
+});
+
+=end code
+
+=head1 DESCRIPTION
+
+Код приложения, которое выполняется 
+
+Являет собой контекст безопасности, описывает пользователя и привелегии, так же
+у программы есть текущий контекст безопасности, по умолчанию он C<nobody>.
+
+=head1 MEMBERS
+
+=head2 C<[get] principal>
+
+Идентификатор пользователя, владельца контекста.
+
+=head2 C<[get] rolesAssigned>
+
+Список назначенных (активных) ролей пользователю.
+
+=head2 C<[get] auth>
+
+Объект асторизации C<IMPL::Security::Auth>, использованный при создании текущего контекста.
+
+=head2 C<[get] authority>
+
+Модуль безопасности, породивший данный контекст. Модуль безопасности, отвечающий
+за создание контекста безопасности должен реализовывать метод
+C<CreateContext($user,$auth,$roles)>
+
+=head2 C<[get] isTrusted>
+
+Возвращает значение является ли контекст доверенным, тоесть клиент
+аутентифицирован и сессия установлена. Если C<false> значит, что сессия была
+начата, однако не установлена до конца.
+
+=head2 C<Impersonate($code)>
+
+Делает контекст текущим и выполняет в нем функцию по ссылке C<$code>. По окончании
+выполнения, контекст восстанавливается в предыдущий (не зависимо от того, что
+с ним происходило во время выполнения C<$code>).
+
+=head2 C<Apply()>
+
+Заменяет текущий контекст на себя, но до конца действия метода C<Impersonate>, если
+таковой был вызван.
+
+=cut