access control

A place for users and developers of the Xataface to discuss and receive support.

Postby compudude86 » Mon Sep 25, 2006 8:56 am

hi,
i want to make it so only certain people can edit and other people can only view, based on the user/password they give. i was thinking to use mysql users to do this-for compatibility purposes, but how would i go about implementing this?
compudude86
 
Posts: 59
Joined: Wed Dec 31, 1969 5:00 pm

Postby njw » Mon Sep 25, 2006 9:23 am

njw
 
Posts: 280
Joined: Wed Dec 31, 1969 5:00 pm

Postby compudude86 » Mon Sep 25, 2006 9:35 am

aahaa! thank you very much for pointing that out!!
compudude86
 
Posts: 59
Joined: Wed Dec 31, 1969 5:00 pm

Postby njw » Mon Sep 25, 2006 10:42 am

No problem :)
njw
 
Posts: 280
Joined: Wed Dec 31, 1969 5:00 pm

Postby compudude86 » Tue Oct 17, 2006 11:13 am

ok, i set it up, any idea how i would be able to "jail" a user to a certain table by username? lets spread this out:

i have 3 users, and tables A-C:

user 3 may view and edit table A, but not b and c, user 2 may only control table b, but not a or c, and user 3 can only read table c, and cannot even see a-b. is that type of thing possible in the authentication systems?
compudude86
 
Posts: 59
Joined: Wed Dec 31, 1969 5:00 pm

Postby shannah » Tue Oct 17, 2006 4:55 pm

Okay.. there are two issues to consider here.

1. Security - making sure that users cannot use the tables/records/fields that you don't want them to.
2. Usability - making the applications flow work properly for the user at hand.

On the security side of things, it is easy to "jail" a user. Simply define the getPermissions() methods on the three tables in such a way that the appropriate permissions are returned for each user. In your example above you would define the getPermissions() method for the A table as:

Code: Select all
function getPermissions(&$record){
    $auth =& Dataface_AuthenticationTool::getInstance();
    $user =& $auth->getLoggedInUser();
         // $user is a Dataface_Record encapsulating the currently logged in user.
   
    // first let's deal with the case that the user is not logged in.
    if ( !$user ) return Dataface_PermissionsTool::NO_ACCESS();
    if ( $user->val('userid') == 3 ) return Dataface_PermissionsTool::ALL();
   
    // If i understand the specs correctly, then user 3 is the only one that can access table 'A' at all
    // so we revoke access to everyone else.
    return Dataface_PermissionsTool::NO_ACCESS();
}



You would do similar things for the other tables to make sure that only authorized users can access them.

On the usability side, there are a number of things that you can do to tailor the application to your needs here.
The permissions will help a lot, but you may end up with a situation where users see "Permission denied" alot. This is where you have to tell your application to be "smart".

This is a fairly big topic that deserves a lot of space and discussion, but I'll begin by listing some of the more common hurdles:

1. The table tabs at the top of the app show up the same for each user - what if you want some tables to be hidden for some users.
2. If no table is specified in the URL, then the user is always directed to the first table in the tables menu. What if you want this to depend on which user is logged in?
3. The default action is 'list'. What if you want this to be different?
4. Some parts of the application may be confusing to some users, and are better hidden (e.g. how to hide the search box).


There may be more issues but their solutions will be similar.

Solutions:

1. The table tabs, for performance reasons, are just statically generated.. they don't take into account any permissions. Of course if a user clicks on a table that he has no access to he'll receive a permission-denied error. So how do we get around this.
a. You could remove these tabs altogether. You can do this by defining a getPreferences() method in the Application's delegate class. This will return an associative array of preferences. see http://framework.weblite.ca/documentation/manual/delegate_classes for more on this.
b. You could override this slot with your own tabs using the 'table_tabs' slot in the Application's delegate class.
e.g:
Code: Select all
function block__table_tabs(){
    $auth =& Dataface_AuthenticationTool::getInstance();
    $user =& $auth->getLoggedInUser();
    // ... now display table tabs depending on who is logged in.

}


.. more later.. i'm out of time for now....

Please let me know if there are particular aspects that you are more interested in so that I can target the response..

best regards

Steve
--
Steve Hannah
@shannah78 (on twitter)
sjhannah.com blog
shannah
 
Posts: 4457
Joined: Wed Dec 31, 1969 5:00 pm

Postby compudude86 » Fri Nov 10, 2006 12:26 pm

ok, i think i just made it more complicated.......

for example......
john doe works for company A, so when he uses his username or password, i want him to only get into (database:DIST table:COMPANY-A), and nothing more. only his username, only that database and table. now, jane doe, works for company B. therefore, she can only access (database:DIST table:COMPANY-B), not company A. then, you have john smith, hes not a distributor, so hes not allowed anywhere near (database:DIST), hes only allowed in (database:BOOK table:PRODUCTS) and he is not allowed editing rights(which i think ive got that figured out so far with the read only/admin priveledges set up) i dont know if it makes any sense, basically i need to access two different database sets, with different permissions, from the same "application"
compudude86
 
Posts: 59
Joined: Wed Dec 31, 1969 5:00 pm

Postby shannah » Fri Nov 10, 2006 5:54 pm

Dataface applications are made to interact with only a single database - but it may be possible to work around this "limitation" for your purposes.

