Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Catalyst::Authentication


Автор: gcc 27.1.2009, 11:26
делаю как в книге, только использую DBI вместе DBIx::Class

Код

use Catalyst qw/ConfigLoader Static::Simple
                Session Session::State::Cookie Session::Store::DBI
                Authentication
                Authentication::Store::DBI
                Authentication::Credential::Password
                           Authorization::Roles
                           Authorization::ACL/;
# setup sessions, authorization, and authentication
## ACL rules
__PACKAGE__->deny_access_unless('/admin', [qw/admin/]);


ругатеся 
Код

perl script/myapp_server.pl
Can't locate Catalyst/Plugin/Authentication/Store/DBI.pm in @INC 
(@INC contains: /home/x0/data/www/MyApp/script/../lib /usr/local/lib/perl5/5.8.8/BSDPAN
 /usr/local/lib/perl5/site_perl/5.8.8/mach /usr/local/lib/perl5/site_perl/5.8.8 /usr/local/lib/perl5/site_perl 
/usr/local/lib/perl5/5.8.8/mach /usr/local/lib/perl5/5.8.8 .) at /usr/local/lib/perl5/site_perl/5.8.8/Catalyst/Utils.pm line 270.
Compilation failed in require at script/myapp_server.pl line 55.


модули в системе стоят, эти модули мне нужно поставить в мой проект? то как поставить их с DBI?  нигде не написано...

чтобы поставить надо знать что такое Session::Store::DBI - это модель, контроллер или view??

на что именнно он ругается?

ЗЫ: каталист с певрого раза не очень понравился, так как все  равно всё надо переделывать под свои нужны и телепатировать с разработчиками





Автор: ginnie 27.1.2009, 12:40
gcc, я, к сожалению, не знаком с Catalyst, поэтому конкретных рекомендаций тебе не дам. Ругается он на Authentication::Store::DBI, т.к. при этом пытается загрузить модуль Catalyst::Plugin::Authentication::Store::DBI, которого нет (в природе  smile).

Автор: gcc 30.1.2009, 18:46
полностью написано про это тут:
http://kobesearch.cpan.org/htdocs/Catalyst-Plugin-Session-Store-DBI/Catalyst/Plugin/Session/Store/DBI.pm.html



сейчас делаю по этому
http://search.cpan.org/~hkclark/Catalyst-Manual-5.7016/lib/Catalyst/Manual/Tutorial/Authorization.pod
http://search.cpan.org/~hkclark/Catalyst-Manual-5.7016/lib/Catalyst/Manual/Tutorial/Authentication.pod

только использую DBI

Автор: gcc 30.1.2009, 21:40
есть сабж такой 

http://search.cpan.org/~hkclark/Catalyst-Manual-5.7016/lib/Catalyst/Manual/Tutorial/Authentication.pod#Displaying_Content_Only_to_Authenticated_Users

откуда там идут значение  c.user_exists и c.user.username в шаблон ?

то есть мне нужно вывести активен ли пользователь или нет, но я не ивжу от куда те парамерты взялись ИМХО ( а шаблон не ТТ)


==============================

это по-моиму это $c->user( )

http://search.cpan.org/~bobtfish/Catalyst-Plugin-Authentication-0.100092/lib/Catalyst/Plugin/Authentication.pm

ЗЫ просто не понятно было где их искать... эти методы

Автор: NuINu 31.1.2009, 01:26
объект c или Сatalyst в ТТ, 
это и есть объект класса приложение к примеру MyApp (из примера)

там есть строчка 
 use Catalyst qw/
.....
           Authentication
......

это добавляет плагин Catalyst::Plugin::Authentication к классу приложеня MyApp
в нем есть куча методов и в частности
user
user_exists

да, а уже то что возврящает user имеест свой метод username(а может это всего лишь поле в хеше)

но вообще говоря архитектура опирается на иделологию класса Class - довольно таки сложная.
я не доконца еще в ней разобрался.

думаю если вы вставите в пример MyAuth Books.pm
след код, получите массу разнообразной информации
#для очень крутой отладки!
use Devel::Symdump;
use Data::Dumper;
sub d1 : Private {
        my $c = shift;
        # !!!!!!!!!!!!! ниже указать Название класса приложения!!!!!!!!!!!!
        my @pkg = qw(MyAuth Catalyst::Plugin::Authentication);
        my $obj = Devel::Symdump->rnew(@pkg);

        print "Scalars:\n";
        my @array = $obj->scalars;
        foreach (@array) {
            print "$_\n";
        }

        print "Arrays:\n";
        @array = $obj->arrays;
        foreach (@array) {
            print "$_\n";
        }

        print "\nHashes:\n";
        @array = $obj->hashes;
        foreach (@array) {
            print "$_\n";
        }

        print "\nFunction:\n";
        @array = $obj->functions;
        foreach (@array) {
            print "$_\n";
        }
        print "\n------------------------------------------\n";
        print Dumper($c);
        print "\n------------------------------------------\n";


}

sub list : Local {
    my ($self, $c) = @_;
    $c->stash->{books} = $c->model('Book')->{manager}->get_books(
                                        sort_by => ['title'],       );
    $c->stash->{template} = 'books/list.tt2';

    d1($c);
}

Автор: gcc 31.1.2009, 13:14
аномалия какая-то

есть код, это файл login.pm

Код

   sub index :Path :Args(0) {
    my ( $self, $c ) = @_;

        # Get the username and password from form
        my $username = $c->request->params->{username} || "";
        my $password = $c->request->params->{password} || "";
    
        # If the username and password values were found in form
        if ($username && $password) {
            # Attempt to log the user in
            if ($c->authenticate({ username => $username,
                                   password => $password  } )) {
                # If successful, then let them use the application
                $c->response->redirect($c->uri_for('/database'));
                return;
            } else {
                # Set an error message
               $c->stash->{template} = '/home/data/www/MyApp/root/login.tt';
                $c->stash->{error_msg} = "Bad username or password.";
            }
        }
   
        # If either of above don't work out, send to the login page
}


