From 5b09ea3e96556650cbbd1da4ebeeea353b240733 Mon Sep 17 00:00:00 2001 From: Jon Lundy Date: Wed, 11 Jan 2023 21:25:20 -0700 Subject: [PATCH] fix: jrd compare logic --- app/webfinger/jrd.go | 78 +++++++++++++++++++++++++++++--------- app/webfinger/jrd_test.go | 4 +- app/webfinger/webfinger.go | 6 ++- 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/app/webfinger/jrd.go b/app/webfinger/jrd.go index 1e7d2b7..b991728 100644 --- a/app/webfinger/jrd.go +++ b/app/webfinger/jrd.go @@ -94,6 +94,15 @@ func (jrd *JRD) GetProperty(uri string) string { } return *jrd.Properties[uri] } +func (a *JRD) SetProperty(name string, value *string) { + if a.Properties == nil { + a.Properties = make(map[string]*string) + } + a.Properties[name] = value +} +func (a *JRD) IsDeleted() bool { + return a.deleted +} // GetProperty Returns the property value as a string. // Per spec a property value can be null, empty string is returned in this case. @@ -115,6 +124,8 @@ func (a *JRD) ApplyEvent(events ...event.Event) { for _, e := range events { switch e := e.(type) { case *SubjectSet: + a.deleted = false + a.Subject = e.Subject a.Aliases = e.Aliases a.Properties = e.Properties @@ -122,7 +133,6 @@ func (a *JRD) ApplyEvent(events ...event.Event) { case *SubjectDeleted: a.deleted = true - a.Subject = "" a.Aliases = a.Aliases[:0] a.Links = a.Links[:0] a.Properties = map[string]*string{} @@ -148,21 +158,36 @@ func (a *JRD) ApplyEvent(events ...event.Event) { const NSpubkey = "https://sour.is/ns/pub" -func (a *JRD) OnClaims(method, pubkey string, jrd *JRD) error { - if a.Version() > 0 { +func (a *JRD) OnDelete(pubkey string, jrd *JRD) error { + if a.Version() == 0 || a.IsDeleted() { + return nil + } + + if v, ok := a.Properties[NSpubkey]; ok && v != nil && *v == pubkey { + // pubkey matches! + } else { + return fmt.Errorf("pubkey does not match") + } + + if a.Subject != jrd.Subject { + return fmt.Errorf("subject does not match") + } + + event.Raise(a, &SubjectDeleted{Subject: jrd.Subject}) + return nil +} + +func (a *JRD) OnClaims(pubkey string, jrd *JRD) error { + if a.Version() > 0 && !a.IsDeleted() { if v, ok := a.Properties[NSpubkey]; ok && v != nil && *v == pubkey { // pubkey matches! } else { return fmt.Errorf("pubkey does not match") } + if a.Subject != jrd.Subject { return fmt.Errorf("subject does not match") } - - if method == "DELETE" { - event.Raise(a, &SubjectDeleted{Subject: jrd.Subject}) - return nil - } } jrd.SetProperty(NSpubkey, &pubkey) @@ -231,7 +256,15 @@ func (a *JRD) OnSubjectSet(subject string, aliases []string, props map[string]*s slice.Zip(slice.FromMap(props)), slice.Zip(slice.FromMap(a.Properties)), ) { - if z.Key != z.Value { + newValue := z.Key + curValue := z.Value + + if newValue.Key != curValue.Key { + modified = true + break + } + + if !cmpPtr(newValue.Value, curValue.Value) { modified = true break } @@ -278,7 +311,15 @@ func (a *JRD) OnLinkSet(o, n *Link) error { slice.Zip(slice.FromMap(n.Properties)), slice.Zip(slice.FromMap(o.Properties)), ) { - if z.Key != z.Value { + newValue := z.Key + curValue := z.Value + + if newValue.Key != curValue.Key { + modified = true + break + } + + if !cmpPtr(newValue.Value, curValue.Value) { modified = true break } @@ -291,13 +332,14 @@ func (a *JRD) OnLinkSet(o, n *Link) error { return nil } -func (a *JRD) IsDeleted() bool { - return a.deleted -} - -func (a *JRD) SetProperty(name string, value *string) { - if a.Properties == nil { - a.Properties = make(map[string]*string) +func cmpPtr[T comparable](l, r *T) bool { + if l == nil { + return r == nil } - a.Properties[name] = value + + if r == nil { + return l == nil + } + + return *l == *r } diff --git a/app/webfinger/jrd_test.go b/app/webfinger/jrd_test.go index 345a365..70e6787 100644 --- a/app/webfinger/jrd_test.go +++ b/app/webfinger/jrd_test.go @@ -158,7 +158,7 @@ func TestApplyEvents(t *testing.T) { } t.Log(string(s)) - if string(s) != `{}` { + if string(s) != `{"subject":"acct:me@sour.is"}` { t.Fatal("output does not match") } } @@ -227,7 +227,7 @@ func TestCommands(t *testing.T) { t.Logf("%#v", c) a, err := ev.Upsert(ctx, es, webfinger.StreamID(c.Subject), func(ctx context.Context, a *webfinger.JRD) error { - a.OnClaims("POST", c.PubKey, c.JRD) + a.OnClaims(c.PubKey, c.JRD) return nil }) is.NoErr(err) diff --git a/app/webfinger/webfinger.go b/app/webfinger/webfinger.go index 6173389..bd22273 100644 --- a/app/webfinger/webfinger.go +++ b/app/webfinger/webfinger.go @@ -117,8 +117,10 @@ func (s *service) ServeHTTP(w http.ResponseWriter, r *http.Request) { } a, err := ev.Upsert(ctx, s.es, StreamID(c.Subject), func(ctx context.Context, a *JRD) error { - a.OnClaims(r.Method, c.PubKey, c.JRD) - return nil + if r.Method == http.MethodDelete { + return a.OnDelete(c.PubKey, c.JRD) + } + return a.OnClaims(c.PubKey, c.JRD) }) if err != nil {