...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
Introduction
...
In the Basic Service example, we learned to perform a heartbeat check on a service, in order to monitor its health.
...
Moreover, the example teaches how to benefit from multitenancy, and how to configure ACLs, in addition to securing the APIs using tenant keys.
Code Walkthrough
...
This page shows you how to interact with the example03 & URAC servicea after you install them and run them. It also demonstrates how SOAJS implements multitenancy.
The code walkthrough is located in a sub page and explained in depth. Click here to read the explanation.
URAC Installation
...
SOAJS User Registration & Access Control (URAC) is a service that manages the Users records and their Access Controls.
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
# go to soajs directory cd /opt/soajs/node_modules # install urac npm install soajs.urac # go to urac directory cd /opt/soajs/node_modules/soajs.urac # export necessary environment variables export SOAJS_PROFILE=/opt/soajs/node_modules/soajs.utilities/data/getStarted/profile.js export SOAJS_ENV=test export SOAJS_SRVIP=127.0.0.1 # run urac node . |
URAC is now running on http://127.0.0.1:4001 and will be used to login with different users. Therefore, its maintenance port is 5001.
Next, a heartbeat request is sent to check the health of the URAC service.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
curl -X GET "http://127.0.0.1:5001/heartbeat" |
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{"result": true,"ts": 1425372634090,"service": {"service": "urac","type": "rest","route": "/heartbeat"}} |
Service Exploration
...
Run the Service
Code Block |
---|
# go to correct directory cd /opt/soajs/node_modules/soajs.examples/example03/ # export necessary environment variables export SOAJS_PROFILE=/opt/soajs/node_modules/soajs.utilities/data/getStarted/profile.js export SOAJS_ENV=test export SOAJS_SRVIP=127.0.0.1 # start service node . |
The service is now running and listens on port 4012. Therefore, its maintenance port is 5012.
Next, a heartbeat request is sent to check the health of the service.
Code Block |
---|
curl -X GET "http://127.0.0.1:5012/heartbeat" |
...
Code Block |
---|
{"result":true,"ts":1425372737466,"service": {"service":"example03","type":"rest","route":"/heartbeat"}} |
Tenant Level Access Control
...
Using the Service APIs
As mentioned previously, this example is multitenant. Therefore, this tutorial simulates several tenants, which will be used across the examples that follow.
...
in order to efficiently share the resources between tenants and clients, while protecting their data.
buildName using application1: Tenant1, package1
As stated above, tenant1 possesses two applications. This examples shows a request to use the buildName API, sent using the external key of tenant1 using package1, which
does not have access to any of the service's APIs. The response should be an error stating that the user is not allowed to access the service API.
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{"result": false,"errors": {"codes": [154],"details": [{"code": 154,"message": "Access denied: The service is not available in your current package."}]}} |
buildName using application2: Tenant1, package1, overriden package
Next, the same API is requested. However, this time, the external key generated for the second application is used.
...
More importantly, the response containts the name of the tenant that requested the query.
buildName using application3: Tenant2, package2
The same API is going to be called again. However, the external key of the third application (tenant2, package2) is used.
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{"result": true,"data": {"tenantName": "Client Two","fullName": "John Thomas"},"soajsauth": "Basic c29hanM6czAxMjlsdlY5QTBZOW5Xd1JFVjJ0NEF0NXVyQjBtQkNydmc="} |
testGet using application3: Tenant2, package2
Using the third application (tenant2, package2), a request for the second API (testGet) of the service is going to be generated. Since this application has access
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{"result": true,"data": {"firstName": "John","lastName": "Smith"},"soajsauth": "Basic c29hanM6czAxYjd3N0NpUWtpVlMtbWsxcG1NbUZDSDNUYmQzSWZzbWk="} |
buildName using application4: Tenant3, package3
Application4 gives tenant3 access to buildName API only. In order to test the validity of this statement, the next request uses API buildName with the external key of application4.
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{"result": true,"data": {"tenantName": "Client Three","fullName": "John Smith"},"soajsauth": "Basic c29hanM6czAxb0VPakE3NTc3djh4MnNlYmVXVm5Tc0pDNVU5Y3pVYlM="} |
testGet using application4: Tenant3, package3
Application4 however, does not have access to testGet. Therefore, requesting this API with the corresponding tenant key of the application 4 should result
...
Our documentation provides a detailed explanation for the concepts of multitenancy and productization.
User Level Access Control
...
The examples above clearly exploit multitenancy using SOAJS, on the tenant level. Indeed, SOAJS permits several tenants to share the same resources (i.e., application, service, etc..).
...
User | tenant | Overrides Package | Overrides Tenant | buildName | testGet | Custom Tenant Information |
---|---|---|---|---|---|---|
User1 | Tenant1 | NO | NO | NO | NO | NA |
User2 | Tenant1 | YES | NO | YES | YES | Changes the tenant name |
User3 | Tenant1 | NO | YES | YES | NO | Changes the tenant name |
The above table shows three users. Each user has the ability to override the permissions their tenant, and its attributed package.
The examples that follow aim to present how a user can override the ACL permissions of the tenant it belongs to AND/OR the package that the tenant is using.
In addition to that, the examples will show that the user also has the ability to change these configurations, which, in this case, is "tenant name".
User1 Tests
URAC Login
Before using the service APIs, a user must be authenticated to the service. Each of the three users has a password. The first step would be to login to URAC
...
Code Block | ||
---|---|---|
| ||
(/opt/soajs/node_modules/soajs/servers/service.js:667 in logErrors): Access denied: The service is not available in your current package. |
User2 Tests
URAC Login
Similar to user1, the example below accesses the URAC service with the user2 account, in order to receive an authentication key.
...
The corresponding response prove the above statement. User2 overrode the package ACL and obtained full access to the service's APIs
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{"result":true,"data":{"firstName":"John","lastName":"Smith"},"soajsauth":"Basic c29hanM6QzAyWWNjQXdaSDBYSnhTMkJ5ejAzZG5RZ1BOdXFFd0d4UmM="} |
User3 Tests
URAC Login
The following request logs in to URAC using user3.
...
Code Block | ||
---|---|---|
| ||
(/opt/soajs/node_modules/soajs/servers/service.js:667 in logErrors): System api access is restricted. api is not in provision. |
Conclusion
...
In conclusion, multitenancy, productization and urac are efficient concepts that allow the tenants and users to share the available resources, in an optimized way, while respecting the privacy of each tenant/user's data,
...