knotserver/config: add PLC URL config option #682

closed
opened by shailpatels.me targeting master from shailpatels.me/core: knotserver_configurable_plc

The knotserver can now use alternative PLCs for DID resolution by setting the env var KNOT_SERVER_PLC_URL. The default identity directory was copied out of the at proto lib and updated to take in a target url for the PLC being used to do this.

Changed files
+34 -7
guard
idresolver
knotserver
+1 -1
guard/guard.go
···
}
func resolveIdentity(ctx context.Context, l *slog.Logger, didOrHandle string) *identity.Identity {
-
resolver := idresolver.DefaultResolver()
+
resolver := idresolver.DefaultResolver(identity.DefaultPLCURL)
ident, err := resolver.ResolveIdent(ctx, didOrHandle)
if err != nil {
l.Error("Error resolving handle", "error", err, "handle", didOrHandle)
+28 -2
idresolver/resolver.go
···
return &base
}
+
func DefaultDirectory(plcUrl string) identity.Directory {
+
base := identity.BaseDirectory{
+
PLCURL: plcUrl,
+
HTTPClient: http.Client{
+
Timeout: time.Second * 10,
+
Transport: &http.Transport{
+
// would want this around 100ms for services doing lots of handle resolution. Impacts PLC connections as well, but not too bad.
+
IdleConnTimeout: time.Millisecond * 1000,
+
MaxIdleConns: 100,
+
},
+
},
+
Resolver: net.Resolver{
+
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
+
d := net.Dialer{Timeout: time.Second * 3}
+
return d.DialContext(ctx, network, address)
+
},
+
},
+
TryAuthoritativeDNS: true,
+
// primary Bluesky PDS instance only supports HTTP resolution method
+
SkipDNSDomainSuffixes: []string{".bsky.social"},
+
UserAgent: "indigo-identity/" + versioninfo.Short(),
+
}
+
cached := identity.NewCacheDirectory(&base, 250_000, time.Hour*24, time.Minute*2, time.Minute*5)
+
return &cached
+
}
+
func RedisDirectory(url string) (identity.Directory, error) {
hitTTL := time.Hour * 24
errTTL := time.Second * 30
···
return redisdir.NewRedisDirectory(BaseDirectory(), url, hitTTL, errTTL, invalidHandleTTL, 10000)
}
-
func DefaultResolver() *Resolver {
+
func DefaultResolver(plcUrl string) *Resolver {
return &Resolver{
-
directory: identity.DefaultDirectory(),
+
directory: DefaultDirectory(plcUrl),
}
}
+1
knotserver/config/config.go
···
JetstreamEndpoint string `env:"JETSTREAM_ENDPOINT, default=wss://jetstream1.us-west.bsky.network/subscribe"`
Owner string `env:"OWNER, required"`
LogDids bool `env:"LOG_DIDS, default=true"`
+
PlcUrl string `env:"PLC_URL, default=https://plc.directory"`
// This disables signature verification so use with caution.
Dev bool `env:"DEV, default=false"`
+2 -2
knotserver/ingester.go
···
}
// resolve this aturi to extract the repo record
-
resolver := idresolver.DefaultResolver()
+
resolver := idresolver.DefaultResolver(h.c.Server.PlcUrl)
ident, err := resolver.ResolveIdent(ctx, repoAt.Authority().String())
if err != nil || ident.Handle.IsInvalidHandle() {
return fmt.Errorf("failed to resolve handle: %w", err)
···
return err
}
-
resolver := idresolver.DefaultResolver()
+
resolver := idresolver.DefaultResolver(h.c.Server.PlcUrl)
subjectId, err := resolver.ResolveIdent(ctx, record.Subject)
if err != nil || subjectId.Handle.IsInvalidHandle() {
+1 -1
knotserver/internal.go
···
func (h *InternalHandle) replyCompare(line git.PostReceiveLine, repoOwner string, gitRelativeDir string, repoName string, ctx context.Context) ([]string, error) {
l := h.l.With("handler", "replyCompare")
-
userIdent, err := idresolver.DefaultResolver().ResolveIdent(ctx, repoOwner)
+
userIdent, err := idresolver.DefaultResolver(h.c.Server.PlcUrl).ResolveIdent(ctx, repoOwner)
user := repoOwner
if err != nil {
l.Error("Failed to fetch user identity", "err", err)
+1 -1
knotserver/router.go
···
l: log.FromContext(ctx),
jc: jc,
n: n,
-
resolver: idresolver.DefaultResolver(),
+
resolver: idresolver.DefaultResolver(c.Server.PlcUrl),
}
err := e.AddKnot(rbac.ThisServer)