view Lib/IMPL/Security.pm @ 308:47a09a8dc23a

sync
author sergey
date Thu, 18 Apr 2013 20:06:05 +0400
parents 814d755e5d12
children d5c8b955bf8d
line wrap: on
line source

package IMPL::Security;
use strict;
use Carp qw(carp);

##VERSION##

require IMPL::Exception;
require IMPL::Security::Rule::RoleCheck;

use IMPL::require { 
    Principal => 'IMPL::Security::Principal',
    AbstractContext => 'IMPL::Security::AbstractContext',
    Context => 'IMPL::Security::Context'
};

our @RULES;

sub AccessCheck {
    my ($self, $object, $desiredAccess, $context) = @_;
    
    $context ||= $self->context;
    
    $_->($self,$object,$desiredAccess,$context) or return 0 foreach @{$self->Rules};
    
    return 1;
}

sub Take {
    my ($self,$principal,$refRoles) = @_;
    
    die new IMPL::NotImplementedException();
}

sub MakeContext {
    my ($this,$principal,$refRoles,$auth) = @_;
    
    return Context->new(
        principal => $principal,
        rolesAssigned => $refRoles,
        auth => $auth
    );
}

sub Rules {
    return \@RULES;
}

sub principal {
    return
        AbstractContext->current
        && AbstractContext->current->principal
        || Principal->nobody; 
}

sub context {
    AbstractContext->current || Context->nobody;
}

1;

__END__

=pod

=head1 NAME

C<IMPL::Security> - Модуль для работы с функциями авторизации и аутентификации.

=head1 SINOPSYS

=begin code

use IMPL::Security;

my Method {
    my $this = shift;
    
    # access check in the current context, using standard configuration
    IMPL::Security->AccessCheck($this,'Method') or die new IMPL::AccessDeniedException("Access is denied");
    
    #some more results 
}

my DelegationMethod {
    
    my $this = shift;
    
    #forced delegation 
    my $delegatedContext = IMPL::Security::Context->new(
        principal => IMPL::Security::Principal->new(
            name => 'suser'
        ),
        rolesAssigned => ['administrator']
    )
    
    my $result;
    
    $delegatedContext->Impersonate(sub{
        $result = $this->Method();
    });
    
    return $result;
}

my SafeDelegationMethod {
    
    my $this = shift;
    
    my $delegatedContext = IMPL::Security->Take( suser => 'administrator' );
    
    my $result;
    
    $delegatedContext->Impersonate(sub{
        $result = $this->Method();
    });
    
    return $result;
}

=end code

=head1 DESCRIPTION

Модуль для инфраструктуры безопасности, реализует основные функции для авторизации
и аутентификации пользователей.

Модуль аутентификации, реализиция которого зависит от приложения, аутентифицирует
пользователя, при этом создается контекст безопасности, который содержит
идентификатор пользователя и список активных ролей.

При проверке прав доступа происходит последовательная проверка правил доступа,
если все правила выполнены, то доступ разрешается.

=head1 MEMBERS

=over

=item C<AccessCheck($object,$desiredAccess,$context)>

Метод. Проверка доступа к объекту с определенными правами, в определенном контексте безопасности.

=over

=item C<$object>

Объект доступа.

=item C<$desiredAccess>

Требуемые права доступа.

=item C<$context>

Контекст безопасности, если не указан, то используется текущий C<< IMPL::Security::Context->contextCurrent >>

=item C<returns>

C<true | false> - результат проверки

=back

=item C<MakeContext($principal,$role,$auth)>

Создает контекст безопасности, инициализируя его передданными параметрами.

=over

=item C<$principal>

Объект пользователя

=item C<$role>

Роль или ссылка на массив ролей

=item C<$auth>

Объект аутентификации

=back

=item C<Take($principal,$role)>

Метод. Делегирует текущему пользователю полномочия другого пользователя. При этом выполняется проверка
правомерности такой операции. В случае неудачи вызывается исключение.

=over

=item C<$principal>

Либо имя пользователя либо объект C<IMPL::Security::Principal>.

=item C<$role>

Либо имя либо ссылка на роль, или ссылка на массив либо имен, либо ролей.

=item C<returns>

Новый контекст безопасности.

=back

=item C<Rules()>

Возвращает список правил которые выполняются при проверках доступа. Пререопределите этот
метод, чтобы возвращать собственный список правил. Список правил является ссылкой на массив
элементами которого являются функции.

=begin code

package MySecurity;

use parent qw(IMPL::Security);

sub Rules {
    return [
        \&Rule1,
        \&Rule2,
        #...
    ]
}

=end code

=item C<[static,get] authority>

Метод, позволяющий получить текущий источник системы безопасности. Источник безопасности, это модуль,
который получает входные данные и использует их для работы системы безопасности.

=back

=cut