# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

---

paths:

  /metalakes/{metalake}/users:
    parameters:
      - $ref: "./openapi.yaml#/components/parameters/metalake"

    get:
      tags:
        - access control
      summary: List users (names)
      operationId: listUsers
      parameters:
        - $ref: "#/components/parameters/details"
      responses:
        "200":
          description: Returns the list of users if {details} is true, otherwise returns the list of user name
          content:
            application/vnd.gravitino.v1+json:
              schema:
                oneOf:
                  - $ref: "#/components/responses/UserListResponse"
                  - $ref: "./openapi.yaml#/components/schemas/NameListResponse"
              examples:
                UserListResponse:
                  $ref: "#/components/examples/UserListResponse"
                NameListResponse:
                  $ref: "#/components/examples/NameListResponse"
        "400":
          $ref: "./openapi.yaml#/components/responses/BadRequestErrorResponse"
        "404":
          description: Not Found - The specified metalake does not exist
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                NoSuchMetalakeException:
                  $ref: "./metalakes.yaml#/components/examples/NoSuchMetalakeException"

        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

    post:
      tags:
        - access control
      summary: Add user
      operationId: addUser
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UserAddRequest"
            examples:
              UserAddRequest:
                $ref: "#/components/examples/UserAddRequest"

      responses:
        "200":
          description: Returns the added user object
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "#/components/responses/UserResponse"
              examples:
                UserResponse:
                  $ref: "#/components/examples/UserResponse"
        "409":
          description: Conflict - The target user already exists in the specified metalake
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                UserAlreadyExistsException:
                  $ref: "#/components/examples/UserAlreadyExistsException"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

  /metalakes/{metalake}/users/{user}:
    parameters:
      - $ref: "./openapi.yaml#/components/parameters/metalake"
      - $ref: "./openapi.yaml#/components/parameters/user"

    get:
      tags:
        - access control
      summary: Get user
      operationId: getUser
      description: Returns the specified user information in the specified metalake
      responses:
        "200":
          description: Returns the user object
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "#/components/responses/UserResponse"
                examples:
                  UserResponse:
                    $ref: "#/components/examples/UserResponse"
        "404":
          description: Not Found - The specified user does not exist in the specified metalake
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                NoSuchMetalakeException:
                  $ref: "./metalakes.yaml#/components/examples/NoSuchMetalakeException"
                NoSuchUserException:
                  $ref: "#/components/examples/NoSuchUserException"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

    delete:
      tags:
        - access control
      summary: Remove user
      operationId: removeUser
      responses:
        "200":
          $ref: "./openapi.yaml#/components/responses/RemoveResponse"
        "400":
          $ref: "./openapi.yaml#/components/responses/BadRequestErrorResponse"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

components:
  parameters:
    details:
      name: details
      in: query
      description: Include detailed information about the user
      required: false
      schema:
        type: boolean
        default: false

  schemas:
    User:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: The name of the user
        roles:
          type: array
          items:
            type: string
          description: The roles of the user
        audit:
          $ref: "./openapi.yaml#/components/schemas/Audit"

    UserAddRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: The name of the user

  responses:
    UserResponse:
      type: object
      properties:
        code:
          type: integer
          format: int32
          description: Status code of the response
          enum:
            - 0
        user:
          $ref: "#/components/schemas/User"

    UserListResponse:
      type: object
      properties:
        code:
          type: integer
          format: int32
          description: Status code of the response
          enum:
            - 0
        users:
          type: array
          description: A list of user objects
          items:
            $ref: "#/components/schemas/User"

  examples:
    UserAddRequest:
      value: {
        "name": "user1",
      }

    NameListResponse:
      value: {
        "code": 0,
        "names": [ "user1", "user2" ]
      }

    UserResponse:
      value: {
        "code": 0,
        "user": {
          "name": "user1",
          "roles": [],
          "audit": {
            "creator": "gravitino",
            "createTime": "2023-12-08T06:41:25.595Z"
          },
        }
      }

    UserListResponse:
      value: {
        "code": 0,
        "users": [ {
          "name": "user1",
          "roles": [ ],
          "audit": {
            "creator": "gravitino",
            "createTime": "2023-12-08T06:41:25.595Z"
          },
        } ]
      }

    UserAlreadyExistsException:
      value: {
        "code": 1004,
        "type": "UserAlreadyExistsException",
        "message": "User already exists",
        "stack": [
          "org.apache.gravitino.exceptions.UserAlreadyExistsException: User already exists: user1"
        ]
      }

    NoSuchUserException:
      value: {
        "code": 1003,
        "type": "NoSuchUserException",
        "message": "User does not exist",
        "stack": [
          "org.apache.gravitino.exceptions.NoSuchUserException: User does not exist",
          "..."
        ]
      }