yii authenticate system based on usergroups instead of roles - php

I'm trying to build my own custom authenticate system on this framework.
I've set up RBAC of Yii. It's working well. It gives me roles.
Later on I've edited the code and now I can get users id, and username also.
But what I want is a bit more complicated.
I don't like this role system of RBAC, because you have fixed roles written inside code.
My idea is a user having usergroup ID. and in database I can manipulate what can does each usergroup.
So for example user loggs in and wants to make new topic,
While authenticate RBAC uses usergroup ID to connect to database and get all data according to this usergroup.
then it creates something like:
$this->setState('create_new_topoic', <info from database);
$this->setState('edit_topic', <info from database);
$this->setState('view_topic'', <info from database);
And then during application in controllers and views I will just use everywhere
if (isset(Yii::app()->user->create_new_topoic) AND (Yii::app()->user->create_new_topoic>0))
{ show 'create new topic button' }
Is this normal practice? I'm interested in how this will react on load of server and MYSQL. I'm overloading my application or such system is ok for server to handle?

What you want is what RBAC exactly can do. In fact, you give a ROLE to user instead of GROUP. Idea is:
Create Your operations (For example create/update)
Create appropriate roles based on your operations (For example Modifier, who can perform create and update)
Assign to users one or more appropriate roles
Wherever/Whenever you can easily check access of your users by their roles
Talking in code:
$rbac=Yii::app()->CAuthManager();
$rbac->createOperation('create','This is a description for this operation')
$rbac->createRole('modifier','This is a description for this role')
$rbac->assign('modifier','USER_ID')
$rbac->checkAccess('modifier')
Please do not limit yourself into RBAC methods provided by Yii. You can do every manipulations in your database and write your own customized methods. (I mean, while you are using rbac, you can customize the way you use it. For example considering groups as roles)
To be more clear, you can read Yii's RBAC document:
Yii's IAuthManager - RBAC

RBAC works just fine. Another method is 1) Assigning User Type to session variable at time of login. 2) Checking User Type in the View. The user table needs a User Type column obviously. I think that approach is fine, and it won't overload your server. Of course it will add a few miliseconds but it is required if you want the same view to display different things based on role.
In your UserIdentity File (/protected/components)
public function authenticate()
{
....
$this->setState('type', $user->type); //Set's Type here
$user->save();
....
}
In Your Views/Controllers
<?php if (Yii::app()->user->type == 'Finance') : ?>
{some code}
<?php else: ?>
{other code}

Related

CakePHP: How to use a function with a model in every controller?

I have a project which includes admin and user section. Both section use the same controllers, just different functions and templates (ex: viewAdmin() and viewUser()). In function beforeRender() of every controllers, I set variable $admin as true for admin functions and false for user functions.
For authentication, I use Shibboleth. Shibboleth uses data from LDAP, while user types were saved in SQL-Database, that means while it can check if the login and password are false, it can't check if the user is admin or not. An user can go to ADMIN section as long as they use the right action (ex: go to the link http://example.com/tool/viewAdmin).
To prevent this, I will have to:
Load model Users
Compare the environment variable uid (login name) with the "login" columns in Users table in my SQL-Database
See the "type" column in Users table to know if user is admin or not.
Compare the result with value of $admin and redirect to an error page when necessary.
The problem is: I don't want to repeat those steps for EVERY controllers.
Currently I have 2 ideas:
Write a function in UsersController, and use it in every controllers.
Create a component and load it in every controllers.
Both methods require me changing code in all controllers. I would like to hear a better way with less work, perhaps by changing app.php or bootstrap.php.
Any suggestion is appreciated.
To share methods in CakePHP controllers you can do:
Create component and include in controller
Or create method in AppController and use it in child controllers
Or PHP way create Trait.
But when you authorize users, then all user data is stored in session, incl. is user roles (example admin, regular, member,.. )
Use the official CakePHP authentication plugin and extend the LDAP adapter with the additional code check you need. This is very easy to do and also a very clean way of solving the problem. Disclaimer: I'm one of the authors of the authentication plugin. https://github.com/cakephp/authentication
Or if you want to stay agnostic to any framework, use my library that is based on the authentication plugin and was decoupled from any framework but still works just nice with Cake https://github.com/Phauthentic/authentication.

How to use ACL plugin in marketplace website?

I am new to CakePHP, planning to develop a marketplace website using CakePHP. Four types of users will use this website.
1. Anonymous
2. Administrator
3. Service Provider
4. Service Seeker
Can i use ACL plugin to develop the website. OR should i store these users in different tables and use this technique? CakePHP 2.x Auth with Two Separate Logins
Kinldy guide me which technique to use with it's structure.
Here, ACL will be the best solution. You don't have to manage anything manually. You only have to implement ACL successfully, that's it.
Having separate logins is against KISS and doesn't make much sense in any case. The only difference for example between a frontend and backend login is usually the view. Nothing else. If you have different user types they will still have a single login. Even if their data differs this should be abstracted by having one table that deals with the accounts (users) and another that is associated and contains the data (User hasOne FooProfile, User hasOne BarProfile). The association to the data or profile type table can be done on the fly after login depending on the user type.
ACL is relativly complicated and can become slow. Depending on the requirements I would evaluate role based access as well. I've written an easy to use RBAC adapter for CakePHP. See the test case to get an idea how it works. Basically you just have to define a map for the roles. By default the users table needs a field roleit can contain a single role or a comma separated list of roles. You can even have a table with roles but then need to generate that comma separated list, because thats what the adapter is expecting.

