Need help with routing in Mojolicious - perl

I have the "Pages" controller with the "show" method and "Auths" controller with the "check" method which returns 1 if user is authenticated.
I have "default" page ("/profile").
I need to redirect to / if the user is authenticated and redirect all pages to / with the authorization form if the user is not authenticated. My code does not want to work properly (auth based on the FastNotes example application): (
auths#create_form - html-template with the authorization form.
$r->route('/') ->to('auths#create_form') ->name('auths_create_form');
$r->route('/login') ->to('auths#create') ->name('auths_create');
$r->route('/logout') ->to('auths#delete') ->name('auths_delete');
$r->route('/signup') ->via('get') ->to('users#create_form') ->name('users_create_form');
$r->route('/signup') ->via('post') ->to('users#create') ->name('users_create');
#$r->route('/profile') ->via('get') ->to('pages#show', id => 'profile') ->name('pages_profile');
my $rn = $r->bridge('/')->to('auths#check');
$rn->route ->to('pages#show', id => 'profile') ->name('pages_profile');
$rn->route('/core/:controller/:action/:id')
->to(controller => 'pages',
action => 'show',
id => 'profile')
->name('pages_profile');
# Route to the default page controller
$r->route('/(*id)')->to('pages#show')->name('pages_show');

It seems you want / to render either a login form OR a profile page. The code above will always show / as login because it hits that route condition first and will never care if you're authenticated or not.
Try a switch in your initial route for / (your default route after the bridge is unnecessary).
my $r = $self->routes;
$r->get('/' => sub {
my $self = shift;
# Check whatever you set during authentication
my $template = $self->session('user') ? '/profile' : '/login';
$self->render( template => $template );
});
A couple of notes on your example:
Its much easier to help debug issues if you use Mojolicious::Lite for examples.
Try using under instead of bridge.
Try using $r->get(..) instead of $r->route(..)->via(..)
Hope this helps.

Related

YII : How to redirect in afterAction under component controller class "CController"

I need your help to resolve my issue. I'm stuck here from approx 3-4 hours.
I made custom roles and permissions to every user. I have executed the code under component controller class's function afterAction. But if user don't have the access of the clicked action then it should be redirect to error page. When i use redirect function it says Cannot modify header information - headers already sent. I will be highly thankful if anyone can help me out. Here is my code
if (isset(yii::app()->user->id)) {
$controller = yii::app()->controller->id;
$action = yii::app()->controller->action->id;
$noAuthControllerAction = array();
$noAuthControllerAction[] = 'site/index';
$controllerAction = $controller . '/' . $action;
if (!in_array($controllerAction, $noAuthControllerAction)) {
$isAllowed = $this->isAllowed($controller, $action);
if (!$isAllowed) {
$this->redirect(array('site/denied'));
}
}
}
parent::afterAction($action);
Always use accessRules() in your controller for roles and permissions for more information see Yii Documentation for authentication and authorization
In your controller
A basic role-based access control looks like this :
array('allow', // allow authenticated owner users to perform the following actions.
'actions' => array('sales', 'export', 'invoice', 'payment'),
'users' => array('#'),
'roles' => array('owner'),
),
A custom expression role-based access control looks like this : (This is what you need)
array('deny', // deny authenticated owner users to perform the following actions if store is not yet selected.
'actions' => array('sales', 'export', 'invoice', 'payment'),
'users' => array('#'),
'roles' => array('owner'),
'deniedCallback' => function() {
Yii::app()->controller->redirect(array('/store/location'));
},
'expression' => '!Yii::app()->user->isStoreSelected()',
),
'expression' is your rule, and if rule is not met then 'deniedCallback' will redirect you to desired 'controller/action' in this case '/store/location'.
Also don't use
$this->redirect(array('site/denied')) for error handling, instead use
throw new CHttpException(401,'Access denied.');
This is the right way to handle errors in Yii. If you want to customize your error page please refer to Error Handling
afterAction runs after action is rendered. This is the cause of your error.
Use beforeAction event for that. Do you know RBAC? RBAC can help you.
http://www.yiiframework.com/doc/guide/1.1/en/topics.auth#role-based-access-control
You could use accessControl for limit action uses to roles.

Wordpress, redirect a user directly to a custom post edit screen after login

currently I got this:
function redirect_companies()
{
if ( current_user_can( 'ca_company' ) )
{
$screen = get_current_screen();
if ( $screen->post_type != 'unternehmen' && $screen->id != 'profile' )
{
global $current_user;
$current_users_posts = get_posts(
array(
'post_type' => 'unternehmen',
'author' => $current_user->ID
)
);
if ( count( $current_users_posts ) > 1 )
{
$redirect = admin_url( 'edit.php?post_type=unternehmen' );
}
else
{
$redirect = get_edit_post_link( $current_users_posts[0]->ID );
}
wp_redirect( $redirect, 301 );
}
}
}
add_action('current_screen', 'redirect_companies');
What it should do: A user with role 'ca_company' logs into wordpress backend and instantly gets redirected to either the overview screen of the custom post type posts of "unternehmen" or, if only one post by this user exists, to the edit screen of that one post.
Also, it should perform this redirect routine, if the user is trying to access any page that is not from post type "unternehmen" and is not the user-profile-edit screen.
I successfully tested this when I already was logged in as auch user and then trying to access for example the dashboard. This works.
But if I completely log out of WP and then log in again, wordpress is performing this:
http://i.stack.imgur.com/M60aJ.png
... and then my browser is telling me, that there is a redirecting error. Infinite redirecting loop. But why? Why does it even go into that "if" where I check for post type "unternehmen". Because if I log in, I am first getting to dashboard...
Hope someone can help :)
Use this action 'add_action('wp_login', 'do_anything');'. And in callback function you can give link to wp_redirect('link') where you want to redirect your screen.