ошибка
Код

Caught exception in MyApp::View::HTML::Template->process "HTML::Template->new() : Cannot open included file login :
 file not found. at /usr/local/lib/perl5/site_perl/5.8.8/HTML/Template.pm line 1658
    HTML::Template::_init_template('HTML::Template=HASH(0x9af7d10)') called at /usr/local/lib/perl5/site_perl/5.8.8/HTML/Template.pm line 1238
    HTML::Template::_init('HTML::Template=HASH(0x9af7d10)') called at /usr/local/lib/perl5/site_perl/5.8.8/HTML/Template.pm line 1124
    HTML::Template::new('HTML::Template', 'filename', 'login', 'path', 'ARRAY(0x9a9ed6c)', 'die_on_bad_params', 0, 'cache', 1, ...) 
called at /usr/local/lib/perl5/site_perl/5.8.8/Catalyst/View/HTML/Template.pm line 96
    Catalyst::View::HTML::Template::render('MyApp::View::HTML::Template=HASH(0x9799994)', 'MyApp=HASH(0x9b1e488)', 'login') called
 at /usr/local/lib/perl5/site_perl/5.8.8/Catalyst/View/HTML/Template.pm line 59



почему "login" из param идет в шаблон? шаблон ругается на то что откуда-то взляся login

шаблон работатет, тестовые страницы работают

Автор: NuINu 31.1.2009, 19:16
где появляется логин видно из трассировки ошибки.

Caught exception in MyApp::View::HTML::Template->process "HTML::Template->new() : Cannot open included file login :

Catalyst::View::HTML::Template::render('MyApp::View::HTML::Template=HASH(0x9799994)', 'MyApp=HASH(0x9b1e488)', 'login') called at /usr/local/lib/perl5/site_perl/5.8.8/Catalyst/View/HTML/Template.pm line 59

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

Автор: gcc 1.2.2009, 18:42
NuINu, спасибо, поставил в самый вверх путь к шаблону, заработало!


1) в книге нашел такую цитату, но не могу понять как ее использовать?
к чему это, нужно модуль свой написать для кармы? но как модуль который будет сюда прикрутить?
Код

If you prefer not to use roles, you can also use an arbitrary subroutine:
    __PACKAGE__->allow_access_if(
        '/bonus/area',
                   sub { my ($c, $action) = @_;
                 if($c->user->karma > 50){
                       return $ALLOWED
                 }
                 else {
                       return $DENIED
                 }
               }
         );
Here we allow access to /bonus/area only if the user has a karma (as defined by the
user object) greater than 50. Otherwise, the /access_denied action is run instead.


2) как сделать чтобы была доступаня страница под адрессу http://domain.com/ (без параметров)
не могу найти как это сделать, какой это контроллер? smile

3) есть таблица users, и в ней столбец active, если я хочу, например, написать пользователю что он не активен во всех или нескольих контрллерах, нужно использовать begin : Private или как-то под другому, как правильно? 

(или тут просто $c->forward($calss,$method) поможет?)


4) не получилось перевети и понять смысл:
Цитата

# Top-level (Global)

    package MyApp::Controller::Foo;
    sub foo : Global { }

Matches http://localhost:3000/foo. The function name is mapped directly to the application base. You can provide an equivalent function in this case by doing the following:

    package MyApp::Controller::Root
    sub foo : Local { }

# Namespace-Prefixed (Local)

    package MyApp::Controller::My::Controller; 
    sub foo : Local { }

Matches http://localhost:3000/my/controller/foo.

This action type indicates that the matching URL must be prefixed with a modified form of the component's class (package) name. This modified class name excludes the parts that have a pre-defined meaning in Catalyst ("MyApp::Controller" in the above example), replaces "::" with "/", and converts the name to lower case. See "Components" for a full explanation of the pre-defined meaning of Catalyst component class names.

Note that actions with the :Local attribute are equivalent to the <:Path('action_name') > so sub foo : Local { } is equivalent to -

    sub foo : Path('foo') { }

# Private

    sub foo : Private { }

Matches no URL, and cannot be executed by requesting a URL that corresponds to the action key. Catalyst's :Private attribute is exclusive and doesn't work with other attributes (so will not work combined with Path or Chained attributes). With the exception of the index , auto and default actions, Private actions can only be executed from inside a Catalyst application, by calling the forward or detach methods:

    $c->forward('foo');
    # or
    $c->detach('foo');

See "Flow Control" for a full explanation of forward. Note that, as discussed there, when forwarding from another component, you must use the absolute path to the method, so that a private bar method in your MyApp::Controller::Catalog::Order::Process controller must, if called from elsewhere, be reached with $c->forward('/catalog/order/process/bar').


что такое :global, :privat и ;local?

Args - это массив который идет как param просто парметры /Args[0]/Args[1]/Args[2]
sub bar : Path('foo/bar') { } - этот метод будет загружатся если путь такой 'foo/bar'

http://search.cpan.org/~hkclark/Catalyst-Manual-5.7016/lib/Catalyst/Manual/Intro.pod#Action_types

не могу понять как использовать Catalyst::DispatchType::Chained  http://search.cpan.org/~mramberg/Catalyst-Runtime-5.71000/lib/Catalyst/DispatchType/Chained.pm ?



Автор: gcc 1.2.2009, 20:00
кстате, если пользователь хочет скрыть какую-то информацию (программно), то целесобразно тут использовать Catalyst::Plugin::Authorization::Roles  ?

