swagger: "2.0"
basePath: /api
info:
  description: |
    The Rednerd rendering server. For a list of available rendering engines
    and their options, see <a href="/docs/engines">Rednerd Engines</a>.

  title: Rednerd API
  version: 0.3.5
consumes:
- application/io.orus.rednerd.v1+json
- application/json
produces:
- application/io.orus.rednerd.v1+json
schemes:
- http
- https
securityDefinitions:
  token:
    type: apiKey
    in: header
    name: Authorization
    description: |
      Authentication by token bearer.

      The token is obtained by user the 'auth' API.

      The header format is <pre>"Authorization: Bearer &lt;token&gt;"</pre>.
  cookie:
    type: apiKey
    in: header
    name: Cookie
    description: |
      Authentication by cookie. See the 'auth' API to get a proper cookie
  apikey:
    type: apiKey
    in: header
    name: Rednerd-API-Key
    description: |
      Authentication by API key.

      Each user can have one or several API keys and can be managed with the
      user-management API.
security:
  - token: []
  - cookie: []
  - apikey: []
tags:
  - name: auth
    description: Authentication
  - name: user-management
    description: User management
  - name: template-management
    description: |
      The template management API let the user save templates for later use with
      the rendering api
  - name: rendering
    description: Rendering API
paths:
  /v1/auth/authenticate:
    post:
      tags:
        - auth
      operationId: authenticate
      security: []
      parameters:
        - name: credentials
          in: body
          schema:
            $ref: "#/definitions/credentials"
      responses:
        200:
          description: A Json Web Token with a 5 minutes validity
          schema:
            type: string
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'
  /v1/auth/refresh_token:
    post:
      tags:
        - auth
      operationId: refresh-token
      responses:
        200:
          description: A Json Web Token with a 5 minutes validity
          schema:
            type: string
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'
  /v1/auth/userinfo:
    get:
      tags:
        - auth
      operationId: userinfo
      responses:
        200:
          description: Returns the user information
          schema:
            $ref: "#/definitions/userinfo"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'

  /v1/user:
    get:
      tags:
        - user-management
      operationId: user-list
      responses:
        200:
          description: |
            List the users
          schema:
            type: array
            items:
              $ref: "#/definitions/userinfo"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'

    post:
      tags:
        - user-management
      operationId: user-add
      parameters:
        - in: body
          name: user
          schema:
            $ref: '#/definitions/userinfo'
      responses:
        201:
          description: |
            The created user
          schema:
            $ref: "#/definitions/userinfo"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'

  /v1/user/{username}:
    parameters:
      - name: username
        type: string
        in: path
        required: true
    get:
      tags:
        - user-management
      operationId: user-get
      responses:
        200:
          description: |
            The user information
          schema:
            $ref: "#/definitions/userinfo"
        401:
          $ref: '#/responses/unauthorized'
        404:
          description: the user does not exist
        default:
          $ref: '#/responses/default'
    put:
      tags:
        - user-management
      operationId: user-update
      parameters:
        - in: body
          name: user
          schema:
            $ref: '#/definitions/userinfo'
      responses:
        200:
          description: |
            The user information
          schema:
            $ref: "#/definitions/userinfo"
        401:
          $ref: '#/responses/unauthorized'
        404:
          description: the user does not exist
        default:
          $ref: '#/responses/default'

    delete:
      tags:
        - user-management
      operationId: user-delete
      responses:
        204:
          description: The user was successfully deleted
        401:
          $ref: '#/responses/unauthorized'
        404:
          description: the user does not exist
        default:
          $ref: '#/responses/default'

  /v1/user/{username}/password:
    parameters:
      - name: username
        type: string
        in: path
        required: true
    post:
      tags:
        - user-management
      operationId: user-password-set
      parameters:
        - in: body
          name: body
          schema:
            type: object
            properties:
              password:
                type: string
                description: The user new password
      responses:
        204:
          description: The password was successfully set
        401:
          $ref: '#/responses/unauthorized'
        404:
          description: the user does not exist
        default:
          $ref: '#/responses/default'

    delete:
      tags:
        - user-management
      operationId: user-password-delete
      responses:
        204:
          description: The password was successfully deleted
        401:
          $ref: '#/responses/unauthorized'
        404:
          description: the user does not exist
        default:
          $ref: '#/responses/default'

  /v1/user/{username}/apikey:
    parameters:
      - name: username
        type: string
        in: path
        required: true
    get:
      tags:
        - user-management
      operationId: user-apikey-list
      description: List the user api keys. Only the 'admin' user can manipulate the API keys.
      responses:
        200:
          description: The user api keys
          schema:
            type: array
            items:
              $ref: '#/definitions/apikey'
        401:
          $ref: '#/responses/unauthorized'
        404:
          description: the user does not exist
        default:
          $ref: '#/responses/default'
    post:
      tags:
        - user-management
      operationId: user-apikey-add
      description: Create a new api key for the user. Only the 'admin' user can manipulate the API keys.
      parameters:
        - in: body
          name: apikey
          schema:
            $ref: '#/definitions/apikey'
      responses:
        201:
          description: The api key was successfully created
          schema:
            $ref:  '#/definitions/apikey'
        401:
          $ref: '#/responses/unauthorized'
        404:
          description: the user does not exist
        default:
          $ref: '#/responses/default'

  /v1/user/{username}/apikey/{name}:
    parameters:
      - name: username
        type: string
        in: path
        required: true
      - name: name
        type: string
        in: path
        required: true
    delete:
      tags:
        - user-management
      operationId: user-apikey-delete
      description: Remove a API key. Only the 'admin' user can manipulate the API keys.
      responses:
        204:
          description: The api key was successfully deleted
        401:
          $ref: '#/responses/unauthorized'
        404:
          description: the user or key does not exist
        default:
          $ref: '#/responses/default'

  /v1/template:
    get:
      tags:
        - template-management
      operationId: template-list
      responses:
        200:
          description: |
            List the user templates and the shared templates it has access to
          schema:
            type: array
            items:
              $ref: "#/definitions/template"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'

  /v1/template/{account}:
    parameters:
      - name: account
        type: string
        in: path
        required: true
    get:
      tags:
        - template-management
      operationId: account-template-list
      responses:
        200:
          description: |
            List the user templates and the shared templates it has access to
          schema:
            type: array
            items:
              $ref: "#/definitions/template"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'
    post:
      tags:
        - template-management
      operationId: account-template-add
      parameters:
        - in: body
          name: template
          schema:
            $ref: "#/definitions/template"
      responses:
        201:
          description: Successfully added the new template
          schema:
            $ref: "#/definitions/template"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'

  /v1/template/{account}/{name}:
    parameters:
      - name: account
        type: string
        in: path
        required: true
      - name: name
        type: string
        in: path
        required: true
    get:
      tags:
        - template-management
      operationId: account-template-get
      responses:
        200:
          description: The requested template
          schema:
            $ref: "#/definitions/template"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'
    put:
      tags:
        - template-management
      operationId: account-template-update
      parameters:
        - in: body
          name: template
          schema:
            $ref: "#/definitions/template"
      responses:
        200:
          description: Successfully updated the template
          schema:
            $ref: "#/definitions/template"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'
    delete:
      tags:
        - template-management
      operationId: account-template-delete
      responses:
        204:
          description: Successfully deleted the template
          schema:
            $ref: "#/definitions/template"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'

  /v1/varlist:
    post:
      description: |
        Extract the list of variables present in the template. The list is not
        quaranteed to be accurate depending on the template language.
      tags:
        - template-management
      operationId: template-varlist
      parameters:
        - name: request
          in: body
          schema:
            $ref: "#/definitions/template"
      responses:
        200:
          description: The list of variables found in the template
          schema:
            type: array
            items:
              type: string
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'

  /v1/render:
    post:
      description: |
        Render a template.

        If provided, the template can be a complete definition (without a "account"
        and a "name"), or only a "account" and a "name" corresponding to a template
        previously created with the template management API. In both case the
        data must be provided.

        Alternatively, a single document can be provided that will be renderer into
        another type, without processing any template. In this case the "data" must
        not be provided.
      tags:
        - rendering
      operationId: render
      parameters:
        - name: request
          in: body
          schema:
            $ref: "#/definitions/render-request"

      responses:
        200:
          description: The rendered documents
          schema:
            type: array
            items:
              $ref: "#/definitions/document"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'

  /v1/template/{account}/{id}/render:
    parameters:
      - name: account
        type: string
        in: path
        required: true
      - name: id
        type: string
        in: path
        required: true
    post:
      description: Render an existing template into a list of documents
      tags:
        - rendering
      operationId: template-render
      parameters:
        - name: request
          in: body
          schema:
            $ref: "#/definitions/render-template-request"
      responses:
        200:
          description: The rendered documents
          schema:
            type: array
            items:
              $ref: "#/definitions/document"
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'
    get:
      description: Render an existing template into a single document
      tags:
        - rendering
      operationId: render-one
      parameters:
        - name: data
          type: string
          in: query
          description: |
            A JSON object containing the variables to inject into the template.
        - name: accept
          in: query
          type: string
          description: |
            The mimetype expected after a rendering.
        - name: meta
          type: array
          items:
            type: string
          in: query
          description: |
            A list of metadata in the form "Name: Value"
      responses:
        200:
          description: The rendered document
          schema: {}
        401:
          $ref: '#/responses/unauthorized'
        default:
          $ref: '#/responses/default'


