Controller level permission - acl

Consider following code:
$acl = new Phalcon\Acl\Adapter\Memory();
$acl->setDefaultAction(Phalcon\Acl::DENY);
//Register roles
$acl->addRole(new Phalcon\Acl\Role('guest'));
$acl->addRole(new Phalcon\Acl\Role('member', 'guest'));
$acl->addRole(new Phalcon\Acl\Role('admin', 'user'));
$acl->addResource(new Phalcon\Acl\Resource('user'));
$acl->addResource(new Phalcon\Acl\Resource('index'));
$acl->allow('member', 'user', array());
$acl->allow('guest', 'index', array());
$acl->isAllowed('guest','index','index'); //returns false
I want grant permission at controller level, I mean when write:
$acl->allow('member', 'user');
It grant member of actions of user controller, I do not want add all actions of user controller manually. How can I implement this idea?

There is a good example implementing Acl in the sample application called INVO, the Security plugin implements an Acl list, the resources regarding the public areas use a '*' as a wildcard to add a rule for every action in the controller:
<?php
$publicResources = array(
'index' => array('index'),
'about' => array('index'),
'session' => array('index', 'register', 'start', 'end'),
'contact' => array('index', 'send')
);
foreach($publicResources as $resource => $actions){
$acl->addResource(new Phalcon\Acl\Resource($resource), $actions);
}
//Grant access to public areas to both users and guests
foreach($roles as $role){
foreach($publicResources as $resource => $actions){
$acl->allow($role->getName(), $resource, '*');
}
}

Related

How to add a role to user when having basic User model in Yii2

Building a lightweight app using basic installation of Yii2.
I need to assign a role for a user but don't want to have users and user roles stored in database.
How can I set a role for users defined in User->users class?
Default User model and default user definition look like this:
class User extends \yii\base\BaseObject implements \yii\web\IdentityInterface
{
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
private static $users = [
'100' => [
'id' => '100',
'username' => 'admin',
'password' => 'admin',
'authKey' => 'test100key',
'accessToken' => '100-token',
],
You can use RBAC PhpManager for that that will store all roles info in files instead.
First configure your AuthManager component in config/web.php:
// ...
'components' => [
// ...
'authManager' => [
'class' => 'yii\rbac\PhpManager',
],
// ...
],
By default it uses 3 files to keep the data:
#app/rbac/items.php
#app/rbac/assignments.php
#app/rbac/rules.php
So make sure there is folder rbac in your application's root and that it's write-able by the www process. If you want to place the files somewhere else (or rename them) you can provide the new path in the configuration like:
'authManager' => [
'class' => 'yii\rbac\PhpManager',
'itemFile' => // new path here for items,
'assignmentFile' => // new path here for assignments,
'ruleFile' => // new path here for rules,
],
The rest now is just like in the Authorization Guide.
Prepare roles and permissions (example in console command - by running this command once you set all roles; remember that if you want to run it in console you need also configure console.php with the same component).
Assign role to a user (example - here it's done during the signup but you can do it also in the above command).
Now you can control access with direct check or behavior configuration.

Yii2-user: How to create admin user in batch mode?

When deploying my application there is of course always an admin user.
How can I create such an admin user as a first user without any interaction ...
... by means of SQL?
... using a Yii2-migration?
Found it. There is an easy way to do this with Yii2 builtin migrations.
In Yii2-user there are some hooks we can use to create users.
This code has to be inserted in a migration. after creating a new migration ./yii migrate/create, preferably after creating initial tables in the database:
use yii\db\Transaction;
use app\models\user\User;
public function safeUp()
{
$transaction = $this->getDb()->beginTransaction();
$user = \Yii::createObject([
'class' => User::className(),
'scenario' => 'create',
'email' => 'admin',
'username' => 'admin#example.com',
'password' => 'mysecret',
]);
if (!$user->insert(false)) {
$transaction->rollBack();
return false;
}
$user->confirm();
$transaction->commit();
}
The skeleton code can be found in ./migrations/....
Don't forget to add database config parameters in ./config/db.php
and the user module in ./config/console.php

User login action is not working, showing invalid username and password in CakePHP3

I am trying to implement login functionality in CakePHP3 by following all prescribed ways. I have already tried many alternatives apart from main method found on Authentication page of official Cake website.
The error, I am receiving is "Invalid username or password". Below is a snapshot of code, I have used. Please note, I have followed proper naming conventions of CakePHP so no config issue should be there. Plus the issue is in 3.x version so don't answer for older versions please.
File: UsersController > Login Action
public function login() {
if($this->Auth->user()){
$this->Flash->error(__('You are already logged in!'));
return $this->redirect($this->Auth->redirectUrl());
}
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
$this->Flash->success(__('You\'re successfully logged-in.'));
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Username or password is incorrect'));
}
}
File: AppController > Initialize Function
public function initialize()
{
parent::initialize();
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
],
'authError' => 'Did you really think you are allowed to see that?',
'authenticate' => [
'Form' => [
'fields' => ['username' => 'username']
]
],
'storage' => 'Session'
]);
$this->Auth->allow(['display']);
$this->Auth->allow(['register']);
}
File: Login View
<?php
echo $this->Form->create();
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->button('Login', ['class' => 'btn']);
echo $this->Form->end();
?>
Hope, I haven't missed anything but still it is not working as intended.
Any suggestion will be appreciated.
TIA
It is not working without PasswordHasher in Auth component.
You should add it in /src/Model/Entity/User.php
Add below code at the end. Also add use Cake\Auth\DefaultPasswordHasher;
protected function _setPassword($value){
$hasher = new DefaultPasswordHasher();
return $hasher->hash($value);
}
After this add new user and try to login with it.
Is your user entity using the DefaultPasswordHasher in the file src/Model/Entity/User.php?
Just a thought...

