access to custom admin menu item by role in Drupal 7 - drupal-7

I added a custom admin menu item which I'd like to show up for non-admin users with specific roles. Is there a way to accomplish this?
Thanks in advance!
Lee

Create custom access callback in your custom hook_menu:
//custom hook_menu()
$items['menu'] = array(
.................
'access callback' => 'my_custom_callback'
);
function my_custom_callback() {
global $user;
if (in_array('[YOUR_ROLE]', array_values($user->roles))) {
return TRUE;
}
}

Related

knp menu bundle symfony

I have been using a fos user Bundle where each of user is assigned to a group and each group is provided with a specific role as per fos user bundle everything works fine.
Now to make a menu system I am trying to use Knp menu bundle.Now to make menu structure I want to pass roles of each group to menu system(dynamically).So that changing role of specific group can allow the menu system to change dynamically.
I have already configured menu bundle as per documentation
knp menu bundle documentation
here I have added a class named menu builder inside namespace Admin\Bundle\HomeBundle\Menu; Now I need to call group roles of current logged in user and add them to menu dynamically also i need to make some of these roles to sub menu within same main menu.
Please improve me if I am on wrong way (if any) and process how I can dynamically include roles of group to menu using Knp menu bundle as a sevice.
Thanks in advance.
I find out another solution in Symfony 3. You can get security.authorization_checker from the container and use it in menu
namespace AppBundle\Menu;
use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
class Builder implements ContainerAwareInterface
{
use ContainerAwareTrait;
public function topHeaderMenu(FactoryInterface $factory, array $options)
{
$checker = $this->container->get('security.authorization_checker');
$menu = $factory->createItem('root');
$menu->setChildrenAttribute('class','links-top list-inline');
if ($checker->isGranted('ROLE_ADMIN')) {
$menu->addChild('admin panel', array('route' => 'admin'));
}
if ($checker->isGranted('ROLE_USER')) {
$menu->addChild('account', array('route' => 'login'));
$menu->addChild('logout', array('route' => 'logout'));
} else {
$menu->addChild('registration', array('route' => 'registration'));
$menu->addChild('login', array('route' => 'login'));
}
return $menu;
}
}
In Symfony3 the best and easiest solution for me was in MenuBuilder.php :
use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
class MenuBuilder implements ContainerAwareInterface
{
use ContainerAwareTrait;
public function __construct(FactoryInterface $factory, AuthorizationCheckerInterface $authorizationChecker)
{
$this->factory = $factory;
$this->checker = $authorizationChecker;
}
public function mainMenu(array $options)
{
$menu = $this->factory->createItem('root');
$menu->addChild('Home', array('route' => 'homepage'));
$menu->addChild('Blog', array('route' => 'blog_homepage'));
$menu['Blog']->addChild('About', array('route' => 'blog_about'));
$menu['Blog']->addChild('Contact Us', array('route' => 'blog_contact'));
if($this->checker->isGranted('ROLE_ADMIN')) {
$menu->addChild('Admin', array('route' => 'sonata_admin_dashboard'));
}
$menu->addChild('User', array('route' => 'fos_user_profile_show'));
$menu['User']->addChild('Register', array('route' => 'fos_user_registration_register'));
$menu['User']->addChild('Change password', array('route' => 'fos_user_change_password'));
$menu['User']->addChild('Log Out', array('route' => 'fos_user_security_logout'));
// ... add more children
return $menu;
}
}
Donf forget to add "#security.authorization_checker" to arguments in your service

cakephp auth component, use two models

