Something went wrong. Try again.
A community based topic aggregation platform built on atproto
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192package main
import ( "bytes" "context" "encoding/json" "errors" "fmt" "io" "log/slog" "net/http" "time")
// pdsAuthTimeout bounds the instance's own PDS login at startup.//// Without it this used http.Post, which uses http.DefaultClient — and// http.DefaultClient has no timeout at all. A PDS that accepted the connection// but never responded would hang the boot indefinitely, with the process// looking alive to the orchestrator but serving nothing.const pdsAuthTimeout = 15 * time.Second
// maxPDSErrorBodyBytes bounds how much of a PDS error body is read into the// returned error, so a misbehaving server cannot force an unbounded read.const maxPDSErrorBodyBytes = 4 << 10
// authenticateWithPDS creates a session on the PDS and returns an access// token. The instance needs its own PDS account to write the community records// it owns.func authenticateWithPDS(ctx context.Context, pdsURL, handle, password string) (string, error) { type createSessionRequest struct { Identifier string `json:"identifier"` Password string `json:"password"` }
type createSessionResponse struct { DID string `json:"did"` Handle string `json:"handle"` AccessJwt string `json:"accessJwt"` }
reqBody, err := json.Marshal(createSessionRequest{ Identifier: handle, Password: password, }) if err != nil { return "", fmt.Errorf("failed to marshal request: %w", err) }
ctx, cancel := context.WithTimeout(ctx, pdsAuthTimeout) defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, pdsURL+"/xrpc/com.atproto.server.createSession", bytes.NewReader(reqBody)) if err != nil { return "", fmt.Errorf("failed to build PDS request: %w", err) } req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req) // coves:allow-bare-client: pdsURL is a.cfg.PDS.URL, operator config; this is the AppView authenticating to its own PDS at startup if err != nil { return "", fmt.Errorf("failed to call PDS: %w", err) } defer func() { if closeErr := resp.Body.Close(); closeErr != nil { slog.Error("failed to close PDS response body", "error", closeErr) } }()
if resp.StatusCode != http.StatusOK { body, readErr := io.ReadAll(io.LimitReader(resp.Body, maxPDSErrorBodyBytes)) if readErr != nil { return "", fmt.Errorf("PDS returned status %d and failed to read body: %w", resp.StatusCode, readErr) } // The password is never echoed back by createSession, so the body is // safe to surface here; it is the only useful diagnostic for a // misconfigured instance account. return "", fmt.Errorf("PDS returned status %d: %s", resp.StatusCode, string(body)) }
var session createSessionResponse if err := json.NewDecoder(resp.Body).Decode(&session); err != nil { return "", fmt.Errorf("failed to decode response: %w", err) } if session.AccessJwt == "" { return "", errors.New("PDS returned a session with no access token") }
return session.AccessJwt, nil}