diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml index 76aa0dea81..0920c81141 100644 --- a/.github/workflows/api-tests.yml +++ b/.github/workflows/api-tests.yml @@ -152,7 +152,17 @@ jobs: checks: all report: false args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links' - + + - name: Run Groups API tests + if: steps.changes.outputs.groups == 'true' + uses: schemathesis/action@v1 + with: + schema: api/openapi/groups.yml + base-url: ${{ env.GROUPS_URL }} + checks: all + report: false + args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links' + - name: Run Clients API tests if: steps.changes.outputs.clients == 'true' uses: schemathesis/action@v1 diff --git a/api/openapi/bootstrap.yml b/api/openapi/bootstrap.yml index b64ec96da0..47584ce0b9 100644 --- a/api/openapi/bootstrap.yml +++ b/api/openapi/bootstrap.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9013 @@ -88,6 +88,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /{domainID}/clients/configs/{configId}: get: operationId: getConfig @@ -167,6 +168,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /{domainID}/clients/configs/certs/{configId}: patch: operationId: updateConfigCerts @@ -199,6 +201,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /{domainID}/clients/configs/connections/{configId}: put: operationId: updateConfigConnections @@ -230,6 +233,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /clients/bootstrap/{externalId}: get: operationId: getBootstrapConfig @@ -255,6 +259,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /clients/bootstrap/secure/{externalId}: get: operationId: getSecureBootstrapConfig @@ -281,6 +286,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /{domainID}/clients/state/{configId}: put: operationId: updateConfigState @@ -310,6 +316,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /health: get: summary: Retrieves service health check info. diff --git a/api/openapi/certs.yml b/api/openapi/certs.yml index f265225197..4d726b3c83 100644 --- a/api/openapi/certs.yml +++ b/api/openapi/certs.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9019 @@ -53,6 +53,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /{domainID}/certs/{certID}: get: operationId: getCert @@ -106,6 +107,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /{domainID}/serials/{clientID}: get: operationId: getSerials @@ -133,6 +135,7 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /health: get: summary: Retrieves service health check info. diff --git a/api/openapi/clients.yml b/api/openapi/clients.yml index 8705ac4c82..579c9eb3dd 100644 --- a/api/openapi/clients.yml +++ b/api/openapi/clients.yml @@ -867,6 +867,35 @@ paths: "500": $ref: "#/components/responses/ServiceError" + /{domainID}/clients/roles/available-actions: + get: + operationId: listAvailableActions + tags: + - Roles + summary: Retrieves available actions. + description: | + Retrieves a list of available actions. + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/ListAvailableActionsRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + /health: get: summary: Retrieves service health check info. diff --git a/api/openapi/domains.yml b/api/openapi/domains.yml index 699501e644..83f95acbb9 100644 --- a/api/openapi/domains.yml +++ b/api/openapi/domains.yml @@ -637,6 +637,35 @@ paths: description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + + /domains/roles/available-actions: + get: + operationId: listAvailableActions + tags: + - Roles + summary: Retrieves available actions. + description: | + Retrieves a list of available actions. + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/ListAvailableActionsRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" /health: get: diff --git a/api/openapi/groups.yml b/api/openapi/groups.yml new file mode 100644 index 0000000000..f0e7195315 --- /dev/null +++ b/api/openapi/groups.yml @@ -0,0 +1,1608 @@ +# Copyright (c) Abstract Machines +# SPDX-License-Identifier: Apache-2.0 + +openapi: 3.0.3 +info: + title: SuperMQ Groups Service + description: | + This is the Groups Server based on the OpenAPI 3.0 specification. It is the HTTP API for managing platform groups. You can now help us improve the API whether it's by making changes to the definition itself or to the code. + Some useful links: + - [The SuperMQ repository](https://github.com/absmach/supermq) + contact: + email: info@abstractmachines.fr + license: + name: Apache 2.0 + url: https://github.com/absmach/supermq/blob/main/LICENSE + version: 0.15.1 + +servers: + - url: http://localhost:9004 + - url: https://localhost:9004 + +tags: + - name: Groups + description: CRUD operations for your groups + externalDocs: + description: Find out more about users groups + url: https://docs.supermq.abstractmachines.fr/ + - name: Roles + description: All operations involving roles for groups + externalDocs: + description: Find out more about roles + url: https://docs.supermq.abstractmachines.fr/ + - name: Health + description: Health check operations + externalDocs: + description: Find out more about health checks + url: https://docs.supermq.abstractmachines.fr/ + +paths: + /{domainID}/groups: + post: + operationId: createGroup + tags: + - Groups + summary: Creates new group + description: | + Creates new group that can be used for grouping entities. New account will + be uniquely identified by its identity. + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + requestBody: + $ref: "#/components/requestBodies/GroupCreateReq" + security: + - bearerAuth: [] + responses: + "201": + $ref: "#/components/responses/GroupCreateRes" + "400": + description: Failed due to malformed JSON. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "409": + description: Failed due to using an existing identity. + "415": + description: Missing or invalid content type. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + get: + operationId: listGroups + summary: Lists groups. + description: | + Lists groups up to a max level of hierarchy that can be fetched in one + request ( max level = 5). Result can be filtered by metadata. Groups will + be returned as JSON array or JSON tree. Due to performance concerns, result + is returned in subsets. + tags: + - Groups + security: + - bearerAuth: [] + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/Limit" + - $ref: "#/components/parameters/Offset" + - $ref: "#/components/parameters/Level" + - $ref: "#/components/parameters/Tree" + - $ref: "#/components/parameters/Metadata" + - $ref: "#/components/parameters/GroupName" + - $ref: "#/components/parameters/ParentID" + responses: + "200": + $ref: "#/components/responses/GroupPageRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: Group does not exist. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}: + get: + operationId: getGroup + summary: Gets group info. + description: | + Gets info on a group specified by id. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + security: + - bearerAuth: [] + responses: + "200": + $ref: "#/components/responses/GroupRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: Group does not exist. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + put: + operationId: updateGroup + summary: Updates group data. + description: | + Updates Name, Description or Metadata of a group. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + security: + - bearerAuth: [] + requestBody: + $ref: "#/components/requestBodies/GroupUpdateReq" + responses: + "200": + $ref: "#/components/responses/GroupRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: Group does not exist. + "409": + description: Failed due to using an existing identity. + "415": + description: Missing or invalid content type. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + delete: + summary: Delete group for a group with the given id. + description: | + Delete group removes a group with the given id from repo + and removes all the policies related to this group. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + security: + - bearerAuth: [] + responses: + "204": + description: Group deleted. + "400": + description: Failed due to malformed query parameters. + "401": + description: Missing or invalid access token provided. + "403": + description: Unauthorized access to group id. + "404": + description: A non-existent entity request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/enable: + post: + operationId: enableGroup + summary: Enables a group + description: | + Enables a specific group that is identifier by the group ID. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + security: + - bearerAuth: [] + responses: + "200": + $ref: "#/components/responses/GroupRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "409": + description: Failed due to already enabled group. + "415": + description: Missing or invalid content type. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/disable: + post: + operationId: disableGroup + summary: Disables a group + description: | + Disables a specific group that is identifier by the group ID. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + security: + - bearerAuth: [] + responses: + "200": + $ref: "#/components/responses/GroupRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "409": + description: Failed due to already disabled group. + "415": + description: Missing or invalid content type. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/hierarchy: + get: + operationId: listGroupHierarchy + summary: Lists groups hierarchy. + description: | + Lists groups heirarchy up to a max level of hierarchy that can be fetched in one + request ( max level = 5). Result can be filtered by metadata. Groups will + be returned as JSON array or JSON tree. Due to performance concerns, result + is returned in subsets. + tags: + - Groups + security: + - bearerAuth: [] + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "#/components/parameters/Level" + - $ref: "#/components/parameters/Tree" + - $ref: "#/components/parameters/Direction" + responses: + "200": + $ref: "#/components/responses/GroupsHierarchyPageRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: Group does not exist. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/parent: + post: + operationId: setGroupParentGroup + summary: Sets a parent group for a group. + description: | + Sets a parent group for a specific group that is identified by the group ID. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + requestBody: + $ref: "#/components/requestBodies/GroupParentReq" + security: + - bearerAuth: [] + responses: + "200": + description: Parent group set. + "400": + description: Failed due to malformed group's ID. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + delete: + operationId: removeGroupParentGroup + summary: Removes a parent group from a group. + description: | + Removes a parent group from a specific group that is identified by the group ID. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + requestBody: + $ref: "#/components/requestBodies/GroupParentReq" + security: + - bearerAuth: [] + responses: + "200": + description: Parent group removed. + "400": + description: Failed due to malformed group's ID. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/children: + post: + operationId: addChildrenGroups + summary: Add children groups. + description: | + Adds children groups for a specific group that is identified by the group ID. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + requestBody: + $ref: "#/components/requestBodies/GroupChildrenReq" + security: + - bearerAuth: [] + responses: + "204": + description: Children groups added successfully. + "400": + description: Failed due to malformed JSON. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "409": + description: Failed due to using an existing identity. + "415": + description: Missing or invalid content type. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + delete: + operationId: removeChildrenGroups + summary: Remove children groups. + description: | + Removes children groups for a specific group that is identified by the group ID. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + requestBody: + $ref: "#/components/requestBodies/GroupChildrenReq" + security: + - bearerAuth: [] + responses: + "204": + description: Children groups removed successfully. + "400": + description: Failed due to malformed JSON. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "409": + description: Failed due to using an existing identity. + "415": + description: Missing or invalid content type. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + get: + operationId: listChildrenGroups + summary: List children of a certain group + description: | + Lists groups up to a max level of hierarchy that can be fetched in one + request ( max level = 5). Result can be filtered by metadata. Groups will + be returned as JSON array or JSON tree. Due to performance concerns, result + is returned in subsets. + tags: + - Groups + security: + - bearerAuth: [] + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "#/components/parameters/Limit" + - $ref: "#/components/parameters/Offset" + - $ref: "#/components/parameters/StartLevel" + - $ref: "#/components/parameters/EndLevel" + - $ref: "#/components/parameters/Tree" + - $ref: "#/components/parameters/Metadata" + - $ref: "#/components/parameters/GroupName" + responses: + "200": + $ref: "#/components/responses/GroupPageRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: Group does not exist. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/children/all: + delete: + operationId: removeAllChildrenGroups + summary: Remove all children groups. + description: | + Removes all children groups for a specific group that is identified by the group ID. + tags: + - Groups + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + security: + - bearerAuth: [] + responses: + "204": + description: Children groups removed successfully. + "400": + description: Failed due to malformed JSON. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "409": + description: Failed due to using an existing identity. + "415": + description: Missing or invalid content type. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/roles: + post: + operationId: createGroupRole + summary: Creates a role for a group + description: | + Creates a role for a specific group that is identified by the group ID. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + requestBody: + $ref: "./schemas/roles.yml#/components/requestBodies/CreateRoleReq" + security: + - bearerAuth: [] + responses: + "201": + $ref: "./schemas/roles.yml#/components/responses/CreateRoleRes" + "400": + description: Failed due to malformed group's ID. + "401": + description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + get: + operationId: listGroupRoles + tags: + - Roles + summary: Retrieves groups roles. + description: | + Retrieves a list of group roles. Due to performance concerns, data + is retrieved in subsets. The API groups must ensure that the entire + dataset is consumed either by making subsequent requests, or by + increasing the subset size of the initial request. + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "#/components/parameters/Limit" + - $ref: "#/components/parameters/Offset" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/ListRolesRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/roles/{roleName}: + get: + operationId: getGroupRole + tags: + - Roles + summary: Retrieves group role. + description: | + Retrieves a specific group role that is identified by the role name. + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/GetRoleRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + put: + operationId: updateGroupRole + summary: Updates group role. + description: | + Updates a specific group role that is identified by the role name. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + requestBody: + $ref: "./schemas/roles.yml#/components/requestBodies/UpdateRoleReq" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/GetRoleRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + delete: + operationId: deleteGroupRole + summary: Deletes group role. + description: | + Deletes a specific group role that is identifier by the role name. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + security: + - bearerAuth: [] + responses: + "204": + description: Role deleted. + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/roles/{roleName}/actions: + post: + operationId: addGroupRoleAction + summary: Adds a role action for a group role. + description: | + Adds a role action for a specific group role that is identified by the role name. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + requestBody: + $ref: "./schemas/roles.yml#/components/requestBodies/AddRoleActionsReq" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/AddRoleActionsRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + get: + operationId: listGroupRoleActions + tags: + - Roles + summary: Lists group role actions. + description: | + Retrieves a list of group role actions. + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/ListRoleActionsRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/roles/{roleName}/actions/delete: + post: + operationId: deleteGroupRoleAction + summary: Deletes role actions for a group role. + description: | + Deletes a role action for a specific group role that is identified by the role name. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + requestBody: + $ref: "./schemas/roles.yml#/components/requestBodies/AddRoleActionsReq" + security: + - bearerAuth: [] + responses: + "204": + description: Role actions deleted. + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/roles/{roleName}/actions/delete-all: + post: + operationId: deleteAllGroupRoleActions + summary: Deletes all role actions for a group role. + description: | + Deletes all role actions for a specific group role that is identified by the role name. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + security: + - bearerAuth: [] + responses: + "204": + description: All role actions deleted. + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/roles/{roleName}/members: + post: + operationId: addGroupRoleMember + summary: Adds a member to a group role. + description: | + Adds a member to a specific group role that is identified by the role name. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + requestBody: + $ref: "./schemas/roles.yml#/components/requestBodies/AddRoleMembersReq" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/AddRoleMembersRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + get: + operationId: listGroupRoleMembers + tags: + - Roles + summary: Lists group role members. + description: | + Retrieves a list of group role members. + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/ListRoleMembersRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/roles/{roleName}/members/delete: + post: + operationId: deleteGroupRoleMembers + summary: Deletes members from a group role. + description: | + Deletes a member from a specific group role that is identified by the role name. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + requestBody: + $ref: "./schemas/roles.yml#/components/requestBodies/AddRoleMembersReq" + security: + - bearerAuth: [] + responses: + "204": + description: Role members deleted. + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/{groupID}/roles/{roleName}/members/delete-all: + post: + operationId: deleteAllGroupRoleMembers + summary: Deletes all members from a group role. + description: | + Deletes all members from a specific group role that is identified by the role name. + tags: + - Roles + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + - $ref: "#/components/parameters/GroupID" + - $ref: "./schemas/roles.yml#/components/parameters/RoleName" + security: + - bearerAuth: [] + responses: + "204": + description: All role members deleted. + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /{domainID}/groups/roles/available-actions: + get: + operationId: listAvailableActions + tags: + - Roles + summary: Retrieves available actions. + description: | + Retrieves a list of available actions. + parameters: + - $ref: "auth.yml#/components/parameters/DomainID" + security: + - bearerAuth: [] + responses: + "200": + $ref: "./schemas/roles.yml#/components/responses/ListAvailableActionsRes" + "400": + description: Failed due to malformed query parameters. + "401": + description: | + Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. + "404": + description: A non-existent entity request. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" + + /health: + get: + operationId: health + summary: Retrieves service health check info. + tags: + - Health + security: [] + responses: + "200": + $ref: "#/components/responses/HealthRes" + "500": + $ref: "#/components/responses/ServiceError" + +components: + schemas: + GroupReqObj: + type: object + properties: + name: + type: string + example: groupName + description: Free-form group name. Group name is unique on the given hierarchy level. + description: + type: string + example: long group description + description: Group description, free form text. + parent_id: + type: string + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + description: Id of parent group, it must be existing group. + metadata: + type: object + example: { "domain": "example.com" } + description: Arbitrary, object-encoded groups's data. + status: + type: string + description: Group Status + format: string + example: enabled + required: + - name + + Group: + type: object + properties: + id: + type: string + format: uuid + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + description: Unique group identifier generated by the service. + name: + type: string + example: groupName + description: Free-form group name. Group name is unique on the given hierarchy level. + domain_id: + type: string + format: uuid + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + description: ID of the domain to which the group belongs.. + parent_id: + type: string + format: uuid + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + description: Group parent identifier. + description: + type: string + example: long group description + description: Group description, free form text. + metadata: + type: object + example: { "role": "general" } + description: Arbitrary, object-encoded groups's data. + path: + type: string + example: bb7edb32-2eac-4aad-aebe-ed96fe073879.bb7edb32-2eac-4aad-aebe-ed96fe073879 + description: Hierarchy path, concatenated ids of group ancestors. + level: + type: integer + description: Level in hierarchy, distance from the root group. + format: int32 + example: 2 + maximum: 5 + created_at: + type: string + format: date-time + example: "2019-11-26 13:31:52" + description: Datetime when the group was created. + updated_at: + type: string + format: date-time + example: "2019-11-26 13:31:52" + description: Datetime when the group was created. + status: + type: string + description: Group Status + format: string + example: enabled + xml: + name: group + + Members: + type: object + properties: + id: + type: string + format: uuid + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + description: User unique identifier. + first_name: + type: string + example: John + description: User's first name. + last_name: + type: string + example: Doe + description: User's last name. + email: + type: string + example: user@supermq.com + description: User's email address. + tags: + type: array + minItems: 0 + items: + type: string + example: ["computations", "datasets"] + description: User tags. + credentials: + type: object + properties: + username: + type: string + example: john_doe + description: User's username. + secret: + type: string + example: password + minimum: 8 + description: User secret password. + metadata: + type: object + example: { "role": "general" } + description: Arbitrary, object-encoded user's data. + status: + type: string + description: User Status + format: string + example: enabled + created_at: + type: string + format: date-time + example: "2019-11-26 13:31:52" + description: Time when the group was created. + updated_at: + type: string + format: date-time + example: "2019-11-26 13:31:52" + description: Time when the group was created. + xml: + name: members + + GroupsPage: + type: object + properties: + groups: + type: array + minItems: 0 + uniqueItems: true + items: + $ref: "#/components/schemas/Group" + total: + type: integer + example: 1 + description: Total number of items. + offset: + type: integer + description: Number of items to skip during retrieval. + limit: + type: integer + example: 10 + description: Maximum number of items to return in one page. + required: + - groups + - total + - offset + + GroupsHierarchyPage: + type: object + properties: + level: + type: integer + example: 1 + description: Level of hierarchy. + direction: + type: integer + example: -1 + description: Direction of hierarchy traversal. + groups: + type: array + minItems: 0 + uniqueItems: true + items: + $ref: "#/components/schemas/Group" + + MembersPage: + type: object + properties: + members: + type: array + minItems: 0 + uniqueItems: true + items: + $ref: "#/components/schemas/Members" + total: + type: integer + example: 1 + description: Total number of items. + offset: + type: integer + description: Number of items to skip during retrieval. + limit: + type: integer + example: 10 + description: Maximum number of items to return in one page. + required: + - members + - total + - level + + GroupUpdate: + type: object + properties: + name: + type: string + example: groupName + description: Free-form group name. Group name is unique on the given hierarchy level. + description: + type: string + example: long description but not too long + description: Group description, free form text. + metadata: + type: object + example: { "role": "general" } + description: Arbitrary, object-encoded groups's data. + required: + - name + - metadata + - description + + ParentGroupReqObj: + type: object + properties: + group_id: + type: string + format: uuid + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + description: Parent group unique identifier. + required: + - group_id + + ChildrenGroupReqObj: + type: object + properties: + groups: + type: array + minItems: 1 + items: + type: string + format: uuid + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + description: Children group IDs. + required: + - groups + + Error: + type: object + properties: + error: + type: string + description: Error message + example: { "error": "malformed entity specification" } + + HealthRes: + type: object + properties: + status: + type: string + description: Service status. + enum: + - pass + version: + type: string + description: Service version. + example: 0.0.1 + commit: + type: string + description: Service commit hash. + example: 7d6f4dc4f7f0c1fa3dc24eddfb18bb5073ff4f62 + description: + type: string + description: Service description. + example: service + build_time: + type: string + description: Service build time. + example: 1970-01-01_00:00:00 + + parameters: + Referer: + name: Referer + description: Host being sent by browser. + in: header + schema: + type: string + required: true + + UserID: + name: userID + description: Unique user identifier. + in: path + schema: + type: string + format: uuid + minLength: 36 + maxLength: 36 + pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$" + required: true + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + + Status: + name: status + description: User account status. + in: query + schema: + type: string + default: enabled + required: false + example: enabled + + Tags: + name: tags + description: User tags. + in: query + schema: + type: array + minItems: 0 + uniqueItems: true + items: + type: string + required: false + example: ["yello", "orange"] + + GroupName: + name: name + description: Group's name. + in: query + schema: + type: string + required: false + example: "groupName" + + GroupDescription: + name: name + description: Group's description. + in: query + schema: + type: string + required: false + example: "group description" + + GroupID: + name: groupID + description: Unique group identifier. + in: path + schema: + type: string + format: uuid + minLength: 36 + maxLength: 36 + pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$" + required: true + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + + ChannelID: + name: channelID + description: Unique channel identifier. + in: path + schema: + type: string + format: uuid + minLength: 36 + maxLength: 36 + pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$" + required: true + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + + MemberID: + name: memberID + description: Unique member identifier. + in: path + schema: + type: string + format: uuid + minLength: 36 + maxLength: 36 + pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$" + required: true + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + + ParentID: + name: parentID + description: Unique parent identifier for a group. + in: query + schema: + type: string + format: uuid + required: false + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + + Level: + name: level + description: Level of hierarchy up to which to retrieve groups from given group id. + in: query + schema: + type: integer + minimum: 1 + maximum: 5 + required: false + + StartLevel: + name: start_level + description: Level of hierarchy from which to start retrieving groups from given group id. + in: query + schema: + type: integer + required: false + + EndLevel: + name: end_level + description: Level of hierarchy up to which to retrieve groups from given group id. + in: query + schema: + type: integer + required: false + + Direction: + name: direction + description: Direction of hierarchy traversal. + in: query + schema: + type: integer + required: false + + Tree: + name: tree + description: Specify type of response, JSON array or tree. + in: query + required: false + schema: + type: boolean + default: false + + Metadata: + name: metadata + description: Metadata filter. Filtering is performed matching the parameter with metadata on top level. Parameter is json. + in: query + schema: + type: string + minimum: 0 + required: false + + Limit: + name: limit + description: Size of the subset to retrieve. + in: query + schema: + type: integer + default: 10 + maximum: 100 + minimum: 1 + required: false + example: "100" + + Offset: + name: offset + description: Number of items to skip during retrieval. + in: query + schema: + type: integer + default: 0 + minimum: 0 + required: false + example: "0" + + requestBodies: + GroupCreateReq: + description: JSON-formatted document describing the new group to be registered + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/GroupReqObj" + + GroupUpdateReq: + description: JSON-formated document describing the metadata and name of group to be update + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/GroupUpdate" + + GroupParentReq: + description: JSON-formated document describing the parent group to be set to or removed from a group. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ParentGroupReqObj" + + GroupChildrenReq: + description: JSON-formated document describing the children groups to be added to a group. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ChildrenGroupReqObj" + + responses: + GroupCreateRes: + description: Registered new group. + headers: + Location: + schema: + type: string + format: url + description: Registered group relative URL in the format `/groups/` + content: + application/json: + schema: + $ref: "#/components/schemas/Group" + links: + get: + operationId: getGroup + parameters: + groupID: $response.body#/id + get_children: + operationId: listChildren + parameters: + groupID: $response.body#/id + get_parent: + operationId: listParents + parameters: + groupID: $response.body#/id + get_channels: + operationId: listGroupsInChannel + parameters: + memberID: $response.body#/id + get_users: + operationId: listGroupsByUser + parameters: + memberID: $response.body#/id + update: + operationId: updateGroup + parameters: + groupID: $response.body#/id + disable: + operationId: disableGroup + parameters: + groupID: $response.body#/id + enable: + operationId: enableGroup + parameters: + groupID: $response.body#/id + assign: + operationId: assignUser + parameters: + groupID: $response.body#/id + unassign: + operationId: unassignUser + parameters: + groupID: $response.body#/id + + GroupRes: + description: Data retrieved. + content: + application/json: + schema: + $ref: "#/components/schemas/Group" + links: + get_children: + operationId: listChildren + parameters: + groupID: $response.body#/id + get_parent: + operationId: listParents + parameters: + groupID: $response.body#/id + get_channels: + operationId: listGroupsInChannel + parameters: + memberID: $response.body#/id + get_users: + operationId: listGroupsByUser + parameters: + memberID: $response.body#/id + assign: + operationId: assignUser + parameters: + groupID: $response.body#/id + unassign: + operationId: unassignUser + parameters: + groupID: $response.body#/id + + GroupPageRes: + description: Data retrieved. + content: + application/json: + schema: + $ref: "#/components/schemas/GroupsPage" + + GroupsHierarchyPageRes: + description: Group hierarchy retrieved. + content: + application/json: + schema: + $ref: "#/components/schemas/GroupsHierarchyPage" + + MembersPageRes: + description: Group members retrieved. + content: + application/json: + schema: + $ref: "#/components/schemas/MembersPage" + + HealthRes: + description: Service Health Check. + content: + application/health+json: + schema: + $ref: "#/components/schemas/HealthRes" + + ServiceError: + description: Unexpected server-side error occurred. + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: | + * User access: "Authorization: Bearer " + + refreshAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: | + * User refresh token used to get another access token: "Authorization: Bearer " +security: + - bearerAuth: [] + - refreshAuth: [] diff --git a/api/openapi/http.yml b/api/openapi/http.yml index afc9812320..c132fb3e05 100644 --- a/api/openapi/http.yml +++ b/api/openapi/http.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:8008 diff --git a/api/openapi/invitations.yml b/api/openapi/invitations.yml index de36fc9dcb..10cc2adc35 100644 --- a/api/openapi/invitations.yml +++ b/api/openapi/invitations.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9020 diff --git a/api/openapi/journal.yml b/api/openapi/journal.yml index 519e40ed5b..8ebebb28cb 100644 --- a/api/openapi/journal.yml +++ b/api/openapi/journal.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9021 diff --git a/api/openapi/notifiers.yml b/api/openapi/notifiers.yml index 4aec9b385d..0a2ce7a432 100644 --- a/api/openapi/notifiers.yml +++ b/api/openapi/notifiers.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9014 diff --git a/api/openapi/provision.yml b/api/openapi/provision.yml index 5c3bbf2b62..d487bbd234 100644 --- a/api/openapi/provision.yml +++ b/api/openapi/provision.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9016 @@ -44,6 +44,8 @@ paths: description: Failed due to malformed JSON. "401": description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. "415": description: Missing or invalid content type. "422": @@ -64,6 +66,8 @@ paths: $ref: "#/components/responses/ProvisionRes" "401": description: Missing or invalid access token provided. + "403": + description: Failed to perform authorization over the entity. "415": description: Missing or invalid content type. "422": diff --git a/api/openapi/readers.yml b/api/openapi/readers.yml index c56afc3d05..6436bbdca2 100644 --- a/api/openapi/readers.yml +++ b/api/openapi/readers.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9003 @@ -35,7 +35,7 @@ tags: url: https://docs.supermq.abstractmachines.fr/ paths: - /{domainID}/channels/{chanId}/messages: + /channels/{chanId}/messages: get: operationId: getMessages summary: Retrieves messages sent to single channel @@ -47,7 +47,6 @@ paths: tags: - readers parameters: - - $ref: "#/components/parameters/DomainID" - $ref: "#/components/parameters/ChanId" - $ref: "#/components/parameters/Limit" - $ref: "#/components/parameters/Offset" diff --git a/api/openapi/schemas/roles.yml b/api/openapi/schemas/roles.yml index 958c8c3211..e62389f746 100644 --- a/api/openapi/schemas/roles.yml +++ b/api/openapi/schemas/roles.yml @@ -163,6 +163,20 @@ components: "c01ed106-e52d-4aa4-bed3-39f360177cfa", ] + AvailableActionsObj: + type: object + properties: + available_actions: + type: array + description: List of all available actions. + items: + type: string + example: + [ + "read", + "update", + ] + parameters: RoleName: name: roleName @@ -255,3 +269,10 @@ components: application/json: schema: $ref: '#/components/schemas/RoleMembersObj' + + ListAvailableActionsRes: + description: Available actions retrieved successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/AvailableActionsObj' diff --git a/api/openapi/twins.yml b/api/openapi/twins.yml index 94fea19248..aad406266a 100644 --- a/api/openapi/twins.yml +++ b/api/openapi/twins.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9018 diff --git a/api/openapi/users.yml b/api/openapi/users.yml index 615772b9d9..9d7d679a74 100644 --- a/api/openapi/users.yml +++ b/api/openapi/users.yml @@ -13,7 +13,7 @@ info: license: name: Apache 2.0 url: https://github.com/absmach/supermq/blob/main/LICENSE - version: 0.14.0 + version: 0.15.1 servers: - url: http://localhost:9002 @@ -25,10 +25,10 @@ tags: externalDocs: description: Find out more about users url: https://docs.supermq.abstractmachines.fr/ - - name: Groups - description: Everything about your Groups + - name: Health + description: Health check operations externalDocs: - description: Find out more about users groups + description: Find out more about health checks url: https://docs.supermq.abstractmachines.fr/ paths: @@ -628,532 +628,135 @@ paths: "500": $ref: "#/components/responses/ServiceError" - /users/tokens/issue: - post: - operationId: issueToken - summary: Issue Token - description: | - Issue Access and Refresh Token used for authenticating into the system. - tags: - - Users - requestBody: - $ref: "#/components/requestBodies/IssueTokenReq" - responses: - "200": - $ref: "#/components/responses/TokenRes" - "400": - description: Failed due to malformed JSON. - "401": - description: Missing or invalid access token provided. - "404": - description: A non-existent entity request. - "415": - description: Missing or invalid content type. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - /users/tokens/refresh: - post: - operationId: refreshToken - summary: Refresh Token - description: | - Refreshes Access and Refresh Token used for authenticating into the system. - tags: - - Users - security: - - refreshAuth: [] - responses: - "200": - $ref: "#/components/responses/TokenRes" - "400": - description: Failed due to malformed JSON. - "401": - description: Missing or invalid access token provided. - "404": - description: A non-existent entity request. - "415": - description: Missing or invalid content type. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - /{domainID}/groups: - post: - operationId: createGroup - tags: - - Groups - summary: Creates new group - description: | - Creates new group that can be used for grouping entities. New account will - be uniquely identified by its identity. - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - requestBody: - $ref: "#/components/requestBodies/GroupCreateReq" - security: - - bearerAuth: [] - responses: - "201": - $ref: "#/components/responses/GroupCreateRes" - "400": - description: Failed due to malformed JSON. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: A non-existent entity request. - "409": - description: Failed due to using an existing identity. - "415": - description: Missing or invalid content type. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - get: - operationId: listGroups - summary: Lists groups. - description: | - Lists groups up to a max level of hierarchy that can be fetched in one - request ( max level = 5). Result can be filtered by metadata. Groups will - be returned as JSON array or JSON tree. Due to performance concerns, result - is returned in subsets. - tags: - - Groups - security: - - bearerAuth: [] - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/Limit" - - $ref: "#/components/parameters/Offset" - - $ref: "#/components/parameters/Level" - - $ref: "#/components/parameters/Tree" - - $ref: "#/components/parameters/Metadata" - - $ref: "#/components/parameters/GroupName" - - $ref: "#/components/parameters/ParentID" - responses: - "200": - $ref: "#/components/responses/GroupPageRes" - "400": - description: Failed due to malformed query parameters. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: Group does not exist. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - /{domainID}/groups/{groupID}: - get: - operationId: getGroup - summary: Gets group info. - description: | - Gets info on a group specified by id. - tags: - - Groups - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - security: - - bearerAuth: [] - responses: - "200": - $ref: "#/components/responses/GroupRes" - "400": - description: Failed due to malformed query parameters. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: Group does not exist. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - put: - operationId: updateGroup - summary: Updates group data. - description: | - Updates Name, Description or Metadata of a group. - tags: - - Groups - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - security: - - bearerAuth: [] - requestBody: - $ref: "#/components/requestBodies/GroupUpdateReq" - responses: - "200": - $ref: "#/components/responses/GroupRes" - "400": - description: Failed due to malformed query parameters. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: Group does not exist. - "409": - description: Failed due to using an existing identity. - "415": - description: Missing or invalid content type. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - delete: - summary: Delete group for a group with the given id. - description: | - Delete group removes a group with the given id from repo - and removes all the policies related to this group. - tags: - - Groups - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - security: - - bearerAuth: [] - responses: - "204": - description: Group deleted. - "400": - description: Failed due to malformed query parameters. - "401": - description: Missing or invalid access token provided. - "403": - description: Unauthorized access to group id. - "404": - description: A non-existent entity request. - "500": - $ref: "#/components/responses/ServiceError" - - /{domainID}/groups/{groupID}/children: - get: - operationId: listChildren - summary: List children of a certain group - description: | - Lists groups up to a max level of hierarchy that can be fetched in one - request ( max level = 5). Result can be filtered by metadata. Groups will - be returned as JSON array or JSON tree. Due to performance concerns, result - is returned in subsets. - tags: - - Groups - security: - - bearerAuth: [] - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - - $ref: "#/components/parameters/Limit" - - $ref: "#/components/parameters/Offset" - - $ref: "#/components/parameters/Level" - - $ref: "#/components/parameters/Tree" - - $ref: "#/components/parameters/Metadata" - - $ref: "#/components/parameters/GroupName" - - $ref: "#/components/parameters/ParentID" - responses: - "200": - $ref: "#/components/responses/GroupPageRes" - "400": - description: Failed due to malformed query parameters. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: Group does not exist. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - /{domainID}/groups/{groupID}/parents: - get: - operationId: listParents - summary: List parents of a certain group - description: | - Lists groups up to a max level of hierarchy that can be fetched in one - request ( max level = 5). Result can be filtered by metadata. Groups will - be returned as JSON array or JSON tree. Due to performance concerns, result - is returned in subsets. - tags: - - Groups - security: - - bearerAuth: [] - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - - $ref: "#/components/parameters/Limit" - - $ref: "#/components/parameters/Offset" - - $ref: "#/components/parameters/Level" - - $ref: "#/components/parameters/Tree" - - $ref: "#/components/parameters/Metadata" - - $ref: "#/components/parameters/GroupName" - - $ref: "#/components/parameters/ParentID" - responses: - "200": - $ref: "#/components/responses/GroupPageRes" - "400": - description: Failed due to malformed query parameters. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: Group does not exist. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - /{domainID}/groups/{groupID}/enable: - post: - operationId: enableGroup - summary: Enables a group - description: | - Enables a specific group that is identifier by the group ID. - tags: - - Groups - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - security: - - bearerAuth: [] - responses: - "200": - $ref: "#/components/responses/GroupRes" - "400": - description: Failed due to malformed query parameters. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: A non-existent entity request. - "409": - description: Failed due to already enabled group. - "415": - description: Missing or invalid content type. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - /{domainID}/groups/{groupID}/disable: - post: - operationId: disableGroup - summary: Disables a group - description: | - Disables a specific group that is identifier by the group ID. - tags: - - Groups - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - security: - - bearerAuth: [] - responses: - "200": - $ref: "#/components/responses/GroupRes" - "400": - description: Failed due to malformed query parameters. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: A non-existent entity request. - "409": - description: Failed due to already disabled group. - "415": - description: Missing or invalid content type. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - /{domainID}/groups/{groupID}/users/assign: - post: - operationId: assignUser - summary: Assigns a user to a group - description: | - Assigns a specific user to a group that is identifier by the group ID. - tags: - - Groups - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - requestBody: - $ref: "#/components/requestBodies/AssignUserReq" - security: - - bearerAuth: [] - responses: - "200": - description: Member assigned. - "400": - description: Failed due to malformed group's ID. - "401": - description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. - "404": - description: A non-existent entity request. - "415": - description: Missing or invalid content type. - "422": - description: Database can't process request. - "500": - $ref: "#/components/responses/ServiceError" - - /{domainID}/groups/{groupID}/users/unassign: - post: - operationId: unassignUser - summary: Unassigns a user to a group - description: | - Unassigns a specific user to a group that is identifier by the group ID. + /{domainID}/clients/{clientID}/users: + get: + operationId: listUsersInClient tags: - - Groups + - Users + summary: List users associated with a client + description: | + Retrieves a list of users associated with a client. Due to performance concerns, data + is retrieved in subsets. The API must ensure that the entire + dataset is consumed either by making subsequent requests, or by + increasing the subset size of the initial request. parameters: - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/GroupID" - requestBody: - $ref: "#/components/requestBodies/AssignUserReq" - security: - - bearerAuth: [] + - $ref: "#/components/parameters/ClientID" + - $ref: "#/components/parameters/Limit" + - $ref: "#/components/parameters/Offset" + - $ref: "#/components/parameters/Level" + - $ref: "#/components/parameters/Tree" + - $ref: "#/components/parameters/Metadata" + - $ref: "#/components/parameters/ChannelName" + - $ref: "#/components/parameters/ParentID" responses: - "204": - description: Member unassigned. + "200": + $ref: "#/components/responses/MembersPageRes" "400": - description: Failed due to malformed group's ID. + description: Failed due to malformed query parameters. "401": - description: Missing or invalid access token provided. + description: | + Missing or invalid access token provided. + This endpoint is available only for administrators. "403": description: Failed to perform authorization over the entity. "404": description: A non-existent entity request. - "415": - description: Missing or invalid content type. "422": description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" - - /{domainID}/channels/{memberID}/groups: + + /{domainID}/users: get: - operationId: listGroupsInChannel - summary: Get group associated with the member + summary: List users assigned to domain description: | - Gets groups associated with the channel member specified by id. + List users assigned to domain that is identified by the domain ID. tags: - - Groups + - Users parameters: - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/MemberID" - $ref: "#/components/parameters/Limit" - $ref: "#/components/parameters/Offset" - $ref: "#/components/parameters/Metadata" - $ref: "#/components/parameters/Status" - - $ref: "#/components/parameters/Tags" security: - bearerAuth: [] responses: "200": - $ref: "#/components/responses/GroupPageRes" + $ref: "#/components/responses/UserPageRes" + description: List of users assigned to domain. "400": - description: Failed due to malformed query parameters. + description: Failed due to malformed domain's ID. "401": description: Missing or invalid access token provided. "403": - description: Failed to perform authorization over the entity. + description: Unauthorized access the domain ID. "404": - description: Group does not exist. + description: A non-existent entity request. "422": description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" - /{domainID}/users/{memberID}/groups: - get: - operationId: listGroupsByUser - summary: Get group associated with the member + /users/tokens/issue: + post: + operationId: issueToken + summary: Issue Token description: | - Gets groups associated with the user member specified by id. + Issue Access and Refresh Token used for authenticating into the system. tags: - - Groups - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/MemberID" - - $ref: "#/components/parameters/Limit" - - $ref: "#/components/parameters/Offset" - - $ref: "#/components/parameters/Metadata" - - $ref: "#/components/parameters/Status" - - $ref: "#/components/parameters/Tags" - security: - - bearerAuth: [] + - Users + requestBody: + $ref: "#/components/requestBodies/IssueTokenReq" responses: "200": - $ref: "#/components/responses/GroupPageRes" + $ref: "#/components/responses/TokenRes" "400": - description: Failed due to malformed query parameters. + description: Failed due to malformed JSON. "401": description: Missing or invalid access token provided. - "403": - description: Failed to perform authorization over the entity. "404": - description: Group does not exist. + description: A non-existent entity request. + "415": + description: Missing or invalid content type. "422": description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" - /{domainID}/users: - get: - summary: List users assigned to domain + + /users/tokens/refresh: + post: + operationId: refreshToken + summary: Refresh Token description: | - List users assigned to domain that is identified by the domain ID. + Refreshes Access and Refresh Token used for authenticating into the system. tags: - - Domains - parameters: - - $ref: "auth.yml#/components/parameters/DomainID" - - $ref: "#/components/parameters/Limit" - - $ref: "#/components/parameters/Offset" - - $ref: "#/components/parameters/Metadata" - - $ref: "#/components/parameters/Status" + - Users security: - - bearerAuth: [] + - refreshAuth: [] responses: "200": - $ref: "#/components/responses/UserPageRes" - description: List of users assigned to domain. + $ref: "#/components/responses/TokenRes" "400": - description: Failed due to malformed domain's ID. + description: Failed due to malformed JSON. "401": description: Missing or invalid access token provided. - "403": - description: Unauthorized access the domain ID. "404": description: A non-existent entity request. + "415": + description: Missing or invalid content type. "422": description: Database can't process request. "500": $ref: "#/components/responses/ServiceError" + /health: get: operationId: health summary: Retrieves service health check info. tags: - - health + - Health security: [] responses: "200": @@ -1214,33 +817,6 @@ components: required: - credentials - GroupReqObj: - type: object - properties: - name: - type: string - example: groupName - description: Free-form group name. Group name is unique on the given hierarchy level. - description: - type: string - example: long group description - description: Group description, free form text. - parent_id: - type: string - example: bb7edb32-2eac-4aad-aebe-ed96fe073879 - description: Id of parent group, it must be existing group. - metadata: - type: object - example: { "domain": "example.com" } - description: Arbitrary, object-encoded groups's data. - status: - type: string - description: Group Status - format: string - example: enabled - required: - - name - User: type: object properties: @@ -1301,64 +877,6 @@ components: xml: name: user - Group: - type: object - properties: - id: - type: string - format: uuid - example: bb7edb32-2eac-4aad-aebe-ed96fe073879 - description: Unique group identifier generated by the service. - name: - type: string - example: groupName - description: Free-form group name. Group name is unique on the given hierarchy level. - domain_id: - type: string - format: uuid - example: bb7edb32-2eac-4aad-aebe-ed96fe073879 - description: ID of the domain to which the group belongs.. - parent_id: - type: string - format: uuid - example: bb7edb32-2eac-4aad-aebe-ed96fe073879 - description: Group parent identifier. - description: - type: string - example: long group description - description: Group description, free form text. - metadata: - type: object - example: { "role": "general" } - description: Arbitrary, object-encoded groups's data. - path: - type: string - example: bb7edb32-2eac-4aad-aebe-ed96fe073879.bb7edb32-2eac-4aad-aebe-ed96fe073879 - description: Hierarchy path, concatenated ids of group ancestors. - level: - type: integer - description: Level in hierarchy, distance from the root group. - format: int32 - example: 2 - maximum: 5 - created_at: - type: string - format: date-time - example: "2019-11-26 13:31:52" - description: Datetime when the group was created. - updated_at: - type: string - format: date-time - example: "2019-11-26 13:31:52" - description: Datetime when the group was created. - status: - type: string - description: Group Status - format: string - example: enabled - xml: - name: group - Members: type: object properties: @@ -1445,31 +963,6 @@ components: - total - offset - GroupsPage: - type: object - properties: - groups: - type: array - minItems: 0 - uniqueItems: true - items: - $ref: "#/components/schemas/Group" - total: - type: integer - example: 1 - description: Total number of items. - offset: - type: integer - description: Number of items to skip during retrieval. - limit: - type: integer - example: 10 - description: Maximum number of items to return in one page. - required: - - groups - - total - - offset - MembersPage: type: object properties: @@ -1585,26 +1078,6 @@ components: required: - username - GroupUpdate: - type: object - properties: - name: - type: string - example: groupName - description: Free-form group name. Group name is unique on the given hierarchy level. - description: - type: string - example: long description but not too long - description: Group description, free form text. - metadata: - type: object - example: { "role": "general" } - description: Arbitrary, object-encoded groups's data. - required: - - name - - metadata - - description - AssignReqObj: type: object properties: @@ -1837,6 +1310,19 @@ components: pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$" required: true example: bb7edb32-2eac-4aad-aebe-ed96fe073879 + + ClientID: + name: clientID + description: Unique client identifier. + in: path + schema: + type: string + format: uuid + minLength: 36 + maxLength: 36 + pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$" + required: true + example: bb7edb32-2eac-4aad-aebe-ed96fe073879 MemberID: name: memberID @@ -1977,22 +1463,6 @@ components: schema: $ref: "#/components/schemas/Username" - GroupCreateReq: - description: JSON-formatted document describing the new group to be registered - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/GroupReqObj" - - GroupUpdateReq: - description: JSON-formated document describing the metadata and name of group to be update - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/GroupUpdate" - AssignReq: description: JSON-formated document describing the policy related to assigning members to a group required: true @@ -2159,99 +1629,6 @@ components: schema: $ref: "#/components/schemas/UsersPage" - GroupCreateRes: - description: Registered new group. - headers: - Location: - schema: - type: string - format: url - description: Registered group relative URL in the format `/groups/` - content: - application/json: - schema: - $ref: "#/components/schemas/Group" - links: - get: - operationId: getGroup - parameters: - groupID: $response.body#/id - get_children: - operationId: listChildren - parameters: - groupID: $response.body#/id - get_parent: - operationId: listParents - parameters: - groupID: $response.body#/id - get_channels: - operationId: listGroupsInChannel - parameters: - memberID: $response.body#/id - get_users: - operationId: listGroupsByUser - parameters: - memberID: $response.body#/id - update: - operationId: updateGroup - parameters: - groupID: $response.body#/id - disable: - operationId: disableGroup - parameters: - groupID: $response.body#/id - enable: - operationId: enableGroup - parameters: - groupID: $response.body#/id - assign: - operationId: assignUser - parameters: - groupID: $response.body#/id - unassign: - operationId: unassignUser - parameters: - groupID: $response.body#/id - - GroupRes: - description: Data retrieved. - content: - application/json: - schema: - $ref: "#/components/schemas/Group" - links: - get_children: - operationId: listChildren - parameters: - groupID: $response.body#/id - get_parent: - operationId: listParents - parameters: - groupID: $response.body#/id - get_channels: - operationId: listGroupsInChannel - parameters: - memberID: $response.body#/id - get_users: - operationId: listGroupsByUser - parameters: - memberID: $response.body#/id - assign: - operationId: assignUser - parameters: - groupID: $response.body#/id - unassign: - operationId: unassignUser - parameters: - groupID: $response.body#/id - - GroupPageRes: - description: Data retrieved. - content: - application/json: - schema: - $ref: "#/components/schemas/GroupsPage" - MembersPageRes: description: Group members retrieved. content: diff --git a/groups/api/http/transport.go b/groups/api/http/transport.go index 8384398c90..1caee6a4a7 100644 --- a/groups/api/http/transport.go +++ b/groups/api/http/transport.go @@ -6,6 +6,7 @@ package api import ( "log/slog" + "github.com/absmach/supermq" "github.com/absmach/supermq/groups" "github.com/absmach/supermq/internal/api" "github.com/absmach/supermq/pkg/apiutil" @@ -13,6 +14,7 @@ import ( roleManagerHttp "github.com/absmach/supermq/pkg/roles/rolemanager/api" "github.com/go-chi/chi/v5" kithttp "github.com/go-kit/kit/transport/http" + "github.com/prometheus/client_golang/prometheus/promhttp" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) @@ -133,5 +135,8 @@ func MakeHandler(svc groups.Service, authn authn.Authentication, mux *chi.Mux, l }) }) + mux.Get("/health", supermq.Health("groups", instanceID)) + mux.Handle("/metrics", promhttp.Handler()) + return mux }