mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
06147abd5d
Signed-off-by: DL6ER <dl6er@dl6er.de>
571 lines
20 KiB
YAML
571 lines
20 KiB
YAML
openapi: 3.0.2
|
|
components:
|
|
paths:
|
|
auth:
|
|
get:
|
|
summary: Check if authentication is required
|
|
tags:
|
|
- Authentication
|
|
operationId: "get_auth"
|
|
security: []
|
|
description: |
|
|
The API may chose to reply with a valid session if no authentication is needed for this server.
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'auth.yaml#/components/schemas/session'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
examples:
|
|
auth_okay:
|
|
$ref: 'auth.yaml#/components/examples/auth_okay'
|
|
no_login_required:
|
|
$ref: 'auth.yaml#/components/examples/no_login_required'
|
|
'401':
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'auth.yaml#/components/schemas/session'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
examples:
|
|
login_required:
|
|
$ref: 'auth.yaml#/components/examples/login_required'
|
|
login_required_2fa:
|
|
$ref: 'auth.yaml#/components/examples/login_required_2fa'
|
|
post:
|
|
summary: Submit password for login
|
|
tags:
|
|
- Authentication
|
|
operationId: "add_auth"
|
|
security: []
|
|
description: |
|
|
Authenticate using a password. The password isn't stored in the session nor used to create the session token. Instead, the session token is produced using a cryptographically secure random number generator. A CSRF token is utilized to guard against CSRF attacks and is necessary when using Cookie-based authentication. However, it's not needed with other authentication methods.
|
|
|
|
Both the Session ID (SID) and CSRF token remain valid for the session's duration. The session can be extended before its expiration by performing any authenticated action. By default, the session lasts for 5 minutes. It can be invalidated by either logging out or deleting the session. Additionally, the session becomes invalid when the password is altered or a new application password is created.
|
|
|
|
If two-factor authentication (2FA) is activated, the Time-based One-Time Password (TOTP) token must be included in the request body. Be aware that the TOTP token, generated by your authenticator app, is only valid for 30 seconds. If the TOTP token is missing, invalid, or has been used previously, the login attempt will be unsuccessful.
|
|
requestBody:
|
|
description: Callback payload
|
|
content:
|
|
'application/json':
|
|
schema:
|
|
$ref: 'auth.yaml#/components/schemas/password'
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'auth.yaml#/components/schemas/session'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
examples:
|
|
login_okay:
|
|
$ref: 'auth.yaml#/components/examples/login_okay'
|
|
no_login_required:
|
|
$ref: 'auth.yaml#/components/examples/no_login_required'
|
|
'400':
|
|
description: Bad Request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'auth.yaml#/components/errors/bad_request'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
examples:
|
|
no_payload:
|
|
$ref: 'auth.yaml#/components/examples/errors/no_payload'
|
|
no_password:
|
|
$ref: 'auth.yaml#/components/examples/errors/no_password'
|
|
password_inval:
|
|
$ref: 'auth.yaml#/components/examples/errors/password_inval'
|
|
totp_missing:
|
|
$ref: 'auth.yaml#/components/examples/errors/totp_missing'
|
|
'401':
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'common.yaml#/components/errors/unauthorized'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
examples:
|
|
totp_invalid:
|
|
$ref: 'auth.yaml#/components/examples/errors/totp_invalid'
|
|
totp_reused:
|
|
$ref: 'auth.yaml#/components/examples/errors/totp_reused'
|
|
'429':
|
|
description: Too Many Requests
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'common.yaml#/components/errors/too_many_requests'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
examples:
|
|
rate_limit:
|
|
$ref: 'auth.yaml#/components/examples/errors/rate_limit'
|
|
no_seats:
|
|
$ref: 'auth.yaml#/components/examples/errors/no_seats'
|
|
delete:
|
|
summary: Delete session
|
|
tags:
|
|
- Authentication
|
|
operationId: "delete_groups"
|
|
description: |
|
|
This endpoint can be used to delete the current session. It will
|
|
invalidate the session token and the CSRF token. The session can be
|
|
extended before its expiration by performing any authenticated action.
|
|
By default, the session lasts for 5 minutes. It can be invalidated by
|
|
either logging out or deleting the session. Additionally, the session
|
|
becomes invalid when the password is altered or a new application
|
|
password is created.
|
|
|
|
You can also delete a session by its ID using the `DELETE /auth/session/{id}` endpoint.
|
|
|
|
Note that you cannot delete the current session if you have not
|
|
authenticated (e.g., no password has been set on your Pi-hole).
|
|
responses:
|
|
'204':
|
|
description: No Content (deleted)
|
|
'404':
|
|
description: Not Found (no session active)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: 'common.yaml#/components/schemas/took'
|
|
'401':
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'common.yaml#/components/errors/unauthorized'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
session_list:
|
|
get:
|
|
summary: List of all current sessions
|
|
tags:
|
|
- Authentication
|
|
operationId: "get_auth_sessions"
|
|
description: List of all current sessions including their validity and further information about the client such as the IP address and user agent.
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'auth.yaml#/components/schemas/sessions_list'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
'401':
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'common.yaml#/components/errors/unauthorized'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
totp:
|
|
get:
|
|
summary: Suggest new TOTP credentials
|
|
tags:
|
|
- Authentication
|
|
operationId: "get_auth_totp"
|
|
description: Suggest new TOTP credentials for two-factor authentication (2FA)
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'auth.yaml#/components/schemas/totp'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
'401':
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'common.yaml#/components/errors/unauthorized'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
session:
|
|
delete:
|
|
summary: Delete session by ID
|
|
parameters:
|
|
- $ref: 'auth.yaml#/components/parameters/id'
|
|
tags:
|
|
- Authentication
|
|
operationId: "delete_auth_session"
|
|
description: |
|
|
Using this endpoint, a session can be deleted by its ID.
|
|
responses:
|
|
'204':
|
|
description: No Content (deleted)
|
|
'404':
|
|
description: Not Found (session not found)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: 'common.yaml#/components/schemas/took'
|
|
'400':
|
|
description: Bad Request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'auth.yaml#/components/errors/bad_request'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
examples:
|
|
missing_session_id:
|
|
$ref: 'auth.yaml#/components/examples/errors/missing_session_id'
|
|
session_id_oob:
|
|
$ref: 'auth.yaml#/components/examples/errors/no_password'
|
|
session_not_in_use:
|
|
$ref: 'auth.yaml#/components/examples/errors/session_not_in_use'
|
|
'401':
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'common.yaml#/components/errors/unauthorized'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
app:
|
|
get:
|
|
summary: Create new application password
|
|
tags:
|
|
- Authentication
|
|
operationId: "add_app"
|
|
description: |
|
|
Create a new application password. The generated password is shown only once and cannot be retrieved later so make sure to store it in a safe place. The application password can be used to authenticate against the API instead of the regular password. It does not require 2FA verification. Generating a new application password will invalidate all currently active sessions.
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'auth.yaml#/components/schemas/app'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
'401':
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: 'common.yaml#/components/errors/unauthorized'
|
|
- $ref: 'common.yaml#/components/schemas/took'
|
|
|
|
schemas:
|
|
session:
|
|
type: object
|
|
required:
|
|
- session
|
|
properties:
|
|
session:
|
|
type: object
|
|
description: Session object
|
|
required:
|
|
- valid
|
|
- sid
|
|
- csrf
|
|
- validity
|
|
- totp
|
|
properties:
|
|
valid:
|
|
type: boolean
|
|
description: Valid session indicator (client is authenticated)
|
|
totp:
|
|
type: boolean
|
|
description: Whether 2FA (TOTP) is enabled on this Pi-hole
|
|
sid:
|
|
type: string
|
|
description: Session ID
|
|
nullable: true
|
|
csrf:
|
|
type: string
|
|
description: CSRF token
|
|
nullable: true
|
|
validity:
|
|
type: integer
|
|
description: Remaining lifetime of this session unless refreshed (seconds)
|
|
|
|
password:
|
|
type: object
|
|
description: Password to be sent to the API
|
|
properties:
|
|
password:
|
|
type: string
|
|
description: Password to be used for login
|
|
example: abcdef
|
|
sessions_list:
|
|
type: object
|
|
description: List of all current sessions
|
|
properties:
|
|
sessions:
|
|
type: array
|
|
items:
|
|
type: object
|
|
description: Session object
|
|
properties:
|
|
id:
|
|
type: number
|
|
description: Session ID
|
|
current_session:
|
|
type: boolean
|
|
description: Indicator if this is the current session
|
|
valid:
|
|
type: boolean
|
|
description: Valid session indicator (existing sessions may be invalid due to timeout)
|
|
tls:
|
|
type: object
|
|
description: TLS (end-to-end encryption) information
|
|
properties:
|
|
login:
|
|
type: boolean
|
|
description: Indicator if TLS (end-to-end encryption) has been used during login for this session
|
|
mixed:
|
|
type: boolean
|
|
description: Indicator if TLS (end-to-end encryption) is used only partially for this session
|
|
app:
|
|
type: boolean
|
|
description: Indicator if this session was initiated using an application password
|
|
login_at:
|
|
type: integer
|
|
description: Timestamp of login (seconds since epoch)
|
|
last_active:
|
|
type: integer
|
|
description: Timestamp of last activity (seconds since epoch)
|
|
valid_until:
|
|
type: integer
|
|
description: Timestamp of session expiration (seconds since epoch)
|
|
remote_addr:
|
|
type: string
|
|
description: IP address of the client
|
|
user_agent:
|
|
type: string
|
|
description: User agent of the client
|
|
example:
|
|
- id: 1
|
|
current_session: true
|
|
valid: true
|
|
tls:
|
|
login: true
|
|
mixed: false
|
|
app: false
|
|
login_at: 1580000000
|
|
last_active: 1580000000
|
|
valid_until: 1580000300
|
|
remote_addr: "192.168.0.34"
|
|
user_agent: "Mozilla/5.0 (X11; Linux x86_64; rv:107.0) Gecko/20100101 Firefox/107.0"
|
|
totp:
|
|
type: object
|
|
description: TOTP secret suggestion
|
|
properties:
|
|
totp:
|
|
type: object
|
|
properties:
|
|
type:
|
|
type: string
|
|
account:
|
|
type: string
|
|
issuer:
|
|
type: string
|
|
algorithm:
|
|
type: string
|
|
digits:
|
|
type: integer
|
|
period:
|
|
type: integer
|
|
offset:
|
|
type: integer
|
|
secret:
|
|
type: string
|
|
codes:
|
|
type: array
|
|
items:
|
|
type: integer
|
|
app:
|
|
type: object
|
|
description: Application password
|
|
properties:
|
|
app:
|
|
type: object
|
|
properties:
|
|
password:
|
|
type: string
|
|
hash:
|
|
type: string
|
|
example:
|
|
password: "7ua0rHPZixX6B3bTa5o4Dv08iyEIm/2q9qgLrF9MNVw="
|
|
hash: "$BALLOON-SHA256$v=1$s=1024,t=32$4ERwJD4XucRP4PcDHNLiAg==$kSy0Eou8RUVtK2UTbc5MCpItV8YC3VRuoGhoENxSQ2I="
|
|
|
|
errors:
|
|
bad_request:
|
|
type: object
|
|
description: Bad request
|
|
properties:
|
|
error:
|
|
type: object
|
|
properties:
|
|
key:
|
|
type: string
|
|
description: "Machine-readable error type"
|
|
message:
|
|
type: string
|
|
description: "Human-readable error message"
|
|
hint:
|
|
type: string
|
|
description: "Additional data (if available)"
|
|
nullable: true
|
|
|
|
examples:
|
|
auth_okay:
|
|
summary: Authentication valid
|
|
value:
|
|
session:
|
|
valid: true
|
|
totp: false
|
|
sid: null
|
|
csrf: null
|
|
validity: 300
|
|
login_okay:
|
|
summary: Login successful
|
|
value:
|
|
session:
|
|
valid: true
|
|
totp: false
|
|
sid: "vFA+EP4MQ5JJvJg+3Q2Jnw="
|
|
csrf: "Ux87YTIiMOf/GKCefVIOMw="
|
|
validity: 300
|
|
no_login_required:
|
|
summary: No login required for this client
|
|
value:
|
|
session:
|
|
valid: true
|
|
totp: false
|
|
sid: null
|
|
csrf: null
|
|
validity: -1
|
|
login_required:
|
|
summary: Login required, 2FA disabled
|
|
value:
|
|
session:
|
|
valid: false
|
|
totp: false
|
|
sid: null
|
|
csrf: null
|
|
validity: -1
|
|
login_required_2fa:
|
|
summary: Login required, 2FA enabled
|
|
value:
|
|
session:
|
|
valid: false
|
|
totp: true
|
|
sid: null
|
|
csrf: null
|
|
validity: -1
|
|
login_failed:
|
|
summary: Login failed
|
|
value:
|
|
session:
|
|
valid: false
|
|
totp: false
|
|
sid: null
|
|
csrf: null
|
|
validity: -1
|
|
errors:
|
|
no_payload:
|
|
summary: Bad request (no valid JSON payload)
|
|
value:
|
|
error:
|
|
key: "bad_request"
|
|
message: "No valid JSON payload found"
|
|
hint: null
|
|
no_password:
|
|
summary: Bad request (no password)
|
|
value:
|
|
error:
|
|
key: "bad_request"
|
|
message: "No password found in JSON payload"
|
|
hint: null
|
|
password_inval:
|
|
summary: Bad request (password is not a string)
|
|
value:
|
|
error:
|
|
key: "bad_request"
|
|
message: "Field password has to be of type 'string'"
|
|
hint: null
|
|
totp_missing:
|
|
summary: Bad request (2FA token missing)
|
|
value:
|
|
error:
|
|
key: "bad_request"
|
|
message: "No 2FA token found in JSON payload"
|
|
hint: null
|
|
missing_session_id:
|
|
summary: Bad request (missing session ID)
|
|
value:
|
|
error:
|
|
key: "bad_request"
|
|
message: "Missing or invalid session ID"
|
|
hint: null
|
|
session_id_oob:
|
|
summary: Bad request (session ID out of bounds)
|
|
value:
|
|
error:
|
|
key: "bad_request"
|
|
message: "Session ID out of bounds"
|
|
hint: null
|
|
session_not_in_use:
|
|
summary: Bad request (session not in use)
|
|
value:
|
|
error:
|
|
key: "bad_request"
|
|
message: "Session ID not in use"
|
|
hint: null
|
|
totp_invalid:
|
|
summary: 2FA token invalid
|
|
value:
|
|
error:
|
|
key: "unauthorized"
|
|
message: "Invalid 2FA token"
|
|
hint: null
|
|
totp_reused:
|
|
summary: 2FA token reused
|
|
value:
|
|
error:
|
|
key: "unauthorized"
|
|
message: "Reused 2FA token"
|
|
hint: "wait for new token"
|
|
rate_limit:
|
|
summary: Rate limit exceeded
|
|
value:
|
|
error:
|
|
key: "rate_limiting"
|
|
message: "Rate-limiting login attempts"
|
|
hint: null
|
|
no_seats:
|
|
summary: No free API seats available
|
|
value:
|
|
error:
|
|
key: "api_seats_exceeded"
|
|
message: "API seats exceeded"
|
|
hint: "increase webserver.api.max_sessions"
|
|
parameters:
|
|
id:
|
|
in: path
|
|
name: id
|
|
schema:
|
|
type: integer
|
|
required: true
|
|
description: Session ID
|
|
example: 0
|