Автор: NuINu 2.2.2009, 23:29
1: Здесь речь идет уже не о аутентификации(идентификация кто - это), а авторизации(т.е о правах пользователя идентификация - а что ему можно)
конкретно правах на основе некоего счетчика - карма - он ведется отдельно, считай как на форуме.
так вот при достижении конкретного значения счетчика пользователю открываются некие возможности а именно доступ в /bonus/area

2: Root.pm метод default

3: выясни, прежде всего для себя чего ты хочешь добиться этим полем - актив. либо запрета аутентификации тогда актив имеет занчение 0 и 1. и мы ограничиваем пользователя по маске, либо все, либо ничего.
либо мы ограничиваем пользователя в некоторых правах, т.е. в авторизации.
тогда это поле может содержать (имя отношение один(пользователь) ко многим (активе)) список ссылок (к которым данный пользователь имеет доступ и некие условные обозначения к примеру NULL и ALL)
это будет пример авторизации на основе списков доступа хранящихся персонально для каждого пользователя в базе

4:  я пользуюсь гугл переводчиком, думаю он поможет и тебе. 
global, local .... perldoc Catalyst::Manual::Intro

все я спать smile

Автор: gcc 2.2.2009, 23:43
Цитата(NuINu @ 2.2.2009,  23:29)

3: выясни, прежде всего для себя чего ты хочешь добиться этим полем - актив. либо запрета аутентификации тогда актив имеет занчение 0 и 1. и мы ограничиваем пользователя по маске, либо все, либо ничего.
либо мы ограничиваем пользователя в некоторых правах, т.е. в авторизации.
тогда это поле может содержать (имя отношение один(пользователь) ко многим (активе)) список ссылок (к которым данный пользователь имеет доступ и некие условные обозначения к примеру NULL и ALL)
это будет пример авторизации на основе списков доступа хранящихся персонально для каждого пользователя в базе


понтяно при 0 - запретить, при 1 оазрешить

я хотел запретить публиковать и разрешить смотреть. Вопрос хотел узнать про то, куда мне это вставить, точнее мне нужно как-то метод в модуле аутентификации переопределить? чтобы не ковырять сам модуль, ну и чтобы дополнительный SQL dbi запрос не делать?

Автор: NuINu 3.2.2009, 16:24
так вот, 0 и 1 это разрешить запретить аутентификацию! т.е ригистрацию пользователя. а значит здесь управляем на уровне доступа ко ВСЕМУ ресурсу.

то о чем ты говоришь это уже уровень авторизации, т.е управление доступом для АУТЕНТИФИЦИРОВАННЫХ полльзователей.

посмотри учебник по Authorization smile он следующий за аутентификцией.

таким образом если делать авторизацию с использованием ролей
надо создать роли viewer и editor
и соответсвенно присвоить пользователям эти роли.
а в контроллерах проверять какую роль играет текущий пользователь.

на счет запроса SQL- не надо экономить на спичках.

а модуль ковырять и не надо подлючаешь в головном модуле модуль Authorization и все.

Автор: gcc 3.2.2009, 16:50
Цитата(NuINu @ 3.2.2009,  16:24)
пользователям эти роли.
а в контроллерах проверять какую роль играет текущий пользователь.

но если у меня этих контроллеров штук 100, в каждом контроллере это менять?

тогда переделать модуль который смотрит логин и пароль, чтобы он смотрел сразу остальное... спасибо

Добавлено @ 16:54
Цитата(NuINu @ 3.2.2009,  16:24)
надо создать роли viewer и editor
и соответсвенно присвоить пользователям эти роли.

а гостевую сессию как туда вставить? или не активного пользователя, так наверное

Код

    __PACKAGE__->allow_access_if(
        '/bonus/area',
                   sub { my ($c, $action) = @_;
                 if($c->user->karma > 50){
                       return $ALLOWED
                 }
                 else {
                       return $DENIED
                 }
               }
         );


Добавлено @ 16:56

очень много всего в этом каталисте, потерятся можно... вообщем я написал - работает... сейчас буду прикручивать остальое...

Автор: gcc 6.2.2009, 02:08
подскажите, как вывести имя пользователя?

Код

 $c->stash->{user_username} = $c->user( );    


выводится ссылка на хэш, если написать так 
Код

 $c->stash->{user_username} = values %{$c->user( )} ;   

то число 1/8

Автор: gcc 6.2.2009, 02:57
Цитата(NuINu @ 31.1.2009,  01:26)


        # !!!!!!!!!!!!! ниже указать Название класса приложения!!!!!!!!!!!!
        my @pkg = qw(MyAuth Catalyst::Plugin::Authentication);
        my $obj = Devel::Symdump->rnew(@pkg);

    


что такое MyAuth?

запутался, как в другом модуле посмотреть отладку? 

кстате, если отладку вклчить в каиалисе это тоже самое?

пробовал так не получается
        my @pkg = qw(MyApp MyApp::Controller::Root);
        my @pkg = qw(Root MyApp::Controller::Root);

Автор: NuINu 6.2.2009, 09:45
Цитата(gcc @  6.2.2009,  00:08 Найти цитируемый пост)
подскажите, как вывести имя пользователя?


в шаблоне 
Код

           [% IF c.user_exists %]
               Please Note: You are already logged in as '[% c.user.username %]'.
               You can <a href="[% c.uri_for('/logout') %]">logout</a> here.
           [% ELSE %]
               You need to log in to use this application.
           [% END %]


я же уже говорил операции user и user_exist добавляются к объекту $c при подключении плагина
Authentication


Цитата(gcc @  6.2.2009,  00:57 Найти цитируемый пост)
что такое MyAuth?

