Yii role access via accessRules without AuthAssignment table - php

Yii framework 1.1.14
I have set the following in my controller:
public function accessRules()
{
return array(
array(
'deny',
'controllers' => array(
'site',
'hotels',
'channels'
),
'roles' => array('General')
)
);
}
I have created a custom CDbAuthManager called CDbAuthManagerExtension, declared in config/main.php:
'authManager' => array(
'class' => 'CDbAuthManagerExtension',
'connectionID' => 'db'
),
In CDbAuthManagerExtension I have declared my getRoles($user_id) function.
But when I run the code I get the following error:
CDbCommand failed to execute the SQL statement: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'h2g.AuthAssignment' doesn't exist. The SQL statement executed was: SELECT *
FROM `AuthAssignment`
WHERE userid=:userid
I don't want to set up the AuthAssignments table and I don't see why it's looking at it when I've specified the roles in the accessRules function? Does anyone know how to stop it looking for the AuthAssignments table?

You are using a DbAuthManger meaning it has to lookup a DB table to get the assignments, it is not looking for the roles as such it is looking for the role assignments to users and determines whether the current user has the authorizations computed both based on the roles assigned to him and the roles that are allowed an action.
If you don't want to use the name AuthAssigment for the table and use another table you can specify it in your config like this
'authManager' => array(
'class' => 'CDbAuthManagerExtension',
'connectionID' => 'db'
'assignmentTable'=>'MyCustomTable'
),
There are two other tables you can modify their locations as well read CDbAuthManager doc here
If you however do not wish to have a table at all then you should not use the DbAuthManager and use the PHPAuthManager, which stores the assignment data in a php file as an array It is configured by CPhpAuthManager see doc here. You can extend this class with your customization and use it in your config instead

Related

How to specify a target entity type with sonata_type_collection

