hook_permission and control access [how to redirect to the login page if user not logged in] - drupal-7

How does one limit "what" can access a page. I have little understanding on how to use hook_permission() to set user permission based on a role to control access to hook_menu() items. However, what if I have a hook_menu() item that is to be used solely by the system itself? For example, say I have a registration page in a custom module: module/register - Anyone can access that page. Then, say I have an another page which is only for admin. So, I register another item in hook_menu(), call it module/register/reg_user_details - I do not want anyone to be able to browse to module/register/reg_user_details
Instead I want page to be visible only when user is logged in, I have already created a hook_permission
/**
* Implements hook_menu()
*
*/
function video_subtitles_menu() {
$items = array();
$items['video_subtitles/upload'] = array( //this creates a URL that will call this form at "video_subtitles_test/upload"
'title' => 'Upload Subtitle', //page title
'description' => 'Uploading subtitle for videos',
'page callback' => 'drupal_get_form', //this is the function that will be called when the page is accessed. for a form, drupal_get_form need to be used
'page arguments' => array('video_upload_subtitles_form'), //Name of the Uplaod Form
'access callback' => 'user_access',
'access arguments' => array('administer video_subtitles module'),
);
$items['player/video_subtitle_status'] = array(
'page callback' => 'video_subtitle_status',
'access callback' => 'user_access',
'access arguments' => array('administer video_subtitles status'),
);
return $items;
}
/**
* Implements hook_permission.
*/
function video_subtitles_permission() {
return array(
'administer video_subtitles module' => array(
'title' => t('Administer video_subtitles module'),
'description' => t('Access the video_subtitles upload module Page'),
),
'administer video_subtitles status' => array(
'title' => t('Administer video_subtitles module status'),
'description' => t('Access the video_subtitles module status Page'),
));
}
So User is not able to access my page unless user is logged in, but
what I need user should be redirected to the login page when he is not logged in as admin , if he successfully login it should be redirected to my page.
visit url d-7/example/my-module
if already logged in show the page
if not logged in redirect to the login page
if user logged in successfully redirect to d-7/example/my-module page
What is best way to achieve this
Similar Question
using-hook-menu-with-hook-permission-access-denied
using-hook-menu-and-hook-permission-to-control-access
can-someone-explain-access-arguments-in-drupal

Related

CakePHP login redirects users back to login page (IE11 and Edge)

I have a CakePHP application (v 2.7), which contains a fairly standard login element using the Auth component. This works fine for the majority of users, however, a handful of users are reporting that they cannot sign in - when they attempt to do so they are redirected back to the login page, with no error message.
I have built some logging in to the site to check what is happening and it seems that the login is going through fine (everything in my login action is logged working as desired) until they hit the redirect part of the code, then they are not redirected to the intended page.
All the users who are having problems seem to be coming to the site through the same company network - not sure if that's of relevance or not! However, all have cookies enabled (I have added a script to display an error if they are not enabled).
I have tested the site in IE11, Edge 11, 12 + 13 (the browsers that users appear to be having issues with) but cannot replicate the issue, regardless of the security settings on the browser.
Could this issue be related to settings in the network that the users are accessing the site from? Are there any settings I should try to get them to check? Sorry - I'm pretty stumped by this one, as I just cannot replicate it, any pointers towards the questions I should be asking would be useful.
The relevant sections of my code are below. If there are any bits that would be helpful please let me know.
Thanks in advance for any help.
In the AppController (components)
public $components = array(
'Session',
'Cookie',
'Security' => array(
'csrfExpires' => '+300 minutes',
'csrfUseOnce' => false
),
'Auth' => array(
'loginAction' => array('controller' => 'users', 'action' => 'login', 'admin' => false),
'loginRedirect' => array('controller' => 'course_sections', 'action' => 'index', 'admin' => false),
'logoutRedirect' => array('controller' => 'website_pages', 'action' => 'view', 'home', 'admin' => false),
'authorize' => array('Controller'),
'authenticate' => array(
'all' => array(
'scope' => array('User.is_archived' => 0, 'Client.is_active' => 1),
'contain' => array('UserGroup'),
'passwordHasher' => 'Blowfish'
),
'Form' => array(
'fields' => array(
'username' => 'email',
'password' => 'password'
)
)
),
'Acl'
);
In the UsersController
public function login(){
// If user has submitted the form
if ($this->request->is(array('post', 'put'))) {
if ($this->Auth->login()) {
$this->log('Successfully logged in. Cookie Status: ' . $this->request->data['User']['cookies'], $this->Auth->user('public_id'));
// Redirect
return $this->redirect($this->Auth->redirectUrl());
} else {
// Log failed login attempt
$this->log('Unsusccessful login attempt using email: ' . $this->request->data['User']['email'], 'nosuccess');
$this->Session->setFlash($this->FlashMessage->translateFlash('invalid_login', false));
}
}
}
I am using database backed sessions, but the issue is the same whether using these or PHP ones.

CakePHP 2.7.1 unauthorizedRedirect

In my AppController I have this code for the component
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
),
'unauthorizedRedirect' => array(
'controller' => 'member',
'action' => 'index'
)
),
'Session',
'DebugKit.Toolbar'
);
So, unauthorizedRedirect is working fine. I tried to type the URL the user has no access to and fortunately, I am redirected to 'localhost/appname/member/'.
My concern is that, this only applies to one type of logged in user.
Let us say a logged in user tried to access localhost/appname/admin/add_post/. Since only admins have access to that page, the user will be redirected to localhost/appname/member/. What if it's an admin who accessed an unauthorized page? Of course, that admin will have to redirected somewhere, but not to localhost/appname/member/.
How can I solve this?
I believe there are many ways. You are already using the ACL which is one way. Or another "lazy" way to do this is to use the beforeFilter method inside the AppController.
Ok, so after several hours of researching and stuff I was able to come up with a solution.
This is the code for the AppCntroller:
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
),
'unauthorizedRedirect' => false
),
'Session',
'DebugKit.Toolbar'
);
What this does is rather than redirecting the user to another page, it will just show 'error400.ctp'.
Now, we don't want to show the default CakePHP error layout so we still have to edit it or make a custom one.
Create a new file under 'View/Layouts/your_error_file.ctp'. After that, go to 'View/Errors/error_file.ctp' and paste the following code:
$this->layout = 'your_error_file'

