mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-05-09 02:00:17 +02:00
nip29: refine group-events relationships and write some tests.
This commit is contained in:
parent
ed3642f112
commit
48db1df66c
@ -20,6 +20,18 @@ type Group struct {
|
|||||||
LastMembersUpdate nostr.Timestamp
|
LastMembersUpdate nostr.Timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewGroup(id string) *Group {
|
||||||
|
now := nostr.Now()
|
||||||
|
return &Group{
|
||||||
|
ID: id,
|
||||||
|
Name: id,
|
||||||
|
Members: make(map[string]*Role),
|
||||||
|
LastMetadataUpdate: now,
|
||||||
|
LastAdminsUpdate: now,
|
||||||
|
LastMembersUpdate: now,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (group Group) ToMetadataEvent() *nostr.Event {
|
func (group Group) ToMetadataEvent() *nostr.Event {
|
||||||
evt := &nostr.Event{
|
evt := &nostr.Event{
|
||||||
Kind: nostr.KindSimpleGroupMetadata,
|
Kind: nostr.KindSimpleGroupMetadata,
|
||||||
@ -65,7 +77,7 @@ func (group Group) ToAdminsEvent() *nostr.Event {
|
|||||||
for member, role := range group.Members {
|
for member, role := range group.Members {
|
||||||
if role != nil {
|
if role != nil {
|
||||||
// is an admin
|
// is an admin
|
||||||
tag := make([]string, 0, 3+len(role.Permissions))
|
tag := make([]string, 3, 3+len(role.Permissions))
|
||||||
tag[0] = "p"
|
tag[0] = "p"
|
||||||
tag[1] = member
|
tag[1] = member
|
||||||
tag[2] = role.Name
|
tag[2] = role.Name
|
||||||
@ -99,13 +111,11 @@ func (group *Group) MergeInMetadataEvent(evt *nostr.Event) error {
|
|||||||
if evt.Kind != nostr.KindSimpleGroupMetadata {
|
if evt.Kind != nostr.KindSimpleGroupMetadata {
|
||||||
return fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupMetadata, evt.Kind)
|
return fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupMetadata, evt.Kind)
|
||||||
}
|
}
|
||||||
|
if evt.CreatedAt < group.LastMetadataUpdate {
|
||||||
if evt.CreatedAt <= group.LastMetadataUpdate {
|
|
||||||
return fmt.Errorf("event is older than our last update (%d vs %d)", evt.CreatedAt, group.LastMetadataUpdate)
|
return fmt.Errorf("event is older than our last update (%d vs %d)", evt.CreatedAt, group.LastMetadataUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
group.LastMetadataUpdate = evt.CreatedAt
|
group.LastMetadataUpdate = evt.CreatedAt
|
||||||
group.ID = evt.Tags.GetD()
|
|
||||||
group.Name = group.ID
|
group.Name = group.ID
|
||||||
|
|
||||||
if tag := evt.Tags.GetFirst([]string{"name", ""}); tag != nil {
|
if tag := evt.Tags.GetFirst([]string{"name", ""}); tag != nil {
|
||||||
@ -132,8 +142,7 @@ func (group *Group) MergeInAdminsEvent(evt *nostr.Event) error {
|
|||||||
if evt.Kind != nostr.KindSimpleGroupAdmins {
|
if evt.Kind != nostr.KindSimpleGroupAdmins {
|
||||||
return fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupAdmins, evt.Kind)
|
return fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupAdmins, evt.Kind)
|
||||||
}
|
}
|
||||||
|
if evt.CreatedAt < group.LastAdminsUpdate {
|
||||||
if evt.CreatedAt <= group.LastAdminsUpdate {
|
|
||||||
return fmt.Errorf("event is older than our last update (%d vs %d)", evt.CreatedAt, group.LastAdminsUpdate)
|
return fmt.Errorf("event is older than our last update (%d vs %d)", evt.CreatedAt, group.LastAdminsUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +157,18 @@ func (group *Group) MergeInAdminsEvent(evt *nostr.Event) error {
|
|||||||
if !nostr.IsValidPublicKeyHex(tag[1]) {
|
if !nostr.IsValidPublicKeyHex(tag[1]) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
role := group.Members[tag[1]]
|
||||||
|
if role == nil {
|
||||||
|
role = &Role{Name: tag[2]}
|
||||||
|
group.Members[tag[1]] = role
|
||||||
|
}
|
||||||
|
if role.Permissions == nil {
|
||||||
|
role.Permissions = make(map[Permission]struct{}, len(tag)-3)
|
||||||
|
}
|
||||||
|
for _, perm := range tag[2:] {
|
||||||
|
role.Permissions[Permission(perm)] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -157,8 +178,7 @@ func (group *Group) MergeInMembersEvent(evt *nostr.Event) error {
|
|||||||
if evt.Kind != nostr.KindSimpleGroupMembers {
|
if evt.Kind != nostr.KindSimpleGroupMembers {
|
||||||
return fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupMembers, evt.Kind)
|
return fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupMembers, evt.Kind)
|
||||||
}
|
}
|
||||||
|
if evt.CreatedAt < group.LastMembersUpdate {
|
||||||
if evt.CreatedAt <= group.LastMembersUpdate {
|
|
||||||
return fmt.Errorf("event is older than our last update (%d vs %d)", evt.CreatedAt, group.LastMembersUpdate)
|
return fmt.Errorf("event is older than our last update (%d vs %d)", evt.CreatedAt, group.LastMembersUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,6 +193,11 @@ func (group *Group) MergeInMembersEvent(evt *nostr.Event) error {
|
|||||||
if !nostr.IsValidPublicKeyHex(tag[1]) {
|
if !nostr.IsValidPublicKeyHex(tag[1]) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, exists := group.Members[tag[1]]
|
||||||
|
if !exists {
|
||||||
|
group.Members[tag[1]] = EmptyRole
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
61
nip29/nip29_test.go
Normal file
61
nip29/nip29_test.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package nip29
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ALICE = "eadad094b75b4690e7ee7124522861b8d81d5ed92e81eb678e776d1164d1efe9"
|
||||||
|
BOB = "6ac475cdf30e2006ee5142559544e86f8f1b485a9c8c1f2da467996fb7fcdfe7"
|
||||||
|
CAROL = "f81982b8b6ba354a1e09acfda348512ef93e5778847fb5f4b30fe6b0042f4b36"
|
||||||
|
DEREK = "24a049c4e5c9cff1764c312b2e0fa59a02af235b37809180b3f2c7b2ec3dbdfd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGroupEventBackAndForth(t *testing.T) {
|
||||||
|
group1 := NewGroup("xyz")
|
||||||
|
group1.Name = "banana"
|
||||||
|
group1.Private = true
|
||||||
|
meta1 := group1.ToMetadataEvent()
|
||||||
|
if meta1.Tags.GetD() != "xyz" ||
|
||||||
|
meta1.Tags.GetFirst([]string{"name", "banana"}) == nil ||
|
||||||
|
meta1.Tags.GetFirst([]string{"private"}) == nil {
|
||||||
|
t.Fatalf("translation of group1 to meta1data event failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
group2 := NewGroup("abc")
|
||||||
|
group2.Members[ALICE] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermAddUser: {}}}
|
||||||
|
group2.Members[BOB] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermEditMetadata: {}}}
|
||||||
|
group2.Members[CAROL] = EmptyRole
|
||||||
|
group2.Members[DEREK] = EmptyRole
|
||||||
|
admins2 := group2.ToAdminsEvent()
|
||||||
|
if admins2.Tags.GetD() != "abc" ||
|
||||||
|
len(admins2.Tags) != 3 ||
|
||||||
|
admins2.Tags.GetFirst([]string{"p", ALICE, "nada", "add-user"}) == nil ||
|
||||||
|
admins2.Tags.GetFirst([]string{"p", BOB, "nada", "edit-metadata"}) == nil {
|
||||||
|
t.Fatalf("translation of group2 to admins event failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
members2 := group2.ToMembersEvent()
|
||||||
|
if members2.Tags.GetD() != "abc" ||
|
||||||
|
len(members2.Tags) != 5 ||
|
||||||
|
members2.Tags.GetFirst([]string{"p", ALICE}) == nil ||
|
||||||
|
members2.Tags.GetFirst([]string{"p", BOB}) == nil ||
|
||||||
|
members2.Tags.GetFirst([]string{"p", CAROL}) == nil ||
|
||||||
|
members2.Tags.GetFirst([]string{"p", DEREK}) == nil {
|
||||||
|
t.Fatalf("translation of group2 to members2 event failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
group1.MergeInMembersEvent(members2)
|
||||||
|
if len(group1.Members) != 4 || group1.Members[ALICE] != EmptyRole || group1.Members[DEREK] != EmptyRole {
|
||||||
|
t.Fatalf("merge of members2 into group1 failed")
|
||||||
|
}
|
||||||
|
group1.MergeInAdminsEvent(admins2)
|
||||||
|
if len(group1.Members) != 4 || group1.Members[ALICE].Name != "nada" || group1.Members[DEREK] != EmptyRole {
|
||||||
|
t.Fatalf("merge of admins2 into group1 failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
group2.MergeInMetadataEvent(meta1)
|
||||||
|
if group2.Name != "banana" || group2.ID != "abc" {
|
||||||
|
t.Fatalf("merge of meta1 into group2 failed")
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user