CakePHP 2 - Issue allowing Controller's action - cakephp

this is my situation:
I have a lang function in mi PluginAppController, where it change the locale language and it is redirected to the referer page.
I have a flag's images menu where users can do clic over them to change language too.
Then, because I have an authentication system, I want to allow users run only this action ('lang').
The problem is that my system takes the URL, but it is the referer URL, because at the end of the lang action I redirect to the referer, so I can't allow or deny this action.
My lang action code:
public function lang($lang = 'spa'){
$this->Session->write('Config.language', $lang);
$this->redirect($this->referer());
}

Do you want to allow the access to an action named "lang"?
Then put this in your beforeFilter (AppController, not your plugin's AppController)
$this->Auth->allow('lang')
Of course, this is assuming you don't have another action in your app with that name, in which case you need to check the request and determine if it is coming from your plugin
if ($this->request->params['plugin'] == 'yourPlugin' && $this->request->params['controller'] == 'controllerOfYourPlugin') {
$this->Auth->allow('lang');
}

Related

Symfony - catch automatic redirection to login_path

I need to catch/stop/do own stuff before redirection to the security.yml´s login_path when user is not signed in. Security example:
access_control:
- { path: ^/xy, role: ROLE_USER }
I tried to use kernel.request and kernel.controller services but these both actions are triggered after the redirection. I just need to do some own stuff, but every time I go to /xy (not signed), I am instantly redirected to login_path. And I am unable to stop it. We are using FOSUserBundle.
Thanks for help!
Define an event listener on kernel.request, then check if you are inside the appropriate page (the login page, in your case), then do whatever you want with the response (redirect, create a new response, you name it)

Which is the best way to restrict access to certain pages in my website to certain users other than admin using cakephp

I have a website where all the pages are accessible to the public except for one Releases page which is user specific or maybe to a specific group .I have a seperate login page to gain access to 'Releases' page based on authentication.How do I go about this?Using Acl or Authorize function?I am very confused..Also do i need to use the same users table for authenticating this page, in that case do I use this User login page as an elemnt in my other login page.Could somebody please hint me on how to proceed?
ACL is overkill for many situations.
What I normally do is something like this in my controller:
public function releases() {
$this->_allowedGroups(array(1,2,3));
// rest of code here
}
Then in my app controller:
public function _allowedGroups($groups=array()) {
if( !in_array($this->Auth->user('group_id'), $groups) ) {
$this->redirect(array('controller'=>'users', 'action'=>'login'));
}
}
Acl should do your work.
And is there any specific need that you are using a separate login page??
A single login page and and a single users table should suffice your needs if you implement acl. Only those users who have rights to view the Requests page will be allowed to do so.
you may do something like this..
on core.php, put
Configure::write('Routing.prefixes', array('release'));
and do the verification on the AppController:
class AppController extends Controller{
public function beforeFilter(){
if (isset($this->params['prefix']) and $this->params['prefix'] == 'release'){
if ($this->Session->read("User.type") != 'admin'){
//redirect the user or throw an error...
}
}
}
}
so, youdomain.com/release/* will only be accesible by your administrators...
also, i don't see why you need two logins pages... you could just put a flag on your users table saying if the user is or not an admin... and on the login, set the User.type property on session.
if you don't need of complex permissions control, i think you don't need use ACL.

Cakephp 2.x Authentication Prefix admin and agent

Iam writing an application with cakephp where i will have admin and agents where they can login to the system. Admin will have different layout from the agents. I have already create the the users table where i added a role field (admin,agent) ,i added the prefixes in core.php
Configure::write('Routing.prefixes', array('admin','agent'));
I managed to create the login and the logout for admin, but still iam confused how i should proceed with the rest. For Example i dont understand how beforeFilter() and isAuthorized() functions works. How i can check if user has access to that function or not. Also the redirections if a someone try to access this page domain.com/admin to be redirected to admin/login page .
Thanks.
Use the beforeFilter() to control access to each action, the below example will only allow access to the view and index action - any other action will be blocked :
$this->Auth->allow('view', 'index');
if you want to allow access to all the actions in your controller , try this in your before filter:
$this->Auth->allow();
To control who has access to what you could use a simple function in your app controller like so:
protected function _isAuthorized($role_required) {
if ($this->Auth->user('role') != $role_required) {
$this->Session->setFlash("your message here...");
$this->redirect("wherever you want the user to go to...");
}
}
In your controller action, eg. admin_delete on the first line you would do the following:
$this->_isAuthorized('admin');
Finally the redirect works like so:
$this->redirect(array('controller' => 'home', 'action' => 'dashboard'));
if you are redirecting within the same controller simply do the following:
$this->redirect('dashboard');
Hope this helps.
What i usually do is extend my App controller into an AdminAppController and SiteController , in the AdminAppController I have the following code in my beforeFilter:
$controller = strtolower($this->params["controller"]);
$action = strtolower($this->params["action"]);
$crole = $this->Auth->user("role");
$allowed = false;
$roles = array(
"all"=>array("user#login","user#register","user#forgot"),
"admin"=>array("pages#index","pages#view")
);
if(in_array($controller."#".$action,$roles["all"])){
$allowed = true;
}else{
if(in_array($controller."#".$action,$roles[$crole])){
$allowed = true;
}
}
if($allowed==false){
$this->setFlash("Access denied message...");
$this->redirect("...");
}
Don't know if this is the best practice but it works just fine. I normally hate CakePHP's built in Authorization system.
To check for allowance per role, I think it's best to use the Auth->allow([...]) in a per controller basis.
I find it best to check in Controller::beforeFilter() with a:
switch ($role) {
case 'admin':
$this->Auth->allow(...); //Allow delete
//notice no break; statement, so next case will execute too if admin
case 'manager':
$this->Auth->allow(...); //Allow edit
case default:
$this->Auth->allow(...); //Allow index
}
While you can check in AppController, I don't want to remember to change two files when I edit just one.

cakephp auth redirect and referrer

Let me explain the situation before I ask the question. I have a site, domain.com. the page sub.domain.com requires a user to be logged in to access. If I allow access to sub.domain.com/login which provides a form whose action is domain.com/login, it sends the data to domain.com/login and redirects back to sub.domain.com/login like it should. However, if I try to access sub.domain.com (which requires authentication) it redirects to domain.com/login correctly, but doesn't redirect back to sub.domain.com after logging in. I found the error to be that the redirect when not logged in wasn't sending the referrer header. Is there a way to make it so that if a user tries to access a page on a subdomain that requires authentication, that it will redirect him to domain.com/login, then back to where he originally was?
Does redirect always need to redirect back to sub.domain.com? If so, i'd suggest setting the AuthComponents loginRedirect attribute to the location you want the user to be redirected to. See this page: http://book.cakephp.org/1.3/en/view/1270/loginRedirect
Also, that page says that CakePHP automatically stores the controller-action pair you were accessing before the login in your session. So maybe you should also check whether your session is shared between the domain.com and sub.domain.com.
One final comment: what does happen after login? Are you redirected to the controller/action on domain.com or aren't you redirected at all?
NOTE: I'm assuming you're using CakePHP 1.3 and use the AuthComponent for logging users in.
Ok, it all had to do with routes. I finally was able to get it working by setting up a switch statement in my routes.php file:
switch(Configure::read('subdomain'))
{
case 'subdomain':
Router::connect('/login', array('controller'=>'users', 'action'=>'login'));
}
And set up my bootstrap like so:
preg_match('/^(?:www\.)?(?:(.+)\.)?(.+\..+)$/i', env('HTTP_HOST'), $matches);
$subdomain = empty($matches[1]) ? false : $matches[1];
if( strlen($subdomain) > 0 && $subdomain != "www" )
{
if($subdomain == 'api')
$_GET["url"] = $subdomain . "/" . (isset($_GET["url"]) ? $_GET["url"] : "");
Configure::write('subdomain', $subdomain);
}

(O)Auth with ExtJS

today i tried to get django-piston and ExtJS working. I used the ExtJS restful example and the piston example to create a little restful webapp. Everything works fine except the authentication.
Whats the best way to get Basic/Digest/OAuth authentication working with ExtJS?
Atm I'm not sure where to set the Username/Password.
Thanks
If you want to use piston with ExtJS, I would suggest writing an anonymous handler that checks the user is logged in via standard auth.
Try this:
class AnonymousUserProfileHandler(BaseHandler):
fields = ('title', 'url', 'affiliation')
model = UserProfile
def read(self, request, nickname):
profile = UserProfile.objects.get(nickname=nickname)
if request.user == profile.user:
return profile
class UserProfileHandler(BaseHandler):
anonymous = AnonymousUserProfileHandler
allowed_methods = ('GET')
fields = ('title', 'url', 'affiliation')
model = UserProfile
def read(self, request, nickname):
profile = UserProfile.objects.get(nickname=nickname)
return profile
In this example, when UserProfileHandler is called, without any authorization, it delegates to the anonymous handler. The anonymous handler checks whether the user is logged in via the usual request.user mode. If there is a valid user, it returns their profile object. You would then, obviously, mark the view calling this as requiring login.
The point is: when extJS makes its JSON call, it will send authentication data via the usual cookie. If you use an "anonymous" handler in Piston, but manually check the user is logged in before returning the data, then you essentially use traditional auth for your own site.

Resources