I am using Sonata Page Bundle to build a set of page with information about items -- one item per page. On each page, I want to include multiple synonyms for the item. I have created a Synonym entity with two fields.
I now want to use an add() method within my configureFormFields definition to add a reference to my new Synonym entity. The following code yields an error saying that The current field 'Synonym' is not linked to an admin. Please create one for the target entity : '':
->add('Synonym', 'sonata_type_collection', array(
'label' => "Synonyms",
'cascade_validation' => true,
'required' => false
), array(
'edit' => 'inline',
'inline' => 'table'
))
... and I have tried modifying the code so it looks like:
'cascade_validation' => true,
'required' => false,
'target_entity' => 'AppBundle\Entity\Synonym'
), array(
... which results in the same error.
How do I tell my admin class that this is a reference to a set of Synonym objects that I want to edit inline?
Edit:
I have also tried
'targetEntity' => 'AppBundle\Entity\Synonym'
... with no luck. The application is still seemingly having trouble figuring out what the entity I'm targeting is.
An at least partial answer was found in adding an "admin_code" definition to my array, as described at
https://symfony.com/doc/master/bundles/SonataAdminBundle/reference/form_types.html
I still get an error, but it is now at least a different error.

CakePHP 3.2 - Specify different datasource for session handler

I am having an issue specifying a different datasource to use in a custom session handler inside config/app.php. Here are the relevant bits:
config/app.php
<?php
return [
... ,
'Datasources' => [
'default' => [...],
'test' => [...],
'session' => [...]
],
'Session' => [
'defaults' => 'database',
'ini' => ['session.cookie_domain' => '.example.com'],
'handler' => [
'engine' => 'CustomSessionHandler', // file and class name of custom handler
'model' => 'sessions' // table name
]
]
];
CustomSessionHandler.php is a copy of the default DatabaseSession.php with a few customisations in the query building to work with our existing sessions table schema.
Right now, it's trying to use the 'default' datasource, and as you might guess, I'm trying to get it to use the 'session' datasource. However I can't find any information on how to do that.
Any assistance is greatly appreciated!
The session handler only knows about the model, respectively the table class, and it shouldn't really know more than that.
So what you could do is configure that table class to use a non-default connection. If you don't have a concrete SessionsTable class yet, create one, and override Table::defaultConnectionName(), like
public static function defaultConnectionName()
{
return 'session';
}
See also Cookbook > Database Access & ORM > Table Objects > Configuring Connections

Doubts about Yii2 RBAC

I've been developing web apps using Yii 1.1.14 so far, but now it's time for an upgrade.
The company where I work has developed its own Access Control system, and I was really OK with it until I saw what it was really like... A combination of 8 tables in the database (not counting the users table), with a bunch of foreign keys.
1 table for controllers
1 table for the actions
1 table for the menu categories
1 table for types of users
And the other tables basically just connect 2 or 3 of those tables at a time.
It works well, but in my point of view it's highly time consuming to maintain all those tables, and at some point, when your application goes online, if it hits a certain amount of users it could get really slow. specially because 2 of those tables have the user's table primary key as foreign key.
So I've decided that, when I start developing on Yii 2, I'm going to start using RBAC, so I started looking for tutorials online... Only finding many different versions of the same code with author's role, and permissions for create or update posts.
I found a combination of 5 videos on Youtube, but they are about Yii 1 RBAC. They were helpful because I managed to understand most of RBAC's functionality, but I still have some doubts that I'll
enumerate below. And keep in mind that for this Access Control system I'm using the DBManager class.
My Doubts
Yii 1's RBAC used to have 3 tables: auth_assignment, auth_item and auth_item_child. Now in Yii 2 RBAC, a new table appears that is called auth_rule and I still don't understand what that specific table is doing there, how to use it or how to populate it.
I see that it's possible to restrict the user's access to some actions by using the controller's behavior method, and assigning access to some actions depending on the user's role, but when it comes to this I have to split my question into 2:
2.1. First: If you can just restrict the access to actions by setting it up in the behaviors method, then what's the use of saving permissions to the auth_item table?
2.2. Second: If you DO decide to control access according to permissions, then how exactly do you do it, because I find myself writing the following type of code inside of every function and I don't think using RBAC is supposed to be this tedious. There has to be another way.
public function actionView($id)
{
if(Yii::$app->user->can('view-users')){
return $this->render('view', [
'model' => $this->findModel($id),
]);
}else{
#Redirect to a custom made action that will show a view
#with a custom error message
$this->redirect(['//site/notauthorized']);
}
}
Because of the Access Control System that we use right now, when a user logs in, a complex query is executed that will end up returning an array that will be saved as a session variable, and will be used to create a menu with as many dropdownlists as menu categories, that the controllers that the user has access to belong to. How can this be done with RBAC?
I can only really answer 2.2 of your question, as 3 doesn't sound at all like something an RBAC should do. You could, however, get the information you needed from the rules table most likely, provided you followed a naming convention that matched your controllers or actions.
On to answering 2.2 though:
You can simply set the behavior like such:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => ['view'],
'roles' => ['view-users'], //<-- Note, rule instead of role
],
]
]
}
This doesn't solve a different problem of 'view-own-users' style permissions, as this needs to inspect the ActiveRecord model (well, at least it does in my application). If You want to achieve this, take a look at my post in the Yii forums here:
http://www.yiiframework.com/forum/index.php/topic/60439-yii2-rbac-permissions-in-controller-behaviors/#entry269913
I use it in one of the simplest method,I use them in the behaviours of my controller.
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['sysadmin'],
'actions' => ['index','view','update'],
],
[
'allow' => true,
'roles' => ['staff'],
'actions' => ['index','create','update','view'],
],
],
],
];
}
Here roles are the one created in the auth-item table in the database and they have been assigned for users in auth-assignment table. In the behaviours we just use it as above. In the above code sysadmin can have access to index, view and update action, whereas staff can have access to index,create, update and view action.
Yii2 needs a little setup when it comes to using RBAC under your controllers AccessControl. I got around it by making my own AccessRule file.
namespace app\components;
use Yii;
class AccessRule extends \yii\filters\AccessRule
{
protected function matchRole($user)
{
if (empty($this->roles)) {
return true;
}
foreach ($this->roles as $role) {
if(Yii::$app->authManager->checkAccess($user->identity->code, $role))
return true;
}
return false;
}
then in your controller u can use something like this:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'ruleConfig' => [
'class' => 'app\components\AccessRule'
],
'rules' => [
[
'actions' => ['index', 'resource-type'],
'allow'=> true,
'roles' => ['admin'],
],
],
],
];
}
Where admin is defined as a auth_item and the user is in the auth_item_assignments.
As I have created a new Rbac system for yii2. you can direct permission for a action and action will show you are not authorisez for this action.
By this you find that you will only provide access for action that need to identify.
I uploaded my detail here you can find lot of solution here.
This is the best solution i could come up with when facing the need to filter access by permissions, it's bothersome but can be useful if you're trying to create roles in a productive enviroment and want to use rbac.
use yii\web\ForbiddenHttpException;
if(Yii::$app->user->can('view-users')){
return $this->render('view', [
'model' => $this->findModel($id),
]);
}else{
throw new ForbiddenHttpException('You dont have access to this site');
}

