c2b1b7b751
- new app/api/routes/api/ package with shared require_session (401) and require_csrf (presence-only X-CSRF-Token, 403) dependencies - GET /api/config returns masked config sections; PUT /api/config reuses save_config_updates (blank secret keeps old; invalid -> 422, no write) - session-protected; PUT also CSRF-protected - register router in app/main.py; regenerate openapi/ - tests/test_api_config.py
499 lines
12 KiB
YAML
499 lines
12 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Home Automation Backend (Python)
|
|
description: Home automation backend with auth, runtime config, Home Assistant integrations,
|
|
TickTick integration, and SQLite-backed recorders.
|
|
version: 0.1.0
|
|
paths:
|
|
/status:
|
|
get:
|
|
tags:
|
|
- system
|
|
summary: Get Status
|
|
operationId: get_status_status_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/StatusResponse'
|
|
/login:
|
|
get:
|
|
tags:
|
|
- auth
|
|
summary: Login Page
|
|
operationId: login_page_login_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
post:
|
|
tags:
|
|
- auth
|
|
summary: Login Submit
|
|
operationId: login_submit_login_post
|
|
requestBody:
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
$ref: '#/components/schemas/Body_login_submit_login_post'
|
|
required: true
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
'422':
|
|
description: Validation Error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HTTPValidationError'
|
|
/config/change-password:
|
|
post:
|
|
tags:
|
|
- auth
|
|
summary: Change Password Submit
|
|
operationId: change_password_submit_config_change_password_post
|
|
requestBody:
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
$ref: '#/components/schemas/Body_change_password_submit_config_change_password_post'
|
|
required: true
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
'422':
|
|
description: Validation Error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HTTPValidationError'
|
|
/logout:
|
|
post:
|
|
tags:
|
|
- auth
|
|
summary: Logout
|
|
operationId: logout_logout_post
|
|
requestBody:
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
$ref: '#/components/schemas/Body_logout_logout_post'
|
|
required: true
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema: {}
|
|
'422':
|
|
description: Validation Error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HTTPValidationError'
|
|
/:
|
|
get:
|
|
tags:
|
|
- pages
|
|
summary: Home
|
|
operationId: home__get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
/admin:
|
|
get:
|
|
tags:
|
|
- pages
|
|
summary: Admin Redirect
|
|
operationId: admin_redirect_admin_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
/config:
|
|
get:
|
|
tags:
|
|
- pages
|
|
summary: Config Page
|
|
operationId: config_page_config_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
post:
|
|
tags:
|
|
- pages
|
|
summary: Config Submit
|
|
operationId: config_submit_config_post
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
/config/smtp/test:
|
|
post:
|
|
tags:
|
|
- pages
|
|
summary: Smtp Test Submit
|
|
operationId: smtp_test_submit_config_smtp_test_post
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
/api/config:
|
|
get:
|
|
tags:
|
|
- api-config
|
|
summary: Get Config
|
|
description: Return all configuration sections. Secret field values are masked
|
|
(empty string).
|
|
operationId: get_config_api_config_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ConfigResponse'
|
|
put:
|
|
tags:
|
|
- api-config
|
|
summary: Put Config
|
|
description: 'Save configuration updates.
|
|
|
|
|
|
- Blank secret value keeps the existing stored value (no change).
|
|
|
|
- Invalid values return 422 and nothing is written to the database.'
|
|
operationId: put_config_api_config_put
|
|
parameters:
|
|
- name: X-CSRF-Token
|
|
in: header
|
|
required: false
|
|
schema:
|
|
anyOf:
|
|
- type: string
|
|
- type: 'null'
|
|
title: X-Csrf-Token
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ConfigUpdateRequest'
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ConfigUpdateResponse'
|
|
'422':
|
|
description: Validation Error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HTTPValidationError'
|
|
/homeassistant/publish:
|
|
post:
|
|
tags:
|
|
- homeassistant
|
|
summary: Publish From Homeassistant
|
|
operationId: publish_from_homeassistant_homeassistant_publish_post
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema: {}
|
|
/location/record:
|
|
post:
|
|
tags:
|
|
- location
|
|
summary: Create Location Record
|
|
operationId: create_location_record_location_record_post
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema: {}
|
|
/poo/record:
|
|
post:
|
|
tags:
|
|
- poo
|
|
summary: Create Poo Record
|
|
operationId: create_poo_record_poo_record_post
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema: {}
|
|
/poo/latest:
|
|
get:
|
|
tags:
|
|
- poo
|
|
summary: Notify Latest Poo
|
|
operationId: notify_latest_poo_poo_latest_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema: {}
|
|
/public-ip/check:
|
|
get:
|
|
tags:
|
|
- public-ip
|
|
summary: Run Public Ip Check
|
|
operationId: run_public_ip_check_public_ip_check_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PublicIPCheckResponse'
|
|
/ticktick/auth/start:
|
|
get:
|
|
tags:
|
|
- ticktick
|
|
summary: Start Ticktick Auth
|
|
operationId: start_ticktick_auth_ticktick_auth_start_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema: {}
|
|
/ticktick/auth/code:
|
|
get:
|
|
tags:
|
|
- ticktick
|
|
summary: Handle Ticktick Auth Code
|
|
operationId: handle_ticktick_auth_code_ticktick_auth_code_get
|
|
responses:
|
|
'200':
|
|
description: Successful Response
|
|
content:
|
|
application/json:
|
|
schema: {}
|
|
components:
|
|
schemas:
|
|
Body_change_password_submit_config_change_password_post:
|
|
properties:
|
|
current_password:
|
|
type: string
|
|
title: Current Password
|
|
new_password:
|
|
type: string
|
|
title: New Password
|
|
confirm_password:
|
|
type: string
|
|
title: Confirm Password
|
|
csrf_token:
|
|
type: string
|
|
title: Csrf Token
|
|
type: object
|
|
required:
|
|
- current_password
|
|
- new_password
|
|
- confirm_password
|
|
- csrf_token
|
|
title: Body_change_password_submit_config_change_password_post
|
|
Body_login_submit_login_post:
|
|
properties:
|
|
username:
|
|
type: string
|
|
title: Username
|
|
password:
|
|
type: string
|
|
title: Password
|
|
csrf_token:
|
|
type: string
|
|
title: Csrf Token
|
|
type: object
|
|
required:
|
|
- username
|
|
- password
|
|
- csrf_token
|
|
title: Body_login_submit_login_post
|
|
Body_logout_logout_post:
|
|
properties:
|
|
csrf_token:
|
|
type: string
|
|
title: Csrf Token
|
|
type: object
|
|
required:
|
|
- csrf_token
|
|
title: Body_logout_logout_post
|
|
ConfigField:
|
|
properties:
|
|
env_name:
|
|
type: string
|
|
title: Env Name
|
|
label:
|
|
type: string
|
|
title: Label
|
|
value:
|
|
type: string
|
|
title: Value
|
|
secret:
|
|
type: boolean
|
|
title: Secret
|
|
input_type:
|
|
type: string
|
|
title: Input Type
|
|
configured:
|
|
type: boolean
|
|
title: Configured
|
|
type: object
|
|
required:
|
|
- env_name
|
|
- label
|
|
- value
|
|
- secret
|
|
- input_type
|
|
- configured
|
|
title: ConfigField
|
|
ConfigResponse:
|
|
properties:
|
|
sections:
|
|
items:
|
|
$ref: '#/components/schemas/ConfigSection'
|
|
type: array
|
|
title: Sections
|
|
type: object
|
|
required:
|
|
- sections
|
|
title: ConfigResponse
|
|
ConfigSection:
|
|
properties:
|
|
name:
|
|
type: string
|
|
title: Name
|
|
fields:
|
|
items:
|
|
$ref: '#/components/schemas/ConfigField'
|
|
type: array
|
|
title: Fields
|
|
type: object
|
|
required:
|
|
- name
|
|
- fields
|
|
title: ConfigSection
|
|
ConfigUpdateRequest:
|
|
properties:
|
|
updates:
|
|
additionalProperties:
|
|
type: string
|
|
type: object
|
|
title: Updates
|
|
type: object
|
|
required:
|
|
- updates
|
|
title: ConfigUpdateRequest
|
|
description: Flat mapping of env_name → value, mirroring the existing form semantics.
|
|
ConfigUpdateResponse:
|
|
properties:
|
|
sections:
|
|
items:
|
|
$ref: '#/components/schemas/ConfigSection'
|
|
type: array
|
|
title: Sections
|
|
type: object
|
|
required:
|
|
- sections
|
|
title: ConfigUpdateResponse
|
|
HTTPValidationError:
|
|
properties:
|
|
detail:
|
|
items:
|
|
$ref: '#/components/schemas/ValidationError'
|
|
type: array
|
|
title: Detail
|
|
type: object
|
|
title: HTTPValidationError
|
|
PublicIPCheckResponse:
|
|
properties:
|
|
status:
|
|
type: string
|
|
enum:
|
|
- first_seen
|
|
- unchanged
|
|
- changed
|
|
- error
|
|
title: Status
|
|
checked_at:
|
|
type: string
|
|
format: date-time
|
|
title: Checked At
|
|
changed:
|
|
type: boolean
|
|
title: Changed
|
|
type: object
|
|
required:
|
|
- status
|
|
- checked_at
|
|
- changed
|
|
title: PublicIPCheckResponse
|
|
StatusResponse:
|
|
properties:
|
|
status:
|
|
type: string
|
|
title: Status
|
|
type: object
|
|
required:
|
|
- status
|
|
title: StatusResponse
|
|
ValidationError:
|
|
properties:
|
|
loc:
|
|
items:
|
|
anyOf:
|
|
- type: string
|
|
- type: integer
|
|
type: array
|
|
title: Location
|
|
msg:
|
|
type: string
|
|
title: Message
|
|
type:
|
|
type: string
|
|
title: Error Type
|
|
type: object
|
|
required:
|
|
- loc
|
|
- msg
|
|
- type
|
|
title: ValidationError
|