diff lib/IMPL/Security/AbstractContext.pm @ 407:c6e90e02dd17 ref20150831

renamed Lib->lib
author cin
date Fri, 04 Sep 2015 19:40:23 +0300
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/IMPL/Security/AbstractContext.pm	Fri Sep 04 19:40:23 2015 +0300
@@ -0,0 +1,167 @@
+package IMPL::Security::AbstractContext;
+use strict;
+use warnings;
+
+use IMPL::Const qw(:prop);
+
+use IMPL::require {
+    Role => 'IMPL::Security::Role',
+    Principal => 'IMPL::Security::Principal',
+    Exception => 'IMPL::Exception',
+    NotImplementedException => '-IMPL::NotImplementedException'
+};
+
+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,@args) = @_;
+    
+    my $old = $current;
+    $current = $this;
+    my $result;
+    my $e;
+    
+    {
+        local $@;
+        eval {
+            $result = $code->(@args);
+        };
+        $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 isNobody {
+    return (shift->principal == Principal->nobody ? 1 : 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,set] 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>, если
+таковой был вызван.
+
+=head2 C<Satisfy(@roles)>
+
+Проверяет наличие необходимых ролей у контекста. Данный метод позволяет
+абстрагироваться от механизмов связи контекста и ролей. Возвращает истинное
+значение если список необходимых ролей у пользователя имеется.
+
+=cut