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.
+1
-1
guard/guard.go
+1
-1
guard/guard.go
···
196
}
197
198
func resolveIdentity(ctx context.Context, l *slog.Logger, didOrHandle string) *identity.Identity {
199
-
resolver := idresolver.DefaultResolver()
200
ident, err := resolver.ResolveIdent(ctx, didOrHandle)
201
if err != nil {
202
l.Error("Error resolving handle", "error", err, "handle", didOrHandle)
···
196
}
197
198
func resolveIdentity(ctx context.Context, l *slog.Logger, didOrHandle string) *identity.Identity {
199
+
resolver := idresolver.DefaultResolver(identity.DefaultPLCURL)
200
ident, err := resolver.ResolveIdent(ctx, didOrHandle)
201
if err != nil {
202
l.Error("Error resolving handle", "error", err, "handle", didOrHandle)
+28
-2
idresolver/resolver.go
+28
-2
idresolver/resolver.go
···
42
return &base
43
}
44
45
func RedisDirectory(url string) (identity.Directory, error) {
46
hitTTL := time.Hour * 24
47
errTTL := time.Second * 30
···
49
return redisdir.NewRedisDirectory(BaseDirectory(), url, hitTTL, errTTL, invalidHandleTTL, 10000)
50
}
51
52
-
func DefaultResolver() *Resolver {
53
return &Resolver{
54
-
directory: identity.DefaultDirectory(),
55
}
56
}
57
···
42
return &base
43
}
44
45
+
func DefaultDirectory(plcUrl string) identity.Directory {
46
+
base := identity.BaseDirectory{
47
+
PLCURL: plcUrl,
48
+
HTTPClient: http.Client{
49
+
Timeout: time.Second * 10,
50
+
Transport: &http.Transport{
51
+
// would want this around 100ms for services doing lots of handle resolution. Impacts PLC connections as well, but not too bad.
52
+
IdleConnTimeout: time.Millisecond * 1000,
53
+
MaxIdleConns: 100,
54
+
},
55
+
},
56
+
Resolver: net.Resolver{
57
+
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
58
+
d := net.Dialer{Timeout: time.Second * 3}
59
+
return d.DialContext(ctx, network, address)
60
+
},
61
+
},
62
+
TryAuthoritativeDNS: true,
63
+
// primary Bluesky PDS instance only supports HTTP resolution method
64
+
SkipDNSDomainSuffixes: []string{".bsky.social"},
65
+
UserAgent: "indigo-identity/" + versioninfo.Short(),
66
+
}
67
+
cached := identity.NewCacheDirectory(&base, 250_000, time.Hour*24, time.Minute*2, time.Minute*5)
68
+
return &cached
69
+
}
70
+
71
func RedisDirectory(url string) (identity.Directory, error) {
72
hitTTL := time.Hour * 24
73
errTTL := time.Second * 30
···
75
return redisdir.NewRedisDirectory(BaseDirectory(), url, hitTTL, errTTL, invalidHandleTTL, 10000)
76
}
77
78
+
func DefaultResolver(plcUrl string) *Resolver {
79
return &Resolver{
80
+
directory: DefaultDirectory(plcUrl),
81
}
82
}
83
+1
knotserver/config/config.go
+1
knotserver/config/config.go
···
22
JetstreamEndpoint string `env:"JETSTREAM_ENDPOINT, default=wss://jetstream1.us-west.bsky.network/subscribe"`
23
Owner string `env:"OWNER, required"`
24
LogDids bool `env:"LOG_DIDS, default=true"`
25
26
// This disables signature verification so use with caution.
27
Dev bool `env:"DEV, default=false"`
···
22
JetstreamEndpoint string `env:"JETSTREAM_ENDPOINT, default=wss://jetstream1.us-west.bsky.network/subscribe"`
23
Owner string `env:"OWNER, required"`
24
LogDids bool `env:"LOG_DIDS, default=true"`
25
+
PlcUrl string `env:"PLC_URL, default=https://plc.directory"`
26
27
// This disables signature verification so use with caution.
28
Dev bool `env:"DEV, default=false"`
+2
-2
knotserver/ingester.go
+2
-2
knotserver/ingester.go
···
120
}
121
122
// resolve this aturi to extract the repo record
123
-
resolver := idresolver.DefaultResolver()
124
ident, err := resolver.ResolveIdent(ctx, repoAt.Authority().String())
125
if err != nil || ident.Handle.IsInvalidHandle() {
126
return fmt.Errorf("failed to resolve handle: %w", err)
···
233
return err
234
}
235
236
-
resolver := idresolver.DefaultResolver()
237
238
subjectId, err := resolver.ResolveIdent(ctx, record.Subject)
239
if err != nil || subjectId.Handle.IsInvalidHandle() {
···
120
}
121
122
// resolve this aturi to extract the repo record
123
+
resolver := idresolver.DefaultResolver(h.c.Server.PlcUrl)
124
ident, err := resolver.ResolveIdent(ctx, repoAt.Authority().String())
125
if err != nil || ident.Handle.IsInvalidHandle() {
126
return fmt.Errorf("failed to resolve handle: %w", err)
···
233
return err
234
}
235
236
+
resolver := idresolver.DefaultResolver(h.c.Server.PlcUrl)
237
238
subjectId, err := resolver.ResolveIdent(ctx, record.Subject)
239
if err != nil || subjectId.Handle.IsInvalidHandle() {
+1
-1
knotserver/internal.go
+1
-1
knotserver/internal.go
···
145
146
func (h *InternalHandle) replyCompare(line git.PostReceiveLine, repoOwner string, gitRelativeDir string, repoName string, ctx context.Context) ([]string, error) {
147
l := h.l.With("handler", "replyCompare")
148
-
userIdent, err := idresolver.DefaultResolver().ResolveIdent(ctx, repoOwner)
149
user := repoOwner
150
if err != nil {
151
l.Error("Failed to fetch user identity", "err", err)
···
145
146
func (h *InternalHandle) replyCompare(line git.PostReceiveLine, repoOwner string, gitRelativeDir string, repoName string, ctx context.Context) ([]string, error) {
147
l := h.l.With("handler", "replyCompare")
148
+
userIdent, err := idresolver.DefaultResolver(h.c.Server.PlcUrl).ResolveIdent(ctx, repoOwner)
149
user := repoOwner
150
if err != nil {
151
l.Error("Failed to fetch user identity", "err", err)
+1
-1
knotserver/router.go
+1
-1
knotserver/router.go