A little-used feature of the df_init() method is that it can take an optional third parameter - an associative array of options that are used as the conf.ini options. This will allow you to theoretically connect to multiple databases (you would choose which database you need to connect to at the beginning of your application's index.php file.

For example:
Code: Select all
require_once '/path.to.dataface/dataface-public-api.php';
$conf = parse_ini_file('conf.ini', true);
if ( $_REQUEST['-db'] == 'BOOK' ) $conf['_database']['name'] = 'BOOK';
else $conf['_database']['name'] = 'OTHERDB';

df_init(__FILE__, '/url.to.dataface', $conf);
$app =& Dataface_Application::getInstance();
$app->display();

?>


Then from anywhere in your application (e.g. your triggers, etc..) you can always find out which database you are using by:

Code: Select all
$app =& Dataface_Application::getInstance();
$db_name = $app->_conf['_database']['name'];




An alternative strategy (which is probably better) is just to have separate dataface applications for each database. If there are common elements between the databases you can use symbolic links to share common configuration files, etc..

One bit of curiosity, is why use multiple dbs? Why not just use one db?

Hope this helps a little.

-Steve
--
Steve Hannah
@shannah78 (on twitter)
sjhannah.com blog
shannah
 
Posts: 4457
Joined: Wed Dec 31, 1969 5:00 pm

Postby compudude86 » Sun Nov 19, 2006 6:35 am

i see. two reasons for the multiple databases, 1. the distributors cant look at the other distributors products, as its in contracts that their pricing cant be viewed by the other distributors, and 2 because we will be taking the distributors databases and appending them to the main database after we verify them. theres something like 7-9 distributors, each must have their own table, which can only be pulled up by the right user. basically, i want to define the proper DB, table, and permissions by the username.
compudude86
 
Posts: 59
Joined: Wed Dec 31, 1969 5:00 pm

Postby Aoirthoir » Sun Nov 19, 2006 8:46 pm

I'm personally using multiple databases to keep information organized by type. All customer tables in one DB, all vendor tables in another etc. Also since I am using VMware Server Edition, and currently running an Ubuntu LAMP within that, Ive got soft links from /var/lib/mysql/tablename to /media/somevirtualdrive which allows me to keep all of my related tables on its own virtual drive..so a back up is real easy. Ive got to keep the DBs seperated in that case to insure they remain 4gig or less each. A bit of work..but in the long run its saved me lots and lots of time with restores.
Aoirthoir
 
Posts: 420
Joined: Wed Dec 31, 1969 5:00 pm

Postby compudude86 » Mon Nov 20, 2006 11:35 am

i see. so is there a way to assign a database:table by user? so lets say user a logs in, the app knows that user A is supposed to get user:book but user B is supposed to get dist:companyB ? if that makes sense
compudude86
 
Posts: 59
Joined: Wed Dec 31, 1969 5:00 pm

Postby shannah » Mon Nov 20, 2006 3:53 pm

yes this is possible.. but it will require at least a little PHP, depending on which way you do it.

Is it possible to have different users access it at different subdomains? E.g. users from companyB log in using
companyB.yourdomain.com
and users from company A log in using
companyA.yourdomain.com

That way you can easily extract which database you want to use via the $_SERVER['HTTP_HOST'] variable.


Then, altering the example from the above post:
Code: Select all
require_once '/path.to.dataface/dataface-public-api.php';
$conf = parse_ini_file('conf.ini', true);

list($company) = explode('.', $_SERVER['HTTP_HOST']);
      // extracts the first part of the domain from the request.
      // e.g. if the domain was companyA.yourdomain.com, then $company
      // would now contain the string 'companyA'


$conf['_database']['name'] = $company;
      // Let's assume here that all of our databases are named after companies
      // e.g. databases:  companyA, companyB, companyC, etc...
      // Then this will set the database's name to that company

df_init(__FILE__, '/url.to.dataface', $conf);
$app =& Dataface_Application::getInstance();
$app->display();

?>


Hopefully this helps you a little with the idea.

-Steve
--
Steve Hannah
@shannah78 (on twitter)
sjhannah.com blog
shannah
 
Posts: 4457
Joined: Wed Dec 31, 1969 5:00 pm

Postby njw » Tue Nov 21, 2006 3:29 am

Could you do this from a User table? Perhaps always connect initially to the first database, go through login, get the correct database from the user table row and then switch if necessary.

I am still a bit at a loss as to why you need more than one database though, as you should be able to put all the tables into one database and then use permissions to allow users to access individual tables. It would make management of the data simpler!
njw
 
Posts: 280
Joined: Wed Dec 31, 1969 5:00 pm

Postby shannah » Tue Nov 21, 2006 2:12 pm

Yes.. this is a clever idea.
I suppose that at any point of your application, you could make a call to mysql_select_db() and switch databases.

Clever .. very clever...

-Steve
--
Steve Hannah
@shannah78 (on twitter)
sjhannah.com blog
shannah
 
Posts: 4457
Joined: Wed Dec 31, 1969 5:00 pm

Postby Aoirthoir » Tue Nov 21, 2006 5:21 pm

Then this is something I definitely want to explore. It would make things a lot easier. Even from the point of view of an app...say one DB for my vendors, the other for the patients and so on as mentioned. Then list those in the original DB...

So the initial path.to.dataface.app/index.php could simply be an entry way to multiple DF apps.

Also....a while ago you were working on storing the df settings in a DB instead of in ini files. And if I understand correctly..the ini settings are in variables..so couldnt we make our own calls to a DB and replace those values ourselves?

Thanks.
Aoirthoir
 
Posts: 420
Joined: Wed Dec 31, 1969 5:00 pm

Next

Return to Xataface Users

Who is online

Users browsing this forum: No registered users and 38 guests

Powered by Dataface
© 2005-2007 Steve Hannah All rights reserved