My site has a public section for employees and back end for admin. It uses 2 different models, Employee and Admin.
I want to use Auth component for employee login and admin login. I know how to setup Auth component to use a Model other than default User model. But can i have auth component use 2 models, one for Employee authentication and other for Admin authentication? I am using admin_ prefix routing.
Is this possible? I searched but all i could found was tutorials on howto make Auth component use models other than User model.
Please advise!
EDIT
I use separate login forms for admin login and employee login. Both use the employee controller, but separate actions.
http://api.cakephp.org/class/auth-component
check the property authenticate, your answer is there!
and more :
http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html.
Look at authentication handlers!
Here is an example directly from cake page
<?php
// Basic setup
$this->Auth->authenticate = array('Form');
// Pass settings in
$this->Auth->authenticate = array(
'Form' => array('userModel' => 'Member'),
'Basic' => array('userModel' => 'Member')
);
Just put something else instead of Form and Basic and associate the good Model
Considering you are using two radio buttons for Employee and Admin. Then you can use the following code into the login method.
function login()
{
if ($this->request->is('post'))
{
$logged_in = false;
$login_type = $this->request->data['User']['login_type']
if ($login_type == 'Admin')
{
$this->Auth->authenticate = array('Form' => array('userModel' => 'Admin' ));
}
else //if ($login_type == 'Employee')
{
$this->Auth->authenticate = array('Form' => array('userModel' => 'Employee' ));
}
$this->Auth->constructAuthenticate();
if ($this->Auth->login())
{
$logged_in = true;
/*.... Do what you want............*/
}
}
}

Cakephp: Admin Login as User onClick

i am looking for a way how i (logged in as Administrator) can log me in as a specific user (that i select from a list of users, list is already present) onclick without knowing it's password?
All users have different passwords, so equal passwords are not an option.
OK, Question closed. Here is the solution:
P.S. group with id 2 is my Admin Group.
function loginasuser($user_id = null) {
if (!$user_id) {
$this->Session->setFlash(__('Invalid User.', true));
$this->redirect(array('action'=>'index'));
}
$data = $this->Auth->user();
if($data['User']['group_id'] == 2 || $_SESSION['Auth']['Admin']['id']==$user_id) {
$user_data = $this->User->find('first', array('conditions' => array('User.id' => $user_id)));
if ($user_data['User']['group_id']==2 && $user_data['User']['id']<>$_SESSION['Auth']['Admin']['id']) {
$this->Session->setFlash(__('You can only log in as user', true));
$this->redirect($this->Auth->redirect('/users'));
}
$_SESSION['Auth']['User']['id']=$user_data['User']['id'];
$_SESSION['Auth']['User']['username']=$user_data['User']['username'];
$_SESSION['Auth']['User']['group_id']=$user_data['User']['group_id'];
$_SESSION['Auth']['User']['client_id']=$user_data['User']['client_id'];
$_SESSION['Auth']['User']['created']=$user_data['User']['created'];
$_SESSION['Auth']['User']['modified']=$user_data['User']['modified'];
$_SESSION['Auth']['Admin']['id']=$data['User']['id'];
if($_SESSION['Auth']['User']['group_id']==2) {
$this->redirect($this->Auth->redirect('/ADMINHOME'));
}
else {
$this->redirect($this->Auth->redirect('/USERSHOME'));
}
}
else {
$this->Session->setFlash(__('Only admins are alowed to do so!', true));
$this->redirect(array('action'=>'index'));
}
}
And to go back as admin, you could do:
<? if($_SESSION['Auth']['Admin']['id']>0) { ?>
Go Back as Admin<? }
You can use "username" (email Id) to create session.
On Onclick , trigger an Ajax call, pass the username and set the session using that username.
(Just trigger this call when admin change the selection box, onChange(this.value))
Then just redirect user to end user home page. Put a link to come back to admin dashboard. This helps admin can login as other user.
(Use different session namespace for admin and end user)
$_SESSION['user'] for end user and $_SESSIION['admin'] for admin user.

CakePHP + Facebook

