Mercurial > pub > Impl
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