diff --git a/ApiDocs/_apidoc.js b/ApiDocs/_apidoc.js
index 90706b7..13a3516 100644
--- a/ApiDocs/_apidoc.js
+++ b/ApiDocs/_apidoc.js
@@ -1739,4 +1739,3486 @@
* "errorCode":500,
* "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
* }
+ *//**
+ * @api {ServiceMethod: create} /organizations/create create
+ * @apiName CreateOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables any user with valid Token to create the specific organization and store its information (metadata).
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} name Specified organization name
+ * @apiParam {String} email Specified organization e-mail
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of objects) for the relevant organization
+ * @apiSuccess {String} id Generated id for the created organization
+ * @apiSuccess {String} name Specified organization name
+ * @apiSuccess {String} email Specified organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field Duplication of the Organization name
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/create",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/create",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Organization name: 'org name' already in use"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/create"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/create"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Organization name: 'org name' already in use"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/create (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com"
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Organization name: 'org name' already in use"
+ * }
+ */{
+ "name": "Organization service",
+ "version": "2.1.4-SNAPSHOT",
+ "description": "Organization service API",
+ "title": "API documentation for the Organization Service",
+ "template": {
+ "forceLanguage" : "en"
+ },
+ "order": [
+ "Overview",
+ "GettingStarted",
+ "TransportProtocols",
+ "InteractiveAPIExplorer",
+ "CreateOrganization",
+ "GetOrganization",
+ "UpdateOrganization",
+ "DeleteOrganization",
+ "LeaveOrganization",
+ "GetUserOrganizationsMembership",
+ "InviteMember",
+ "GetOrganizationMembers",
+ "UpdateOrganizationMemberRole",
+ "KickoutMember",
+ "AddOrganizationApiKey",
+ "DeleteOrganizationApiKey"
+ ]
+}
+/**
+ * @api {ServiceMethod: getUserOrganizationsMembership} /organizations/getUserOrganizationsMembership getUserOrganizationsMembership
+ * @apiName GetUserOrganizationsMembership
+ * @apiGroup Member
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables each organization member to get the list of all relevant organizations (full info) which the member was invited.
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ *
+ * @apiSuccess {Object[]} organizations List of all Organizations (Array of objects) which the member was invited
+ * @apiSuccess {Object[]} organizations.apiKeys List of all API keys (Array of objects) for the relevant organization
+ * @apiSuccess {String} organizations.id Already generated id for the created organization
+ * @apiSuccess {String} organizations.name Organization name
+ * @apiSuccess {String} organizations.email Organization e-mail
+ * @apiSuccess {String} organizations.ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field Invalid or expired token
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/getUserOrganizationsMembership",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * }
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/getUserOrganizationsMembership",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Token verification failed"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/getUserOrganizationsMembership"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * }
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/getUserOrganizationsMembership"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Token verification failed"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/getUserOrganizationsMembership (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Token verification failed"
+ * }
+ *//**
+ * @api {ServiceMethod: kickoutMember} /organizations/kickoutMember kickoutMember
+ * @apiName KickoutMember
+ * @apiGroup Member
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to remove the existent organization member with any accessible role.
+ *
Nevertheless at least one Owner (origin or granted one) should be persisted in the organization
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} userId Already stored id for the specific organization issued by relevant authority (Auth0)
+ *
+ * @apiSuccess Acknowledgment Empty object
+ *
+ * @apiError {String} field Single (last one) organization Owner is requested to be removed from the relevant organization
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/kickoutMember",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/kickoutMember",
+ * "sid":1,
+ * "d":{}
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/kickoutMember"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{},
+ * "metadata":{
+ * "q": "/organizations/kickoutMember"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/kickoutMember (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients"
+ * }
+ *
+ * Response:
+ * {
+ *
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * }
+ */
+/**
+ * @api {ServiceMethod: addOrganizationApiKey} /organizations/addOrganizationApiKey addOrganizationApiKey
+ * @apiName AddOrganizationApiKey
+ * @apiGroup ApiKey
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to create the API keys (token) for the relevant organization and further
+ * to be used (write and read ability) by potential users of the Configuration service according to appropriate permission level.
+ * Each API key got the unique name which couldn't be duplicated. Thus Owners could issue the API keys with all accessible roles but the Admins are restricted by the "Admin" or "Member" role API keys issuing.
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored org-id for the specific organization
+ * @apiParam {String} apiKeyName Specified name for the relevant API key
+ * @apiParam {Map} claims () Describes given identity on some role
+ * @apiParam {Object} claims.role Specified role (Owner/Admin/Member - permission level for the relevant API key)
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of Objects) in the relevant organization
+ * @apiSuccess {String} id Stored org-id for the relevant organization
+ * @apiSuccess {String} name Organization name
+ * @apiSuccess {String} email Organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field API key name duplication
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/addOrganizationApiKey",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * "claims": {
+ * "role":"Owner"
+ * }
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/addOrganizationApiKey",
+ * "sid":1,
+ * "d":{
+ * "apiKeys": [
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Owner"},
+ * "key": "API-TOKEN"
+ * }
+ * ],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"apiKey name:'specifiedApiKeyName' already exists"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/addOrganizationApiKey"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * "claims": {
+ * "role":"Admin"
+ * }
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys": [
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Admin"},
+ * "key": "API-TOKEN"
+ * },
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Owner"},
+ * "key": "API-TOKEN"
+ * }
+ * ],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/addOrganizationApiKey"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"apiKey name:'specifiedApiKeyName' already exists"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/addOrganizationApiKey (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * "claims": {
+ * "role":"Member"
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys": [
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Member"},
+ * "key": "API-TOKEN"
+ * },
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Admin"},
+ * "key": "API-TOKEN"
+ * },
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Owner"},
+ * "key": "API-TOKEN"
+ * }
+ * ],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"apiKey name:'specifiedApiKeyName' already exists"
+ * }
+ *//**
+ * @api {ServiceMethod: delete} /organizations/delete delete
+ * @apiName DeleteOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only Owners to delete relevant organization.
+ *
All relevant API keys issued for organization also deleted thus become invalid after specific period of time is left upon this operation was done.
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ *
+ * @apiSuccess {Boolean} deleted The "true" statement
+ * @apiSuccess {String} organizationId Already Stored id for the specific organization
+ *
+ * @apiError {String} field Invalid or non-existent organization id
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/delete",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/delete",
+ * "sid":1,
+ * "d":{
+ * "deleted": true,
+ * "organizationId": "ORG-ID"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"ORG-ID"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/delete"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "deleted": true,
+ * "organizationId": "ORG-ID"
+ * },
+ * "metadata":{
+ * "q": "/organizations/delete"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"ORG-ID"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/delete (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ *
+ * Response:
+ * {
+ * "deleted": true,
+ * "organizationId": "ORG-ID"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"ORG-ID"
+ * }
+ *//**
+ * @api {ServiceMethod: deleteOrganizationApiKey} /organizations/deleteOrganizationApiKey deleteOrganizationApiKey
+ * @apiName DeleteOrganizationApiKey
+ * @apiGroup ApiKey
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to delete the API keys (token) from the relevant organization.
+ *
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} apiKeyName Specified name for the relevant API key
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of Objects) in the relevant organization
+ * @apiSuccess {String} id Stored org-id for the relevant organization
+ * @apiSuccess {String} name Organization name
+ * @apiSuccess {String} email Organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field Permission denied for specified organization member either organization outsider
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/deleteOrganizationApiKey",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/deleteOrganizationApiKey",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/deleteOrganizationApiKey"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/deleteOrganizationApiKey"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/createRepository (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * }
+ *//**
+ * @api {ServiceMethod: getOrganization} /organizations/getOrganization getOrganization
+ * @apiName GetOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables all members of the relevant organization to get the full organization information.
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of objects) for the relevant organization
+ * @apiSuccess {String} id Already generated id for the created organization
+ * @apiSuccess {String} name Organization name
+ * @apiSuccess {String} email Organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field user isn't the member (outsider) of the specified organization
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/getOrganization",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/getOrganization",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * errorCode":500,
+ * "errorMessage":"user: 'null', name: 'id@clients', is not a member of organization: 'ORG-ID'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/getOrganization"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/getOrganization"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'null', name: 'id@clients', is not a member of organization: 'ORG-ID'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/getOrganization (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"user: 'null', name: 'id@clients', is not a member of organization: 'ORG-ID'"
+ * }
+ *//**
+ * @api {ServiceMethod: leaveOrganization} /organizations/leaveOrganization leaveOrganization
+ * @apiName LeaveOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables each organization member to step-out (leave) from the relevant organization.
+ *
Nevertheless at least one Owner (origin or granted one) should be persisted in the organization.
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ *
+ * @apiSuccess Acknowledgment Empty object
+ *
+ * @apiError {String} field Single (last one) organization Owner requested to leave the relevant organization
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/leaveOrganization",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/leaveOrganization",
+ * "sid":1,
+ * "d":{}
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/leaveOrganization"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{},
+ * "metadata":{
+ * "q": "/organizations/leaveOrganization"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/leaveOrganization (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ *
+ * Response:
+ * {
+ *
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * }
+ *//**
+ * @apiDefine BadRequestError
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiError BadRequestError The request didn't pass validation
+ *
+ * @apiErrorExample Error-Response:
+ * {
+ * "errorCode": "400"
+ * "errorMessage": "Bad request."
+ * }
+ */
+
+/**
+ * @apiDefine InternalServerError
+ *
+ * @apiError (Error 500) InternalServerError Error happened during request processing
+ *
+ * @apiErrorExample Error-Response:
+ * {
+ * "errorCode": "500"
+ * "errorMessage": "Error message"
+ * }
+ */
+
+/**
+ * @apiDefine ServiceUnavailableError
+ *
+ * @apiError (Error 503) ServiceUnavailableError Service in not available to accept requests
+ *
+ * @apiErrorExample Error-Response:
+ * {
+ * "errorCode": "503"
+ * "errorMessage": "No reachable member with such service: %s"
+ * }
+ */
+/**
+ * @api {ServiceMethod: updateOrganization} /organizations/updateOrganization updateOrganization
+ * @apiName UpdateOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to update (edit)
+ * the specific organization information (name or email) optionally.
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} name New specified organization name
+ * @apiParam {String} email New specified organization e-mail
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of objects) for the relevant organization
+ * @apiSuccess {String} id Already generated id for the created organization
+ * @apiSuccess {String} name New specified organization name
+ * @apiSuccess {String} email New specified organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field Organization e-mail wasn't specified
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/updateOrganization",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/updateOrganization",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Organization email cannot be empty"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/updateOrganization"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/updateOrganization"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Organization email cannot be empty"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/updateOrganization (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com"
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Organization email cannot be empty"
+ * }
+ *//**
+ * @api {ServiceMethod: inviteMember} /organizations/inviteMember inviteMember
+ * @apiName InviteMember
+ * @apiGroup Member
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to invite a valid user
+ * (which client id issued by relevant authority - Auth0) to step into relevant organization with relevant member's role (permission level).
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} userId Already stored id for the specific organization issued by relevant authority (Auth0)
+ * @apiParam {String} role Specified permission level (roles: Owner/Admin/Member) granted for the organization members
+ *
+ * @apiSuccess Acknowledgment Empty object
+ *
+ * @apiError {String} field Invalid role for specified organization member is applied
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/inviteMember",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Owner"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/inviteMember",
+ * "sid":1,
+ * "d":{}
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/inviteMember"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Admin"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{},
+ * "metadata":{
+ * "q": "/organizations/inviteMember"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/inviteMember (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Member"
+ * }
+ *
+ * Response:
+ * {
+ *
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * }
+ *//**
+ * @api {ServiceMethod: updateOrganizationMemberRole} /organizations/updateOrganizationMemberRole updateOrganizationMemberRole
+ * @apiName UpdateOrganizationMemberRole
+ * @apiGroup Member
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to upgrade/downgrade relevant organization members' roles.
+ *
Any of the members who posses Admin role couldn't upgrade themselves whereby only the members with higher - Owner roles are able to do that.
+ * Nevertheless any member with Admin or Owner role could downgrade themselves as do the members with Owner role could downgrade the members with Admin role.
+ * Furthermore at least one Owner (origin or granted one) should be persisted in the organization.
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} userId Already stored id for the specific organization issued by relevant authority (Auth0)
+ * @apiParam {String} role any of accessible member's role (Owner/Admin/Member)
+ *
+ * @apiSuccess Acknowledgment Empty object
+ *
+ * @apiError {String} field Invalid role for specified organization member is applied
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/updateOrganizationMemberRole",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Owner"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/updateOrganizationMemberRole",
+ * "sid":1,
+ * "d":{}
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/updateOrganizationMemberRole"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Admin"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{},
+ * "metadata":{
+ * "q": "/organizations/updateOrganizationMemberRole"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/updateOrganizationMemberRole (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Member"
+ * }
+ *
+ * Response:
+ * {
+ *
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * }
+ *//**
+ * @api . Getting Started
+ * @apiName GettingStarted
+ * @apiGroup Overview
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiDescription Organization service enable you to integrate the API in order to create and manage the organizations.
+ * Besides the origin owner unique ability to create the organization there is a necessity for each organization member to achieve appropriate
+ * managers' permission level (roles: Owner | Admin) granted by other managers of the relevant organization for management ability.
+ * Thus each organization could be deleted or relevant credentials updated, authorized users could be invited to and removed from the relevant organization,
+ * each member could get the info about the relevant organization and also to know the own membership in the all related organizations.
+ * Organization managers could provide and delete the relevant API keys (permission level with appropriate assigned role: Owner | Admin | Member) which are
+ * vital leverage (write or read permission provision) for the Configuration service management and security purpose.
+ *
+ * >Note: API keys assigned with some of the relevant roles (Owner | Admin | Member) are visible to organization members' similar roles only via
+ * permission level (role) in the specific Organization:
+ * >
-Owner could observe all accessible API keys
+ * >
-Admin could observe only the "Admin" and "Member" API keys
+ * >
-Member could observe only the "Member" API keys
+ *
+ * Getting Started
+ *
+ *
+ * All API endpoints documented below are the integral part of Configuration service host address.
+ *
You can try out any query in realtime using our interactive API.
+ * Actually service requires authentication, so there is a necessity to get the token issued via secured authority.
+ * Thus, firstly we recommend to create an account in Auth0 and issue the token whereby to perform the valid requests across all service endpoints.
+ *
+ * Validation for the object entities is handled by Scalecube services and do the next upon the request object:
+ * >~ ignores any excessive keys and values added besides the required parameters
+ * >
~ doesn't ignore the keys duplicates and takes the last values which applied for each of the relevant key duplicate
+ *
+ * >Contracts validation is implemented for specific parameters which value type is string and can only contain characters
+ * in range A-Z, a-z, 0-9 as well as underscore, period, dash & percent. Appropriate validation will be added soon.
+ */
+
+ /**
+ * @api . Transport protocols API
+ * @apiName TransportProtocols
+ * @apiGroup Overview
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Successful requests and responses
+ * @apiDescription You are able to manage the service API through the three types of transport protocols which are supported.
+ *
Upon relevant Host address was set the request should contain the following structure according to transport protocol usage:
+
+ Websocket (WS)
+ - "q": The query of the relevant service name and method used
+ - "sid": The stream identifier (couldn't be reused upon current stream connection is opened)
+ - "d": The request data object (parameters and values)
+
RSocket (RS)
+ - "metadata": object which contains "q": The query of the relevant service name and method used
+ - "d": object: The request data (parameters and values)
+
HTTP
+ - "endpoint url": host address/serviceName/method
+ - "method" request: POST
+ - "headers": Content-Type application/json
+ - "body" json: The request data object (parameters and values)
+
+
+ * @apiParamExample {json} WebSocket:
+ Request:
+ {
+ "q": "/serviceName/method_name",
+ "sid":int,
+ "d": {
+ "relevant request parameters and values"
+ }
+ }
+
+ Response:
+ {
+ "q":"/serviceName/method_name",
+ "sid":int,
+ "d":{
+ "relevant response parameters and values"
+ }
+ }
+ {
+ "sig":1,
+ "sid":int
+ }
+
+ * @apiParamExample {json} RSocket:
+ Request:
+ {
+ "metadata": {
+ "q": "/serviceName/method_name"
+ },
+ "data": {
+ "relevant request parameters and values"
+ }
+ }
+
+ Response:
+ {
+ "data":{
+ "relevant response parameters and values"
+ },
+ "metadata":{
+ "q": "/serviceName/method_name"
+ }
+ }
+ * @apiParamExample {json} HTTP:
+ Request:
+ https://localhost:port/serviceName/method_name (endpoint url)
+
+ Body:
+ {
+ "relevant request parameters and values"
+ }
+
+ Response:
+ {
+ "relevant response parameters and values"
+ }
+ */
+
+ /**
+ * @api . Interactive API Explorer
+ * @apiName InteractiveAPIExplorer
+ * @apiGroup Overview
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiDescription WebSocket and RSocket transports are accessible to apply via in-house developed API Explorer called Sandbox thus to connect and run follow up the next steps:
+
+ - Navigate to the sandbox: Scalecube sandbox
+ - Click on the Settings button then set the relevant Host address for the chosen transport
+ - Click on Import icon and copy-paste the template.json file path for Organization service endpoints.json
+ - Click on the Connect button (now you are connected to the environment) and push Send button to make your request
+
+ *//**
+ * @api {ServiceMethod: getOrganizationMembers} /organizations/getOrganizationMembers getOrganizationMembers
+ * @apiName GetOrganizationMembers
+ * @apiGroup Member
+ * @apiVersion 2.1.4-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to fetch all the members from the relevant organization.
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ *
+ * @apiSuccess {Object[]} members List of all the members (Array of Objects) in the specified organization
+ *
+ * @apiError {String} field user isn't the manager either outsider of the specified organization
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/getOrganizationMembers",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/getOrganizationMembers",
+ * "sid":1,
+ * "d":{
+ * "members":[
+ * {"id":"id@clients","role":"Owner"},
+ * {"id":"id@clients","role":"Admin"},
+ * {"id":"id@clients","role":"Member"}
+ * ]
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/getOrganizationMembers"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "members":[
+ * {"id":"id@clients","role":"Owner"},
+ * {"id":"id@clients","role":"Admin"},
+ * {"id":"id@clients","role":"Member"}
+ * ]
+ * },
+ * "metadata":{
+ * "q": "/organizations/getOrganizationMembers"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/getOrganizationMembers (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ *
+ * Response:
+ * {
+ * "members":[
+ * {"id":"id@clients","role":"Owner"},
+ * {"id":"id@clients","role":"Admin"},
+ * {"id":"id@clients","role":"Member"}
+ * ]
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * }
+ *//**
+ * @api {ServiceMethod: create} /organizations/create create
+ * @apiName CreateOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables any user with valid Token to create the specific organization and store its information (metadata).
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} name Specified organization name
+ * @apiParam {String} email Specified organization e-mail
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of objects) for the relevant organization
+ * @apiSuccess {String} id Generated id for the created organization
+ * @apiSuccess {String} name Specified organization name
+ * @apiSuccess {String} email Specified organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field Duplication of the Organization name
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/create",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/create",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Organization name: 'org name' already in use"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/create"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/create"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Organization name: 'org name' already in use"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/create (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com"
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Organization name: 'org name' already in use"
+ * }
+ */{
+ "name": "Organization service",
+ "version": "2.1.5-SNAPSHOT",
+ "description": "Organization service API",
+ "title": "API documentation for the Organization Service",
+ "template": {
+ "forceLanguage" : "en"
+ },
+ "order": [
+ "Overview",
+ "GettingStarted",
+ "TransportProtocols",
+ "InteractiveAPIExplorer",
+ "CreateOrganization",
+ "GetOrganization",
+ "UpdateOrganization",
+ "DeleteOrganization",
+ "LeaveOrganization",
+ "GetUserOrganizationsMembership",
+ "InviteMember",
+ "GetOrganizationMembers",
+ "UpdateOrganizationMemberRole",
+ "KickoutMember",
+ "AddOrganizationApiKey",
+ "DeleteOrganizationApiKey"
+ ]
+}
+/**
+ * @api {ServiceMethod: getUserOrganizationsMembership} /organizations/getUserOrganizationsMembership getUserOrganizationsMembership
+ * @apiName GetUserOrganizationsMembership
+ * @apiGroup Member
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables each organization member to get the list of all relevant organizations (full info) which the member was invited.
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ *
+ * @apiSuccess {Object[]} organizations List of all Organizations (Array of objects) which the member was invited
+ * @apiSuccess {Object[]} organizations.apiKeys List of all API keys (Array of objects) for the relevant organization
+ * @apiSuccess {String} organizations.id Already generated id for the created organization
+ * @apiSuccess {String} organizations.name Organization name
+ * @apiSuccess {String} organizations.email Organization e-mail
+ * @apiSuccess {String} organizations.ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field Invalid or expired token
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/getUserOrganizationsMembership",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * }
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/getUserOrganizationsMembership",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Token verification failed"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/getUserOrganizationsMembership"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * }
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/getUserOrganizationsMembership"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Token verification failed"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/getUserOrganizationsMembership (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Token verification failed"
+ * }
+ *//**
+ * @api {ServiceMethod: kickoutMember} /organizations/kickoutMember kickoutMember
+ * @apiName KickoutMember
+ * @apiGroup Member
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to remove the existent organization member with any accessible role.
+ *
Nevertheless at least one Owner (origin or granted one) should be persisted in the organization
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} userId Already stored id for the specific organization issued by relevant authority (Auth0)
+ *
+ * @apiSuccess Acknowledgment Empty object
+ *
+ * @apiError {String} field Single (last one) organization Owner is requested to be removed from the relevant organization
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/kickoutMember",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/kickoutMember",
+ * "sid":1,
+ * "d":{}
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/kickoutMember"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{},
+ * "metadata":{
+ * "q": "/organizations/kickoutMember"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/kickoutMember (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients"
+ * }
+ *
+ * Response:
+ * {
+ *
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * }
+ */
+/**
+ * @api {ServiceMethod: addOrganizationApiKey} /organizations/addOrganizationApiKey addOrganizationApiKey
+ * @apiName AddOrganizationApiKey
+ * @apiGroup ApiKey
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to create the API keys (token) for the relevant organization and further
+ * to be used (write and read ability) by potential users of the Configuration service according to appropriate permission level.
+ * Each API key got the unique name which couldn't be duplicated. Thus Owners could issue the API keys with all accessible roles but the Admins are restricted by the "Admin" or "Member" role API keys issuing.
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored org-id for the specific organization
+ * @apiParam {String} apiKeyName Specified name for the relevant API key
+ * @apiParam {Map} claims () Describes given identity on some role
+ * @apiParam {Object} claims.role Specified role (Owner/Admin/Member - permission level for the relevant API key)
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of Objects) in the relevant organization
+ * @apiSuccess {String} id Stored org-id for the relevant organization
+ * @apiSuccess {String} name Organization name
+ * @apiSuccess {String} email Organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field API key name duplication
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/addOrganizationApiKey",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * "claims": {
+ * "role":"Owner"
+ * }
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/addOrganizationApiKey",
+ * "sid":1,
+ * "d":{
+ * "apiKeys": [
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Owner"},
+ * "key": "API-TOKEN"
+ * }
+ * ],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"apiKey name:'specifiedApiKeyName' already exists"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/addOrganizationApiKey"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * "claims": {
+ * "role":"Admin"
+ * }
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys": [
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Admin"},
+ * "key": "API-TOKEN"
+ * },
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Owner"},
+ * "key": "API-TOKEN"
+ * }
+ * ],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/addOrganizationApiKey"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"apiKey name:'specifiedApiKeyName' already exists"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/addOrganizationApiKey (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * "claims": {
+ * "role":"Member"
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys": [
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Member"},
+ * "key": "API-TOKEN"
+ * },
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Admin"},
+ * "key": "API-TOKEN"
+ * },
+ * {
+ * "name": "specifiedApiKeyName",
+ * "claims": {"role": "Owner"},
+ * "key": "API-TOKEN"
+ * }
+ * ],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"apiKey name:'specifiedApiKeyName' already exists"
+ * }
+ *//**
+ * @api {ServiceMethod: delete} /organizations/delete delete
+ * @apiName DeleteOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only Owners to delete relevant organization.
+ *
All relevant API keys issued for organization also deleted thus become invalid after specific period of time is left upon this operation was done.
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ *
+ * @apiSuccess {Boolean} deleted The "true" statement
+ * @apiSuccess {String} organizationId Already Stored id for the specific organization
+ *
+ * @apiError {String} field Invalid or non-existent organization id
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/delete",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/delete",
+ * "sid":1,
+ * "d":{
+ * "deleted": true,
+ * "organizationId": "ORG-ID"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"ORG-ID"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/delete"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "deleted": true,
+ * "organizationId": "ORG-ID"
+ * },
+ * "metadata":{
+ * "q": "/organizations/delete"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"ORG-ID"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/delete (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ *
+ * Response:
+ * {
+ * "deleted": true,
+ * "organizationId": "ORG-ID"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"ORG-ID"
+ * }
+ *//**
+ * @api {ServiceMethod: deleteOrganizationApiKey} /organizations/deleteOrganizationApiKey deleteOrganizationApiKey
+ * @apiName DeleteOrganizationApiKey
+ * @apiGroup ApiKey
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to delete the API keys (token) from the relevant organization.
+ *
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} apiKeyName Specified name for the relevant API key
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of Objects) in the relevant organization
+ * @apiSuccess {String} id Stored org-id for the relevant organization
+ * @apiSuccess {String} name Organization name
+ * @apiSuccess {String} email Organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field Permission denied for specified organization member either organization outsider
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/deleteOrganizationApiKey",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/deleteOrganizationApiKey",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/deleteOrganizationApiKey"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/deleteOrganizationApiKey"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/createRepository (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "apiKeyName": "specifiedApiKeyName",
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * }
+ *//**
+ * @api {ServiceMethod: getOrganization} /organizations/getOrganization getOrganization
+ * @apiName GetOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables all members of the relevant organization to get the full organization information.
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of objects) for the relevant organization
+ * @apiSuccess {String} id Already generated id for the created organization
+ * @apiSuccess {String} name Organization name
+ * @apiSuccess {String} email Organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field user isn't the member (outsider) of the specified organization
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/getOrganization",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/getOrganization",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * errorCode":500,
+ * "errorMessage":"user: 'null', name: 'id@clients', is not a member of organization: 'ORG-ID'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/getOrganization"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/getOrganization"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'null', name: 'id@clients', is not a member of organization: 'ORG-ID'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/getOrganization (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"specifiedOrganizationName",
+ * "email":"specifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"user: 'null', name: 'id@clients', is not a member of organization: 'ORG-ID'"
+ * }
+ *//**
+ * @api {ServiceMethod: leaveOrganization} /organizations/leaveOrganization leaveOrganization
+ * @apiName LeaveOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables each organization member to step-out (leave) from the relevant organization.
+ *
Nevertheless at least one Owner (origin or granted one) should be persisted in the organization.
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ *
+ * @apiSuccess Acknowledgment Empty object
+ *
+ * @apiError {String} field Single (last one) organization Owner requested to leave the relevant organization
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/leaveOrganization",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/leaveOrganization",
+ * "sid":1,
+ * "d":{}
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/leaveOrganization"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{},
+ * "metadata":{
+ * "q": "/organizations/leaveOrganization"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/leaveOrganization (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ *
+ * Response:
+ * {
+ *
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"At least one Owner should be persisted in the organization: 'ORG-ID'"
+ * }
+ *//**
+ * @apiDefine BadRequestError
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiError BadRequestError The request didn't pass validation
+ *
+ * @apiErrorExample Error-Response:
+ * {
+ * "errorCode": "400"
+ * "errorMessage": "Bad request."
+ * }
+ */
+
+/**
+ * @apiDefine InternalServerError
+ *
+ * @apiError (Error 500) InternalServerError Error happened during request processing
+ *
+ * @apiErrorExample Error-Response:
+ * {
+ * "errorCode": "500"
+ * "errorMessage": "Error message"
+ * }
+ */
+
+/**
+ * @apiDefine ServiceUnavailableError
+ *
+ * @apiError (Error 503) ServiceUnavailableError Service in not available to accept requests
+ *
+ * @apiErrorExample Error-Response:
+ * {
+ * "errorCode": "503"
+ * "errorMessage": "No reachable member with such service: %s"
+ * }
+ */
+/**
+ * @api {ServiceMethod: updateOrganization} /organizations/updateOrganization updateOrganization
+ * @apiName UpdateOrganization
+ * @apiGroup Organization
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to update (edit)
+ * the specific organization information (name or email) optionally.
+ * >Note: this method returns all organization info thus API keys with:
+ * >
-all accessible permission levels ("Owner" | "Admin" | "Member") will be returned only for the related Organization Owner
+ * >
-"Admin" | "Member" permission levels will be returned only for the related Organization Admin
+ * >
-"Member" permission level will be returned only for the related Organization Member
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} name New specified organization name
+ * @apiParam {String} email New specified organization e-mail
+ *
+ * @apiSuccess {Object[]} apiKeys List of all API keys (Array of objects) for the relevant organization
+ * @apiSuccess {String} id Already generated id for the created organization
+ * @apiSuccess {String} name New specified organization name
+ * @apiSuccess {String} email New specified organization e-mail
+ * @apiSuccess {String} ownerId id for clients already generated by relevant authority (Auth0)
+ *
+ * @apiError {String} field Organization e-mail wasn't specified
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/updateOrganization",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/updateOrganization",
+ * "sid":1,
+ * "d":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Organization email cannot be empty"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/updateOrganization"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * },
+ * "metadata":{
+ * "q": "/organizations/updateOrganization"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Organization email cannot be empty"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/updateOrganization (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com"
+ * }
+ *
+ * Response:
+ * {
+ * "apiKeys":[],
+ * "id":"ORG-ID",
+ * "name":"newSpecifiedOrganizationName",
+ * "email":"newSpecifiedOrganization@email.com",
+ * "ownerId":"id@clients"
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Organization email cannot be empty"
+ * }
+ *//**
+ * @api {ServiceMethod: inviteMember} /organizations/inviteMember inviteMember
+ * @apiName InviteMember
+ * @apiGroup Member
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to invite a valid user
+ * (which client id issued by relevant authority - Auth0) to step into relevant organization with relevant member's role (permission level).
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} userId Already stored id for the specific organization issued by relevant authority (Auth0)
+ * @apiParam {String} role Specified permission level (roles: Owner/Admin/Member) granted for the organization members
+ *
+ * @apiSuccess Acknowledgment Empty object
+ *
+ * @apiError {String} field Invalid role for specified organization member is applied
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/inviteMember",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Owner"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/inviteMember",
+ * "sid":1,
+ * "d":{}
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/inviteMember"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Admin"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{},
+ * "metadata":{
+ * "q": "/organizations/inviteMember"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/inviteMember (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Member"
+ * }
+ *
+ * Response:
+ * {
+ *
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * }
+ *//**
+ * @api {ServiceMethod: updateOrganizationMemberRole} /organizations/updateOrganizationMemberRole updateOrganizationMemberRole
+ * @apiName UpdateOrganizationMemberRole
+ * @apiGroup Member
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to upgrade/downgrade relevant organization members' roles.
+ *
Any of the members who posses Admin role couldn't upgrade themselves whereby only the members with higher - Owner roles are able to do that.
+ * Nevertheless any member with Admin or Owner role could downgrade themselves as do the members with Owner role could downgrade the members with Admin role.
+ * Furthermore at least one Owner (origin or granted one) should be persisted in the organization.
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ * @apiParam {String} userId Already stored id for the specific organization issued by relevant authority (Auth0)
+ * @apiParam {String} role any of accessible member's role (Owner/Admin/Member)
+ *
+ * @apiSuccess Acknowledgment Empty object
+ *
+ * @apiError {String} field Invalid role for specified organization member is applied
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/updateOrganizationMemberRole",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Owner"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/updateOrganizationMemberRole",
+ * "sid":1,
+ * "d":{}
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/updateOrganizationMemberRole"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Admin"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{},
+ * "metadata":{
+ * "q": "/organizations/updateOrganizationMemberRole"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/updateOrganizationMemberRole (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID",
+ * "userId": "id@clients",
+ * "role": "Member"
+ * }
+ *
+ * Response:
+ * {
+ *
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"Unknown role: Boss"
+ * }
+ *//**
+ * @api . Getting Started
+ * @apiName GettingStarted
+ * @apiGroup Overview
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiDescription Organization service enable you to integrate the API in order to create and manage the organizations.
+ * Besides the origin owner unique ability to create the organization there is a necessity for each organization member to achieve appropriate
+ * managers' permission level (roles: Owner | Admin) granted by other managers of the relevant organization for management ability.
+ * Thus each organization could be deleted or relevant credentials updated, authorized users could be invited to and removed from the relevant organization,
+ * each member could get the info about the relevant organization and also to know the own membership in the all related organizations.
+ * Organization managers could provide and delete the relevant API keys (permission level with appropriate assigned role: Owner | Admin | Member) which are
+ * vital leverage (write or read permission provision) for the Configuration service management and security purpose.
+ *
+ * >Note: API keys assigned with some of the relevant roles (Owner | Admin | Member) are visible to organization members' similar roles only via
+ * permission level (role) in the specific Organization:
+ * >
-Owner could observe all accessible API keys
+ * >
-Admin could observe only the "Admin" and "Member" API keys
+ * >
-Member could observe only the "Member" API keys
+ *
+ * Getting Started
+ *
+ *
+ * All API endpoints documented below are the integral part of Configuration service host address.
+ *
You can try out any query in realtime using our interactive API.
+ * Actually service requires authentication, so there is a necessity to get the token issued via secured authority.
+ * Thus, firstly we recommend to create an account in Auth0 and issue the token whereby to perform the valid requests across all service endpoints.
+ *
+ * Validation for the object entities is handled by Scalecube services and do the next upon the request object:
+ * >~ ignores any excessive keys and values added besides the required parameters
+ * >
~ doesn't ignore the keys duplicates and takes the last values which applied for each of the relevant key duplicate
+ *
+ * >Contracts validation is implemented for specific parameters which value type is string and can only contain characters
+ * in range A-Z, a-z, 0-9 as well as underscore, period, dash & percent. Appropriate validation will be added soon.
+ */
+
+ /**
+ * @api . Transport protocols API
+ * @apiName TransportProtocols
+ * @apiGroup Overview
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Successful requests and responses
+ * @apiDescription You are able to manage the service API through the three types of transport protocols which are supported.
+ *
Upon relevant Host address was set the request should contain the following structure according to transport protocol usage:
+
+ Websocket (WS)
+ - "q": The query of the relevant service name and method used
+ - "sid": The stream identifier (couldn't be reused upon current stream connection is opened)
+ - "d": The request data object (parameters and values)
+
RSocket (RS)
+ - "metadata": object which contains "q": The query of the relevant service name and method used
+ - "d": object: The request data (parameters and values)
+
HTTP
+ - "endpoint url": host address/serviceName/method
+ - "method" request: POST
+ - "headers": Content-Type application/json
+ - "body" json: The request data object (parameters and values)
+
+
+ * @apiParamExample {json} WebSocket:
+ Request:
+ {
+ "q": "/serviceName/method_name",
+ "sid":int,
+ "d": {
+ "relevant request parameters and values"
+ }
+ }
+
+ Response:
+ {
+ "q":"/serviceName/method_name",
+ "sid":int,
+ "d":{
+ "relevant response parameters and values"
+ }
+ }
+ {
+ "sig":1,
+ "sid":int
+ }
+
+ * @apiParamExample {json} RSocket:
+ Request:
+ {
+ "metadata": {
+ "q": "/serviceName/method_name"
+ },
+ "data": {
+ "relevant request parameters and values"
+ }
+ }
+
+ Response:
+ {
+ "data":{
+ "relevant response parameters and values"
+ },
+ "metadata":{
+ "q": "/serviceName/method_name"
+ }
+ }
+ * @apiParamExample {json} HTTP:
+ Request:
+ https://localhost:port/serviceName/method_name (endpoint url)
+
+ Body:
+ {
+ "relevant request parameters and values"
+ }
+
+ Response:
+ {
+ "relevant response parameters and values"
+ }
+ */
+
+ /**
+ * @api . Interactive API Explorer
+ * @apiName InteractiveAPIExplorer
+ * @apiGroup Overview
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiDescription WebSocket and RSocket transports are accessible to apply via in-house developed API Explorer called Sandbox thus to connect and run follow up the next steps:
+
+ - Navigate to the sandbox: Scalecube sandbox
+ - Click on the Settings button then set the relevant Host address for the chosen transport
+ - Click on Import icon and copy-paste the template.json file path for Organization service endpoints.json
+ - Click on the Connect button (now you are connected to the environment) and push Send button to make your request
+
+ *//**
+ * @api {ServiceMethod: getOrganizationMembers} /organizations/getOrganizationMembers getOrganizationMembers
+ * @apiName GetOrganizationMembers
+ * @apiGroup Member
+ * @apiVersion 2.1.5-SNAPSHOT
+ * @apiPermission Request / Response / Error-response
+ *
+ * @apiDescription This operation enables only organization managers (Owner | Admin) to fetch all the members from the relevant organization.
+ *
+ * @apiParam {Object} token The requested token issued by relevant authority (Auth0)
+ * @apiParam {String} organizationId Already stored id for the specific organization
+ *
+ * @apiSuccess {Object[]} members List of all the members (Array of Objects) in the specified organization
+ *
+ * @apiError {String} field user isn't the manager either outsider of the specified organization
+ *
+ * @apiErrorExample {json} WebSocket
+ * Request:
+ * {
+ * "q":"/organizations/getOrganizationMembers",
+ * "sid": 1,
+ * "d":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "q":"/organizations/getOrganizationMembers",
+ * "sid":1,
+ * "d":{
+ * "members":[
+ * {"id":"id@clients","role":"Owner"},
+ * {"id":"id@clients","role":"Admin"},
+ * {"id":"id@clients","role":"Member"}
+ * ]
+ * }
+ *
+ * }
+ *
+ * {
+ * "sig":1,
+ * "sid":1
+ * }
+ *
+ * Error Response:
+ * {
+ * "sig":2,
+ * "q":"/io.scalecube.services.error/500",
+ * "sid":1,
+ * "d":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * }
+ * }
+ *
+ * @apiErrorExample {json} RSocket
+ * Request:
+ * {
+ * "metadata":{
+ * "q": "/organizations/getOrganizationMembers"
+ * },
+ * "data":{
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ * }
+ *
+ * Response:
+ * {
+ * "data":{
+ * "members":[
+ * {"id":"id@clients","role":"Owner"},
+ * {"id":"id@clients","role":"Admin"},
+ * {"id":"id@clients","role":"Member"}
+ * ]
+ * },
+ * "metadata":{
+ * "q": "/organizations/getOrganizationMembers"
+ * }
+ * }
+ *
+ * Error Response:
+ * {
+ * "data":{
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * },
+ * "metadata":{
+ * "q":"/io.scalecube.services.error/500"
+ * }
+ * }
+ *
+ * @apiErrorExample{json} HTTP
+ * Request:
+ * https://localhost:port/organizations/getOrganizationMembers (endpoint url)
+ *
+ * Body:
+ * {
+ * "token": {
+ * "token":"Auth0-TOKEN"
+ * },
+ * "organizationId":"ORG-ID"
+ * }
+ *
+ * Response:
+ * {
+ * "members":[
+ * {"id":"id@clients","role":"Owner"},
+ * {"id":"id@clients","role":"Admin"},
+ * {"id":"id@clients","role":"Member"}
+ * ]
+ * }
+ *
+ * Error Response:
+ * {
+ * "errorCode":500,
+ * "errorMessage":"user: 'id@clients', name: 'null', not in role Owner or Admin of organization: 'specifiedOrganizationName'"
+ * }
*/
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d576498..a5d0cf6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
scalecube-organization-parent
- 2.1.3-SNAPSHOT
+ 2.1.5-SNAPSHOT
pom
@@ -25,7 +25,7 @@
0.3.9
- 2.5.4
+ 2.5.9
1.0.7
5.3.2
2.9.8
diff --git a/scalecube-organization-api/pom.xml b/scalecube-organization-api/pom.xml
index 8f10ff7..81d9fb8 100644
--- a/scalecube-organization-api/pom.xml
+++ b/scalecube-organization-api/pom.xml
@@ -4,7 +4,7 @@
io.scalecube
scalecube-organization-parent
- 2.1.3-SNAPSHOT
+ 2.1.5-SNAPSHOT
scalecube-organization-api
diff --git a/scalecube-organization-api/src/main/java/io/scalecube/account/api/ApiKey.java b/scalecube-organization-api/src/main/java/io/scalecube/account/api/ApiKey.java
index a7693d3..06ee492 100644
--- a/scalecube-organization-api/src/main/java/io/scalecube/account/api/ApiKey.java
+++ b/scalecube-organization-api/src/main/java/io/scalecube/account/api/ApiKey.java
@@ -4,10 +4,15 @@
public class ApiKey {
+ protected String keyId;
protected String name;
protected Map claims;
protected String key;
+ public String keyId() {
+ return this.keyId;
+ }
+
public String name() {
return this.name;
}
@@ -31,6 +36,9 @@ public boolean equals(Object o) {
ApiKey apiKey = (ApiKey) o;
+ if (keyId != null ? !keyId.equals(apiKey.keyId) : apiKey.keyId != null) {
+ return false;
+ }
if (name != null ? !name.equals(apiKey.name) : apiKey.name != null) {
return false;
}
@@ -42,7 +50,8 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
- int result = name != null ? name.hashCode() : 0;
+ int result = keyId != null ? keyId.hashCode() : 0;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (claims != null ? claims.hashCode() : 0);
result = 31 * result + (key != null ? key.hashCode() : 0);
return result;
diff --git a/scalecube-organization/pom.xml b/scalecube-organization/pom.xml
index 3e129a6..f46ee78 100644
--- a/scalecube-organization/pom.xml
+++ b/scalecube-organization/pom.xml
@@ -4,7 +4,7 @@
io.scalecube
scalecube-organization-parent
- 2.1.3-SNAPSHOT
+ 2.1.5-SNAPSHOT
scalecube-organization
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/OrganizationServiceImpl.java b/scalecube-organization/src/main/java/io/scalecube/organization/OrganizationServiceImpl.java
index 16e3023..d519bde 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/OrganizationServiceImpl.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/OrganizationServiceImpl.java
@@ -84,8 +84,6 @@ public Mono createOrganization(CreateOrganizationReq
CreateOrganization.builder()
.tokenVerifier(tokenVerifier)
.repository(repository)
- .keyPairGenerator(keyPairGenerator)
- .keyStore(keyStore)
.build()
.execute(request);
@@ -134,6 +132,7 @@ public Mono deleteOrganization(DeleteOrganizationReq
DeleteOrganization.builder()
.tokenVerifier(tokenVerifier)
.repository(repository)
+ .keyStore(keyStore)
.build()
.execute(request);
logger.debug("deleteOrganization: exit, request: {}, response: {}", request, response);
@@ -266,6 +265,7 @@ public Mono addOrganizationApiKey(AddOrganizationApiKey
AddOrganizationApiKey.builder()
.tokenVerifier(tokenVerifier)
.repository(repository)
+ .keyPairGenerator(keyPairGenerator)
.keyStore(keyStore)
.build()
.execute(request);
@@ -291,6 +291,7 @@ public Mono deleteOrganizationApiKey(
DeleteOrganizationApiKey.builder()
.tokenVerifier(tokenVerifier)
.repository(repository)
+ .keyStore(keyStore)
.build()
.execute(request);
logger.debug(
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/domain/Organization.java b/scalecube-organization/src/main/java/io/scalecube/organization/domain/Organization.java
index 83bb30b..15a237c 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/domain/Organization.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/domain/Organization.java
@@ -15,7 +15,6 @@ public class Organization extends Entity {
private String name;
private String email;
- private String keyId;
private Set members = new HashSet<>();
private Set apiKeys = new HashSet<>();
@@ -27,14 +26,12 @@ public class Organization extends Entity {
* @param id organization id.
* @param name organization name.
* @param email organization email.
- * @param keyId organization key id.
* @param creatorUserId user id of organization creator.
*/
- public Organization(String id, String name, String email, String keyId, String creatorUserId) {
+ public Organization(String id, String name, String email, String creatorUserId) {
this.id = requireNonNull(id, "organization id cannot be null");
this.name = requireNonNull(name, "organization name cannot be null");
this.email = requireNonNull(email, "organization email cannot be null");
- this.keyId = requireNonNull(keyId, "organization keyId cannot be null");
addMember(
new OrganizationMember(
@@ -50,10 +47,6 @@ public String email() {
return email;
}
- public String keyId() {
- return keyId;
- }
-
public Set members() {
return Collections.unmodifiableSet(members);
}
@@ -101,7 +94,6 @@ public String toString() {
.add("id='" + id + "'")
.add("name='" + name + "'")
.add("email='" + email + "'")
- .add("keyId='" + keyId + "'")
.add("members=" + members)
.toString();
}
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/operation/AddOrganizationApiKey.java b/scalecube-organization/src/main/java/io/scalecube/organization/operation/AddOrganizationApiKey.java
index 62a9c5a..8c596b5 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/operation/AddOrganizationApiKey.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/operation/AddOrganizationApiKey.java
@@ -12,15 +12,20 @@
import io.scalecube.organization.tokens.TokenVerifier;
import io.scalecube.organization.tokens.store.ApiKeyBuilder;
import io.scalecube.organization.tokens.store.KeyStore;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
import java.util.EnumSet;
+import java.util.UUID;
public class AddOrganizationApiKey
extends ServiceOperation {
+ private final KeyPairGenerator keyPairGenerator;
private final KeyStore keyStore;
private AddOrganizationApiKey(Builder builder) {
super(builder.tokenVerifier, builder.repository);
+ this.keyPairGenerator = builder.keyPairGenerator;
this.keyStore = builder.keyStore;
}
@@ -47,16 +52,15 @@ protected GetOrganizationResponse process(
throw new AccessPermissionException(
String.format(
"user: '%s', name: '%s', role: '%s' cannot add api key with higher role '%s'",
- context.profile().userId(),
- context.profile().name(),
- callerRole,
- targetRole));
+ context.profile().userId(), context.profile().name(), callerRole, targetRole));
}
}
}
- ApiKey apiKey = ApiKeyBuilder.build(keyStore, organization, request);
+ String keyId = UUID.randomUUID().toString();
+ KeyPair keyPair = generateKeyPair(keyId);
+ ApiKey apiKey = ApiKeyBuilder.build(keyPair.getPrivate(), organization.id(), keyId, request);
organization.addApiKey(apiKey);
context.repository().save(organization.id(), organization);
@@ -81,6 +85,12 @@ protected void validate(AddOrganizationApiKeyRequest request, OperationServiceCo
}
}
+ private KeyPair generateKeyPair(String keyId) {
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+ keyStore.store(keyId, keyPair);
+ return keyPair;
+ }
+
@Override
protected Token getToken(AddOrganizationApiKeyRequest request) {
return request.token();
@@ -93,6 +103,7 @@ public static Builder builder() {
public static class Builder {
private TokenVerifier tokenVerifier;
private OrganizationsRepository repository;
+ private KeyPairGenerator keyPairGenerator;
private KeyStore keyStore;
public Builder tokenVerifier(TokenVerifier tokenVerifier) {
@@ -105,6 +116,11 @@ public Builder repository(OrganizationsRepository repository) {
return this;
}
+ public Builder keyPairGenerator(KeyPairGenerator keyPairGenerator) {
+ this.keyPairGenerator = keyPairGenerator;
+ return this;
+ }
+
public Builder keyStore(KeyStore keyStore) {
this.keyStore = keyStore;
return this;
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/operation/CreateOrganization.java b/scalecube-organization/src/main/java/io/scalecube/organization/operation/CreateOrganization.java
index 4e713b7..779bcc1 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/operation/CreateOrganization.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/operation/CreateOrganization.java
@@ -9,21 +9,12 @@
import io.scalecube.organization.repository.OrganizationsRepository;
import io.scalecube.organization.tokens.IdGenerator;
import io.scalecube.organization.tokens.TokenVerifier;
-import io.scalecube.organization.tokens.store.KeyStore;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.util.UUID;
public final class CreateOrganization
extends OrganizationInfoOperation {
- private final KeyPairGenerator keyPairGenerator;
- private final KeyStore keyStore;
-
private CreateOrganization(Builder builder) {
super(builder.tokenVerifier, builder.repository);
- this.keyPairGenerator = builder.keyPairGenerator;
- this.keyStore = builder.keyStore;
}
public static Builder builder() {
@@ -40,14 +31,6 @@ protected CreateOrganizationResponse process(
Organization organization = createOrganization(request, context, id);
- try {
- generateOrganizationKeyPair(organization);
- } catch (Exception ex) {
- // failed to persist organization secret rollback
- context.repository().deleteById(organization.id());
- throw ex;
- }
-
return new CreateOrganizationResponse(
OrganizationInfo.builder()
.id(organization.id())
@@ -63,17 +46,11 @@ private Organization createOrganization(
id,
request.name(),
request.email(),
- UUID.randomUUID().toString(),
context.profile().userId());
return context.repository().save(organization.id(), organization);
}
- private void generateOrganizationKeyPair(Organization organization) {
- KeyPair keyPair = keyPairGenerator.generateKeyPair();
- keyStore.store(organization.keyId(), keyPair);
- }
-
@Override
protected Token getToken(CreateOrganizationRequest request) {
return request.token();
@@ -82,8 +59,6 @@ protected Token getToken(CreateOrganizationRequest request) {
public static class Builder {
private TokenVerifier tokenVerifier;
private OrganizationsRepository repository;
- private KeyPairGenerator keyPairGenerator;
- private KeyStore keyStore;
public Builder tokenVerifier(TokenVerifier tokenVerifier) {
this.tokenVerifier = tokenVerifier;
@@ -95,16 +70,6 @@ public Builder repository(OrganizationsRepository repository) {
return this;
}
- public Builder keyPairGenerator(KeyPairGenerator keyPairGenerator) {
- this.keyPairGenerator = keyPairGenerator;
- return this;
- }
-
- public Builder keyStore(KeyStore keyStore) {
- this.keyStore = keyStore;
- return this;
- }
-
public CreateOrganization build() {
return new CreateOrganization(this);
}
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/operation/DeleteOrganization.java b/scalecube-organization/src/main/java/io/scalecube/organization/operation/DeleteOrganization.java
index 05d20f6..e0f3558 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/operation/DeleteOrganization.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/operation/DeleteOrganization.java
@@ -6,12 +6,16 @@
import io.scalecube.organization.domain.Organization;
import io.scalecube.organization.repository.OrganizationsRepository;
import io.scalecube.organization.tokens.TokenVerifier;
+import io.scalecube.organization.tokens.store.KeyStore;
public class DeleteOrganization
extends ServiceOperation {
+ private final KeyStore keyStore;
- private DeleteOrganization(TokenVerifier tokenVerifier, OrganizationsRepository repository) {
+ private DeleteOrganization(
+ TokenVerifier tokenVerifier, OrganizationsRepository repository, KeyStore keyStore) {
super(tokenVerifier, repository);
+ this.keyStore = keyStore;
}
@Override
@@ -20,6 +24,10 @@ protected DeleteOrganizationResponse process(
Organization organization = getOrganization(request.organizationId());
checkOwnerAccess(organization, context.profile());
context.repository().deleteById(organization.id());
+ organization.apiKeys().stream()
+ .map(apiKey -> apiKey.keyId())
+ .filter(keyId -> keyId != null && !keyId.isEmpty())
+ .forEach(keyId -> keyStore.delete(keyId));
return new DeleteOrganizationResponse(organization.id(), true);
}
@@ -42,6 +50,7 @@ public static Builder builder() {
public static class Builder {
private TokenVerifier tokenVerifier;
private OrganizationsRepository repository;
+ private KeyStore keyStore;
public Builder tokenVerifier(TokenVerifier tokenVerifier) {
this.tokenVerifier = tokenVerifier;
@@ -54,7 +63,12 @@ public Builder repository(OrganizationsRepository repository) {
}
public DeleteOrganization build() {
- return new DeleteOrganization(tokenVerifier, repository);
+ return new DeleteOrganization(tokenVerifier, repository, keyStore);
+ }
+
+ public Builder keyStore(KeyStore keyStore) {
+ this.keyStore = keyStore;
+ return this;
}
}
}
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/operation/DeleteOrganizationApiKey.java b/scalecube-organization/src/main/java/io/scalecube/organization/operation/DeleteOrganizationApiKey.java
index 91a3387..c1b79b1 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/operation/DeleteOrganizationApiKey.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/operation/DeleteOrganizationApiKey.java
@@ -7,13 +7,17 @@
import io.scalecube.organization.domain.Organization;
import io.scalecube.organization.repository.OrganizationsRepository;
import io.scalecube.organization.tokens.TokenVerifier;
+import io.scalecube.organization.tokens.store.KeyStore;
public class DeleteOrganizationApiKey
extends ServiceOperation {
+ private final KeyStore keyStore;
+
private DeleteOrganizationApiKey(
- TokenVerifier tokenVerifier, OrganizationsRepository repository) {
+ TokenVerifier tokenVerifier, OrganizationsRepository repository, KeyStore keyStore) {
super(tokenVerifier, repository);
+ this.keyStore = keyStore;
}
@Override
@@ -27,6 +31,16 @@ protected GetOrganizationResponse process(
checkSuperUserAccess(organization, context.profile());
+ organization.apiKeys().stream()
+ .filter(apiKey -> apiKey.name().equalsIgnoreCase(request.apiKeyName()))
+ .findAny()
+ .ifPresent(
+ foundApiKey -> {
+ if (foundApiKey.keyId() != null) {
+ keyStore.delete(foundApiKey.keyId());
+ }
+ });
+
organization.removeApiKey(request.apiKeyName());
context.repository().save(organization.id(), organization);
@@ -54,6 +68,7 @@ public static Builder builder() {
public static class Builder {
private TokenVerifier tokenVerifier;
private OrganizationsRepository repository;
+ private KeyStore keyStore;
public Builder tokenVerifier(TokenVerifier tokenVerifier) {
this.tokenVerifier = tokenVerifier;
@@ -65,8 +80,13 @@ public Builder repository(OrganizationsRepository repository) {
return this;
}
+ public Builder keyStore(KeyStore keyStore) {
+ this.keyStore = keyStore;
+ return this;
+ }
+
public DeleteOrganizationApiKey build() {
- return new DeleteOrganizationApiKey(tokenVerifier, repository);
+ return new DeleteOrganizationApiKey(tokenVerifier, repository, keyStore);
}
}
}
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/repository/couchbase/CouchbaseRepositoryFactory.java b/scalecube-organization/src/main/java/io/scalecube/organization/repository/couchbase/CouchbaseRepositoryFactory.java
index f5da862..ac29aee 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/repository/couchbase/CouchbaseRepositoryFactory.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/repository/couchbase/CouchbaseRepositoryFactory.java
@@ -4,11 +4,13 @@
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import io.scalecube.organization.repository.OrganizationsRepository;
+import java.time.Duration;
import java.util.List;
+import reactor.core.publisher.Mono;
public final class CouchbaseRepositoryFactory {
- private final Bucket bucket;
+ private Bucket bucket;
/**
* Creates a couchbase repository factory, initializes two couchbase clusters.
@@ -20,10 +22,11 @@ public CouchbaseRepositoryFactory(CouchbaseSettings settings) {
Cluster cluster = nodes.isEmpty() ? CouchbaseCluster.create() : CouchbaseCluster.create(nodes);
- bucket =
+ bucket = Mono.fromCallable(() ->
cluster
.authenticate(settings.username(), settings.password())
- .openBucket(settings.organizationsBucketName());
+ .openBucket(settings.organizationsBucketName())).retryBackoff(3, Duration.ofSeconds(1))
+ .block(Duration.ofSeconds(30));
}
public OrganizationsRepository organizations() {
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/tokens/JwtApiKey.java b/scalecube-organization/src/main/java/io/scalecube/organization/tokens/JwtApiKey.java
index aacaf71..ae8175e 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/tokens/JwtApiKey.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/tokens/JwtApiKey.java
@@ -18,10 +18,11 @@ public JwtApiKey() {}
* @param claims Key claims.
* @param apiKey The API key.
*/
- public JwtApiKey(String name, Map claims, String apiKey) {
+ public JwtApiKey(String name, Map claims, String apiKey, String keyId) {
super.name = name;
super.claims = claims;
super.key = apiKey;
+ super.keyId = keyId;
}
public static Builder builder() {
@@ -37,6 +38,8 @@ public static final class Builder {
private String name;
private Long tokenTimeToLiveInMillis;
private String audience;
+ private String keyId;
+ private Key signingKey;
public Builder name(String name) {
this.name = name;
@@ -68,24 +71,37 @@ public Builder expiration(Long tokenTimeToLiveInMillis) {
return this;
}
+ public Builder keyId(String keyId) {
+ this.keyId = keyId;
+ return this;
+ }
+
+ public Builder signingKey(Key signingKey) {
+ this.signingKey = signingKey;
+ return this;
+ }
+
+ public Builder audience(String audience) {
+ this.audience = audience;
+ return this;
+ }
+
/**
* Constructs an API key object and signs it using the secret
argument.
*
- * @param keyId The token signing key id.
- * @param signingKey The token signing key.
* @return an API key.
*/
- public ApiKey build(String keyId, Key signingKey) {
+ public ApiKey build() {
final WebToken jwt = new WebToken(this.issuer, this.subject);
final String apiKey =
jwt.createToken(
- this.id, this.audience, this.tokenTimeToLiveInMillis, keyId, signingKey, claims);
- return new JwtApiKey(this.name, this.claims, apiKey);
- }
-
- public Builder audience(String audience) {
- this.audience = audience;
- return this;
+ this.id,
+ this.audience,
+ this.tokenTimeToLiveInMillis,
+ this.keyId,
+ this.signingKey,
+ claims);
+ return new JwtApiKey(this.name, this.claims, apiKey, keyId);
}
}
}
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/ApiKeyBuilder.java b/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/ApiKeyBuilder.java
index 4fb532e..1e29336 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/ApiKeyBuilder.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/ApiKeyBuilder.java
@@ -23,13 +23,14 @@ public final class ApiKeyBuilder {
* Builds an APiKey based on the organization
, claims and
* apiKeyName
arguments.
*
- * @param keyStore key store.
- * @param organization organization context of the API key.
+ * @param signingKey private key of key pair.
+ * @param orgId organization Id.
+ * @param keyId generated keyId for storage.
* @param request context for creating the API key.
* @return a signed ApiKey instance
*/
public static ApiKey build(
- KeyStore keyStore, Organization organization, AddOrganizationApiKeyRequest request) {
+ PrivateKey signingKey, String orgId, String keyId, AddOrganizationApiKeyRequest request) {
final Map tokenClaims =
request.claims() == null || request.claims().isEmpty() ? new HashMap<>() : request.claims();
@@ -38,17 +39,17 @@ public static ApiKey build(
tokenClaims.put(ROLE_KEY, Role.Member.toString());
}
- PrivateKey signingKey = keyStore.getPrivateKey(organization.keyId());
-
return JwtApiKey.builder()
.issuer(ISSUER)
- .subject(organization.id())
+ .subject(orgId)
.name(request.apiKeyName())
.claims(tokenClaims)
- .id(organization.id())
- .audience(organization.id())
+ .id(orgId)
+ .audience(orgId)
.expiration(tokenExpiration.value().orElse(null))
- .build(organization.keyId(), signingKey);
+ .keyId(keyId)
+ .signingKey(signingKey)
+ .build();
}
private static boolean isRoleValid(String role) {
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/KeyStore.java b/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/KeyStore.java
index a3cf689..04dc9ad 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/KeyStore.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/KeyStore.java
@@ -20,4 +20,6 @@ public interface KeyStore {
PublicKey getPublicKey(String keyId);
PrivateKey getPrivateKey(String keyId);
+
+ void delete(String keyId);
}
diff --git a/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/VaultKeyStore.java b/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/VaultKeyStore.java
index 2d0dfe9..8b05166 100644
--- a/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/VaultKeyStore.java
+++ b/scalecube-organization/src/main/java/io/scalecube/organization/tokens/store/VaultKeyStore.java
@@ -129,6 +129,18 @@ public PrivateKey getPrivateKey(String keyId) {
}
}
+ @Override
+ public void delete(String keyId) {
+ String path = getPath(keyId);
+
+ try {
+ vaultLogical().delete(path);
+ } catch (VaultException e) {
+ LOGGER.error("Error deleting key pair from Vault path={}", path, e);
+ throw new KeyStoreException(e);
+ }
+ }
+
private Logical vaultLogical() {
return vault
.withRetries(
diff --git a/scalecube-organization/src/test/java/io/scalecube/organization/OrganizationServiceApiKeyTest.java b/scalecube-organization/src/test/java/io/scalecube/organization/OrganizationServiceApiKeyTest.java
index 6e90d74..bfc0fa4 100644
--- a/scalecube-organization/src/test/java/io/scalecube/organization/OrganizationServiceApiKeyTest.java
+++ b/scalecube-organization/src/test/java/io/scalecube/organization/OrganizationServiceApiKeyTest.java
@@ -222,9 +222,8 @@ void addOrganizationApiKeyByAdmin() {
.verifyComplete();
// add api key by admin
StepVerifier.create(
- createService(adminUser)
- .addOrganizationApiKey(
- new AddOrganizationApiKeyRequest(token, organizationId, "apiKey", null)))
+ service.addOrganizationApiKey(
+ new AddOrganizationApiKeyRequest(token, organizationId, "apiKey", null)))
.expectSubscription()
.assertNext(
x -> {
diff --git a/scalecube-organization/src/test/java/io/scalecube/organization/repository/couchbase/JacksonTranslationServiceTest.java b/scalecube-organization/src/test/java/io/scalecube/organization/repository/couchbase/JacksonTranslationServiceTest.java
index 98312d1..460e140 100644
--- a/scalecube-organization/src/test/java/io/scalecube/organization/repository/couchbase/JacksonTranslationServiceTest.java
+++ b/scalecube-organization/src/test/java/io/scalecube/organization/repository/couchbase/JacksonTranslationServiceTest.java
@@ -41,7 +41,7 @@ void shouldEncodeUserOrgMembership() {
@Test
void shouldEncodeOrganization() {
JacksonTranslationService service = new JacksonTranslationService();
- String s = service.encode(new Organization("1", "TEST-ORG", "test@scalecube.io", "1", "1"));
+ String s = service.encode(new Organization("1", "TEST-ORG", "test@scalecube.io", "1"));
assertNotNull(s);
}
@@ -51,15 +51,13 @@ void shouldDecodeOrganization() {
String id = "org-id";
String name = "org-name";
String email = "test@scalecube.io";
- String keyId = "org-key-id";
String ownerUserId = "owner-user-id";
- String s = service.encode(new Organization(id, name, email, keyId, ownerUserId));
+ String s = service.encode(new Organization(id, name, email, ownerUserId));
Organization org = service.decode(s, Organization.class);
assertNotNull(org);
assertThat(org.id(), is(id));
assertThat(org.name(), is(name));
assertThat(org.email(), is(email));
- assertThat(org.keyId(), is(keyId));
assertThat(org.members().iterator().next().id(), is(ownerUserId));
}
}
diff --git a/scalecube-organization/src/test/java/io/scalecube/organization/token/store/PropertiesFileKeyStore.java b/scalecube-organization/src/test/java/io/scalecube/organization/token/store/PropertiesFileKeyStore.java
index 8e3a508..4411e50 100644
--- a/scalecube-organization/src/test/java/io/scalecube/organization/token/store/PropertiesFileKeyStore.java
+++ b/scalecube-organization/src/test/java/io/scalecube/organization/token/store/PropertiesFileKeyStore.java
@@ -71,6 +71,12 @@ public PrivateKey getPrivateKey(String keyId) {
}
}
+ @Override
+ public void delete(String keyId) {
+ properties.remove(properties.getProperty(keyId + "-public"));
+ properties.remove(properties.getProperty(keyId + "-private"));
+ }
+
private String encodeKey(Key key) {
return new String(Base64.getEncoder().encode(key.getEncoded()));
}