# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

openapi: 3.0.3
info:
  title: SuperMQ Users Service
  description: |
    This is the Users Server based on the OpenAPI 3.0 specification.  It is the HTTP API for managing platform users. 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.18.0

servers:
  - url: http://localhost:9002
  - url: https://localhost:9002

tags:
  - name: Users
    description: Everything about your Users
    externalDocs:
      description: Find out more about users
      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:
  /users:
    post:
      operationId: createUser
      tags:
        - Users
      summary: Registers user account
      description: |
        Registers new user account given email and password. New account will
        be uniquely identified by its email address.
      requestBody:
        $ref: "#/components/requestBodies/UserCreateReq"
      security: []
      responses:
        "201":
          $ref: "#/components/responses/UserCreateRes"
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "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: listUsers
      tags:
        - Users
      summary: List users
      description: |
        Retrieves a list of users. 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: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
        - $ref: "#/components/parameters/Metadata"
        - $ref: "#/components/parameters/Status"
        - $ref: "#/components/parameters/FirstName"
        - $ref: "#/components/parameters/LastName"
        - $ref: "#/components/parameters/Username"
        - $ref: "#/components/parameters/Email"
        - $ref: "#/components/parameters/Tag"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserPageRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
            This endpoint is available only for administrators.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/profile:
    get:
      operationId: getProfile
      summary: Gets info on currently logged in user.
      description: |
        Gets info on currently logged in user. Info is obtained using
        authorization token
      tags:
        - Users
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/{userID}:
    get:
      operationId: getUser
      summary: Retrieves a user
      description: |
        Retrieves a specific user that is identifier by the user ID.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "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"

    patch:
      operationId: updateUser
      summary: Updates first, last name and metadata of the user.
      description: |
        Updates name and metadata of the user with provided ID. Name and metadata
        is updated using authorization token and the new received info.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      requestBody:
        $ref: "#/components/requestBodies/UserUpdateReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "400":
          description: Failed due to malformed JSON.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: Failed due to non existing user.
        "401":
          description: Missing or invalid access token provided.
        "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 a user
      description: |
        Delete a specific user that is identifier by the user ID.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      security:
        - bearerAuth: []
      responses:
        "204":
          description: User 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.
        "405":
          description: Method not allowed.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/{userID}/username:
    patch:
      operationId: updateUsername
      summary: Updates user's username.
      description: |
        Updates username of the user with provided ID. Username is
        updated using authorization token and the new received username.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      requestBody:
        $ref: "#/components/requestBodies/UpdateUsernameReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "400":
          description: Failed due to malformed JSON.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: Failed due to non existing user.
        "401":
          description: Missing or invalid access token provided.
        "409":
          description: Failed due to using an existing username.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/{userID}/tags:
    patch:
      operationId: updateTags
      summary: Updates tags of the user.
      description: |
        Updates tags of the user with provided ID. Tags is updated using
        authorization token and the new tags received in request.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      requestBody:
        $ref: "#/components/requestBodies/UserUpdateTagsReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "400":
          description: Failed due to malformed JSON.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: Failed due to non existing user.
        "401":
          description: Missing or invalid access token provided.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/{userID}/picture:
    patch:
      operationId: updateProfilePicture
      summary: Updates the user's profile picture.
      description: |
        Updates the user's profile picture with provided ID. Profile picture is
        updated using authorization token and the new received picture.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      requestBody:
        $ref: "#/components/requestBodies/UserUpdateProfilePictureReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "400":
          description: Failed due to malformed JSON.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: Failed due to non existing user.
        "401":
          description: Missing or invalid access token provided.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/{userID}/email:
    patch:
      operationId: updateEmail
      summary: Updates email of the user.
      description: |
        Updates email of the user with provided ID. Email is
        updated using authorization token and the new received email.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      requestBody:
        $ref: "#/components/requestBodies/UserUpdateEmailReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "400":
          description: Failed due to malformed JSON.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: Failed due to non existing user.
        "401":
          description: Missing or invalid access token provided.
        "409":
          description: Failed due to using an existing email.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/{userID}/role:
    patch:
      operationId: updateRole
      summary: Updates the user's role.
      description: |
        Updates role for the user with provided ID.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      requestBody:
        $ref: "#/components/requestBodies/UserUpdateRoleReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "400":
          description: Failed due to malformed JSON.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: Failed due to non existing user.
        "401":
          description: Missing or invalid access token provided.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/{userID}/disable:
    post:
      operationId: disableUser
      summary: Disables a user
      description: |
        Disables a specific user that is identifier by the user ID.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "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 user.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/{userID}/enable:
    post:
      operationId: enableUser
      summary: Enables a user
      description: |
        Enables a specific user that is identifier by the user ID.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/UserID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "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 user.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/secret:
    patch:
      operationId: updateSecret
      summary: Updates secret of currently logged in user.
      description: |
        Updates secret of currently logged in user. Secret is updated using
        authorization token and the new received info.
      tags:
        - Users
      requestBody:
        $ref: "#/components/requestBodies/UserUpdateSecretReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserRes"
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: Failed due to non existing user.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /users/search:
    get:
      operationId: searchUsers
      summary: Search users
      description: |
        Search users by name and identity.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
        - $ref: "#/components/parameters/Username"
        - $ref: "#/components/parameters/FirstName"
        - $ref: "#/components/parameters/LastName"
        - $ref: "#/components/parameters/Email"
        - $ref: "#/components/parameters/UserID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/UserPageRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "500":
          $ref: "#/components/responses/ServiceError"

  /password/reset-request:
    post:
      operationId: requestPasswordReset
      summary: User password reset request
      description: |
        Generates a reset token and sends and
        email with link for resetting password.
      tags:
        - Users
      parameters:
        - $ref: "#/components/parameters/Referer"
      requestBody:
        $ref: "#/components/requestBodies/RequestPasswordReset"
      responses:
        "201":
          description: Users link for resetting password.
        "400":
          description: Failed due to malformed JSON.
        "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"

  /password/reset:
    put:
      operationId: resetPassword
      summary: User password reset endpoint
      description: |
        When user gets reset token, after he submitted
        email to `/password/reset-request`, posting a
          new password along to this endpoint will change password.
      tags:
        - Users
      requestBody:
        $ref: "#/components/requestBodies/PasswordReset"
      responses:
        "201":
          description: User link .
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: Entity not found.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "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"

  /users/send-verification:
    post:
      operationId: sendVerification
      tags:
        - Users
      summary: Sends a verification email
      description: |
        Sends a verification email to the user.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Sent verification email if registered.
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /verify-email:
    get:
      operationId: verifyEmail
      tags:
        - Users
      summary: Verify user's email
      description: |
        Verify user's email using the token from the verification link.
      parameters:
        - $ref: "#/components/parameters/VerificationToken"
      responses:
        "200":
          description: Email verified successfully.
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "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:
    UserReqObj:
      type: object
      properties:
        first_name:
          type: string
          example: firstName
          description: User's first name.
        last_name:
          type: string
          example: lastName
          description: User's last name.
        email:
          type: string
          example: "user@example.com"
          description: User's email address will be used as its unique identifier.
        tags:
          type: array
          minItems: 0
          items:
            type: string
          example: ["tag1", "tag2"]
          description: User tags.
        credentials:
          type: object
          properties:
            username:
              type: string
              example: "userName"
              description: User's username for example 'userName' will be used as its unique identifier.
            secret:
              type: string
              format: password
              example: password
              minimum: 8
              description: Free-form account secret used for acquiring auth token(s).
          required:
            - username
            - secret
        metadata:
          type: object
          example: { "domain": "example.com" }
          description: Arbitrary, object-encoded user's data.
        profile_picture:
          type: string
          example: "https://example.com/profile.jpg"
          description: User's profile picture URL that is represented as a string.
        status:
          type: string
          description: User Status
          format: string
          example: enabled
          enum:
            - enabled
            - disabled
      required:
        - credentials
        - first_name
        - last_name
        - email

    User:
      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.
        tags:
          type: array
          minItems: 0
          items:
            type: string
          example: ["tag1", "tag2"]
          description: User tags.
        email:
          type: string
          example: "john.doe@supermq.com"
          description: User email for example email address.
        credentials:
          type: object
          properties:
            username:
              type: string
              example: john_doe
              description: User's username for example john_doe for Mr John Doe.
        metadata:
          type: object
          example: { "address": "example" }
          description: Arbitrary, object-encoded user's data.
        profile_picture:
          type: string
          example: "https://example.com/profile.jpg"
          description: User's profile picture URL that is represented as a string.
        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: user

    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

    UsersPage:
      type: object
      properties:
        users:
          type: array
          minItems: 0
          uniqueItems: true
          items:
            $ref: "#/components/schemas/User"
        total:
          type: integer
          example: 1
          description: Total number of items.
        offset:
          type: integer
          example: 1
          description: Number of items to skip during retrieval.
        limit:
          type: integer
          example: 10
          description: Maximum number of items to return in one page.
      required:
        - users
        - total
        - limit

    UserUpdate:
      type: object
      properties:
        first_name:
          type: string
          example: firstName
          description: User's first name.
        last_name:
          type: string
          example: lastName
          description: User's last name.
        metadata:
          type: object
          example: { "role": "general" }
          description: Arbitrary, object-encoded user's data.
      required:
        - first_name
        - last_name
        - metadata

    UserTags:
      type: object
      properties:
        tags:
          type: array
          example: ["yello", "orange"]
          description: User tags.
          minItems: 0
          uniqueItems: true
          items:
            type: string

    UserProfilePicture:
      type: object
      properties:
        profile_picture:
          type: string
          example: "https://example.com/profile.jpg"
          description: User's profile picture URL that is represented as a string.
      required:
        - profile_picture

    Email:
      type: object
      properties:
        email:
          type: string
          example: user@supermq.com
          description: User email address.
      required:
        - email

    UserSecret:
      type: object
      properties:
        old_secret:
          type: string
          example: oldpassword
          minimum: 8
          description: Old user secret password.
        new_secret:
          type: string
          example: newpassword
          minimum: 8
          description: New user secret password.
      required:
        - old_secret
        - new_secret

    UserRole:
      type: object
      properties:
        role:
          type: string
          enum: ["admin", "user"]
          example: user
          description: User role example.
      required:
        - role

    Username:
      type: object
      properties:
        username:
          type: string
          example: "admin"
          description: User's username for example 'admin' will be used as its unique identifier.
      required:
        - username

    AssignReqObj:
      type: object
      properties:
        members:
          type: array
          minItems: 0
          items:
            type: string
          description: Members IDs
          example:
            [
              "bb7edb32-2eac-4aad-aebe-ed96fe073879",
              "bb7edb32-2eac-4aad-aebe-ed96fe073879",
            ]
        relation:
          type: string
          example: "m_write"
          description: Permission relations.
        member_kind:
          type: string
          example: "user"
          description: Member kind.
      required:
        - members
        - relation
        - member_kind

    AssignUserReqObj:
      type: object
      properties:
        user_ids:
          type: array
          minItems: 0
          items:
            type: string
          description: User IDs
          example:
            [
              "bb7edb32-2eac-4aad-aebe-ed96fe073879",
              "bb7edb32-2eac-4aad-aebe-ed96fe073879",
            ]
        relation:
          type: string
          example: "m_write"
          description: Permission relations.
      required:
        - user_ids
        - relation

    IssueToken:
      type: object
      properties:
        username:
          type: string
          example: myUsername
          description: Users' username.
        password:
          type: string
          example: password
          minimum: 8
          description: User secret password.
      required:
        - username
        - password

    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_name> 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
      example: "example.com"
      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

    Username:
      name: username
      description: User's username.
      in: query
      schema:
        type: string
      required: false
      example: "username"

    FirstName:
      name: first_name
      description: User's first name.
      in: query
      schema:
        type: string
      required: false
      example: "Jane"

    LastName:
      name: last_name
      description: User's last name.
      in: query
      schema:
        type: string
      required: false
      example: "Doe"

    Email:
      name: email
      description: User's email address.
      in: query
      schema:
        type: string
        format: email
      required: false
      example: "admin@example.com"

    Status:
      name: status
      description: User account status.
      in: query
      schema:
        type: string
        default: enabled
      required: false
      example: enabled

    Tag:
      name: tag
      description: User tag.
      in: query
      schema:
        type: string
      required: false
      example: "orange"

    GroupName:
      name: name
      description: Group's name.
      in: query
      schema:
        type: string
      required: false
      example: "groupName"

    ChannelName:
      name: name
      description: Channel's name.
      in: query
      schema:
        type: string
      required: false
      example: "channelName"

    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

    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
      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

    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: object
        properties:
          key:
            type: string
            description: Metadata key to filter by.
      example: { "key": "value" }
      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"

    VerificationToken:
      name: token
      description: Verification token.
      in: query
      schema:
        type: string
      required: true

  requestBodies:
    UserCreateReq:
      description: JSON-formatted document describing the new user to be registered
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/UserReqObj"

    UserUpdateReq:
      description: JSON-formated document describing the metadata and name of user to be update
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/UserUpdate"

    UserUpdateTagsReq:
      description: JSON-formated document describing the tags of user to be update
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/UserTags"

    UserUpdateProfilePictureReq:
      description: JSON-formated document describing the profile picture of user to be update
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/UserProfilePicture"

    UserUpdateEmailReq:
      description: Email change data. User can change its email.
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Email"

    UserUpdateSecretReq:
      description: Secret change data. User can change its secret.
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/UserSecret"

    UserUpdateRoleReq:
      description: JSON-formated document describing the role of the user to be updated
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/UserRole"

    UpdateUsernameReq:
      description: JSON-formated document describing the username of the user to be updated
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Username"

    AssignReq:
      description: JSON-formated document describing the policy related to assigning members to a group
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AssignReqObj"

    AssignUserReq:
      description: JSON-formated document describing the policy related to assigning users to a group
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AssignUserReqObj"

    IssueTokenReq:
      description: Login credentials.
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IssueToken"

    RequestPasswordReset:
      description: Initiate password request procedure.
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              email:
                type: string
                format: email
                example: user@example.com
                description: User email.

    PasswordReset:
      description: Password reset request data, new password and token that is appended on password reset link received in email.
      content:
        application/json:
          schema:
            type: object
            properties:
              password:
                type: string
                format: password
                description: New password.
                example: "12345678"
                minimum: 8
              confirm_password:
                type: string
                format: password
                description: New confirmation password.
                example: "12345678"
                minimum: 8
              token:
                type: string
                format: jwt
                description: Reset token generated and sent in email.

    PasswordChange:
      description: Password change data. User can change its password.
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              password:
                type: string
                format: password
                minimum: 8
                description: New password.
              old_password:
                type: string
                minimum: 8
                format: password
                description: Old password.

  responses:
    UserCreateRes:
      description: Registered new user.
      headers:
        Location:
          schema:
            type: string
            format: url
          description: Registered user relative URL in the format `/users/<user_id>`
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/User"
      links:
        get:
          operationId: getUser
          parameters:
            userID: $response.body#/id
        update:
          operationId: updateUser
          parameters:
            userID: $response.body#/id
        update_username:
          operationId: updateUsername
          parameters:
            userID: $response.body#/id
        update_tags:
          operationId: updateTags
          parameters:
            userID: $response.body#/id
        update_profile_picture:
          operationId: updateProfilePicture
          parameters:
            userID: $response.body#/id
        update_email:
          operationId: updateEmail
          parameters:
            userID: $response.body#/id
        update_role:
          operationId: updateRole
          parameters:
            userID: $response.body#/id
        disable:
          operationId: disableUser
          parameters:
            userID: $response.body#/id
        enable:
          operationId: enableUser
          parameters:
            userID: $response.body#/id

    UserRes:
      description: Data retrieved.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/User"

    UserPageRes:
      description: Data retrieved.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/UsersPage"

    TokenRes:
      description: JSON-formated document describing the user access token used for authenticating into the syetem and refresh token used for generating another access token
      content:
        application/json:
          schema:
            type: object
            properties:
              access_token:
                type: string
                example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjU3OTMwNjksImlhdCI6MTY2NTc1NzA2OSwiaXNzIjoibWFpbmZsdXguYXV0aCIsInN1YiI6ImFkbWluQGV4YW1wbGUuY29tIiwiaXNzdWVyX2lkIjoiZmRjZWVhNWYtNjYxNy00MjY1LWJhZDUtMzYxOTNhOTQ0NjMwIiwidHlwZSI6MH0.3gNd_x01QEiZfQxuQoEyqCqTrcxRkXHO7A4iG_gzu3c
                description: User access token.
              refresh_token:
                type: string
                example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjU3OTMwNjksImlhdCI6MTY2NTc1NzA2OSwiaXNzIjoibWFpbmZsdXguYXV0aCIsInN1YiI6ImFkbWluQGV4YW1wbGUuY29tIiwiaXNzdWVyX2lkIjoiZmRjZWVhNWYtNjYxNy00MjY1LWJhZDUtMzYxOTNhOTQ0NjMwIiwidHlwZSI6MH0.3gNd_x01QEiZfQxuQoEyqCqTrcxRkXHO7A4iG_gzu3c
                description: User refresh token.
              access_type:
                type: string
                example: access
                description: User access token type.

    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 <user_access_token>"

    refreshAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        * User refresh token used to get another access token: "Authorization: Bearer <user_refresh_token>"
security:
  - bearerAuth: []
  - refreshAuth: []
