diff --git a/docs/api/accesscontrol.md b/docs/api/accesscontrol.md
index 757e35cc..269f37ad 100644
--- a/docs/api/accesscontrol.md
+++ b/docs/api/accesscontrol.md
@@ -63,6 +63,16 @@ Sets the API token for the object, to request a token create an account in http
| atokenpi | string | The API token to use to connect with TerminusX |
+## setApiKey
+##### accessControl.setApiKey(atokenpi)
+Sets the API token for the object, to request a token create an account in https://terminusdb.com/
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| atokenpi | string | The API token to use to connect with TerminusX |
+
+
## getAPIUrl
##### accessControl.getAPIUrl(cloudAPIUrl) ⇒ string
Get a API url from cloudAPIUrl
@@ -80,10 +90,35 @@ Get all the system database roles types.
**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+## getAllOrganizations
+##### accessControl.getAllOrganizations() ⇒ Promise
+This end point works only in basic authentication admin user
+Get all the system organizations list
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+
## createOrganization
##### accessControl.createOrganization(orgName) ⇒ Promise
-Any user can create their own organization.
-IMPORTANT This does not work with the API-TOKEN.
+This works only in the local database
+TerminusX - Any user can create their own organization. -
+TerminusX - IMPORTANT This does not work with the API-TOKEN.
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| orgName | string | The organization name to create |
+
+**Example**
+```javascript
+accessControl.createOrganization("my_org_name").then(result=>{
+ console.log(result)
+})
+```
+
+## deleteOrganization
+##### accessControl.deleteOrganization(orgName) ⇒ Promise
+This api works only in the local installation
**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
@@ -271,6 +306,45 @@ accessControl.getTeamUserRole().then(result=>{
{"userRole":"Role/admin"}
```
+## getTeamUserRoles
+##### accessControl.getTeamUserRoles([userName], [orgName]) ⇒ Promise
+Get the user role for a given organization or the default organization,
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| [userName] | string | The organization name. |
+| [orgName] | string | The organization name. |
+
+**Example**
+```javascript
+accessControl.getTeamUserRole("myUser").then(result=>{
+ console.log(result)
+})
+
+//response object example
+{
+ "@id": "User/myUser",
+ "capability": [
+ {
+ "@id":"Capability/server_access",
+ "@type":"Capability",
+ "role": [{
+ "@id":"Role/reader",
+ "@type":"Role",
+ "action": [
+ "instance_read_access",
+ ],
+ "name":"reader"
+ }],
+ "scope":"Organization/myteam"
+ }
+ ],
+ "name": "myUser"
+}
+```
+
## removeUserFromOrg
##### accessControl.removeUserFromOrg(userId, [orgName]) ⇒ Promise
Remove an user from an organization, only an admin user can remove an user from an organization
@@ -427,3 +501,106 @@ accessControl.deleteAccessRequest("djjdshhsuuwewueueuiHYHYYW.......").then(resul
console.log(result)
})
```
+
+## createRole
+##### accessControl.createRole([name], [actions]) ⇒ Promise
+Create a new role in the system database, (this api is enabled only in the local installation)
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| [name] | string | The role name. |
+| [actions] | array | A list of actions |
+
+**Example**
+```javascript
+accessControl.createRole("Reader",[ACTIONS.INSTANCE_READ_ACCESS]).then(result=>{
+ console.log(result)
+})
+```
+
+## deleteRole
+##### accessControl.deleteRole([name]) ⇒ Promise
+Delete role in the system database, (this api is enabled only in the local installation)
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| [name] | string | The role name. |
+
+**Example**
+```javascript
+accessControl.deleteRole("Reader").then(result=>{
+ console.log(result)
+})
+```
+
+## getAllUsers
+##### accessControl.getAllUsers() ⇒ Promise
+Return the list of all the users (this api is enabled only in the local installation)
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+**Example**
+```javascript
+accessControl.getAllUsers().then(result=>{
+ console.log(result)
+})
+```
+
+## deleteUser
+##### accessControl.deleteUser(userId) ⇒ Promise
+Remove the user from the system database (this api is enabled only in the local installation)
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| userId | string | the document user id |
+
+**Example**
+```javascript
+accessControl.deleteUser(userId).then(result=>{
+ console.log(result)
+})
+```
+
+## createUser
+##### accessControl.createUser(name, [password]) ⇒ Promise
+Add the user into the system database (this api is enabled only in the local installation)
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| name | string | the user name |
+| [password] | string | you need the password for basic authentication |
+
+**Example**
+```javascript
+accessControl.deleteUser(userId).then(result=>{
+ console.log(result)
+})
+```
+
+## manageCapability
+##### accessControl.manageCapability(userId, resourceId, rolesArr, operation) ⇒ Promise
+Grant/Revoke Capability (this api is enabled only in the local installation)
+
+**Returns**: Promise - A promise that returns the call response object, or an Error if rejected.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| userId | string | the document user id |
+| resourceId | string | the resource id (database or team) |
+| rolesArr | array | the roles list |
+| operation | string | grant/revoke operation |
+
+**Example**
+```javascript
+{ "operation" : "grant",
+ "scope" : "Organization/myteam",
+ "user" : "User/myUser",
+ "roles" : ["Role/reader"] }
+```
diff --git a/lib/accessControl.js b/lib/accessControl.js
index d21551be..ff016d29 100644
--- a/lib/accessControl.js
+++ b/lib/accessControl.js
@@ -43,8 +43,10 @@ function AccessControl(cloudAPIUrl, params) {
this.setJwtToken(params.jwt);
} else if (params.token) {
this.setApiToken(params.token);
+ } else if (params.key) {
+ this.setApiKey(params.key);
+ this.user = params.user;
}
-
this.defaultOrganization = this.getDefaultOrganization(params);
}
@@ -68,7 +70,7 @@ AccessControl.prototype.setJwtToken = function (jwt) {
throw new Error('TerminusX Access token required');
}
- this.apiJwtToken = jwt;
+ this.apiKey = jwt;
this.apiType = 'jwt';
};
@@ -81,10 +83,23 @@ AccessControl.prototype.setApiToken = function (token) {
throw new Error('TerminusX Access token required');
}
- this.apiToken = token;
+ this.apiKey = token;
this.apiType = 'apikey';
};
+/**
+ * Sets the API token for the object, to request a token create an account in https://terminusdb.com/
+ * @param {string} atokenpi - The API token to use to connect with TerminusX
+ */
+AccessControl.prototype.setApiKey = function (key) {
+ if (!key) {
+ throw new Error('TerminusDB bacis authentication key required');
+ }
+
+ this.apiKey = key;
+ this.apiType = 'basic';
+};
+
/**
* Get a API url from cloudAPIUrl
* @param {string} cloudAPIUrl - The base url for cloud
@@ -112,14 +127,11 @@ AccessControl.prototype.dispatch = function (requestUrl, action, payload) {
),
);
}
-
- const apiToken = this.apiJwtToken || this.apiToken;
-
return DispatchRequest(
requestUrl,
action,
payload,
- { type: this.apiType, key: apiToken },
+ { type: this.apiType, key: this.apiKey, user: this.user },
);
};
@@ -132,8 +144,19 @@ AccessControl.prototype.getAccessRoles = function () {
};
/**
- * Any user can create their own organization.
- * IMPORTANT This does not work with the API-TOKEN.
+ * This end point works only in basic authentication admin user
+ * Get all the system organizations list
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ */
+
+AccessControl.prototype.getAllOrganizations = function () {
+ return this.dispatch(`${this.baseURL}/organizations`, CONST.GET);
+};
+
+/**
+ * This works only in the local database
+ * TerminusX - Any user can create their own organization. -
+ * TerminusX - IMPORTANT This does not work with the API-TOKEN.
* @param {string} orgName - The organization name to create
* @return {Promise} A promise that returns the call response object, or an Error if rejected.
* @example
@@ -142,20 +165,21 @@ AccessControl.prototype.getAccessRoles = function () {
* })
*/
AccessControl.prototype.createOrganization = function (orgName) {
- if (!orgName) {
- return Promise.reject(
- new Error(
- ErrorMessage.getInvalidParameterMessage(
- 'POST',
- 'Please provide a organization name',
- ),
- ),
- );
- }
+ // maybe we have to review this
+ return this.dispatch(`${this.baseURL}/organizations/${UTILS.encodeURISegment(orgName)}`, CONST.POST, {});
+};
- return this.dispatch(`${this.baseURL}/private/organizations`, CONST.POST, {
- organization: orgName,
- });
+/**
+ * This api works only in the local installation
+ * @param {string} orgName - The organization name to create
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ * @example
+ * accessControl.createOrganization("my_org_name").then(result=>{
+ * console.log(result)
+ * })
+ */
+AccessControl.prototype.deleteOrganization = function (orgName) {
+ return this.dispatch(`${this.baseURL}/organizations/${UTILS.encodeURISegment(orgName)}`, CONST.DELETE);
};
/**
@@ -433,6 +457,53 @@ AccessControl.prototype.getTeamUserRole = function (orgName) {
return this.dispatch(`${this.baseURL}/organizations/${UTILS.encodeURISegment(org)}/role`, CONST.GET);
};
+/**
+ * Get the user role for a given organization or the default organization,
+ * @param {string} [userName] - The organization name.
+ * @param {string} [orgName] - The organization name.
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ * @example
+ * accessControl.getTeamUserRole("myUser").then(result=>{
+ * console.log(result)
+ * })
+ *
+ * //response object example
+ * {
+ * "@id": "User/myUser",
+ * "capability": [
+ * {
+ * "@id":"Capability/server_access",
+ * "@type":"Capability",
+ * "role": [{
+ * "@id":"Role/reader",
+ * "@type":"Role",
+ * "action": [
+ * "instance_read_access",
+ * ],
+ * "name":"reader"
+ * }],
+ * "scope":"Organization/myteam"
+ * }
+ * ],
+ * "name": "myUser"
+ *}
+ */
+
+AccessControl.prototype.getTeamUserRoles = function (userName, orgName) {
+ if (!orgName && !this.defaultOrganization) {
+ return Promise.reject(
+ new Error(
+ ErrorMessage.getInvalidParameterMessage(
+ 'GET',
+ 'Please provide a organization name',
+ ),
+ ),
+ );
+ }
+ const org = orgName || this.defaultOrganization;
+ return this.dispatch(`${this.baseURL}/organizations/${UTILS.encodeURISegment(org)}/users/${UTILS.encodeURISegment(userName)}`, CONST.GET);
+};
+
/**
* Remove an user from an organization, only an admin user can remove an user from an organization
* @param {string} userId - The id of the user to be removed. (this is the document user's @id)
@@ -693,4 +764,100 @@ AccessControl.prototype.deleteAccessRequest = function (acceId, orgName) {
return this.dispatch(`${this.baseURL}/organizations/${UTILS.encodeURISegment(org)}/access_requests/${acceId}`, CONST.DELETE);
};
+/**
+ * Create a new role in the system database, (this api is enabled only in the local installation)
+ * @param {string} [name] - The role name.
+ * @param {array} [actions] - A list of actions
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ * @example
+ * accessControl.createRole("Reader",[ACTIONS.INSTANCE_READ_ACCESS]).then(result=>{
+ * console.log(result)
+ * })
+ *
+ */
+AccessControl.prototype.createRole = function (name, actions) {
+ const payload = { name, action: actions };
+ return this.dispatch(`${this.baseURL}/roles`, CONST.POST, payload);
+};
+
+/**
+ * Delete role in the system database, (this api is enabled only in the local installation)
+ * @param {string} [name] - The role name.
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ * @example
+ * accessControl.deleteRole("Reader").then(result=>{
+ * console.log(result)
+ * })
+ *
+ */
+AccessControl.prototype.deleteRole = function (name) {
+ return this.dispatch(`${this.baseURL}/roles/${UTILS.encodeURISegment(name)}`, CONST.DELETE);
+};
+
+/**
+ * Return the list of all the users (this api is enabled only in the local installation)
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ * @example
+ * accessControl.getAllUsers().then(result=>{
+ * console.log(result)
+ * })
+ *
+ */
+
+AccessControl.prototype.getAllUsers = function () {
+ return this.dispatch(`${this.baseURL}/users`, CONST.GET);
+};
+
+/**
+ * Remove the user from the system database (this api is enabled only in the local installation)
+ * @param {string} userId - the document user id
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ * @example
+ * accessControl.deleteUser(userId).then(result=>{
+ * console.log(result)
+ * })
+ *
+ */
+
+AccessControl.prototype.deleteUser = function (userId) {
+ return this.dispatch(`${this.baseURL}/users/${UTILS.encodeURISegment(userId)}`, CONST.DELETE);
+};
+
+/**
+ * Add the user into the system database (this api is enabled only in the local installation)
+ * @param {string} name - the user name
+ * @param {string} [password] - you need the password for basic authentication
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ * @example
+ * accessControl.deleteUser(userId).then(result=>{
+ * console.log(result)
+ * })
+ *
+ */
+
+AccessControl.prototype.createUser = function (name, password) {
+ const payload = { name, password };
+ return this.dispatch(`${this.baseURL}/users`, CONST.POST, payload);
+};
+
+/**
+ * Grant/Revoke Capability (this api is enabled only in the local installation)
+ * @param {string} userId - the document user id
+ * @param {string} resourceId - the resource id (database or team)
+ * @param {array} rolesArr - the roles list
+ * @param {string} operation - grant/revoke operation
+ * @return {Promise} A promise that returns the call response object, or an Error if rejected.
+ * @example
+ { "operation" : "grant",
+ "scope" : "Organization/myteam",
+ "user" : "User/myUser",
+ "roles" : ["Role/reader"] }
+ */
+AccessControl.prototype.manageCapability = function (userId, resourceId, rolesArr, operation) {
+ const payload = {
+ operation, user: userId, roles: rolesArr, scope: resourceId,
+ };
+ return this.dispatch(`${this.baseURL}/capabilities`, CONST.POST, payload);
+};
+
module.exports = AccessControl;
diff --git a/lib/dispatchRequest.js b/lib/dispatchRequest.js
index 7a8af41f..fc30dc3c 100644
--- a/lib/dispatchRequest.js
+++ b/lib/dispatchRequest.js
@@ -114,9 +114,9 @@ function DispatchRequest(url, action, payload, local_auth, remote_auth = null, c
.delete(url, options)
.then((response) => (getDataVersion ? getResultWithDataVersion(response) : response.data))
.catch((err) => {
- const e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err));
- if (err.response && err.response.data) e.data = err.response.data;
- throw e;
+ // const e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err));
+ // if (err.response && err.response.data) e.data = err.response.data;
+ throw ErrorMessage.apiErrorFormatted(url, options, err);
});
}
case CONST.HEAD: {
@@ -141,11 +141,7 @@ function DispatchRequest(url, action, payload, local_auth, remote_auth = null, c
.get(url, options)
.then((response) => (getDataVersion ? getResultWithDataVersion(response) : response.data))
.catch((err) => {
- const e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err));
- if (err.response && err.response.data) {
- e.data = err.response.data;
- }
- throw e;
+ throw ErrorMessage.apiErrorFormatted(url, options, err);
});
}
case CONST.ADD_CSV:
diff --git a/lib/errorMessage.js b/lib/errorMessage.js
index 22103a06..e706efb1 100644
--- a/lib/errorMessage.js
+++ b/lib/errorMessage.js
@@ -91,7 +91,15 @@ function parseAPIError(response) {
return err;
}
+function apiErrorFormatted(url, options, err) {
+ const e = new Error(getAPIErrorMessage(url, options, err));
+ if (err.response && err.response.data) e.data = err.response.data;
+ if (err.response && err.response.status) e.status = err.response.status;
+ return e;
+}
+
module.exports = {
+ apiErrorFormatted,
getErrorAsMessage,
getAPIErrorMessage,
getAccessDeniedMessage,
diff --git a/lib/query/woqlBuilder.js b/lib/query/woqlBuilder.js
index 2d04dea6..7cc0cca7 100644
--- a/lib/query/woqlBuilder.js
+++ b/lib/query/woqlBuilder.js
@@ -158,39 +158,4 @@ WOQLQuery.prototype.insert = function (id, type, refGraph) {
return this.add_triple(id, 'rdf:type', `@schema:${type}`);
};
-/**
- * @description Creates a pattern matching rule for a quad [Subject, Predicate, Object, Graph]
- * or for a triple [Subject, Predicate, Object]
- * add extra information about the type of the value object
- * @param {string} subject - The IRI of a triple’s subject or a variable
- * @param {string} predicate - The IRI of a property or a variable
- * @param {string | number | boolean} objValue - an specific value
- * @param {string} [graph] - specify a graph type, default is instance schema|instance
- */
-WOQLQuery.prototype.value = function (subject, predicate, objValue, graph) {
- if (typeof objValue === 'string') {
- objValue = this.string(objValue);
- } else if (typeof objValue === 'number') {
- objValue = this.literal(objValue, 'xsd:decimal');
- } else if (typeof objValue === 'boolean') {
- objValue = this.literal(objValue, 'xsd:boolean');
- }
- if (graph) {
- this.quad(subject, predicate, objValue, graph);
- } else {
- this.triple(subject, predicate, objValue);
- }
-};
-
-WOQLQuery.prototype.link = function (a, b, c, g) {
- if (typeof c === 'string') {
- c = this.iri(c);
- }
- if (g) {
- this.quad(a, b, c, g);
- } else {
- this.triple(a, b, c);
- }
-};
-
module.exports = WOQLQuery;
diff --git a/lib/query/woqlQuery.js b/lib/query/woqlQuery.js
index 95eba50c..ea545afe 100644
--- a/lib/query/woqlQuery.js
+++ b/lib/query/woqlQuery.js
@@ -259,6 +259,39 @@ WOQLQuery.prototype.value = function (a, b, c) {
return this;
};
+/**
+ * @description Creates a pattern matching rule for a quad [Subject, Predicate, Object, Graph]
+ * or for a triple [Subject, Predicate, Object]
+ * add extra information about the type of the value object
+ * @param {string} subject - The IRI of a triple’s subject or a variable
+ * @param {string} predicate - The IRI of a property or a variable
+ * @param {string | number | boolean} objValue - an specific value
+ * @param {string} [graph] - specify a graph type, default is instance schema|instance
+ */
+/* WOQLQuery.prototype.value = function (subject, predicate, objValue, graph) {
+ if (typeof objValue === 'string') {
+ objValue = this.string(objValue);
+ } else if (typeof objValue === 'number') {
+ objValue = this.literal(objValue, 'xsd:decimal');
+ } else if (typeof objValue === 'boolean') {
+ objValue = this.literal(objValue, 'xsd:boolean');
+ }
+ if (graph) {
+ return this.quad(subject, predicate, objValue, graph);
+ }
+ return this.triple(subject, predicate, objValue);
+};
+
+WOQLQuery.prototype.link = function (a, b, c, g) {
+ if (typeof c === 'string') {
+ c = this.iri(c);
+ }
+ if (g) {
+ return this.quad(a, b, c, g);
+ }
+ return this.triple(a, b, c);
+}; */
+
WOQLQuery.prototype.quad = function (a, b, c, g) {
if (this.cursor['@type']) this.wrapCursorWithAnd();
const args = this.triple(a, b, c);
diff --git a/lib/utils.js b/lib/utils.js
index 9e88c073..197de385 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -12,6 +12,26 @@
*/
const Utils = {};
+Utils.ACTIONS = {
+ CREATE_DATABASE: 'create_database',
+ DELETE_DATABASE: 'delete_database',
+ SCHEMA_READ_ACCESS: 'schema_read_access',
+ SCHEMA_WRITE_ACCESS: 'schema_write_access',
+ INSTANCE_READ_ACCESS: 'instance_read_access',
+ INSTANCE_WRITE_ACCESS: 'instance_write_access',
+ COMMIT_READ_ACCESS: 'commit_read_access',
+ COMMIT_WRITE_ACCESS: 'commit_write_access',
+ META_READ_ACCESS: 'meta_read_access',
+ META_WRITE_ACCESS: 'meta_write_access',
+ CLASS_FRAME: 'class_frame',
+ BRANCH: 'branch',
+ CLONE: 'clone',
+ FETCH: 'fetch',
+ PUSH: 'push',
+ REBASE: 'rebase',
+ /* MANAGE_CAPABILITIES: 'manage_capabilities', */
+};
+
// ˆˆˆˆˆ&&**(((()*(*#&$*#*(#(#(#)#)#)_
// 'Doc%2F%3D%26test'
//
diff --git a/lib/woqlClient.js b/lib/woqlClient.js
index ed9aa17f..dff87e7c 100644
--- a/lib/woqlClient.js
+++ b/lib/woqlClient.js
@@ -1439,6 +1439,7 @@ WOQLClient.prototype.getPrefixes = function (dbId) {
*/
WOQLClient.prototype.getUserOrganizations = function () {
// this will be change to give back only the organizations list
+ console.log('this.connectionConfig.userOrganizationsURL()', this.connectionConfig.userOrganizationsURL());
return this.dispatch(
CONST.GET,
this.connectionConfig.userOrganizationsURL(),