Implementing Access Control on the Clientside

While most of Access Control is actually implemented and controlled on the Serverside, through the database and Controller.php files, there is a decent amount that needs to be done on the client side as well. Of course, most fundamental of this is setup a way for the end user to select the Access Control permissions they want for a specific resource. This guide points out the broad contours of what is needed in order to have a functioning Access Control App.

Setting Up the Clientside Model

In order to properly use various Boolean Types on the client side, you need to make sure that your clientside model of each resource setup in the access-table has read only properties of all the Boolean Types. This means at the minimum each resource controlled by Access Control will need an edit property in its model on the client. You only need to add the Boolean Types used for that model. If you have properly set up the serverside Model in the toJson function, as documented here, you should have an awareness of which Booleans to be in the model. See the following two examples, which are the process of editing the clientside model for the corresponding toJson functions linked above.

In the first example, there were multiple custom Boolean Types (note the Boolean Types here are the inverse of what was in the array we checked against):

// this code would be in models/template.js
export default Model.extend({
    // ...
    // template permissions, (read only)
    edit: attr('boolean'),
    editTemplate: attr('boolean'),
    deleteTemplate: attr('boolean'),
    overrideFrom: attr('boolean'),
    // ...
});

In the second example (and this is the minimum of what needs to be done for each acl resource model), you would only need to have edit:

export default Model.extend({
    // ...
    // permissions, (read only)
    edit: attr('boolean'),
});

Configuring the Modal

The final set of configuring ember-fw-acl for the first time is making sure that each separate resource setup in Access Control has its own Access Control Modal. While technically, it is possible to set this up as a component, and not merely as a modal, in the apps we always use the access-control modal, and thus, there is really no reason that you should use anything but the modal to setup Access Control clientside. This introduction assumes you know the basics about how to setup make a modal, as documented here. The Access Control Modal is actually quite robust, and allows you to have a pretty large amount of control over how to configure it. The full API docs for the Access Control Component Mixin (which is essentially just made into a modal) can be found here, but we will highlight a few of the more important configuration options which are used in the app. Since this is a modal, of course, all of the configuration must be passed in through the model hash, an example will be given at the end including all of the described properties.

So now we will discuss some of the more important properties which are required, and then some of the optional ones which are very helpful. Remember that each of these is also described in the API docs, so if you want more information, about those described in detail or just mentioned, you can check there.

Required Properties

The only two properties of the model hash which are required in order for the various network requests in the access-control modal (which calls to Access Control serverside) are: id, which is obviously the id of the model you wish to edit the permissions for; and resource, which is the string name of the resource as it was set up in Access Control config (in the serverside setup). As was said above each resource for Access Control must have a separate access-control modal set up (since this resource must be defined differently in each case).

There are a few other properties, while not technically "required" in the sense that the modal will not function if these properties are left out, they are still necessary for the good functioning of the modal:

  • First of these is name, which is the name or title of the specific resource model you are editing. It should always be passed in because there is no default or behavior for if it is null, thus if it is not passed in, the title of the modal will be Access Rules for Resource "".
  • The next property is baseDesc, which is a simple string, and if this is set it will show up as an info icon next to the Base Permission checkbox. This should always be set to a short description of what the "Base" role in Access Control gives you (meaning you have a rule set up, but no Boolean Permissions, including the "edit" permission). This is important for explaining to the end user what the user can do without any special access, and should never be neglected.
  • The final property which is "required" is typeDesc, takes a key-value hash where the key is the name of the Boolean Type from the configuration, and the value is a string containing the description of that permission. For each Boolean Type that the typeDesc is set for, an info icon will appear behind its checkbox. This is required again so that the end user can understand what each permission does because oftentimes, the names alone are not clear enough to know what access they are giving.

Very Helpful Properties

In addition to these "required" properties, there are several properties that will very often be used in the access-control modal, though there may be times in which they are not needed (thus they are "helpful" and not "required"). They include:

  • typeNames is a property that takes a hash of key-value pairs, where the key is the name of the Boolean Type, and the value is a string, which is meant to override the display name. By default, the Boolean Types, when displayed as checkboxes, will use the sentence-case helper (thus a Boolean Type called myBoolType will display as My Bool Type), and this is usually sufficient. However, if you need to override this default behavior, that is what typeNames is for. This property is most often only used for the edit type to change it into Edit Permissions.
  • hideTypes is an array of Boolean Types, which will not be displayed in this modal. This will be used if you have multiple resources, and each resource has different specialized Boolean Types defined in Access Control.
  • typeCategories is an array of hashes that allow you to define broader categories to control the order and headings for your Boolean Types. If this is not defined, the Boolean Types will just display in the order they are placed in the configuration for Access Control. If they are defined here, it will be in the order you place them. Each hash takes two properties: name (a string of the Category name to be displayed), and types (an array of the different types you want to be in this category). Boolean Types are able to be displayed in multiple categories if you desire, but a type that is in hideTypes will not be displayed, even if it is included in typeCategories.

The other properties are used infrequently enough that you should check the API docs if you need them, but are not used frequently enough to comment upon. They include: disableLimitDept, readOnly, typeDefaults, and typeDependencies.

Conclusion

These guides should be enough to get you started on how to design the access-control modal, to help you be able to visualize the use of each of these properties, we have included a slightly modified example from Message Center (using the channel resource because it is more complicated) to show you each of these either required or helpful things. Here it is:

<FwFullscreenModal
    @modal="access-control"
    @size="md"
    @model={{hash
        resource="channel"
        id=currentModel.id
        name=currentModel.name
        disableLimitDept=true
        typeNames=(hash edit="Channel Permissions")
        hideTypes=(array "editTemplate", "overrideFrom", "deleteTemplate")
        baseDesc="This gives users 'read-only' access to the channel. They can see all threads and
          subthreads, both those pinned on the channel's main page, and the historical threads on
          the history page."
        typeDesc=(hash
            edit="This allows users to change permissions for themselves and other users."
            channelEdit="This allows users to edit the channel name and description."
            ...
        )
        typeCategories=(array
            (hash
                name="User Thread"
                types=(array "postThread" "editThread" "unpinThread" "deleteThread")
            )
            (hash
                name="All Threads"
                types=(array "reorderThread" "editAllThread" "unpinAllThread" "deleteAllThread")
            )
            ...
        )
    }}
    @close={{action "closeACLModal"}}
/>

Since typeDesc and typeCategories can get quite long, we have all but the first two entries, but you would need to make sure to include all your different Boolean Types in these two places. This modal also happened to use the optional disableLimitDept, though it didn't use any of the others.

Using the Permissions

When it comes to how to display certain things in the client side upon the basis of Access Control Permissions (such as, for example, showing a button only to those who have the edit permission), this is very simple because of the fact that all the Boolean Types are set up properly within the model of that resource. Thus, all you need to do is call this.get('model.boolName') in javascript or model.boolName in handlebars, which will be a boolean set to the proper value for the currently logged in user. Additionally, if you change permissions in the Access Control Modal, this should be to be able to control permissions for the user within this model automatically (so you shouldn't have to refresh your page, though sometimes you may).