[Catalyst] how to get controller path

Jason Kohles email at jasonkohles.com
Wed Nov 21 15:34:15 GMT 2007


On Nov 21, 2007, at 1:01 AM, Alok Sharma wrote:

> On Tuesday 20 November 2007 18:22:54 Matt S Trout wrote:
>> On Tue, Nov 20, 2007 at 12:27:32PM +0530, Alok Sharma wrote:
>>> Given a path we have ways to get the uri using the method  
>>> uri_for(path).
>>> Is there a  possible way to get the controller path given the uri  
>>> so I am
>>> able to do some thing like this
>>> 	$c->res->redirect(uri); $c->forward(controller_path(uri));
>>
>> Why can't you start off with a controller action?
>>
>> my $action = $c->controller('Foo')->action_for('bar'); #
>> Controller::Foo->bar
>>
>> $c->res->redirect($c->uri_for($action));
>> $c->forward($action->reverse);
>
> I was trying to write a module where the user asks for a particular  
> URI but
> for certain reasons ( say session expired or not yet logged etc. )  
> has to be
> authenticated again and then user will be automatically redirected  
> to the
> requested page,in a way furnishing something before actual request is
> processed.
> For this I saved the URI requested ( say as $path ) as a session  
> variable,
> redirected to the authentication page ( say to the standard login  
> page ). But
> the issue was to redirect to the page requested by the user for  
> which I got
> back the URI path from the session variable, till here all fine. But  
> without
> knowing the action for that URI name I cant forward to it. That is  
> where I
> needed something like 		$c->forward(controller_path(uri));
>
> Or is there another approach to this problem.
>
Instead of trying to forward to the action that the URI would have  
given them, once they have logged in just redirect them back to the  
stored URL, and let the dispatcher handle it as normal.  This also  
avoids problems where you forward to the action they were requesting,  
and they then bookmark that page, which actually bookmarks the login  
page because the URL didn't change with the ->forward().

I usually handle it like this:

package MyApp::Controller::Root;
...
sub access_denied : Private {
	my ( $self, $c ) = @_;

	if ( $c->user_exists ) {
		$c->abort( 'Access Denied' );
	} else {
		$c->flash->{ 'login_dest' } = $c->request->path;
		$c->response->redirect( '/login' );
	}
	return 0;
}

sub login : Local {
	my ( $self, $c ) = @_;

	my $form = $c->model( 'FormFu' )->load_form( 'login.yml' );

	if ( $form->submitted_and_valid ) {
		my $params = $c->request->params;
		my $email = $params->{ 'email' };
		my $pass = $params->{ 'password' };
		if ( $c->login( $email, $pass ) ) {
			$c->response->redirect( $c->flash->{ 'login_dest' } || '/' );
		}
		$c->detach;
	} else {
		$form->form_error_message( 'Incorrect email or password' );
	}
}


package MyApp;
...
sub assert_roles {
	my ( $self, @roles ) = @_;

	if ( ! $self->check_any_user_role( @roles ) ) {
		$self->detach( '/access_denied' );
	}
	return 1;
}

package MyApp::Controller::Admin;
...
sub auto : Private {
	my ( $self, $c ) = @_;

	$c->assert_roles(qw( Administrator SuperAdmin ));
	return 1;
}

-- 
Jason Kohles, RHCA RHCDS RHCE
email at jasonkohles.com - http://www.jasonkohles.com/
"A witty saying proves nothing."  -- Voltaire





More information about the Catalyst mailing list