How can I make Perl Dancer display my index page properly when the back button is used?

When I fill out a form, press submit, and get the results page everything works perfectly. When I want to go back an fill out a new form the page is broken. It seems to be an amalgam of the index page and the results page. The only way I can get it to work is to re-start the Dancer web engine. Here is a copy of the pm that handles the routes:
package NNSP;
use Dancer2;
use Template;
our $VERSION = '0.1';
get '/' => sub {
template 'index';
};
post '/' => sub {
set layout => 'result_format';
template 'result';
};
true;
I think it's better do
template 'result', $hashref, {layout => 'result_format'};
instead of set layout => 'result_format';
or you should do
set layout => 'default_layout';
in hook 'before' or 'before_template' as set sets global parameters.

Create charts for a facebook page via open graph and php

I have created a FB App that grants the following permissions from the user:
1. manage_pages
2. read_insights
By using the app, the user can create a new tab on a page and delete it when this is necessary.
Apart from that, I want to give the option to the user to see some basic stats regarding the page(s) that she creates the tab(s).
For example, I want to retrieve the page views for a certain page for a specific period.
In order to do this I used the following code:
$today = date("Y-m-d");
$until = strtotime($today);
$since = strtotime("2013-08-01");
$pageID = "123";
$page_info = $facebook->api("/$pageID?fields=access_token");
$access_token = $page_info['access_token'];
$params = array(
'access_token' => $access_token,
'since' => $since,
'until' => $until,
);
$insights = $facebook->api("/{$pageID}/insights/page_views/",
"GET",
$params
);
print_r($insights);
The problem is that the result is...somehow empty. More precisely, I receive the following:
Array
(
[data] => Array
(
)
[paging] => Array
(
[previous]=>https://graph.facebook.com/123/insights/page_views/since=1370059200&until=1375329600
[next]=>https://graph.facebook.com/123/insights/page_views/since=1380600000&until=1385870400
)
)
When I use, the same logic to receive insights for my app (without using $token in the $params array), I receive the right data.
In addition to that, I was wondering if there is a way to create charts with this data (directly from FB).
Thx,
Antonis
I managed to solve the problem.
The returning array was empty, because I forgot to check if the user is logged in through facebook...
Regarding the charts, I didn't find any solution directly from facebook, so I used the Charts.js plugin.

Redirect back to page tab after user authenticates?

How should I go about redirecting the user back to my page's tab after they authenticate my app? I cannot put one specific url in for the redirect since my app will live on multiple pages. So somehow I need to grab the page's id and put it into the url. I've tried to use session variables but it doesn't seem to be working for me. :( Here's a portion of my code...
$signed_request = $facebook->getSignedRequest();
$_SESSION['TrueID'] = $signed_request['page']['id'];
$fbconfig['appBaseUrl'] = "http://www.facebook.com/pages/".$_SESSION['TrueID']."/".$_SESSION['TrueID']."?sk=app_241321439259320";
/*
* If user first time authenticated the application facebook
* redirects user to baseUrl, so I checked if any code passed
* then redirect him to the application url
* -mahmud
*/
if (isset($_GET['code'])){
header("Location: " . $fbconfig['appBaseUrl']);
exit;
}
//~~
//
if (isset($_GET['request_ids'])){
//user comes from invitation
//track them if you need
}
As you can see I'm trying to set a session variable to grab the page's id.. but that's not working for me :( The variable echo's out just fine when I visit my page.. but I'm guessing its getting lost somewhere during the authentication.
So when a Page add/install your app, you should store the page's link along with the page's id.
Now when your page tab is loaded, Facebook will send the page parameter which will contain the page id (along with other info, refer to the documentation). You retrieve that id, get the page's link from your db and construct your page tab link, which would be something like (where $page is the page's db record):
$redirect_uri = $page['page_link'] . '?sk=app_' . $APP_ID
Since you are using the PHP-SDK, this is how you construct your login:
$user = $facebook->getUser();
if(!$user) {
$url = $facebook->getLoginUrl(array('redirect_uri' => $redirect_uri, 'scope' => 'read_stream'));
echo "<script>top.location.href = '$url';</script>";
exit;
}
Of course you may not want to redirect to the login directly but instead have a call to action link:
Connect
Best way I found is to set the Site URL in the app settings to http://www.facebook.com/pages/
Then do something like this(tested):
$uid = '';
$facebook = new Facebook(array(
'appId' =>'xxxxxxxxxxxxxxx',
'secret' =>'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'cookie' => true,
'oauth' => true,
));
$uid = $facebook->getUser();
$signedrequest = $facebook->getSignedRequest();
$page_id = $signedrequest["page"]["id"];
$fb_access_token = $signedrequest["oauth_token"];
if($uid==''){
echo '<div id="authenticate">Authorize App</div>';
This might be a little bit of a hack, but it works well for my situation:) Hope it helps someone!