I am trying to implement facebook Connect to my cakephp Application. i am using Nick's Facebook Plugin.
I wanna implement it this way
When a user Visits the Site he should be able to login via Registration on the site or Facebook Connect
Existing users should be able to connect their account to their FB account
People who first time login to the site using FB Connect and dont have an account on the site. should be redirected to a page where they have to enter details to complete the profile.
What i have done -
I have followed the instruction of Nick to implement it and when i click Login - it connects to my app. but i dont understand how to create a username and password associated with the Fb Connect Id. and user it against the FB token.
Apparently I'm doing the same thing a little before you... ;-)
Here's a method for Facebook login I'm using (slightly redacted and annotated):
public function facebook($authorize = null) {
App::import('Lib', 'Facebook.FB');
$Fb = new FB();
$session = $Fb->getSession();
// not logged into Facebook and not a callback either,
// sending user over to Facebook to log in
if (!$session && !$authorize) {
$params = array(
'req_perms' => /* the permissions you require */,
'next' => Router::url(array('action' => 'facebook', 'authorize'), true),
'cancel_url' => Router::url(array('action' => 'login'), true)
);
$this->redirect($Fb->getLoginUrl($params));
}
// user is coming back from Facebook login,
// assume we have a valid Facebook session
$userInfo = $Fb->api('/me');
if (!$userInfo) {
// nope, login failed or something went wrong, aborting
$this->Session->setFlash('Facebook login failed');
$this->redirect(array('action' => 'login'));
}
$user = array(
'User' => array(
'firstname' => $userInfo['first_name'],
'lastname' => $userInfo['last_name'],
'username' => trim(parse_url($userInfo['link'], PHP_URL_PATH), '/'),
'email' => $userInfo['email'],
'email_validated' => $userInfo['verified']
),
'Oauth' => array(
'provider' => 'facebook',
'provider_uid' => $userInfo['id']
)
);
$this->oauthLogin($user);
}
This gives me an array with all the user details I could grab from Facebook and invokes ::oauthLogin, which either logs the user in with the given information or asks the user to fill in missing details and/or creates a new user record in the database. The most important part you get from the Facebook API is the $userInfo['id'] and/or email address, either of which you can use to identify the user in your database. If you're using the AuthComponent, you can "manually" log in the user using $this->Auth->login($user_id), where $user_id is the id of the user in your own database.
private function oauthLogin($data) {
$this->User->create();
// do we already know about these credentials?
$oauth = $this->User->Oauth->find('first', array('conditions' => $data['Oauth']));
if ($oauth) {
// yes we do, let's try to log this user in
if (empty($oauth['User']['id']) || !$this->Auth->login($oauth['User']['id'])) {
$this->Session->setFlash('Login failed');
}
$this->redirect('/');
}
// no we don't, let's see if we know this email address already
if (!empty($data['User']['email'])) {
$user = $this->User->find('first', array('conditions' => array('email' => $data['User']['email'])));
if ($user) {
// yes we do! let's store all data in the session
// and ask the user to associate his accounts
$data['User'] = array_merge($data['User'], $user['User']);
$data['Oauth']['user_id'] = $user['User']['id'];
$this->Session->write('Oauth.associate_accounts', $data);
$this->redirect(array('action' => 'oauth_associate_accounts'));
}
}
// no, this is a new user, let's ask him to register
$this->Session->write('Oauth.register', $data);
$this->redirect(array('action' => 'oauth_register'));
}
Look no further. Here is an excellent article that'll guide you all the way through (minus any readymade plugins):
Integrating Facebook Connect with CakePHP's Auth component
Simply follow the approach described in there.
Cheers,
m^e

Auto login in CakePHP

I am using the registration form for different users? After a new user logs in, the registered users should redirect to an after-login page. We are using Auth component for the authentication.
How do I do this?
If you want the user to auto-login after registering, you can use the AuthComponent's login() method.
if ($this->User->save($this->data)) {
$this->Auth->login($this->data);
}
On newer Cakes, you only need to add
$this->Auth->login();
after you add the user into the database.
I'm not sure what the question is, but it sounds like you're wondering how to send a user somewhere after a successful login. If that's correct, try this:
$this->Auth->loginAction = array (
'controller' => 'whichever_controller',
'action' => 'desired_action',
'admin' => true
);
The admin key may not be necessary if you're not accessing /admin/whichever_controller/desired_action.
You will have to call the login method manually from your register action.
Save the username + unhashed password in an array then call it from the method after the save like this:
$data = array('username' => 'user', 'password' => $unhashedPw);
$this->User->login($data);

Resources