Having troubles with Multi-Auth in Laravel 4

I am trying to implement the multiauth package here: https://github.com/ollieread/multiauth#laravel-multi-auth
for two models I have, Fan and Artist.
I installed the package per the instructions, and then I used in auth.php:
'multi' => array(
'user' => array(
'driver' => 'eloquent',
'model' => 'Fan'
),
'artist' => array(
'driver' => 'database',
'table' => 'artists'
)
),
I tried to emulate the example. However, when I run my original code (that was only predicated on fans, so I had the user auth associated with my Fan model)
When I get to one of my pages with one of the original $friends = Auth::user()->friends (for example) calls, I get the error:
Undefined property: Ollieread\Multiauth\AuthManager::$friends
When friends is clearly a column in the fans table. Any ideas?
You're calling the authed models in the wrong way.
$friends = Auth::user()->friends
That's the old way to do it, where user() was the method that returned the model. Now, the first method is type of auth and I even added in a get() method to make it less confusing.
$friends = Auth::user()->get()->friends;
In your instance, Auth::user() is the Auth instance of the user entry in your config, and Auth::artist() is the Auth instance of the artist entry in your config.
Basically take the way that the original auth library does things, and move it all up one level.
Auth::user()->get()->id // Original: Auth::user()->id
Auth::user()->check() // Original: Auth::check()

Module dependency and relations

"Some commonly used features, such as user management, comment management, may be developed in terms of modules so that they can be reused easily in future projects." - http://www.yiiframework.com/doc/guide/1.1/en/basics.module
I have a lot of projects that requires a user. Every time quite the same database structure and features. Registration, login, logout etc.
Yii tells me that i can reuse modules. Cool... let's start:
I have 3 parts: User, Campaign and Website.
In this project the CampaignModule has a relation to the UserModule (campaign_user [user_id, campaign_id])
The WebsiteModule has a relation to the CampaignModule and to the UserModule.
I want to reuse the UserModule in other projects with features like registration, login, edit etc.
Actual situation:
After creating models with gii every one has relations and dependencies across the modules.
e.g.
UserModule: 'campaigns' => array(self::HAS_MANY, 'Campaign', 'user_id'),
To use the WebsiteModule it's necessary to include the User- and CampaignModule.
Now i even have to include Website- and CampaignModule to use the UserModule!
I also want to update the UserModule across many projects and maybe build a framework with some basic modules.
What is the right way to plan an architecture like this?
There is a yii-user module, what they do, is they allow you to specify additional relations for the User model, on the module configuration:
/**
* #return array relational rules.
*/
public function relations()
{
$relations = Yii::app()->getModule('user')->relations;
if (!isset($relations['profile']))
$relations['profile'] = array(self::HAS_ONE, 'Profile', 'user_id');
return $relations;
}
So you can do something like:
'modules'=>array(
'user' => array(
...
'relations' => array(
'categories' => array(CActiveRecord::HAS_MANY, 'Category', "user_id"),
'account' => array(CActiveRecord::HAS_ONE, 'Account', "user_id"),
),
...
),
),

Categories