Это просто название моего приложения. Глобальный класс.

вот так вот как у вас: my @pkg = qw(MyApp MyApp::Controller::Root);
должно работать. разве что приложение называется не MyApp

ну и поместите эту функцию в тот модуль в котором вы ее вызываете... что то я сомневаюсь что вы ее правльно вызываете... я ее так просто для примера нарисовал.


Цитата(gcc @  6.2.2009,  00:57 Найти цитируемый пост)
кстате, если отладку вклчить в каиалисе это тоже самое?

совершенно другое... но я с отладкой не сильно разбирался... вроде я уже писал как выводить отладочные сообщения?
кхм... странно.. значит показалось- дежа вю

в мануале все написано:
           $c->log->info("Starting the foreach loop here");

           $c->log->debug("Value of \$id is: ".$id);

site_perl/5.8.8/Catalyst/Manual/Tutorial/Debugging.pod

Автор: gcc 6.2.2009, 13:42
Цитата(NuINu @ 6.2.2009,  09:45)
Цитата(gcc @  6.2.2009,  00:08 Найти цитируемый пост)
подскажите, как вывести имя пользователя?


в шаблоне 
Код

           [% IF c.user_exists %]
               Please Note: You are already logged in as '[% c.user.username %]'.
               You can <a href="[% c.uri_for('/logout') %]">logout</a> here.
           [% ELSE %]
               You need to log in to use this application.
           [% END %]


я же уже говорил операции user и user_exist добавляются к объекту $c при подключении плагина
Authentication

сори, забыл сказать шаблон HTML::Template

не работает
Код

<TMPL_VAR NAME="c.user.username">



Автор: NuINu 6.2.2009, 15:00

Цитата(gcc @  6.2.2009,  11:42 Найти цитируемый пост)
сори, забыл сказать шаблон HTML::Template

ну делов то
смотришь доку:  Catalyst::View::HTML::Template
там все передельно ясно написано:
Код

  METHODS
    process
        Renders the template specified in "$c->stash->{template}" or
        "$c->request->match". Template params are set up from the contents
        of "$c->stash", augmented with "base" set to "$c->req->base" and
        "name" to "$c->config->{name}". Output is stored in
        "$c->response->body".

таким образом к объекту $c используя данный шаблонизатор ты никогда не обратишься.
способов это обойти море!
создай переменную в $c->stash->{c} = $c;
можешь это сделать в методе Root::end

или просто создай(т.к я не уверен что в этом шаблонизаторе будут вызываться методы)  
$c->stash->{user_exists} = $c->user_exists;
$c->stash->{username} = $c->user->username;

Автор: gcc 6.2.2009, 15:20
метода $c->user->username нету

это работает: (0 или 1)
Код

$c->stash->{user_exists} = $c->user_exists;



это возвращает ссылку на хеш, не знаю что с ней делать, при разыменовании ключ и значение: число 1/8
Код

    my $ff = $c->user( );
    $c->stash->{user_username} = $ff; 


отлдаку опять не получилось сделать, не знаю что это за хэш...
Код

Catalyst::Authentication::Store::DBI::User=HASH(0x9ae2ec0)


пробую делать отладку...

Автор: NuINu 6.2.2009, 15:30
Цитата(gcc @  6.2.2009,  13:20 Найти цитируемый пост)
метода $c->user->username нету


ну пардон, это может быть хешь
$c->user->{username}

делов то распечатай отладку 
$c->log->debug(Dumper($c));

Автор: gcc 6.2.2009, 15:38
вот отладка
Код

logged in as [info] *** Request 2 (0.333/s) [42050] [Fri Feb 6 14:38:50 2009] *** [debug] "GET" request for "/" from "127.0.0.1" 
[debug] Found sessionid "3d04a4a1476d9f6e404f0dc269abc5afce06a4a2" in cookie [debug] Restored session 
"3d04a4a1476d9f6e404f0dc269abc5afce06a4a2" [debug] $VAR1 = bless( { 'store' => bless( { 'user_table' => 'users', 
'user_role_role_key' => 'role_id', 'user_key' => 'id', 'user_name' => 'username', 'role_table' => 'roles', 'role_name' => 
'role', 'user_role_table' => 'user_roles', 'dbh' => bless( {}, 'DBI::db' ), 'user_role_user_key' => 'user_id', 'class' => 'DBI', 
'role_key' => 'id' }, 'Catalyst::Authentication::Store::DBI' ), 'auth_realm' => 'default', 'user' => { 'email_address' => 't01@na.com', 'password' => 
'e727d1464ae12436e899a726da5b2f11d8381b26', 'active' => '1', 'id' => '1', 'last_name' => 'Blow', 'first_name' => 'Joe', 'username' => 'test01' } }, 
'Catalyst::Authentication::Store::DBI::User' ); .  


должно быть так 
Код

    $c->stash->{user_username} =  $c->user->{username}


но ничего не выводит, пустое значение...  smile 

Автор: NuINu 6.2.2009, 20:13
ну, вывел в отладку то ты что? какую переенную?

хочешь сказать что я это из воздуха взял? 'username' => 'test01' - из вывода твоей же отладки.

ищите и  обрящете!

Автор: gcc 6.2.2009, 22:54
в том и проблема что должно работаеть, но не хочет выводить

Код

    $c->stash->{user_username} =  $c->user->{username};


Код

      logged in as <TMPL_VAR NAME="user_username">. 


что делать дальше, как вывести?
я что-то перепутал?

Автор: NuINu 7.2.2009, 12:09
    $c->stash->{user_username} = $c->user->username;

на будущее, вас ни кто не заставлял выбирать нестандартный путь - HTML::Template, это ваш выбор,
ну раз так, будте готовы приложить немного больше усилий для освоения этого пути, чем другие.

