views:

48

answers:

1

We're developing a web app using the Zend framework and Mysql.

Currently, accounts are unique by email address. We want to be able to allow the admin of an account to grant access to the admin of another account. This person would then be a "user" of the linked account. The account holder would then log into their admin account and then select which linked account they want to access.

Please note: the access should only be one way. Account 1, who grants access to Account 2, should not be able to access account 2. Only account 2 can access account 1. If Account 1 wanted access to account 2, account 2 would then have to grant access to account 1.

What is the best method of going about this?

+1  A: 

I think trying to tie permissions to accounts is your problem, you need to add a second 'layer'. Let's stick with Google Analytics as the example:

Let's say Joe Bloggs wants to use Google Analytics. He first has to create a Google account (assuming he doesn't already have one). He then creates a Google Analytics account for his site. Say Joe then wants to give access to Jane Smith, let's assume she already has a Google account. To give her access all he is doing is giving her Google account access to his site, he's not giving her access to his Google account.

Zend_Acl is role based so let's try and apply ZF concepts to this example. The user management screens in GA allow you to give users either "View reports only" access, or "Account administrator". So you'd define a role in Zend_Acl for each of these access levels:

$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('guest'));
$acl->addRole(new Zend_Acl_Role('admin'), 'guest');

the second parameter on addRole means the role should inherit all permissions from the other role specified. So what I've done above is define two roles: guest and admin; and said admin should inherit all permissions that guest has.

You then have your 'resources', which are the things that can be accessed. So we'll define one for reports, and one for user management:

$acl->add(new Zend_Acl_Resource('reports'));
$acl->add(new Zend_Acl_Resource('users'));

we'll then give 'guest' access to reports, and 'admin' access to users:

$acl->allow('guest', 'reports');
$acl->allow('admin', 'users');

then in the relevant controllers (or plugin, or wherever) you can check permissions:

public function reportsAction()
{
    [...]

    // assume $role contains the role of the currently logged in user
    if (!$acl->isAllowed($role, 'reports')) {
        // show a permissions error
    }
}

public function usersAction()
{
    [...]

    if (!$acl->isAllowed($role, 'users')) {
        // permissions error
    }
}

As far as storing this in MySQL goes, you just need a lookup table that links users, sites (in this example) and roles:

userID | siteID | role
   1       1      admin
   2       1      guest
Tim Fountain