1.0.4 • Published 6 years ago

flexrole v1.0.4

Weekly downloads
2
License
MIT
Repository
github
Last release
6 years ago

FlexRole

Getting Started

To get started working with this express middleware, include the library using the app.use directive.

First, add the package from NPM.

npm install --save flexrole

Second, define a function which returns a uniquely identifying attribute about your user. This function will be used by the middleware to retrieve their groups from the file. You can use request as an input for this function, as it will be called by the middleware at the time of a request. For example, you might define a function like below that returns a user id number for a given user.

const myFn = (req) => {
    //... connect to a database
    //...
    //... select user id from the user's data row
    //...
    return user.id;
};

You can use any sort of data to identify a user: a user id, a unique username, etc. -- however, it is suggested that this data be unmodifiable to preserve the integrity of the back-end configuration.

Additional Notes about the handler function:

  • The function should return a unique property about the user. It needs to work in the context of the middleware.
  • One idea is to return a string value of __GUEST__ if the user is not signed in. Using this method, you can create a user file in users.json and assign it groups that will be assigned to a non-authed user.

Third, create an Object which defines what permissions should be applied to the route.

const myRouteGuardProfile = new Object();
myRouteGuardProfile["GET"]["/api/v1/users/create"] = {
    test: [
        {
            "permission": "b_users_create",
            "required": true
        }
    ]
}

In the above example, all of the permissions listed in the test property will be checked whenever the user access the route GET /api/v1/users/create. The first array dimension is the HTTP verb, the second is the noun string.

Fourth, define the middleware as in-use by express and pass in the identifier function and route map into the middleware. By wrapping the middleware in another middleware (and treating both of them as one), we can respond to the result of the permissions check and respond accordingly.

const flexrole = require('flexrole')({
    identifierFunction: function(req) {
        return "username_here";
    },
    routeMapping: myRouteGuardProfile,
    verbose: true,
});

app.use((req, res, next) => {
    console.log('=> Checking permissions.');
    const result = flexrole(req,res,next);
    console.log(result);
    if (!result) {
        return res.json({
            error_code: 1,
            error_message: "some error message here..."
        })
    }

    next();
});

Finally, configure how the permissions API will handle requests, and assign permissions to your routes using the appropriate functions (see function reference).

Configuration Reference

flexrole_config.json

This file is located in the directory from which Express was launched.

"system": {
    "working_directory": ".",
    "allow_sysadmin": false
}
PropertyTypeDescription
system.working_directoryTextDetermines where the middleware's backbone files will be stored. A '.' is the default and refers to the working directory for the current express instance. A blank value here will be interpreted as the server root (/).
system.allow_sysadminBooleanDetermines if a group with sysadmin set to true will be granted all permissions. This is a dangerous setting, so it is set to false by default.

groups.json

This file is located in the specified working directory.

{
    "groups" : [
        {
            "id": 1,
            "priority": 100,
            "title": "Example Group",
            "sysadmin": false,
            "permissions": [
                { 
                    "node": "b_test_permission",
                    "value": true
                }
            ]
        },
        ...
    ]
}
PropertyTypeDescription
idNumberA numeric value which will identify this group.
priorityNumberA numeric value designating the order in which this group will load its permissions into a composite scheme.
titleTextA text-based name for this group. UTF-8 formatting is preferred.
sysadminBooleanA boolean value designating if this group will be granted all permissions.
permissionsArrayAn array of permission objects with a node and value property. Node refers to the permission node title, value refers to this group's value for that given node. Value must match the type assertion made by the definition for this permission in nodes.json.

nodes.json

This file is located in the specified working directory.

{
    "nodes": [
        {
            "node": "b_test_permission",
            "description": "Controls if a user can access something.",
            "type": "boolean",
            "default": {
                "use": true,
                "value": false
            }
        }
    ]
}
PropertyTypeDescription
nodeTextA text-based title for this permission node.
descriptionTextAn optional description for this node, for implementer use only. Not used by the system.
typeTextA text-based type for this permission node. Permitted Values: boolean, number, string, object
default.useBooleanA boolean value which governs whether a default value will be loaded into each group (otherwise it will remain an anonymous permission)
default.valueanyThe value of the default to be used if default.use is true.

User Files (user-identifier.json)

This file is located in the specified working directory, within a subfolder called users. Each user has a user file. If the file does not exist when the system attempts to read a user's permissions, a file will be created with the name user-[identifier].json where [identifier] is the value returned from the specified identifier function passed to the middleware.

{ "groups": [] }
PropertyTypeDescription
groupsArrayAn array of strings where each string is the name of a properly-defined permission group.

Notes about user files:

  • This will be stored as a unix-based file. There are certain characters which should be checked for and sanitized away in your identifier function. These characters are readily available on the Internet, but some of them include |, *, .., ., \, and other characters which may pose issues. Implement your identifier function with all sanitization done ahead of time, as the middleware does not do this for you.
  • Ensure that Express has the ability to write files into the working directory (wherever you set that to be).

What does it do?

Flexrole is a good way to manage groups of users which might be hitting your API. You can also assign properties to groups, in addition to explicit permissions. Some cool ways to use this might be:

  • Assigning permissions to GET a certain route.
  • Assigning a group-based rate limit using a numeric property attached to a group.
  • Assigning permissions to guest users using a defined schema.

What does it actually do, though? It...

  • Loads permission nodes and groups from files and builds composite permission schemes based on group priority.
  • Receives a request and, based on the user's defined identification function, loads a permissions schema for that user then tests for one or more permission criteria.

What doesn't it do?

Flexrole doesn't handle your rate limits (but that is a good application of flexrole group management). It also doesn't respond to permission refusals for you -- to do this, use the example in the Getting Started section. By wrapping the flexrole middleware call in another middleware, you can respond to the result of the permission test.

Contributing

If you want to contribute to this software, please fork it and submit a pull request when finished. The following guidelines apply to any pull request:

  • Code must be relatively well-documented.
  • It has to work...
  • Any added dependencies must be licensed under the MIT license.
  • The contribution itself, as a derivative work, must be licensed, with unlimited and irrevocable permission for use, under the MIT license.

License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.