первопроходцам всегда трудно.
нехотите проблем или нет сил по для их преодоления выбирайте майнстрим.

Автор: gcc 7.2.2009, 14:56
Цитата(NuINu @ 7.2.2009,  12:09)
$c->stash->{user_username} = $c->user->username;

скажите пожалуйста, где вы увидели метод username ?

метода нету
Код

Caught exception in MyApp::Controller::Root->index "Can't call method "username" on an undefined value at 
/home/data/www/MyApp/script/../lib/MyApp/Controller/Root.pm line 51."


вопрос тот же, как разыменовать и получить имя пользователя?

Автор: KSURi 7.2.2009, 15:34
gcc, за время пока вы обсуждаете один вопрос, уже можно было открыть исходник модуля и посмотреть все нужные методы.

Автор: gcc 7.2.2009, 15:37
KSURi, я перепробывал все методы которые написаны в документаиции к модулю ( я про это писал)

а в отладке написано совсем другое... то что в документации нету...

хэш видно в отладке с именем пользователя 'test01', не получается его разыменовать... 

Автор: NuINu 7.2.2009, 18:31
Цитата(gcc @  7.2.2009,  12:56 Найти цитируемый пост)
скажите пожалуйста, где вы увидели метод username ?

у меня этот медод есть.
просто я использую другой класс
Catalyst::Authentication::Store::RDBO::User
связанный с ORM Rose

в вашем случае
Catalyst::Authentication::Store::DBI::User
конечно его может и не быть. мой промах.

ну тем не менее, попробовать разименовать уже то что вы получили в отладке то можно?
там же есть переменная к которой можно обратиться, так в чем же дело?

дамп чего вы там вывели? $c->user-? тогда так:
 
$c->stash->{user_username} =  $c->user->{user}->{username};


KSURi, 
посмотреть порблематично, дело в том что методы ацессоры добавляются прямо во время выполнения.
и зависят от (в моем случае) от описания полей класса.


gcc, а вы пробуйте, пробуйте.

Автор: KSURi 7.2.2009, 19:12
gcc, документация может быть неполной. Поэтому я и написал, что можно заглянуть в исходники.
NuINu, я так и думал. Но тема уже неделю в топе, думаю за это время можно было найти место где создаются аксессоры.

Автор: gcc 7.2.2009, 19:22
в исходниках модуля Catalyst::Authentication::Store::DBI и Catalyst::Authentication::Store::DBI::User, и по остальным, есть только два метода  sub from_session sub find_user в котором идет работа с БД и все один запрос в каждом метода, дальше я не вижу где тот метода откуда берется имя пользователя, остается один вариант - только разыменовать из отладки (или нет?)  smile 

но я не знаю где это смотреть...

Добавлено @ 19:22
Цитата(NuINu @ 7.2.2009,  18:31)
Цитата(gcc @  7.2.2009,  12:56 Найти цитируемый пост)
скажите пожалуйста, где вы увидели метод username ?


дамп чего вы там вывели? $c->user-? тогда так:
 
$c->stash->{user_username} =  $c->user->{user}->{username};


Код


Caught exception in MyApp::Controller::Root->index "Can't use an undefined value as a HASH reference at
 /home/x0/data/www/MyApp/script/../lib/MyApp/Controller/Root.pm line 51."


извените. забыл сказать, дампером $c->user

Автор: gcc 7.2.2009, 19:42
работает
Код

$c->user->{user}->{username}

Автор: gcc 20.2.2009, 17:12
Код

    __PACKAGE__->deny_access_unless(
            "/add1",
            [qw/admin/],
        );

    __PACKAGE__->deny_access_unless(
            "/add2",
            [qw/admin/],

        );


почему данный код админа не пускает?

он пишет что длступ запрещен, то есть всем запрещает доступ, странно...

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

Автор: gcc 23.2.2009, 10:15
кучу времени потратил, нифига не нашел...

в общем он в тупую не пускает того пользователя которого должен...

или я что-то не понял?

в общем логично написать чтобы запретить всем крмое админа...

кто как делал?

Автор: NuINu 23.2.2009, 11:37
admin это кто? пользователь? а какие у него роли определены? в правилах указываются РОЛИ

Автор: gcc 23.2.2009, 12:18
1) admin это пользователь роли  id 1
Код


INSERT INTO roles VALUES (3, '/add1');

    INSERT INTO user_roles VALUES (1, 3);


Код

[debug] Path is "add1"
[debug] running ACL rule CODE(0x8d52830) defined at .../MyApp.pm line 115 on add1
[error] Class::Throwable : An error occurred while evaluating ACL rules.



2) как мне запретить чтобы пользователи не заходили туда где у них нет "ролей"? потому что роли не реагируют....

Автор: NuINu 23.2.2009, 20:23
Цитата(gcc @  23.2.2009,  10:18 Найти цитируемый пост)
 как мне запретить чтобы пользователи не заходили туда где у них нет "ролей"? потому что роли не реагируют....


просто, прочти документацию. поверь - роли реагируют.


Цитата(gcc @  23.2.2009,  10:18 Найти цитируемый пост)
1) admin это пользователь роли  id 1

а имя у этого id  есть?
вот у роли с id 3 имя есть, и оно '/add1' - это вижу.
а у id 1?

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

