Don't use serialize for the user role Symfony - serialization

I have a project and a Symfony3 Silex 2 API that is based on the database created with SF3.
The problem arises because of the ROLE field in the database, in effect symfony3 stores in the database the user roles via serialize, flint or using a string.
Why Symfony serialize and flint right?
How to solve the problem because Silex does not manage the roles serialize?
Role field BDD:
Silex:
ROLE_MODO,ROLE_SUPER_ADMIN
SF:
a:2:{i:0;s:9:"ROLE_MODO";i:1;s:16:"ROLE_SUPER_ADMIN";}
Thank you.

Make sure in SF3 platform, to map the roles field with simple_array DBAL type instead of array:
#ORM\Column(name="roles", type="simple_array")
The difference is that array type stores their values serialized and simple_array stores their values by using comma separated.

Symfony
I think that ROLE field is mapped as array in doctrine orm, so serialization/unserialization is made automatically by doctrine orm.
http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#array
Silex
You should unserialize roles manually. I don't know how you get user in silex..
class User implements Symfony\Component\Security\Core\User\AdvancedUserInterface
{
...
public function getRoles()
{
return unserialize($this['roles']);
}
...
}

Related

Common authentication table between Yii2 advance and Laravel 5.3

I have already one application built using Yii2 advance and working perfectly.
Now, client's requirement is to create new separate (but related with first) application using Laravel 5.3 and this new system must use the same database of Yii2.
A user should be able to login into both the application.
So, I'm curious is it even possible?
Any help would be appreciated.
Thanks,
Parth vora
Finally, I am able to achieve what I wanted.
So, here are the steps you need follow in your Laravel in order to login into Laravel application using auth table of Yii2:
Yii2 uses "user" name for the auth table, whereas Laravel uses "users".
So add this into your User model:
protected $table = "user";
Yii2 uses "password_hash" field to store the user password, whereas Laravel uses "password".
So add this into your User model:
public function getAuthPassword()
{
return $this->password_hash;
}
Yii2 uses "auth_key" field to store the user's remember token, whereas Laravel uses "remember_token". You also need to increase size of this field from 32 to 100, otherwise you will get an error upon logout.
So add this into your User model:
public function getRememberTokenName()
{
return 'auth_key';
}
You also need to increase the size of 'auth_key' field from 32 to 100, otherwise you will get an error upon logout.
Yii2 uses "int(11)" for created_at and updated_at field type, whereas Laravel uses "timestamp" type.
So add this into your User model:
protected $dateFormat = 'U';
Hope it might helpful to someone.
Thanks

Eloquent: Get pages based on user role

I have a User, Role & Page setup, all with many-to-many relationships and the pivot tables setup in the usual fashion (role_user, page_role), along with the eloquent methods to attach a model to the pivot tables.
My idea is to allow a user to have many roles, and a page can be accessed by many roles.
However now I'd like to return a collection where I have my users details and then the pages they're allowed to access.
The closest I have got is:
return User::find( Auth::user()->id )->with('roles.pages')->first()->roles;
Now this returns each role the user has, and each page that the role can access. Which is correct, however I have duplication on the pages part.
How would I go about getting only a list of pages the user is able to access with no duplication?
Cheers
Read that answer to get you on the track: HasManyThrough with one-to-many relationship
Only for your setup you need to adjust the query - join 2 pivot tables (and make sure they represent real data, ie no rows referencing non-existing models):
// User model
// accessor so you can access it like any relation: $user->pages;
public function getPagesAttribute()
{
if ( ! array_key_exists('pages', $this->relations)) $this->loadPages();
return $this->getRelation('pages');
}
// here you load the pages and set the collection as a relation
protected function loadPages()
{
$pages = Page::join('page_role as pr', 'pr.page_id', '=', 'pages.id')
->join('role_user as ru', 'ru.role_id', '=', 'pr.role_id')
->where('ru.user_id', $this->id)
->distinct()
->get(['pages.*', 'user_id']);
$hasMany = new Illuminate\Database\Eloquent\Relations\HasMany(Page::query(), $this, 'user_id', 'id');
$hasMany->matchMany(array($this), $pages, 'pages');
return $this;
}
One more thing: I hardcoded tables and columns names for sake of simplicity, but in real life I suggest you rely on the relationships and their getters, like: $relation->getTable(), $relation->getForeignKey() etc.
Now suggestion about your code:
return User::find( // 2. query to get the same user
Auth::user()->id // 1. query to get the user and his id
)->with('roles.pages')
->first() // 3. query to get ANOTHER user (or the same, luckily..)
->roles;
Use Auth::id() instead of Auth::user()->id (for Laravel ver 4.1.25+) to avoid redundant query
find() and first() are methods that execute the query, so you just returned the user with id = Auth::user()->id and moment later you fetch another one, who comes first() from the users table..
You don't need to use User::whatever for authenticated user, use Auth::user() instead.
So the code with suggested solution would look like this:
Auth::user()->pages; // collection of Page models with unique entries