Drupal 7 Access Callback Not Working Properly

Drupal 7 Hook_menu access callback is not returning the correct boolean.
Before we begin. YES! Cache is cleared... a lot.
I implemented a simple function for testing:
$items['tutor_review_selection'] = array(
'title' => t('example'),
'page callback' => 'my_module_example_page',
'access callback' => my_module_access( array('administrator') ),
'type' => MENU_NORMAL_ITEM
);
function my_module_access( $roles ) {
global $user;
$check = array_intersect($roles, array_values($user->roles));
return empty( $check ) ? FALSE : TRUE;
}
This returns TRUE for logged in and logged out users.
Here is the important part:
I call 'my_module_access' function in 'my_module_example_page' function and it works correctly.
Can anyone shine some light onto why this would not work in access callback?
Maybe something to do with order of operation?
Cache is cleared.
If you check the Drupal 7 hook_menu documentation you will see the following code:
function mymodule_menu() {
$items['abc/def'] = array(
'page callback' => 'mymodule_abc_view',
'page arguments' => array(1, 'foo'),
);
return $items;
}
'page callback' accepts a string, which is the callback function name. The arguments to be sent to that function are provided in the 'page arguments' array.
edit Note that you should probably create a permission and assign your roles to that permission, then check the permission instead of checking for specific roles.

Drupal7 hook_menu for exists node aliases

I'm developing my module. For module I created special node type and add some nodes with aliases as 'events/my1', 'events/my2' and 'events/my3'.
In module I use hook_menu function
$items['events'] = array(
'title' => t('Events list'),
'access callback' => TRUE,
'page callback' => '_events_list',
'type' => MENU_CALLBACK,
);
$items['events/%'] = array(
'title' => t(''),
'access callback' => TRUE,
'page callback' => '_event_detail',
'page arguments' => array(1),
'type' => MENU_CALLBACK,
);
On url site.com/events/ opened my page from _events_list() function
On url site.com/events/anyurl/ opened content from _event_detail() function
But when I open site.com/events/my1/ then opened default view for node. Not my code from _event_detail().
How I can fix it? I want for each urls from /events/ show code from my function, not default view.
hook_menu defines new URL paths. For existing URL paths, use hook_menu_alter.

How do I make certain menu items visible to certain roles?

In /drupal/admin/structure/menu/manage/main-menu, I have some links that I only want displayed for user's that have a specific permission.
How would I go about this?
In my module, I have
...
$items['resume/joblist'] = array(
'page callback' => 'ac_resume_job_list',
'access arguments' => array('view joblist'),
'title' => 'Job List',
'description' => 'Job List',
);
...
function ac_resume_permission()
{
return array("view joblist" => array("title" => "View Job List"));
}
When I go to "resume/joblist" under a user without the permission, I get the "Access Denied" as expected, however the link is still displayed.
hook_perm() was renamed to hook_permission() in Drupal 7, and there's a bit of a mismatch between view mylink that you define and view joblist that you declare as a permission.
You could change your code to look more like this:
function mymodule_menu() {
$items['mylink'] = array(
'page callback' => 'mymodule_mylink',
'access arguments' => array('view mylink'),
'title' => 'My Link',
'description' => 'My Link',
);
return $items;
}
function mymodule_permission() {
return array(
'view mylink' => array(
'Title' => 'View My Link'
)
);
}
After you clear Drupal's cache navigate to admin/people/permissions and assign your new permission to the role you want to be able to access the page you define in hook_menu().
Once you've done that users with that role will be able to access the page :)
I recommend using the following module: Menu Item Visibility, it does exactly what you need.

Resources