All Yii2 controller not allow action without login or guest must need login

I'm using Yii2 Advance application and i am new in yii2 so how make
all yii2 controller not allow action without login or guest must me login
i mean controllers can not open without login if user not login so redirect in login page this not for one controller i need many controller
You need to add below code in common/main.php after components part.
'as beforeRequest' => [ //if guest user access site so, redirect to login page.
'class' => 'yii\filters\AccessControl',
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'allow' => true,
'roles' => ['#'],
],
],
],
You could simply create a super controller for this :
class Controller extends \yii\web\Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => false,
'roles' => ['?'],
],
],
],
];
}
}
And of course all your controllers should extend this one.
Read more about Access Control Filter.
You can try write in index.php in your backed public directory
No need to repeat in controllers
<?php
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
$config = require __DIR__ . '/../../config/web.php';
$config["controllerNamespace"]='app\controllers\backend';
(new yii\web\Application($config))->run();
if(Yii::$app->user->isGuest){
$request_headers = apache_request_headers();
$srv=$request_headers['Host'];
header("Location: https://".$srv);
die();
}
use RBAC Manager for Yii 2 you can Easy to manage authorization of user.
https://github.com/mdmsoft/yii2-admin.
You could inherit from the yii Controller class where you can override the beforeAction method and in that function you can redirect the user if there is no active logged in session.
Make sure that all of the other controllers what you are using inherited from your new controller class.
EDIT:
In the SuperController beforeAction you can check if the current call is your site/index, if not then redirect to there like:
if($action->controller != "site" && $action->id != "index" ) {
$this->goHome();
}
Make sure that the goHome() take you to your site/index.
And you can split your Site actionIndex() method to an authenticated or not part like:
public function actionIndex() {
if(Yii::$app->user->isGuest) {
return $this->redirect(Url::toRoute('site/login'));
}
else {
...
}
}
Hope this helps.

CakePHP basic auth on API (json) request

I want to make a request to resource/index.json, but since I index is not allowed without authentication it redirects me to login page. That's the behavior I want when no username:password has been sent
The thing is how do I set AuthComponent to work with both Form and Basic and only check for basic when the request goes through api prefix.
Also, does it automatically authenticate when found username and password in the header or do I have to do it manually?
in respective controller add few lines
class NameController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow("index");
}
}
This will allow index without authentication.
I decided to use Friend's of Cake TokenAuthenticate, and yes, it works along with FormAuthenticate so I am able to use both.
As a matter of fact, it automatically chooses the component it's going to use based on if there is an existing _token param or a X-MyApiTokenHeader header.
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form',
'Authenticate.Token' => array(
'parameter' => '_token',
'header' => 'X-MyApiTokenHeader',
'userModel' => 'User',
'scope' => array('User.active' => 1),
'fields' => array(
'username' => 'username',
'password' => 'password',
'token' => 'public_key',
),
'continue' => true
)
)
)
);