Yii. Get Users based on role

I am using native CDbAuthManager to implement RBAC in my webapp. How can I get all the users who has permission to do a role? Suppose I have role named updateprofile. I want to get all the users assigned to that role. I searched the documentation and couldnt find a function.
(I know i can iterate through all user models and do a checkAccess() in a foreach loop, but I prefer a nicer solution )
The easiest way I've found to do this is to create an AuthAssignment model that maps to your auth_assignment table. Then, you can setup relationships, scopes, etc for it and query using it to retrieve all user models. There isn't anything particularly special about the auth_assignment table (as it is mainly just roles in there).
code like
class AuthAssginment extends CActiveRecord{.....
public function getUsersBaseOnRole($role) {
return Yii::app()->db->createCommand()
->select('userid')
->from($this->tableName())
->where('itemname=:role', array(
':role' => $role,))
->queryAll() ;
}....
I think the other replies do not give you the perfect result because roles can be hierarchical and so, you cannot use direct queries or relations. My solution which works well is:
// list all users with 'userManagement' role
if($users = Users::model()->findAll()) {
foreach($users as $id => $user) {
if(!$user->checkAccess('userManagement')) {
unset($users[$id]);
}
}
$users = array_values($users); // to reset indices (optional)
}

Adding more info to Laravel's auth user

I am new to Laravel and I am trying to add some more information to the user variable I am getting back from Auth::user()
To be more detailed, I have a Many-to-Many relationship to a "Privileges" table. As the name suggests, that table holds specific privileges a user can have. In the pivot table, I just hold the the user_id and privilege_id. I have the necessary models set up and everything works fine if I do this in my before filter:
$user = Auth::user();
$user->priviledges()->get();
Now, I would really like to avoid querying every single time I want to find the privileges and would like to have Laravel's Auth class include the privilege information, so that when I do
$user = Auth::user();
I can do a
$user->privileges;
to get an array of all privileges the user has.
Any suggestions for the best approach?
The link to the answer above is not working. However, I found another solution here which worked for me as follows:
First I created a model called EmailPref.php in my own case;
app/model/EmailPref.php
class EmailPref extends Eloquent {
protected $table = 'email_pref';
public function user()
{
return $this->belongsTo('User');
}
}
and then I created a relationship (in my own case) in the User model like so;
app/model/User.php
public function emailPref()
{
return $this->hasOne('EmailPref');
}
I subsequently referenced it anywhere required within my application like so:
Auth::user()->emailPref;
Hence, I was able to add more information to the Auth user.
I'm no Laravel pro, but i think this will solve your problem: http://forums.laravel.io/viewtopic.php?id=1652

WCF RIA Services Authorization

Assume we have two groups "Admins" and "Users". Admins are able to use any operation available in the service but the users can only use some of them.
Should I add the "Admins" group to every single operation or if I just write it on top of the class will do the trick?
Thanks.
Multiple RequiresRole attributes are combined with an AND while multiple roles passed to a single attribute are OR'd. In your case, you'll want to OR the attributes ("User" or "Admin") so you'll have to apply "Admin" to every single method.
// "Admin" && "User", equivalent to using a class attribute for "Admin"
[RequiresRole("Admin"), RequiresRole("User")]
// "Admin" || "User"
[RequiresRole("Admin", "User")]
I had the same problem. Unfortunately you have to set the roles on every method. Alternatively you can use saf-framework to implement acces based authorization.
Otherwise, I would suggest you overwrite the BeforeSubmit() method of you domain service, and check access for your objects there to avoid excessive attributes on each method.
For example you may want to change your access strategy and you don't want to go through every single method and do that.