Demium auth library for Feathers
About
This project assumes the use of Feathers. An open source web framework for building modern real-time applications.
How to use
Installation
First time:
- Include a new file at root level called '.npmrc' with the following content
//registry.npmjs.org/:\_authToken=NPM_TOKEN (REQUEST IT TO THE TECH TEAM)
- Install the library with NPM.
npm i @demium/watchdog_feathers
Already implemented, just want to increase the version:
- Update the library with NPM.
npm u @demium/watchdog_feathers
Use
Now we must import the library in to different points of the service
- Import the library in
/src/app.js
file
const auth = require('@demium/watchdog_feathers');
- Add the following lines before middleware, services and channel configuration
auth.Watchdog.Set({
logger: logger,
service: '',
prefix: '',
app: app,
db: sequelize,
});
app.use(auth.Watchdog.Patrol);
Keep in mind:
-
app
is the express instance with feathers inside. -
sequelize
is the DB instance and should me configured before this code.
This action initialize the watchdog and put it as a middleware in the service, so from now on all the requests are going to pass through the wDog first and are going to be validated before reach the actual service.
- Import the library in
/src/services/index.js
file.
const auth = require('@demium/watchdog_feathers');
- Call the service discovery at the end of the configuration service calls with the following line
app.configure(auth.Watchdog.registerEndpoints());
Keep in mind:
Is very important the we call this function at the end of services registration, if we don't do this, the service discovery is not work as expected.
This action allow the wDog to run a service discovery and insert the endpoints available of the service in the permission table in order to map the privileges of each role.
Filters
The filters allows us to add extra dynamic rules to the access control. Each service must know the filters that has an impact in themselves and modify the behavior accordingly.
We must ask for the filters that we need and act based on the response. To do so, we need to put a hook to the application level in app.hook.js or under an specific service depending on the sub services and le logic that we have implemented.
Hook
By consistency we must create a file called filters.js
under src/hooks
folder:
// import the library
const auth = require('@demium/watchdog_feathers');
module.exports = (options = {}) => {
return async (context) => {
// to retrieve the user locations
// context.params.user.locations
// to validate a filter
// auth.Watchdog.mustFilter('FILTER_NAME')
// after retrieve the filter response, we must act accordingly
return context;
};
};
Locations:
Allows us to ask what are the user locations based in the roles that the user has. The result is an array of location uuids. To do so we must use the context as follow:
const locationsFound = context.params.user.locations;
console.log(locationsFound); // ['location_UUID_1', 'location_UUID_2']
Validate filter
To validate a filter we must call the Watchdog as follow:
const filterResponse = auth.Watchdog.mustFilter('FILTER_NAME');
console.log(filterResponse); // true / false
But also you can request more information about the filter sending the flag extraInfo to true like so:
// setting the second parameter to true we'll get extra info
const filterResponse = auth.Watchdog.mustFilter('FILTER_NAME', true);
console.log(filterResponse);
/*
{
filters_name: 'FILTER_NAME',
filter: true,
roles: [ 'ROLE_1', 'ROLE_2' ],
locations:
[ 'location_UUID_1', 'location_UUID_2' ]
}
*/
References
-
filters_name
The name of the filter that we requested -
filter
Flag that represent if the filter is true or false -
roles
The roles that are validating the filter, basically the roles that have true in the filter, the filter flag can be false but one of the roles can be true. -
locations
The user locations, can be more than one.
Hook Level
In both cases we add the hook in the same way, the only difference is the file that we use to add it.
To do so:
const validateFilters = require('path_to_the_hook_folder/filters.js');
module.exports = {
before: {
all: [validateFilters()],
// ...
},
// ...
};
- Service Level: We integrate the hook in app.hook.js
- Sub-service Level: We integrate the hook under the sub-service hook file.
Dependencies
Environments
- Add
GCLOUD_STORAGE_BUCKET
to match the firebase credentials project (credentials-demiumsuite-dev as default)
export GCLOUD_STORAGE_BUCKET=credentials-demiumsuite-dev
- Add
NPM_TOKEN
to match the token to retrieve and install the library in the environment:
export NPM_TOKEN=XXX
- Add
FILES_PATH
according to the environment that we are using devapi by default
export FILES_PATH='https://devapi.demium.com/v1/storage/'
Credentials
-
Add firebase credentials:
- On local:
- Get a firebase json key from GCP > IAM > Service Accounts > firebase-basics@demiumsuite-dev.iam.gserviceaccount.com > Create key
- Save it in the project root folder as firebase_basics.json
- IMPORTANT: Remember to add it to .gitignore file
- Get a firebase json key from GCP > IAM > Service Accounts > firebase-basics@demiumsuite-dev.iam.gserviceaccount.com > Create key
- On appengines: Provide a GCLOUD_STORAGE_BUCKET with the bucket that provides the firebase_basics.json file. Don't forget to update the file app_example.yaml with the following line: GCLOUD_STORAGE_BUCKET: ${GCLOUD_STORAGE_BUCKET}
- On local:
Handy functions
- If you need to use the user object, you will find it, in the services and hooks, as part of the params object:
- user: The user as a Watchdog.User object
The watchdog library also provides a class called injector that exposes convenience methods to inject the user to the feathers context in a hook context. For example, the Injector.Standard method returns a hook that makes the following assumptions:
- There are a user object into the context.params.headers.user feathers context.
- There are a object in context.data that implements the Host interface.
- There are a parameter, context.method, that have the feathers method that invoke the hook.
Result
The user must have a valid TOKEN
and the token must have the correct roles to allow the user to call the exposed endpoints service.
IMPORTANT INFORMATION
In order to set what and who can interact with the new service where the watchdog was integrated, it is needed to add it to https://bitbucket.org/demiumstartups/authorization_middleware/src/master/src/services.yaml. More info at https://demiumstartups.atlassian.net/wiki/spaces/DST/pages/785940481/Authorization+Engine