Автор: gcc 24.2.2009, 07:33
Код

    --
    -- Add users and roles tables, along with a many-to-many join table
    --
    CREATE TABLE users (
            id            INTEGER PRIMARY KEY,
            username      TEXT,
            password      TEXT,
            email_address TEXT,
            first_name    TEXT,
            last_name     TEXT,
            active        INTEGER
    );
    CREATE TABLE roles (
            id   INTEGER PRIMARY KEY,
            role TEXT
    );
    CREATE TABLE user_roles (
            user_id INTEGER,
            role_id INTEGER,
            PRIMARY KEY (user_id, role_id)
    );
    --
    -- Load up some initial test data
    --
    INSERT INTO users VALUES (1, 'test01', 'mypass', 't01@na.com', 'Joe',  'Blow', 1);
    INSERT INTO users VALUES (2, 'test02', 'mypass', 't02@na.com', 'Jane', 'Doe',  1);
    INSERT INTO users VALUES (3, 'test03', 'mypass', 't03@na.com', 'No',   'Go',   0);
    INSERT INTO roles VALUES (1, 'user');
    INSERT INTO roles VALUES (2, 'admin');
    INSERT INTO user_roles VALUES (1, 1);
    INSERT INTO user_roles VALUES (1, 2);
    INSERT INTO user_roles VALUES (2, 1);
    INSERT INTO user_roles VALUES (3, 1);


id: 1
username: admin
Код

INSERT INTO roles VALUES (3, '/add1');

Код

INSERT INTO user_roles VALUES (1, 3);


какую именно документацию? документации под DBI мало
http://search.cpan.org/~janus/Catalyst-Authentication-Store-DBI-0.01/lib/Catalyst/Authentication/Store/DBI.pm
http://search.cpan.org/~bricas/Catalyst-Plugin-Authorization-Roles-0.07/lib/Catalyst/Plugin/Authorization/Roles.pm

тут
http://search.cpan.org/~hkclark/Catalyst-Manual-5.7016/lib/Catalyst/Manual/Tutorial/Authentication.pod#___top
если точно, то в документации есть про DBIC, это не надо

тут описано для другой таблицы!
http://search.cpan.org/~janus/Catalyst-Authentication-Store-DBI-0.01/lib/Catalyst/Authentication/Store/DBI.pm

я поставил
Код

 __PACKAGE__->config->{'authentication'} = {
    'default_realm' => 'default',
    'realms' => {
      'default' => {
        'credential' => {
          'class'               => 'Password',
          'password_field'      => 'password',
          'password_type'       => 'hashed',
          'password_hash_type'  => 'SHA-1',
        },
        'store' => {
          'class'              => 'DBI',
          'user_table'         => 'users',
          'user_key'           => 'id',
          'user_name'          => 'username',
          'role_table'         => 'roles',
          'role_key'           => 'id',
          'role_name'          => 'role',
          'user_role_table'    => 'user_roles',
          'user_role_user_key' => 'user_id',
          'user_role_role_key' => 'role_id',
        },
      },
    },
  };


все правильно?

я хотел спросить: перед тем как разрешать доступ, нужно доступ запретить всем зарегиритрированным? 
(именно это не написано в документации)

я поставил эти роли, но оно не запрещает просто, не реагирует, забивает на эти роли.
(я выделил жирным чтобы было видно главный вопрос)

если вы делали, то скажите как сделать чтобы они реагировали?
я не вижу где написано в документации чтобы запретить тем у кого нету ролей, повторяю: я добавил роли - не реагирует...

Автор: gcc 24.2.2009, 09:30
http://search.cpan.org/~mramberg/Catalyst-Plugin-Authentication-CDBI-0.10/CDBI.pm

этот модуль мне не нужен?


Автор: gcc 24.2.2009, 11:59
уровни доступа без mysql работают!! 

но как настроить Catalyst::Authentication::Store::DBI ? чтобы эти роли ставить в таблицы СУБД?

NuINu, а можно как-то проверить работает ли этот модуль Catalyst::Authentication::Store::DBI ?

Автор: NuINu 24.2.2009, 13:13
Цитата(gcc @  24.2.2009,  05:33 Найти цитируемый пост)
перед тем как разрешать доступ, нужно доступ запретить всем зарегиритрированным? 
(именно это не написано в документации)


не нужно.


Цитата(gcc @  24.2.2009,  09:59 Найти цитируемый пост)
уровни доступа без mysql работают!! 

ну я тебя поздравляю.

Цитата(gcc @  24.2.2009,  09:59 Найти цитируемый пост)

NuINu, а можно как-то проверить работает ли этот модуль Catalyst::Authentication::Store::DBI ?

можно. просто вставь в него отладочный вывод... или просто активизируй его внутреннюю отладку(она наверняка есть).


Цитата(gcc @  24.2.2009,  09:59 Найти цитируемый пост)
но как настроить Catalyst::Authentication::Store::DBI ?

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

Автор: gcc 18.3.2009, 07:37
ныжно посмотреть id пользователя в котрого активная сессия, и тот который работает

например:
Код


                     if ($loop_data2->{id_un} == $c->user->{user}->{id} 
                             ||  $c->check_user_roles('moder') ) {
                                    $c->stash->{edit} = 1;                    
               bla bla
                            } 

        
но если пользователь 'гость' то выдается ошибка 
Код

[error] Caught exception in MyApp::Controller::view_content_head->view_head "
Can't use an undefined value as a HASH reference at 


приходиться писать так:

