Now that we have identified the user and know his role assignments, we can use that information to say which controllers and actions, and optionally which objects, he has access to.
As with authentication and roles, we don't need to instantiate a
separate access-control object on our own. Instead, the registered Solar_User
object has an
$access property that it sets up
Solar provides different adapters allowing you to discover access-control information from different backends. The current adapters shipped with Solar are as follows:
Solar_Access_Adapter_File: reads access control list from a plain-text file.
Solar_Access_Adapter_None: a null source; always reports that the user is denied access.
Solar_Access_Adapter_Open: another null source; always reports that the user is allowed access.
Solar_Access_Adapter_Sql: selects user access controls from a database table.
Note that these adapters are read-only. They do not create or manage access control lists for you, they only look up which the authorizations for a particular user and roles.
An authenticated identity will never change during the login period. However, access controls might change during the same session; e.g., being promoted from a moderator to an author while logged in. For this reason, the access adapters re-read the control lists from the storage backend on each new page request.
Solar uses a Solar_Access factory to create the adapter instance, so you need to configure the factory to create the kind of adapter you want to use for access control discovery. You can do so in the config file like this:
<?php $config['Solar_Access'] = array( 'adapter' => 'Solar_Access_Adapter_File', );
Now that we have told the factory what adapter to create, we need to configure the adapter itself. Access adapters are much easier to configure than authentication adapters, but each has its own settings. You can look up the config keys for each of them on the following pages:
For example, the configuration for a file-based access adapter to
use an access control list at
would look like this:
<?php $config['Solar_Access_Adapter_File'] = array( 'file' => "$system/config/access.txt", );
Access control lists have one row per entry, and each entry has five elements.
(string) Does this entry
(string) Does this entry specify to a user
'handle', a user
'role', or the
'owner'of a particular object? (More on "ownership access" in a later section.)
(string) If the entry type is
'handle', this identifies the user handle being controlled. There are two special values for this element:
'*'means "all users" (even anonymous/unauthenticated users), and
'+'means "all *authenticated* users".
(string) Alternatively, if the entry type is
'role', this identifies the user role being controlled. The special value
'*'means "all roles".
(string) Finally, if the entry type is
'owner', this value has no effect. You can leave it blank, or put in a
'*'if you want. (More on "ownership access" in a later section.)
(string) What class does this access control apply to? (Typically this is a page-controller class name.) The special value
'*'means "all classes".
(string) What action name does this access control apply to? (Typcially this is the name of a page-controller action.) The special value
'*'means "all actions".
Here's an example of a file-based access control list:
# flag type name class action # ---- ---- ---- ----- ------ # allow any user with an "admin" role access to all actions in all classes allow role admin * * # allow all users access to the actionRead() method in all classes allow handle * * read # allow only authenticated users access to actionComment() in all classes allow handle + * comment # allow only authors to add new pages allow role author Vendor_App_Page add # allow any user with a "moderator" role acces to Vendor_App_Comments::actionDelete() allow role moderator Vendor_App_Comments delete # deny all users access to Vendor_App_Page::actionEdit() ... deny handle * Vendor_App_Page edit # ... except for user authenticated as "kornblum" allow handle kornblum Vendor_App_Page edit
Control lists are processed from top-to-bottom, with later entries overriding previous ones.
Access controls are "deny by default", so if there's no entry for it, the control will be reported as "deny".
Let's say we are using the file-based access adapter to read from a file with the above entries. Let's also say that the user 'kornblum' has just logged in; he has only one role in the system ('moderator').
The Solar_User object, which has a Solar_Access_Adapter instance inside it, automatically goes to access control file and fetches the entries that apply to Kornblum. We can then use the following Solar_Access_Adapter methods to determine if Andy's should be allowed access to particular pages and actions. (Remember, we use a Solar_User object instead of instantiating a separate role adapter instance.)
<?php $class = 'Vendor_App_Page'; $user = Solar_Registry::get('user'); $user->auth->handle; // 'kornblum' $user->access->isAllowed($class, 'read'); // true $user->access->isAllowed($class, 'comment'); // true (if not logged in, false) $user->access->isAllowed($class, 'add'); // false (not an author) $user->access->isAllowed($class, 'edit'); // true $user->access->isAllowed($class, 'foobar'); // false (deny-by-default)