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

openapi: 3.0.3
info:
  title: Magistrala Auth Service
  description: |
    This is the Auth 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 Magistrala repository](https://github.com/absmach/magistrala)
  contact:
    email: info@absmach.eu
  license:
    name: Apache 2.0
    url: https://github.com/absmach/magistrala/blob/main/LICENSE
  version: 0.18.0

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

tags:
  - name: Keys
    description: Everything about your Keys.
    externalDocs:
      description: Find out more about keys
      url: https://magistrala.absmach.eu/docs/
  - name: PATs
    description: Everything about your Personal Access Tokens.
    externalDocs:
      description: Find out more about Personal Access Tokens
      url: https://magistrala.absmach.eu/docs/
  - name: Health
    description: Service health check endpoint.
    externalDocs:
      description: Find out more about health check
      url: https://magistrala.absmach.eu/docs/

paths:
  /keys:
    post:
      operationId: issueKey
      tags:
        - Keys
      summary: Issue API key
      description: |
        Generates a new API key. Thew new API key will
        be uniquely identified by its ID.
      requestBody:
        $ref: "#/components/requestBodies/KeyRequest"
      responses:
        "201":
          description: Issued new key.
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "409":
          description: Failed due to using already existing ID.
        "415":
          description: Missing or invalid content type.
        "500":
          $ref: "#/components/responses/ServiceError"

  /keys/{keyID}:
    get:
      operationId: getKey
      summary: Gets API key details.
      description: |
        Gets API key details for the given key.
      tags:
        - Keys
      parameters:
        - $ref: "#/components/parameters/ApiKeyId"
      responses:
        "200":
          $ref: "#/components/responses/KeyRes"
        "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: Service can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

    delete:
      operationId: revokeKey
      summary: Revoke API key
      description: |
        Revoke API key identified by the given ID.
      tags:
        - Keys
      parameters:
        - $ref: "#/components/parameters/ApiKeyId"
      responses:
        "204":
          description: Key revoked.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: A non-existent entity request.
        "422":
          description: Service can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats:
    post:
      operationId: createPAT
      tags:
        - PATs
      summary: Create a new Personal Access Token
      description: |
        Creates a new Personal Access Token (PAT) for the authenticated user.
      requestBody:
        $ref: "#/components/requestBodies/CreatePATRequest"
      responses:
        "201":
          $ref: "#/components/responses/PATRes"
        "400":
          description: Failed due to malformed JSON or validation errors.
        "401":
          description: Missing or invalid access token provided.
        "415":
          description: Missing or invalid content type.
        "500":
          $ref: "#/components/responses/ServiceError"

    get:
      operationId: listPATs
      tags:
        - PATs
      summary: List all Personal Access Tokens
      description: |
        Lists all Personal Access Tokens (PATs) for the authenticated user.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        "200":
          $ref: "#/components/responses/PATsPageRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "500":
          $ref: "#/components/responses/ServiceError"

    delete:
      operationId: clearAllPATs
      tags:
        - PATs
      summary: Remove all Personal Access Tokens
      description: |
        Removes all Personal Access Tokens (PATs) for the authenticated user.
      responses:
        "200":
          description: All PATs removed successfully.
        "401":
          description: Missing or invalid access token provided.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats/{patID}:
    get:
      operationId: retrievePAT
      tags:
        - PATs
      summary: Retrieve a Personal Access Token
      description: |
        Retrieves details of a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      responses:
        "200":
          $ref: "#/components/responses/PATRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "500":
          $ref: "#/components/responses/ServiceError"

    delete:
      operationId: deletePAT
      tags:
        - PATs
      summary: Delete a Personal Access Token
      description: |
        Deletes a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      responses:
        "204":
          description: PAT deleted successfully.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats/{patID}/name:
    patch:
      operationId: updatePATName
      tags:
        - PATs
      summary: Update Personal Access Token name
      description: |
        Updates the name of a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      requestBody:
        $ref: "#/components/requestBodies/UpdatePATNameRequest"
      responses:
        "202":
          $ref: "#/components/responses/PATRes"
        "400":
          description: Failed due to malformed JSON or validation errors.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "415":
          description: Missing or invalid content type.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats/{patID}/description:
    patch:
      operationId: updatePATDescription
      tags:
        - PATs
      summary: Update Personal Access Token description
      description: |
        Updates the description of a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      requestBody:
        $ref: "#/components/requestBodies/UpdatePATDescriptionRequest"
      responses:
        "202":
          $ref: "#/components/responses/PATRes"
        "400":
          description: Failed due to malformed JSON or validation errors.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "415":
          description: Missing or invalid content type.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats/{patID}/secret/reset:
    patch:
      operationId: resetPATSecret
      tags:
        - PATs
      summary: Reset Personal Access Token secret
      description: |
        Resets the secret of a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      requestBody:
        $ref: "#/components/requestBodies/ResetPATSecretRequest"
      responses:
        "200":
          $ref: "#/components/responses/PATRes"
        "400":
          description: Failed due to malformed JSON or validation errors.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "415":
          description: Missing or invalid content type.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats/{patID}/secret/revoke:
    patch:
      operationId: revokePATSecret
      tags:
        - PATs
      summary: Revoke Personal Access Token secret
      description: |
        Revokes the secret of a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      responses:
        "204":
          description: PAT secret revoked successfully.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats/{patID}/scope:
    get:
      operationId: listScopes
      tags:
        - PATs
      summary: List scopes for a Personal Access Token
      description: |
        Lists all scopes for a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        "200":
          $ref: "#/components/responses/ScopesPageRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "500":
          $ref: "#/components/responses/ServiceError"

    delete:
      operationId: clearAllScopes
      tags:
        - PATs
      summary: Remove all scopes from a Personal Access Token
      description: |
        Removes all scopes from a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      responses:
        "200":
          description: All scopes removed successfully.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats/{patID}/scope/add:
    patch:
      operationId: addScope
      tags:
        - PATs
      summary: Add scope to a Personal Access Token
      description: |
        Adds a scope to a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      requestBody:
        $ref: "#/components/requestBodies/AddScopeRequest"
      responses:
        "200":
          description: Scope added successfully.
        "400":
          description: Failed due to malformed JSON or validation errors.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database cannot process the request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /pats/{patID}/scope/remove:
    patch:
      operationId: removeScope
      tags:
        - PATs
      summary: Remove scope from a Personal Access Token
      description: |
        Removes a scope from a specific Personal Access Token (PAT).
      parameters:
        - $ref: "#/components/parameters/PatID"
      requestBody:
        $ref: "#/components/requestBodies/RemoveScopeRequest"
      responses:
        "200":
          description: Scope removed successfully.
        "400":
          description: Failed due to malformed JSON or validation errors.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: PAT not found.
        "415":
          description: Missing or invalid content type.
        "500":
          $ref: "#/components/responses/ServiceError"

  /health:
    get:
      summary: Retrieves service health check info.
      tags:
        - Health
      security: []
      responses:
        "200":
          $ref: "#/components/responses/HealthRes"
        "500":
          $ref: "#/components/responses/ServiceError"

components:
  schemas:
    PAT:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "c5747f2f-2a7c-4fe1-b41a-51a5ae290945"
          description: Personal Access Token unique identifier
        user_id:
          type: string
          format: uuid
          example: "9118de62-c680-46b7-ad0a-21748a52833a"
          description: User ID of the PAT owner
        name:
          type: string
          example: "My PAT"
          description: Name of the Personal Access Token
        description:
          type: string
          example: "Token for automation"
          description: Description of the Personal Access Token
        secret:
          type: string
          example: "pat_1234567890abcdef"
          description: Secret value of the Personal Access Token
        issued_at:
          type: string
          format: date-time
          example: "2019-11-26T13:31:52Z"
          description: Time when the PAT was issued
        expires_at:
          type: string
          format: date-time
          example: "2020-11-26T13:31:52Z"
          description: Time when the PAT expires
        updated_at:
          type: string
          format: date-time
          example: "2019-11-26T13:31:52Z"
          description: Time when the PAT was last updated
        last_used_at:
          type: string
          format: date-time
          example: "2019-11-26T13:31:52Z"
          description: Time when the PAT was last used
        revoked:
          type: boolean
          example: false
          description: Whether the PAT is revoked
        revoked_at:
          type: string
          format: date-time
          example: "2019-11-26T13:31:52Z"
          description: Time when the PAT was revoked

    PATsPage:
      type: object
      properties:
        total:
          type: integer
          example: 10
          description: Total number of PATs
        offset:
          type: integer
          example: 0
          description: Number of items to skip during retrieval
        limit:
          type: integer
          example: 10
          description: Size of the subset to retrieve
        pats:
          type: array
          items:
            $ref: "#/components/schemas/PAT"
          description: List of Personal Access Tokens

    Scope:
      type: object
      properties:
        optional_domain_id:
          type: string
          format: uuid
          example: "bb7edb32-2eac-4aad-aebe-ed96fe073879"
          description: Optional domain ID for the scope
        entity_type:
          type: string
          enum:
            [groups, channels, clients, domains, users, dashboards, messages]
          example: "groups"
          description: Type of entity the scope applies to
        entity_id:
          type: string
          example: "*"
          description: ID of the entity the scope applies to. '*' means all entities of the specified type.
        operation:
          type: string
          enum:
            [
              create,
              read,
              list,
              update,
              delete,
              share,
              unshare,
              publish,
              subscribe,
            ]
          example: "read"
          description: Operation allowed by this scope

    ScopesPage:
      type: object
      properties:
        total:
          type: integer
          example: 10
          description: Total number of scopes
        offset:
          type: integer
          example: 0
          description: Number of items to skip during retrieval
        limit:
          type: integer
          example: 10
          description: Size of the subset to retrieve
        scopes:
          type: array
          items:
            $ref: "#/components/schemas/Scope"
          description: List of scopes
    Key:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "c5747f2f-2a7c-4fe1-b41a-51a5ae290945"
          description: API key unique identifier
        issuer_id:
          type: string
          format: uuid
          example: "9118de62-c680-46b7-ad0a-21748a52833a"
          description: In ID of the entity that issued the token.
        type:
          type: integer
          example: 0
          description: API key type. Keys of different type are processed differently.
        subject:
          type: string
          format: string
          example: "test@example.com"
          description: User's email or service identifier of API key subject.
        issued_at:
          type: string
          format: date-time
          example: "2019-11-26 13:31:52"
          description: Time when the key is generated.
        expires_at:
          type: string
          format: date-time
          example: "2019-11-26 13:31:52"
          description: Time when the Key expires. If this field is missing,
            that means that Key is valid indefinitely.

  parameters:
    PatID:
      name: patID
      description: Personal Access Token ID.
      in: path
      schema:
        type: string
        format: uuid
      required: true
    DomainID:
      name: domainID
      description: Unique domain identifier.
      in: path
      schema:
        type: string
        format: uuid
      required: true
      example: bb7edb32-2eac-4aad-aebe-ed96fe073879
    Status:
      name: status
      description: Domain status.
      in: query
      schema:
        type: string
        default: enabled
      required: false
      example: enabled
    DomainName:
      name: name
      description: Domain's name.
      in: query
      schema:
        type: string
      required: false
      example: "domainName"
    Permission:
      name: permission
      description: permission.
      in: query
      schema:
        type: string
      required: false
      example: "edit"
    ApiKeyId:
      name: keyID
      description: API Key ID.
      in: path
      schema:
        type: string
        format: uuid
      required: true
    Limit:
      name: limit
      description: Size of the subset to retrieve.
      in: query
      schema:
        type: integer
        default: 10
        maximum: 100
        minimum: 1
      required: false
    Offset:
      name: offset
      description: Number of items to skip during retrieval.
      in: query
      schema:
        type: integer
        default: 0
        minimum: 0
      required: false
    Metadata:
      name: metadata
      description: Metadata filter. Filtering is performed matching the parameter with metadata on top level. Parameter is json.
      in: query
      required: false
      schema:
        type: object
        additionalProperties: {}
    Type:
      name: type
      description: The type of the API Key.
      in: query
      schema:
        type: integer
        default: 0
        minimum: 0
      required: false
    Subject:
      name: subject
      description: The subject of an API Key
      in: query
      schema:
        type: string
      required: false

  requestBodies:
    CreatePATRequest:
      description: JSON-formatted document describing PAT creation request.
      required: true
      content:
        application/json:
          schema:
            type: object
            required:
              - name
              - duration
            properties:
              name:
                type: string
                minLength: 1
                example: "My PAT"
                description: Name of the Personal Access Token
              description:
                type: string
                example: "Token for automation"
                description: Description of the Personal Access Token
              duration:
                type: string
                pattern: "^[0-9]+(ns|us|µs|ms|s|m|h|d|w|y)$"
                example: "30d"
                description: Duration for which the PAT is valid. Format is a duration string (e.g. "30d", "24h", "1y").

    UpdatePATNameRequest:
      description: JSON-formatted document describing PAT name update request.
      required: true
      content:
        application/json:
          schema:
            type: object
            required:
              - name
            properties:
              name:
                type: string
                example: "New PAT Name"
                description: New name for the Personal Access Token

    UpdatePATDescriptionRequest:
      description: JSON-formatted document describing PAT description update request.
      required: true
      content:
        application/json:
          schema:
            type: object
            required:
              - description
            properties:
              description:
                type: string
                example: "New PAT Description"
                description: New description for the Personal Access Token

    ResetPATSecretRequest:
      description: JSON-formatted document describing PAT secret reset request.
      required: true
      content:
        application/json:
          schema:
            type: object
            required:
              - duration
            properties:
              duration:
                type: string
                pattern: "^[0-9]+(ns|us|µs|ms|s|m|h|d|w|y)$"
                example: "30d"
                description: Duration for which the new PAT secret is valid. Format is a duration string (e.g. "30d", "24h", "1y").

    AddScopeRequest:
      description: JSON-formatted document describing add scope request.
      required: true
      content:
        application/json:
          schema:
            type: object
            required:
              - scopes
            properties:
              scopes:
                type: array
                items:
                  $ref: "#/components/schemas/Scope"
                description: List of scopes to add

    RemoveScopeRequest:
      description: JSON-formatted document describing remove scope request.
      required: true
      content:
        application/json:
          schema:
            type: object
            required:
              - scopes_id
            properties:
              scopes_id:
                type: array
                items:
                  type: string
                  format: uuid
                description: List of scope IDs to remove
    KeyRequest:
      description: JSON-formatted document describing key request.
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              type:
                type: integer
                example: 0
                description: API key type. Keys of different type are processed differently.
              duration:
                type: number
                format: integer
                example: 23456
                description: Number of seconds issued token is valid for.

  responses:
    PATRes:
      description: Personal Access Token data.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/PAT"

    PATsPageRes:
      description: Page of Personal Access Tokens.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/PATsPage"

    ScopesPageRes:
      description: Page of scopes.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ScopesPage"
    ServiceError:
      description: Unexpected server-side error occurred.
    KeyRes:
      description: Data retrieved.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Key"
      links:
        revoke:
          operationId: revokeKey
          parameters:
            keyID: $response.body#/id

    HealthRes:
      description: Service Health Check.
      content:
        application/health+json:
          schema:
            $ref: "./schemas/health_info.yaml"

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        * Users access: "Authorization: Bearer <user_token>"

security:
  - bearerAuth: []