Yii framework : role based access control

I am implementing role based access control using yii framework for the application mentioned in the Agile web application development using yii framework book.I have implemented every thing up to page number 189.
page number 189 says that following method can be used to check whether user is allowed to perform some action or not.
If( Yii::app()->user->checkAccess('createIssue')) {
//perform needed logic }
but this method always return false for users who have been assigned to createIssue operation
following is the database diagram for RBAC
i am linking UserID and role for authassignment table using following command.
$auth=Yii::app()->authManager; $auth->assign('member',1);
As you can see my user table and authassignment table does not have direct relationship.
And i have configured main.php file in configuration folder
These are the all we have done so far and could any body share your knowledge with me if any thing is missing here. Thanks in advance for any help.
Come on, man! Of course there must be a direct relationship between users and assigments. In the following piece of code:
$auth=Yii::app()->authManager; $auth->assign('member',1)
'member' belongs to authiments, and '1' is the id of the user being assigned with that role. "userid", in the "authassigment" table, must point to users table.

Using tank_auth with multi type user and HMVC

Using Tank Auth for first time along with HMVC. In my application there are 2 type of user one is say student and another is institute.
I created two modules for each user type and separated the tank auth library , both user's registration, login and tables are different from each other.
Now if I try to add any other page which is common to both users like home page, Which library should be used.
I know there must be better solution to handle multiple user problem.
Please let me know where I'm doing wrong. And what should I do to tackle this problem.
You're right, there's a better way to handle this. Duplicating your user / registration system is the wrong way to go.
You'll need to modify TankAuth to include a user type column, and then check for that user type. I'd suggest a new column in the 'users' table for 'user_role':
https://github.com/ilkon/Tank-Auth/blob/master/schema.sql
You could handle the user_type as either an int or enum. I'd lean towards int since enum is harder to change later. You could also add a new table for user_roles but I usually just store these in a config file.
Once the schema is altered, you'll need to add a reference to the new column (along with possible options) in the Tank_Auth code. You'll need to include it in creation, update (data is passed to model from the tank auth controller: controllers/auth.php) and lookup functions. I would add a lookup by user_role as well to the tank_auth model (application / models / tank_auth / users.php):
function get_user_by_role($role)
{
$this->db->where('LOWER(user_role)=', strtolower($role));
$query = $this->db->get($this->table_name);
if ($query->num_rows() == 1) return $query->row();
return NULL;
}
Lastly, you'll want to set the user role to session on login so that you can track the user type (and what content / functionality they have access to).
I've used Tank_Auth myself for several projects.
building on what calvin said, codeigniter does a good job a securing your application, tank auth will verify them, however you need different user levels, this usually falls under permissions. Your job as a developer is to make sure codeigniter does it's security checks via CSRF & XSS( I would suggest you do this in each validaton rule, rather than globally, especially If your admins need to add any tags not allowed suc as "script"). you can see how I personally setup my controllers regardless of my Auth library here...
You need to have a row in your users table called "permissions" which is either a serialized array or json encoded, or you can do a google search on permission bitmasking, which requires an int field

Creating a User Login System: Put logic in Code or Database

I am trying to create a login system thats generic so that it can be adapted for use in various apps. I decided that 2 main "parts" of the system will be User Meta Data & Roles/Resources/ACL.
1. Metadata
I thought of keeping most data like what meta data are available for users in the database, so that admins can manage them using some GUI.
Problem is how can I then configue how I want inputs to render (textbox, checkbox, radios etc.). Then another problem is validation, filters.
2. ACL
I think for simple ACL it will work fine. But suppose I want say users to be able to modify posts they own. In Zend_ACL that is accomplished with Assertions. I thought that will make a "simple" login system overlly complex? Also it will be hard to build I suppose?
Currently I have my database like
Logging in users: I recommend using a separate controller (call it Auth for instance) that has loginAction and logoutAction. Zend_Auth (Zend_Auth using database) will check the database for the right credentials. Once the user is verified, you will save it in the global accessible place(the Zend_Auth class has methods to do this). This is also a good moment to query which roles the user has and store them.
Metadata part of your application: I'm not sure what the question is exactly but I assume you want to store dynamic information about user and have a GUI for admins to manage this. Why you would render different types of controls? Validating the information can be done by defining a lot of the most common metadata (like Twitter) and create rules for them. In the save action for the metadata you would validate using these rules.
ACL: Resources rarely change, you are better off putting them in a configuration file (for speed). You should give a lot thought to resources: what are they exactly to you? Controllers? Modules? Create a plugin that will preDispatch every request checking the role of the logged in user against the requested resource. E.g.:
$action = $request->getActionName();
$controller = $request->getControllerName();
// role, resource, privilage
if (!$acl->isAllowed($user->role, $controller, $action) {
//go to access denied page!
}
Now that Zend_ACL is used for the global access rules, you are better off checking for specific access inside the action itself (like if ($loggedInUser == $article->author) {//edit the article};).
Also don't forget Zend_ACL can be integrated with Zend_Navigation to hide menu items users are not allowed to use (and more).

Categories