From 3e7d3f4084dc696e2656ad9f125b2f89623e38f6 Mon Sep 17 00:00:00 2001 From: jbergner Date: Thu, 19 Feb 2026 13:35:33 +0100 Subject: [PATCH] added autoreport to keyserver-App --- Dockerfile | 2 ++ main.go | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/Dockerfile b/Dockerfile index b1672bb..6044cd1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,4 +22,6 @@ WORKDIR /app COPY --from=build /out/pgpkeygen /app/pgpkeygen EXPOSE 8080 USER nonroot:nonroot +#export KEYSERVER_URL='http://localhost:8080' +#export KEYSERVER_TOKEN='supersecret' ENTRYPOINT ["/app/pgpkeygen"] diff --git a/main.go b/main.go index 5308bf6..8fb22a5 100644 --- a/main.go +++ b/main.go @@ -1,12 +1,17 @@ package main import ( + "bytes" "embed" + "encoding/json" "errors" "fmt" "html/template" + "io" "log" "net/http" + "net/url" + "os" "strconv" "strings" "time" @@ -47,6 +52,71 @@ type genResult struct { UIDOnKey string // tatsächliche UID im Schlüssel } +type apiUploadReq struct { + Name string `json:"name"` + Email string `json:"email"` + Fingerprint string `json:"fingerprint"` + PublicArmored string `json:"public_armored"` + Filename string `json:"filename,omitempty"` +} + +type apiUploadResp struct { + ID string `json:"id"` + Email string `json:"email"` + Fingerprint string `json:"fingerprint"` + WKDHash string `json:"wkd_hash"` + Domain string `json:"domain"` + Local string `json:"local"` +} + +func uploadPublicKey(res *genResult) (*apiUploadResp, error) { + base := strings.TrimSpace(os.Getenv("KEYSERVER_URL")) + token := strings.TrimSpace(os.Getenv("KEYSERVER_TOKEN")) + if base == "" || token == "" { + return nil, nil // Upload deaktiviert + } + + u, err := url.Parse(base) + if err != nil { + return nil, fmt.Errorf("invalid KEYSERVER_URL: %w", err) + } + u.Path = strings.TrimRight(u.Path, "/") + "/api/v1/keys" + + reqBody := apiUploadReq{ + Name: res.Name, + Email: res.Email, + Fingerprint: res.Fingerprint, + PublicArmored: res.PublicArmored, + Filename: res.Email + ".asc", + } + + b, _ := json.Marshal(reqBody) + httpReq, err := http.NewRequest(http.MethodPost, u.String(), bytes.NewReader(b)) + if err != nil { + return nil, err + } + httpReq.Header.Set("Content-Type", "application/json") + httpReq.Header.Set("Authorization", "Bearer "+token) + + client := &http.Client{Timeout: 10 * time.Second} + httpRes, err := client.Do(httpReq) + if err != nil { + return nil, err + } + defer httpRes.Body.Close() + + if httpRes.StatusCode != http.StatusCreated { + msg, _ := io.ReadAll(io.LimitReader(httpRes.Body, 8<<10)) + return nil, fmt.Errorf("keyserver returned %d: %s", httpRes.StatusCode, strings.TrimSpace(string(msg))) + } + + var out apiUploadResp + if err := json.NewDecoder(httpRes.Body).Decode(&out); err != nil { + return nil, fmt.Errorf("decode response: %w", err) + } + return &out, nil +} + func main() { mux := http.NewServeMux() mux.HandleFunc("/", handleIndex) @@ -97,6 +167,17 @@ func handleGenerate(w http.ResponseWriter, r *http.Request) { http.Error(w, fmt.Sprintf("Fehler beim Erzeugen der Schlüssel: %v", err), http.StatusInternalServerError) return } + + // Optional: Upload zum Keyserver + if up, upErr := uploadPublicKey(res); upErr != nil { + log.Printf("upload failed: %v", upErr) + // Du kannst hier entscheiden: Fehler anzeigen oder nur loggen + // http.Error(w, "Upload fehlgeschlagen: "+upErr.Error(), 502); return + } else if up != nil { + // optional: im UI anzeigen + res.Comment += fmt.Sprintf(" (Uploaded: %s)", up.ID) + } + _ = resultTmpl.Execute(w, res) }