Код

             if  ($c->user_exists()) {
                     if ($loop_data2->{id_un} == $c->user->{user}->{id} 
                             ||  $c->check_user_roles('moder') ) {
                                    $c->stash->{edit = 1;                    
        
                            } 
                    
                }


не карсиво и не удоюно, в исходниках я не нашле ничего, не полдучилось

пробовал сделать так: (не работает)
Код

sub id
{
        my $self = shift;

        my $user_key = $self->{'store'}{'user_key'};
 
    if ($self->{'user'}{$user_key}) {
   return $self->{'user'}{$user_key};
     } else {
   return '0';
     }
}



нашел сам метод
Код

sub user_exists {
        my $c = shift;
        return defined($c->_user) || defined($c->find_realm_for_persisted_user);
}


в DBIx::Class или в Rose:smileB была таккая ошибка когда вы смотрите id?

Автор: NuINu 18.3.2009, 10:40
Цитата(gcc @  18.3.2009,  05:37 Найти цитируемый пост)
в DBIx::Class или в Rose:: DB была таккая ошибка когда вы смотрите id?


данная ошибка:

Цитата(gcc @  18.3.2009,  05:37 Найти цитируемый пост)
[error] Caught exception in MyApp::Controller::view_content_head->view_head "
Can't use an undefined value as a HASH reference at 

это не проблема Rose или DBIx, она вообще к ним никакого отношения не имеет.

у меня, ВСЕГДА проверяется if  ($c->user_exists())
и делается это не везде, а в одном месте
контроллер Root метод auto

тебе надо лучше изучать примеры которые идут с каталистом, ты проскакал галопом по европам, а теперь на ерунде спотыкаешься.
Код

sub auto : Private {
    my ($self, $c) = @_;

        # Allow unauthenticated users to reach the login page.  This
        # allows anauthenticated users to reach any action in the Login
        # controller.  To lock it down to a single action, we could use:
        #   if ($c->action eq $c->controller('Login')->action_for('index'))
        # to only allow unauthenticated access to the 'index' action we
        # added above.
        #позволим неавторизированным пользователям переходить на страницу Логин
    if ($c->controller eq $c->controller('Login')) {
            return 1;
    }

            # If a user doesn't exist, force login
    if (!$c->user_exists) {
            # Dump a log message to the development server debug output
        $c->log->debug('***Root::auto User not found, forwarding to /login');
            # Redirect the user to the login page
        $c->response->redirect($c->uri_for('/login'));
            # Return 0 to cancel 'post-auto' processing and prevent use of application
        return 0;
    }

        # User found, so return 1 to continue with processing after this 'auto'
    return 1;
}



например в данном коде, можно не авторизированного пользователя который не выполнил логин, определить, присвоить ему значение user - гость, а уже у данного пользователя в базе прав должна быть РОЛЬ - гость. и уже весь остальной код должен работать только с ролями(ну вернее может работать)
это будет автоматическая аутентификация(псевдо аутентификация, ведь о пользователе мы при этом ничего не узнали) но эта модель позволит нам работать с ним как с обычным аутентифицированным пользователем.

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

уж сам выбирай как делать.

Автор: gcc 18.3.2009, 11:25
Цитата(NuINu @ 18.3.2009,  10:40)
например в данном коде, можно не авторизированного пользователя который не выполнил логин, определить, присвоить ему значение user - гость, а уже у данного пользователя в базе прав должна быть РОЛЬ - гость. 


не вижу, где там это написано,
http://search.cpan.org/~hkclark/Catalyst-Manual-5.7020/lib/Catalyst/Manual/Tutorial/Authentication.pod
http://search.cpan.org/~hkclark/Catalyst-Manual-5.7020/lib/Catalyst/Manual/Tutorial/Authorization.pod

покажи пожалуйста, как это сделать, присвоить "гостью" имя?

или надо как-то принудительно написать?

ну вот часть кода, то есть лишниый раз над писать if  ($c->user_exists()) {

    
Код

             if  ($c->user_exists()) {
                     if ($loop_data2->{id_un} == $c->user->{user}->{id} 
                             ||  $c->check_user_roles('moder_se') ) {
                                    $c->stash->{edit_se} = 1;                    
        
                            } 
                    
                }
                    
                #    if ($c->user_exists() == 1 && $loop_data2->{id_un} != $c->user->{user}->{id} &&
                #        !$c->check_user_roles('moder_se') ) {
                #    
                #                          $sql = 'AND hiden_co = 0
            #                  AND active_co = 1';
                #    
                #    
                #    }
             if  ($c->user_exists()) {
                        if ($loop_data2->{active_se} == 1 
                            && $loop_data2->{id_un} != $c->user->{user}->{id}
                            && !$c->check_user_roles('moder_se') ) {
                        
                        $c->stash->{no_show} = 1;                        
                    }
                                        
             }    



Автор: NuINu 18.3.2009, 11:37
вот именно про это там действительно не написано, это просто мое предложение

заводишь пользователя nobody
заводишь роль guest

присваиваешь роль пользователю nobody->guest

пишешь приблизительно такой код в контролере Root:
Код

sub auto : Private {
    my ($self, $c) = @_;

        # Allow unauthenticated users to reach the login page.  This
        # allows anauthenticated users to reach any action in the Login
        # controller.  To lock it down to a single action, we could use:
        #   if ($c->action eq $c->controller('Login')->action_for('index'))
        # to only allow unauthenticated access to the 'index' action we
        # added above.
        #позволим неавторизированным пользователям переходить на страницу Логин
    if ($c->controller eq $c->controller('Login')) {
            return 1;
    }
            # If a user doesn't exist, force login
    if (!$c->user_exists) {
         if ($c->authenticate({ username => 'nobody',   password => '111111111111'  } )) {
            return 1;
        } else {
                # Set an error message
            $c->stash->{error_msg} = "Bad database guest role, access denied";
            return 0;
        }
    }

        # User found, so return 1 to continue with processing after this 'auto'
    return 1;
}



Автор: gcc 20.3.2009, 09:46
NuINu, можете подсказать зачем сделан Privat? зачем его используют кроме как в root.pm?

это тоже самое что приватный метод?? 
Код


sub _func {
}

$self->_func;


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

Local - это например helo : Local  будет братся из URL /helo/

вот например, я не понимаю зачем там 2 метода captcha_uri : Private и check_captcha : Private с Privat, и как они вызываються и где? (если приватный - значить замкнутный? но я не вижу чтобы он в том контроллере вызывался)

http://github.com/jrockway/angerwhale/blob/95da08ea31d2005de3b21f93049e89ffcc0ffaf7/lib/Angerwhale/Controller/Captcha.pm


Код

# Captcha.pm
# Copyright (c) 2007 Jonathan Rockway <jrockway@cpan.org>
 
package Angerwhale::Controller::Captcha;
use strict;
use warnings;
use base 'Catalyst::Controller';
use GD::SecurityImage;
use HTTP::Date;
 
=head1 NAME
 
Angerwhale::Controller::Captcha - generate and validate captchas
 
=head1 METHODS
 
=head2 gen_captcha
 
Generate a security image and store it in the session
 
=cut
 
sub gen_captcha : Private {
    my ($self, $c) = @_;
    my($image, $type, $rnd) = GD::SecurityImage->new(height => 20,
                                                     width => 80,
                                                     scramble => 0,
                                                     lines => 2,
                                                     gd_font => 'Large',)
      ->random->create->out;
    
    $c->session->{captcha} = { image => $image,
                               type => $type,
                               rnd => $rnd,
                             };
}
 
=head2 captcha
 
Return the captcha to the browser
 
=cut
 
 
sub captcha : Path {
    my ($self, $c) = @_;
 
    $c->forward('gen_captcha') unless ref $c->session->{captcha};
    
    $c->response->body($c->session->{captcha}->{image});
    $c->response->content_type('image/'. $c->session->{captcha}->{type});
    $c->res->headers->expires( time() );
    $c->res->headers->header( 'Last-Modified' => HTTP::Date::time2str );
    $c->res->headers->header( 'Pragma' => 'no-cache' );
    $c->res->headers->header( 'Cache-Control' => 'no-cache' );
    $c->detach();
}
  
=head2 captcha_uri
 
Return the URI for the captcha, or nothing if the user has
already used the captcha successfully, or he's logged in.
 
=cut
 
sub captcha_uri : Private {
    my ($self, $c) = @_;
    return if $c->stash->{user}; # XXX user
    return if $c->session->{got_captcha};
    return $c->uri_for('/captcha/captcha');
}
  
=head2 check_captcha($guess)
 
Returns true if the guess is the text in the captcha.
 
=cut
 
sub check_captcha : Private {
    my ($self, $c, $guess) = @_;
 
    return unless ref $c->session->{captcha};
    
    if($c->session->{got_captcha} || $c->session->{captcha}->{rnd} eq $guess){
        $c->session->{got_captcha} = 1; # only need to guess one per session
        return 1;
    }
    return;
}
  
1;



Автор: NuINu 20.3.2009, 11:30
Цитата(gcc @  20.3.2009,  07:46 Найти цитируемый пост)
NuINu, можете подсказать зачем сделан Privat? зачем его используют кроме как в root.pm?

это тоже самое что приватный метод?? 

не могу здесь блеснуть какими то глубокими знаниями, тем более что сейчас занимаюсь OpenGL

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

Первым делом адресую тебя к Catalyst::Manual::Intro

там описывается все что связанно с диспетчеризацией сообщений.
в том числе и типы действий.

итак акция(действие) как оно поределено: An action is a subroutine with a special attribute.

т.е метод с неким атрибутом. что уже делает его отличным от обычных методов класса.
как скрытых так и нет.

Именно этот "некий атрибут" делает из метода - Action(действие) которое в последствии окружение каталиста становиться способным воспринимать в контектсте данного контроллера. Т.е класс имеющего помимо обычных методов, еще и методы-действия.

данные методы-действия добавляются в список методов которые будут потом проверяться при диспетчиризации запроса пользователя и диспетчиризации событий вызванных не пользователем а другими методами-действиями.

так вот методы-действия класса Private отличаются только тем(от других методов действий) что не могут быть непосредственно вызваны пользователями(в качестве урла их нельзя указать).
зато их можно использовать при вызове фукнций деспетчеризации каталиста, таких как форвард.

собственно пример как это делать там есть: 
Код

           sub hello : Global {
               my ( $self, $c ) = @_;
               $c->stash->{message} = 'Hello World!';
               $c->forward('show_message');
           }

           sub show_message : Private {
               my ( $self, $c ) = @_;
               $c->res->body( $c->stash->{message} );
           }



обычные же методы класса не доступны для диспетчиризации событий через систему каталиста. тем более недоступны методы с двума подчеркиваниями.

Автор: gcc 20.3.2009, 12:02
спасибо понял, в том примере в котором я показывал те 2 метода вызвались в другом контроллере просто...

мне показалсоь что это что-то другое


Автор: gcc 20.3.2009, 12:02
спасибо понял, в том примере в котором я показывал те 2 метода вызвались в другом контроллере просто...

мне показалсоь что это что-то другое


Автор: shootnix 15.6.2009, 10:36
У меня проблема та же, что и в сабже. Не подскажете, как вы ее решили? 

пишу так:

Код

use Catalyst qw/-Debug ConfigLoader Static::Simple
                Session
                Session::Store::DBI
                Session::State::Cookie
                
                Authentication/;


При вызове метода из плугина выдает вот это:
Код

Caught exception in MyApp::Controller::Root->login "Can't call method "dbh" on an undefined value at /usr/local/share/perl/5.10.0/Catalyst/Authentication/Store/DBI.pm line 115."


Вижу, что грабли с коннектом к базе, но сама модель у меня DBI и настроена. Куда копать?

UPD
Вопрос снимается, нашел косяк, покопавшись в исхониках — имя модели задано жестко DBI, у меня другое было smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)