Access Control Config

Access Control has quite a bit of configuration which needs to be added in order to make it work. In each case, as we describe this, we will be using the configuration from Message Center to have a hands on example of how this will work. This configuration should be set up for each app in server/config/app.php.

Resources

The most important configuration, which must be set in order for access control to function. You need to ensure that all of the different resources that are added in this configuration are also added to the database using the accessUp function that will be described in the next unit (though this can only be done AFTER you have set up configuration, as that function gets information from here). Any time these resources are changed, you will need to have a corresponding database migration to change the access table.

The name of the resource can be anything you want, but it should be recognizable (most likely it should be the name of the model upon which you are setting up rules). In the case of Message Center, the two resources are template and channel because those were the model names. Each resource should be set to an array with a variety of sub properties:

  • table This is the table that is already defined within the database for the resource (so that Access Control can properly setup a foreign key)
  • id This is the id field that is already defined as the AID or string ID field for the table which holds the resource (again so Access Control can properly link as a foreign key)
  • column This is the NEW column name for foreign key column on the Access Table, this should follow our usual naming standards for foreign keys.
  • type This should reflect the column type for the column on the Access Table. It should match the column type of the ID identified above (for AID's this would be integer or for others it will be string)

So, to put everything together then, the resource portion of the configuration is fairly simple, and should look something like this:

'access-control' => [
        'resources' => [
            'template' => [
                'table' => 'msgc_template',
                'id' => 'tempAID',
                'column' => 'FK_tempAID',
                'type' => 'integer'
            ],
            'channel' => [
                'table' => 'msgc_channel',
                'id' => 'chanAID',
                'column' => 'FK_chanAID',
                'type' => 'integer'
            ]
        ],
        ...
    ],

For ease of changing things, even if you only have one resource, you should probably just set this up as an array with a single item, rather than multiple (in case you decide to add another resource later), though some apps may follow a way of setting up only a single resource.

Types

Types is the only other configuration type that must be set up in a database migration, as described on the following page. Additionally, any time any types are added or removed, you must make sure to add or remove them in the database migration. This configuration is very important for the proper functioning of the app, though it is not necessarily required within this config field (there is a default, pre-defined types which will be used if the app does not pass them in). There are two general kinds of types, which should be discussed separately (though, all of these will be passed into the same types array in the config): user types and boolean types.

User Types

The user types are defined by default, and there are only three: dept, group, and user. This kind of type essentially tells Access Control what type of rule is being defined (whether for a group, a department or an individual user), which changes how users are verified behind the scenes and also changes how it is displayed using ember-fw-acl. You are not able to define more user types than these, but you are able to "turn off" these user types at will. If you override the types array, and leave out any of these three user types, you will not be able to make an access rule for that kind of user anymore (for example, you could limit Access Control within an app to only allowing rules for user and group, but not for dept). However, if you want all three types, and you override the array, you will need to ensure you include all three types within the types array. Additionally, leaving out a user type will do so for ALL resources, there is not a way to turn off selecting a department for one resource and not another.

Note: Within the code for Access Control, there is a fourth user type defined, which is role, but it is not fully functioning, so if Admin decide in the future to incorporate role fully as a user type, the code will need to be tweaked in a few places. Because of this however, you cannot call one of your Boolean types by the name role because it will not operate as you would expect (since it is a partially defined user type).

Boolean Types

The second kind of type is boolean types, and this is where you are able to dynamically control the rules to be as granular or as general as you want. There is one mandatory boolean type, which is used by Access Control internally (to allow a user to edit permissions or not), and that is edit. By default, this is the only type that is defined, unless the array is overridden. Some apps only use this to distinguish between those who can edit the resource (meaning edit, delete, edit permissions, and have full access to do anything) and those who can't. Many apps choose to be more granular than this, but if you decide to be more granular, then you need to at the least include edit.

When it comes to deciding on the different Boolean Types, this is a design feature, and must be considered along with the admin to determine how specific the access rules need to be. For the more granular rules, you will need to ensure when you are using the access engine, that you are properly implementing these boolean types in order to limit user's access to the Model appropriately. It is also important to realize that it is best practice to have distinct Boolean Types for each resource (though this is not necessarily required if the Boolean Types are general enough). Individual resources can be different levels of granular/generic depending on design choices (for example, you might have one resource that only uses the edit field, and another that defines 5-7 other Boolean Types).

In all, Boolean Types are by design extremely flexible, and so will be different in every app which incorporates Access Control. These can also be added in a later release than the initial release if admin decide they want there to be more options in Access Control.

Example

So, now that we have described the different types, Message Center used several Boolean Types for both resources. It is usually helpful to delineate the different resource types via comment to help future developers, as Message Center did:

'access-control' => [
    ...
    'types' => [
        //default user types since we are overriding from access control
        'dept', 'group', 'user',
        // template permissions, edit lets you edit permissions
        // edit is internal to access control
        'edit', 'overrideFrom', 'editTemplate', 'deleteTemplate',
        //channel Permissions
        'channelEdit', 'channelDelete', 'postThread', 'editThread', 'editAllThread', 'deleteThread',
        'deleteAllThread', 'unpinThread', 'unpinAllThread', 'manageNotifications'
    ],
    ...
],

Notice that Message Center did not define edit twice (once for each resource), but only once, and this is the only proper way to do this. All resources must implement edit feature at the least to control the Edit Permissions feature of the resource (as this is internal to Access Control), if not more.

Permissions

The final important configuration to mention is the access-control.permissions, which controls who has access to set access rules for which user types. Permissions is an array of roles within the app. If a role is not in the permissions array, then that role is not allowed to create or edit Access Control rules. For each role, you are able to setup permissions in a few different ways:

  • All Permissions - If you just want to give a specific role unlimited access to all user types within Access Control in this app, you can set that role to true, and they will have access to all roles.
  • Limited Permissions - You are also able to limit the permissions settings to only be able to add rules for certain user types. In this case, the role is set to an array, which contains the user types you wish to give access to, which are set to true. If a user type is not included in the array for that role, then it defaults to not having access to that type. In addition to this, there is a self option, which allows you to set up or change permissions in Access Control only for yourself.

Note: These permission settings do not override the edit permission on each specific rule. If a user does not have access to edit the permissions for that item, they will not be able to regardless of settings here. What these settings determine is that assuming a user has access to edit Access Control permissions for an item, which user types is he or she able to set for a rule.

As an example of the different ways you might see permissions set up, here is a fictional permissions configuration to one way that you may use this configuration (these are not all the options, one could even allow a specific role to only be able to set for groups or only for the whole department, etc, but this gives you an idea):

'access-control' => [
    ...
    'permissions' => [
        //global-admin has access to all user types
        'global-admin' => true,
        // admin can add/edit rules for a user or group, but not a department
        'admin' => [
            'group' => true,
            'user' => true
        ],
        //supervisor can only add a rule for individual users, not for depts or groups
        'supervisor' => [
            'user' => true
        ],
        //base users can only manage rules for themselves, not for anyone else
        'base' => [
            'self' => true
        ],
        //any other role in this app, such as stats or robot, would be unable to add rules at all
    ],
],

Other Less Used Config Options

There are a few other options which can be put in the access control config, but probably will not be used. These have pretty standard defaults, but there is an option to override them if the opportunity requires it.

  • Table You are able to override the name of the access table, by changing access-control.table property in the config. By default, the access table is set to {appID}_access (so for Message Center, the table is msgc_access). The only time you would need to change this table is if you already had a database table for your app that was named according to the default, so you needed to distinguish.
  • ID You are able to change the name of the AID on the access table by changing the access-control.id property. By default this property is accessAID, and it probably should not be changed unless you have to change the table name.
  • Columns You are able to override any of the column names for the access table for any of the types, by simply putting them in the column associative array by their type. For example, access-control.columns => ['edit' => 'isEditPermissions'] would override the default column database name for the edit property to "isEditPermissions" instead of "isEditAllowed." This config is not recommended to be used unless there is a very specific need, as the default names are usually pretty solid, but it is there in case you have a use case for it. Here are the defaults:
    • The column name for user defaults to FK_userID
    • The column name for group defaults to FK_groupAID
    • The column name for dept defaults to FK_deptID
    • The column name for edit defaults to isEditAllowed
    • The column name for any booleanType defaults to is{BooleanType} (for example, the column name for overrideFrom from Message Center defaults to isOverrideFrom)