commit 8ea7d55f56548cb5e3c652fb1f435b8efbccd0ea
parent d83bbf9909cc30409e1eff12006c420f3a5ee714
Author: Yannick Rehberger <yr@ityreh.de>
Date: Tue, 21 Apr 2026 19:09:25 +0200
add openapi spec
Diffstat:
5 files changed, 99 insertions(+), 29 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,2 +1,3 @@
.gitignore
**/validation_code
+swagger.json
diff --git a/Makefile.in b/Makefile.in
@@ -59,4 +59,7 @@ gana:
dist:
git archive --format=tar.gz -o taler-directory-${GITVER}.tar.gz --prefix=taler-directory-${GITVER}/ HEAD
-.PHONY: all gana server tools check format uninstall install dist
+openapi:
+ swag init -g main.go --dir ./cmd/taldir-server,./pkg/taldir --outputTypes json --output . -v3.1
+
+.PHONY: all gana server tools check format uninstall install dist openapi
diff --git a/README.md b/README.md
@@ -33,35 +33,35 @@ The following configuration variables exist:
For the `[taldir]` section:
- * "production" (boolean): true for a production deployment. Causes verbose log messages to be inhibited.
- * "db_backend" (string): "sqlite" for the SQLite database backend to be used.
- * "validators" (array): An array of strings for the validators/identity types that can be used. Currently supported values: "email"
- * "email_sender" (string): For email validations, what should the sender address be.
- * "host" (string): For the validation link, which hostname should be used (useful if behind proxy).
- * "bind_to" (string): Where to bind and listen (HTTP server).
- * "salt" (string): The salt to use for identity key hashes in the database may alternatively be an environment variable `TALDIR_SALT`.
- * "monthly_fee" (string): The monthly fee for a registration (Default: "KUDOS:1")
- * "default_doc_filetype" (string): The default file type for the terms of service and privacy policy documents (Default: "text/markdown")
- * "default_doc_lang" (string): The default language for the terms of service and privacy policy documents (Default: "en-US")
- * "default_tos_path" (string): The path for the terms of service documents. Taldir will look for `<lang>.<extension>` depending on the requested file type ("Accept"-header) and locale ("Accept-Language"-header) (Default: "terms/")
- * "default_pp_path" (string): See `default_tos_path` (Default: "privacy/")
- * "challenge_bytes" (number): The number of bytes (entropy) of the generated challenge (Default: 16)
- * "validation_initiation_max" (number): How many challenges can be requested to validate an address (Default: 3)
- * "validation_timeframe" (string): The timeframe in which challenges can be requested up to `validation_initiation_max` times (Default: 10m)
- * "solution_attempt_max" (number): How often can the solution be attempted for a challenge in the `solution_attempt_timeframe` (Default: 3)
- * "solution_attempt_timeframe" (string): The timeframe in which the solution can be attempted `solution_attempt_max` times (Default: "1h")
- * "merchant_baseurl_privat" (string): The base URL for the merchant API to use (Default: "http://merchant.taldir/instances/myInstance")
- * "merchant_token" (string): The access token for the merchant API (Default: "superSecretToken")
- * "validation_landing" (string): The location of the HTML template to use for the validation landing displaying a QR code. (Default: "templates/validation_landing.html"
- * "validation_expiration" (string): The duration for which incomplete registration requests are kept. (Default: "24h")
+- "production" (boolean): true for a production deployment. Causes verbose log messages to be inhibited.
+- "db_backend" (string): "sqlite" for the SQLite database backend to be used.
+- "validators" (array): An array of strings for the validators/identity types that can be used. Currently supported values: "email"
+- "email_sender" (string): For email validations, what should the sender address be.
+- "host" (string): For the validation link, which hostname should be used (useful if behind proxy).
+- "bind_to" (string): Where to bind and listen (HTTP server).
+- "salt" (string): The salt to use for identity key hashes in the database may alternatively be an environment variable `TALDIR_SALT`.
+- "monthly_fee" (string): The monthly fee for a registration (Default: "KUDOS:1")
+- "default_doc_filetype" (string): The default file type for the terms of service and privacy policy documents (Default: "text/markdown")
+- "default_doc_lang" (string): The default language for the terms of service and privacy policy documents (Default: "en-US")
+- "default_tos_path" (string): The path for the terms of service documents. Taldir will look for `<lang>.<extension>` depending on the requested file type ("Accept"-header) and locale ("Accept-Language"-header) (Default: "terms/")
+- "default_pp_path" (string): See `default_tos_path` (Default: "privacy/")
+- "challenge_bytes" (number): The number of bytes (entropy) of the generated challenge (Default: 16)
+- "validation_initiation_max" (number): How many challenges can be requested to validate an address (Default: 3)
+- "validation_timeframe" (string): The timeframe in which challenges can be requested up to `validation_initiation_max` times (Default: 10m)
+- "solution_attempt_max" (number): How often can the solution be attempted for a challenge in the `solution_attempt_timeframe` (Default: 3)
+- "solution_attempt_timeframe" (string): The timeframe in which the solution can be attempted `solution_attempt_max` times (Default: "1h")
+- "merchant_baseurl_privat" (string): The base URL for the merchant API to use (Default: "http://merchant.taldir/instances/myInstance")
+- "merchant_token" (string): The access token for the merchant API (Default: "superSecretToken")
+- "validation_landing" (string): The location of the HTML template to use for the validation landing displaying a QR code. (Default: "templates/validation_landing.html"
+- "validation_expiration" (string): The duration for which incomplete registration requests are kept. (Default: "24h")
For the `[taldir-pq]` section:
- * "host" (string): The host of the Postgres database to use (Default: "localhost")
- * "port" (number): The port of the Postres database to use (Default: 5432)
- * "user" (string): The database user (Default: "taldir")
- * "password" (string): The database user password (Default: "secret")
- * "db_name" (string): The database name (Default: "taldir")
+- "host" (string): The host of the Postgres database to use (Default: "localhost")
+- "port" (number): The port of the Postres database to use (Default: 5432)
+- "user" (string): The database user (Default: "taldir")
+- "password" (string): The database user password (Default: "secret")
+- "db_name" (string): The database name (Default: "taldir")
Examples and defaults for the configuration can be found in the `taldir.conf` file shipped with this software.
@@ -112,8 +112,8 @@ in the `taldir` section in the Taldir configuration file.
Further, a `taldir-<name>` section must exists which contains the following
variables:
- * "challenge_fee" (amount): The cost of a single challenge using this validation method.
- * "command" (string): The program to use to trigger the out of band transfer of the validation code.
+- "challenge_fee" (amount): The cost of a single challenge using this validation method.
+- "command" (string): The program to use to trigger the out of band transfer of the validation code.
## Validator command
@@ -147,6 +147,16 @@ $ cp -r contrib/tos/en terms/
$ cp -r contrib/pp/en terms/
```
+# Generate OpenAPI Spec
+
+You can generate an openapi spec from code to `./swagger.json`:
+
+```
+$ go install github.com/swaggo/swag/v2/cmd/swag@latest
+$ ./configure --prefix=PREFIX
+$ make openapi
+```
+
# Funding
This project is funded through [NGI TALER Fund](https://nlnet.nl/taler), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/TALER-LookupService).
diff --git a/cmd/taldir-server/main.go b/cmd/taldir-server/main.go
@@ -16,6 +16,12 @@
//
// SPDX-License-Identifier: AGPL3.0-or-later
+// @title Taler Directory API
+// @description The Taler Directory (TalDir) maps alias hashes to wallet URIs. Clients register an alias by completing an out-of-band challenge, then look it up later using the hashed alias.
+// @contact.url https://taler.net
+// @license.name AGPL-3.0-or-later
+// @license.url https://www.gnu.org/licenses/agpl-3.0.html
+// @BasePath /
package main
/* TODO
diff --git a/pkg/taldir/taldir.go b/pkg/taldir/taldir.go
@@ -250,6 +250,15 @@ func (t *Taldir) isPMSValid(pms string) (err error) {
// Primary lookup function.
// Allows the caller to query a wallet key using the hash(!) of the
// alias
+//
+// @Summary Look up an alias entry
+// @Description Returns the target URI associated with the given hashed alias.
+// @Tags entries
+// @Produce json
+// @Param h_alias path string true "Crockford base32-encoded SHA-512 hash of the alias"
+// @Success 200 {object} Entry
+// @Failure 404
+// @Router /{h_alias} [get]
func (t *Taldir) getSingleEntry(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var entry Entry
@@ -320,6 +329,20 @@ func saltHAlias(hAlias string, salt string) string {
// Called by the registrant to validate the registration request. The reference ID was
// provided "out of band" using a validation method such as email or SMS
+//
+// @Summary Complete alias registration
+// @Description Submits the solution to the out-of-band challenge to confirm the registration.
+// @Tags registration
+// @Accept json
+// @Param h_alias path string true "Crockford base32-encoded SHA-512 hash of the alias"
+// @Param body body ValidationConfirmation true "Challenge solution"
+// @Success 204 "Registration confirmed"
+// @Failure 400 {object} ErrorDetail "Invalid JSON"
+// @Failure 403 "Wrong solution"
+// @Failure 404 "Validation not found"
+// @Failure 429 "Too many solution attempts"
+// @Failure 500
+// @Router /{h_alias} [post]
func (t *Taldir) validationRequest(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var entry Entry
@@ -426,6 +449,25 @@ func (t *Taldir) isRateLimited(hAlias string) (bool, error) {
return false, nil
}
+// registerRequest initiates the registration or update of an alias.
+//
+// @Summary Initiate alias registration
+// @Description Starts the registration process for an alias. Sends an out-of-band challenge
+// @Description via the specified validator (e.g. email or SMS). If the entry already exists
+// @Description with no changes, returns the remaining validity instead.
+// @Tags registration
+// @Accept json
+// @Produce json
+// @Param alias_type path string true "Alias type (e.g. \"email\", \"sms\")"
+// @Param body body RegisterMessage true "Registration request"
+// @Success 200 {object} object{valid_for=integer} "Existing entry unchanged; returns remaining validity in microseconds"
+// @Success 202 "Challenge sent"
+// @Failure 400 {object} ErrorDetail "Invalid request body or target URI"
+// @Failure 402 "Payment required"
+// @Failure 404 {object} ErrorDetail "Alias type not supported"
+// @Failure 429 {object} RateLimitedResponse "Registration rate limit reached"
+// @Failure 500
+// @Router /register/{alias_type} [post]
func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var req RegisterMessage
@@ -631,6 +673,14 @@ func (t *Taldir) oidcValidatorResponse(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}
+// configResponse returns the service configuration.
+//
+// @Summary Get service configuration
+// @Description Returns service metadata including the supported alias types and monthly fee.
+// @Tags config
+// @Produce json
+// @Success 200 {object} VersionResponse
+// @Router /config [get]
func (t *Taldir) configResponse(w http.ResponseWriter, r *http.Request) {
meths := []AliasType{}
i := 0