From 7163b2283b4542a4d4abfe9a71963f122322bde7 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 8 Nov 2020 19:15:06 +0100 Subject: bug: Id from first operation data, not git + remove root link --- bug/op_create.go | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index 9bb40d35..3c8ce658 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -1,6 +1,7 @@ package bug import ( + "crypto/rand" "encoding/json" "fmt" "strings" @@ -17,6 +18,10 @@ var _ Operation = &CreateOperation{} // CreateOperation define the initial creation of a bug type CreateOperation struct { OpBase + // mandatory random bytes to ensure a better randomness of the data of the first + // operation of a bug, used to later generate the ID + // len(Nonce) should be > 20 and < 64 bytes + Nonce []byte `json:"nonce"` Title string `json:"title"` Message string `json:"message"` Files []repository.Hash `json:"files"` @@ -66,14 +71,19 @@ func (op *CreateOperation) Validate() error { return err } + if len(op.Nonce) > 64 { + return fmt.Errorf("create nonce is too big") + } + if len(op.Nonce) < 20 { + return fmt.Errorf("create nonce is too small") + } + if text.Empty(op.Title) { return fmt.Errorf("title is empty") } - if strings.Contains(op.Title, "\n") { return fmt.Errorf("title should be a single line") } - if !text.Safe(op.Title) { return fmt.Errorf("title is not fully printable") } @@ -98,6 +108,7 @@ func (op *CreateOperation) UnmarshalJSON(data []byte) error { } aux := struct { + Nonce []byte `json:"nonce"` Title string `json:"title"` Message string `json:"message"` Files []repository.Hash `json:"files"` @@ -109,6 +120,7 @@ func (op *CreateOperation) UnmarshalJSON(data []byte) error { } op.OpBase = base + op.Nonce = aux.Nonce op.Title = aux.Title op.Message = aux.Message op.Files = aux.Files @@ -119,9 +131,19 @@ func (op *CreateOperation) UnmarshalJSON(data []byte) error { // Sign post method for gqlgen func (op *CreateOperation) IsAuthored() {} +func makeNonce(len int) []byte { + result := make([]byte, len) + _, err := rand.Read(result) + if err != nil { + panic(err) + } + return result +} + func NewCreateOp(author identity.Interface, unixTime int64, title, message string, files []repository.Hash) *CreateOperation { return &CreateOperation{ OpBase: newOpBase(CreateOp, author, unixTime), + Nonce: makeNonce(20), Title: title, Message: message, Files: files, -- cgit From 2788c5fc87507974d3237d4edc233fda3f784b35 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 29 Nov 2020 20:22:09 +0100 Subject: bug: don't store the id in Bug, match how it's done for Identity --- bug/op_create.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index 3c8ce658..41e0fca1 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -38,6 +38,21 @@ func (op *CreateOperation) Id() entity.Id { return idOperation(op) } +// OVERRIDE +func (op *CreateOperation) SetMetadata(key string, value string) { + // sanity check: we make sure we are not in the following scenario: + // - the bug is created with a first operation + // - Id() is used + // - metadata are added, which will change the Id + // - Id() is used again + + if op.id != entity.UnsetId { + panic("usage of Id() after changing the first operation") + } + + op.OpBase.SetMetadata(key, value) +} + func (op *CreateOperation) Apply(snapshot *Snapshot) { snapshot.addActor(op.Author) snapshot.addParticipant(op.Author) @@ -95,7 +110,7 @@ func (op *CreateOperation) Validate() error { return nil } -// UnmarshalJSON is a two step JSON unmarshaling +// UnmarshalJSON is a two step JSON unmarshalling // This workaround is necessary to avoid the inner OpBase.MarshalJSON // overriding the outer op's MarshalJSON func (op *CreateOperation) UnmarshalJSON(data []byte) error { -- cgit From d96284da646cc1d3e3d7d3b2f7a1ab0e8e7a4d88 Mon Sep 17 00:00:00 2001 From: vince Date: Thu, 9 Jul 2020 14:59:47 +0800 Subject: Change the comment ID to use both bug and comment ID references. Add comment edit command This commit adds the comment edit command, which provides a CLI tool that allows a user to edit a comment. --- bug/op_create.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index 41e0fca1..15fb69b5 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -59,8 +59,9 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) { snapshot.Title = op.Title + commentId := DeriveCommentId(snapshot.Id(), op.Id()) comment := Comment{ - id: op.Id(), + id: commentId, Message: op.Message, Author: op.Author, UnixTime: timestamp.Timestamp(op.UnixTime), @@ -72,7 +73,7 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) { snapshot.Timeline = []TimelineItem{ &CreateTimelineItem{ - CommentTimelineItem: NewCommentTimelineItem(op.Id(), comment), + CommentTimelineItem: NewCommentTimelineItem(commentId, comment), }, } } -- cgit From fcf43915e1736fe0b56f8f06386f68d9b56da7a8 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Mon, 30 Nov 2020 00:41:50 +0100 Subject: bug: fix tests --- bug/op_create.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index 15fb69b5..044ddd72 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -54,6 +54,13 @@ func (op *CreateOperation) SetMetadata(key string, value string) { } func (op *CreateOperation) Apply(snapshot *Snapshot) { + // sanity check: will fail when adding a second Create + if snapshot.id != "" && snapshot.id != entity.UnsetId && snapshot.id != op.Id() { + panic("adding a second Create operation") + } + + snapshot.id = op.Id() + snapshot.addActor(op.Author) snapshot.addParticipant(op.Author) -- cgit From db7074301b6af895b1a47ecd12a5028ac809abfc Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Mon, 30 Nov 2020 01:55:30 +0100 Subject: entity: generalize the combined Ids, use 64 length --- bug/op_create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index 044ddd72..1e944d13 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -66,7 +66,7 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) { snapshot.Title = op.Title - commentId := DeriveCommentId(snapshot.Id(), op.Id()) + commentId := entity.CombineIds(snapshot.Id(), op.Id()) comment := Comment{ id: commentId, Message: op.Message, -- cgit From 3f6ef50883492f77995a7e27872d0b5ae17b9d6a Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 14 Feb 2021 11:36:32 +0100 Subject: bug: migrate to the DAG entity structure! --- bug/op_create.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index 1e944d13..2423e571 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -30,12 +30,8 @@ type CreateOperation struct { // Sign-post method for gqlgen func (op *CreateOperation) IsOperation() {} -func (op *CreateOperation) base() *OpBase { - return &op.OpBase -} - func (op *CreateOperation) Id() entity.Id { - return idOperation(op) + return idOperation(op, &op.OpBase) } // OVERRIDE @@ -61,8 +57,8 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) { snapshot.id = op.Id() - snapshot.addActor(op.Author) - snapshot.addParticipant(op.Author) + snapshot.addActor(op.Author_) + snapshot.addParticipant(op.Author_) snapshot.Title = op.Title @@ -70,12 +66,12 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) { comment := Comment{ id: commentId, Message: op.Message, - Author: op.Author, + Author: op.Author_, UnixTime: timestamp.Timestamp(op.UnixTime), } snapshot.Comments = []Comment{comment} - snapshot.Author = op.Author + snapshot.Author = op.Author_ snapshot.CreateTime = op.Time() snapshot.Timeline = []TimelineItem{ @@ -90,7 +86,7 @@ func (op *CreateOperation) GetFiles() []repository.Hash { } func (op *CreateOperation) Validate() error { - if err := opBaseValidate(op, CreateOp); err != nil { + if err := op.OpBase.Validate(op, CreateOp); err != nil { return err } -- cgit From bd09541752ef4db008500d238762ebe7f2f7be39 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sat, 20 Feb 2021 14:37:06 +0100 Subject: entity: no sign-post needed --- bug/op_create.go | 3 --- 1 file changed, 3 deletions(-) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index 2423e571..e3e38ade 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -27,9 +27,6 @@ type CreateOperation struct { Files []repository.Hash `json:"files"` } -// Sign-post method for gqlgen -func (op *CreateOperation) IsOperation() {} - func (op *CreateOperation) Id() entity.Id { return idOperation(op, &op.OpBase) } -- cgit From f1d4a19af81fcc05ae9d90e018ff141f6521335a Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 14 Mar 2021 18:39:04 +0100 Subject: bug: nonce on all operation to prevent id collision --- bug/op_create.go | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index e3e38ade..37e1ddc5 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -1,7 +1,6 @@ package bug import ( - "crypto/rand" "encoding/json" "fmt" "strings" @@ -18,10 +17,6 @@ var _ Operation = &CreateOperation{} // CreateOperation define the initial creation of a bug type CreateOperation struct { OpBase - // mandatory random bytes to ensure a better randomness of the data of the first - // operation of a bug, used to later generate the ID - // len(Nonce) should be > 20 and < 64 bytes - Nonce []byte `json:"nonce"` Title string `json:"title"` Message string `json:"message"` Files []repository.Hash `json:"files"` @@ -147,19 +142,9 @@ func (op *CreateOperation) UnmarshalJSON(data []byte) error { // Sign post method for gqlgen func (op *CreateOperation) IsAuthored() {} -func makeNonce(len int) []byte { - result := make([]byte, len) - _, err := rand.Read(result) - if err != nil { - panic(err) - } - return result -} - func NewCreateOp(author identity.Interface, unixTime int64, title, message string, files []repository.Hash) *CreateOperation { return &CreateOperation{ OpBase: newOpBase(CreateOp, author, unixTime), - Nonce: makeNonce(20), Title: title, Message: message, Files: files, -- cgit From 214abe4dea1984086e45d1399538fb12aa010642 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sat, 20 Feb 2021 15:48:44 +0100 Subject: WIP operation with files --- bug/op_create.go | 2 ++ 1 file changed, 2 insertions(+) (limited to 'bug/op_create.go') diff --git a/bug/op_create.go b/bug/op_create.go index 37e1ddc5..75b60bd8 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/MichaelMure/git-bug/entity" + "github.com/MichaelMure/git-bug/entity/dag" "github.com/MichaelMure/git-bug/identity" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util/text" @@ -13,6 +14,7 @@ import ( ) var _ Operation = &CreateOperation{} +var _ dag.OperationWithFiles = &CreateOperation{} // CreateOperation define the initial creation of a bug type CreateOperation struct { -- cgit