# memberapi.ose.tw backend ## Quick start ```bash cd backend python -m venv .venv source .venv/bin/activate pip install -e . cp .env.example .env ./scripts/start_dev.sh ``` ## Required DB setup 1. Initialize API client whitelist table with `docs/API_CLIENTS_SQL.sql`. 2. Initialize core tables with `backend/scripts/init_schema.sql`. 3. Generate `api_key_hash` and update `api_clients` records, e.g.: ```bash python scripts/generate_api_key_hash.py 'YOUR_PLAIN_KEY' ``` ## IdP JWT setup(Keycloak 優先) - 若設定 `KEYCLOAK_BASE_URL` + `KEYCLOAK_REALM`,後端會優先走 Keycloak。 - 未設定 Keycloak 時,才走 `AUTHENTIK_*`。 ### Keycloak - 必填: - `KEYCLOAK_BASE_URL` - `KEYCLOAK_REALM` - `KEYCLOAK_CLIENT_ID` - `KEYCLOAK_CLIENT_SECRET` - 可選: - `KEYCLOAK_ISSUER`(預設:`/realms/`) - `KEYCLOAK_JWKS_URL`(預設:`/protocol/openid-connect/certs`) - `KEYCLOAK_TOKEN_ENDPOINT`(預設:`/protocol/openid-connect/token`) - `KEYCLOAK_USERINFO_ENDPOINT`(預設:`/protocol/openid-connect/userinfo`) - `KEYCLOAK_AUDIENCE` - `KEYCLOAK_VERIFY_TLS`(預設 true) ### Authentik(備援) - Configure at least one of: - `AUTHENTIK_JWKS_URL` - `AUTHENTIK_ISSUER` (the service infers `/jwks/`) - Optional: - `AUTHENTIK_AUDIENCE` (enables audience claim validation) - `AUTHENTIK_CLIENT_ID` (used by `/auth/login`, fallback to `AUTHENTIK_AUDIENCE`) - `AUTHENTIK_CLIENT_SECRET` (required if your access/id token uses HS256 signing) - `AUTHENTIK_TOKEN_ENDPOINT` (default: `/application/o/token/`) - `AUTHENTIK_USERINFO_ENDPOINT` (optional, default inferred from issuer/base URL; used to fill missing email/name claims) ## IdP Admin API setup - Keycloak(優先) - `KEYCLOAK_BASE_URL` - `KEYCLOAK_REALM` - `KEYCLOAK_ADMIN_CLIENT_ID` - `KEYCLOAK_ADMIN_CLIENT_SECRET` - `KEYCLOAK_ADMIN_REALM`(可選,預設同 `KEYCLOAK_REALM`) - Authentik(備援) - `AUTHENTIK_BASE_URL` - `AUTHENTIK_ADMIN_TOKEN` - `AUTHENTIK_VERIFY_TLS` ## Main APIs - `GET /healthz` - `GET /auth/oidc/url` - `POST /auth/oidc/exchange` - `GET /me` (Bearer token required) - `GET /me/permissions/snapshot` (Bearer token required) - `POST /internal/users/upsert-by-sub` - `GET /internal/permissions/{user_sub}/snapshot` - `POST /internal/idp/users/ensure`(相容:`/internal/authentik/users/ensure`) - `POST /admin/permissions/grant` - `POST /admin/permissions/revoke` - `GET|POST /admin/systems` - `GET|POST /admin/modules` - `GET|POST /admin/companies` - `GET|POST /admin/sites` - `GET /admin/members` - `GET|POST /admin/permission-groups` - `POST|DELETE /admin/permission-groups/{group_key}/members/{user_sub}` - `POST /admin/permission-groups/{group_key}/permissions/grant|revoke` - `GET /internal/systems` - `GET /internal/modules` - `GET /internal/companies` - `GET /internal/sites` - `GET /internal/members`