responses:
  unauthorized:
    description: Unauthorized
    schema:
      $ref: '#/definitions/error'

  default:
    description: generic error response
    schema:
      $ref: "#/definitions/error"

definitions:
  error:
    type: object
    description: Generic error type
    properties:
      message:
        type: string

  credentials:
    type: object
    description: Credentials for authentication
    properties:
      username:
        type: string
      password:
        type: string
      set-cookie:
        type: boolean
        description: "if true, the response will set a cookie containing the web token"

  userinfo:
    type: object
    description: Current user information
    properties:
      username:
        type: string
        x-go-custom-tag: db:"username"
      is-admin:
        type: boolean
        x-go-custom-tag: db:"is_admin"

  apikey:
    type: object
    description: A user APIkey
    properties:
      name:
        type: string
        x-go-custom-tag: db:"name"
      description:
        type: string
        x-go-custom-tag: db:"description"
      value:
        type: string
        x-go-custom-tag: db:"value"

  metadata:
    type: object
    additionalProperties:
      type: string
    description: |
      A template or document metadata. Some values are interpreted by the
      various engines. For more information about those values,
      see <a href="/docs/engines">Rednerd Engines</a>.
    example:
      { "print-paper-size": "A4 landscape" }

  template:
    type: object
    description: |
      A template definition. At rendering time, the "body" and "metadata"
      fields will be processed by the rendering engine corresponding to the
      template "language" to produce a new document.
      If you need to add metadata that should not be be processed, use
      "static-metadata"
    properties:
      account:
        type: string
        description: The template owner account name
        x-go-custom-tag: db:"account"
      name:
        type: string
        description: |
          The template name, must be unique in an account namespace,
          and should remain simple as it is used as a slug.
        x-go-custom-tag: db:"name"
      version:
        type: string
        description: |
          The template version. Can be any string, the consistency of version
          numbers is the responsibility of the client.
        x-go-custom-tag: db:"version"
      locale:
        type: string
        description: |
          The template default locale, in the i18n standard codification.
        example: "fr_FR"
        x-go-custom-tag: db:"locale"
      title:
        type: string
        description: The template title.
        x-go-custom-tag: db:"title"
      description:
        type: string
        description: A description of the template
        x-go-custom-tag: db:"description"
      language:
        type: string
        description: |
          The templating language used. See
          <a href="/docs/engines">Rednerd Engines</a> for a list of possible
          values.
        example: mustache
        x-go-custom-tag: db:"language"
      produces:
        type: string
        description: |
          The mimetype of the data produced by the template. If the mimetype
          is known by any engine, it can be rendered to other types.
        example: text/html
        x-go-custom-tag: db:"produces"
      data-schema:
        type: object
        description: |
          The json-schema that can validate the input data. Currently ignored.
        additionalProperties: true
        x-go-custom-tag: db:"data_schema"
      static-metadata:
        $ref: "#/definitions/metadata"
        x-go-custom-tag: db:"static_metadata"
      metadata:
        $ref: "#/definitions/metadata"
        x-go-custom-tag: db:"metadata"
      body-format:
        type: string
        description: The body attribute format. Can be 'text' or 'base64'. Default 'base64'
        x-go-custom-tag: db:"-"
      body:
        type: string
        description: Content
        x-go-custom-tag: db:"-"

  accept:
    type: string
    description: |
      The mimetype expected after a rendering.


  render-request:
    type: object
    properties:
      template:
        $ref: "#/definitions/template"
      data:
        $ref: "#/definitions/dataset"
      document:
        description: Document to render. Incompatible with the 'template' and 'data' properties
        $ref: "#/definitions/document"
      metadata:
        $ref: "#/definitions/metadata"
      accept:
        $ref: "#/definitions/accept"

  render-template-request:
    type: object
    properties:
      data:
        $ref: "#/definitions/dataset"
      metadata:
        $ref: "#/definitions/metadata"
      accept:
        $ref: "#/definitions/accept"

  dataset:
    type: array
    description:
      A list of records to render a template
    items:
      $ref: "#/definitions/record"

  record:
    type: object
    additionalProperties: true
    description:
      A record is a set of variables meant to be injected into a template

  render-error:
    type: object
    description: An error that occured during rendering
    x-isnullable: false
    properties:
      engine:
        type: string
        description: The engine that produced the error
      line:
        type: integer
        description: The line number on which the error occured
      message:
        type: string
        description: The error message
      extra:
        type: object
        additionalProperties:
          type: string
        description: |
          Extra context or data about the error, specific to the rendering engine

  document:
    type: object
    description: |
      A final document. Can be returned by a rendering, but also send to render
      for a type conversion without rendering a template.
    properties:
      type:
        type: string
        description: The document mimetype
        example: text/html
      metadata:
        $ref: "#/definitions/metadata"
      body-format:
        type: string
        description: The body attribute format. Can be 'text' or 'base64'. Default 'base64'
      body:
        type: string
        description: Content
      render-errors:
        type: array
        items:
          $ref: "#/definitions/render-error"
        description: A list of non-blocking errors that occured during rendering
