summaryrefslogtreecommitdiffstatshomepage
path: root/entity
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2023-08-14 16:58:06 +0200
committerMichael Muré <batolettre@gmail.com>2023-08-14 16:58:06 +0200
commit297e1931a7b5913275e8e9b0a46494d95e7e5e7c (patch)
tree5c5ef10f66bff4f9e6e3bbe87c70c02940bdbce3 /entity
parentf0167a1d6068d22af5ffff260e2848f7c14a71b3 (diff)
downloadgit-bug-bootstrap-rework-2.tar.gz
git-bug-bootstrap-rework-2.zip
Diffstat (limited to 'entity')
-rw-r--r--entity/boostrap/identity.go80
-rw-r--r--entity/dag/common_test.go10
-rw-r--r--entity/dag/entity.go3
-rw-r--r--entity/dag/entity_actions.go7
-rw-r--r--entity/dag/example_test.go20
-rw-r--r--entity/dag/op_noop.go3
-rw-r--r--entity/dag/op_noop_test.go3
-rw-r--r--entity/dag/op_set_metadata.go18
-rw-r--r--entity/dag/op_set_metadata_test.go2
-rw-r--r--entity/dag/operation.go11
-rw-r--r--entity/dag/operation_pack.go15
-rw-r--r--entity/dag/operation_testing.go2
-rw-r--r--entity/identity.go78
-rw-r--r--entity/operations.go3
14 files changed, 134 insertions, 121 deletions
diff --git a/entity/boostrap/identity.go b/entity/boostrap/identity.go
new file mode 100644
index 00000000..92fb03bf
--- /dev/null
+++ b/entity/boostrap/identity.go
@@ -0,0 +1,80 @@
+package bootstrap
+
+import (
+ "fmt"
+
+ "github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+
+ "github.com/MichaelMure/git-bug/repository"
+ "github.com/MichaelMure/git-bug/util/lamport"
+ "github.com/MichaelMure/git-bug/util/timestamp"
+)
+
+var ErrNoPrivateKey = fmt.Errorf("no private key")
+
+type Key interface {
+ Public() *packet.PublicKey
+ Private() *packet.PrivateKey
+ Validate() error
+ Clone() Key
+ PGPEntity() *openpgp.Entity
+
+ // EnsurePrivateKey attempt to load the corresponding private key if it is not loaded already.
+ // If no private key is found, returns ErrNoPrivateKey
+ EnsurePrivateKey(repo repository.RepoKeyring) error
+}
+
+type Identity interface {
+ Entity
+
+ // Name return the last version of the name
+ // Can be empty.
+ Name() string
+
+ // DisplayName return a non-empty string to display, representing the
+ // identity, based on the non-empty values.
+ DisplayName() string
+
+ // Email return the last version of the email
+ // Can be empty.
+ Email() string
+
+ // Login return the last version of the login
+ // Can be empty.
+ // Warning: this login can be defined when importing from a bridge but should *not* be
+ // used to identify an identity as multiple bridge with different login can map to the same
+ // identity. Use the metadata system for that usage instead.
+ Login() string
+
+ // AvatarUrl return the last version of the Avatar URL
+ // Can be empty.
+ AvatarUrl() string
+
+ // Keys return the last version of the valid keys
+ // Can be empty.
+ Keys() []Key
+
+ // SigningKey return the key that should be used to sign new messages. If no key is available, return nil.
+ SigningKey(repo repository.RepoKeyring) (Key, error)
+
+ // ValidKeysAtTime return the set of keys valid at a given lamport time for a given clock of another entity
+ // Can be empty.
+ ValidKeysAtTime(clockName string, time lamport.Time) []Key
+
+ // LastModification return the timestamp at which the last version of the identity became valid.
+ LastModification() timestamp.Timestamp
+
+ // LastModificationLamports return the lamport times at which the last version of the identity became valid.
+ LastModificationLamports() map[string]lamport.Time
+
+ // IsProtected return true if the chain of git commits started to be signed.
+ // If that's the case, only signed commit with a valid key for this identity can be added.
+ IsProtected() bool
+
+ // Validate check if the Identity data is valid
+ Validate() error
+
+ // NeedCommit indicate that the in-memory state changed and need to be committed in the repository
+ NeedCommit() bool
+}
diff --git a/entity/dag/common_test.go b/entity/dag/common_test.go
index a5cc4009..0ca2736d 100644
--- a/entity/dag/common_test.go
+++ b/entity/dag/common_test.go
@@ -30,7 +30,7 @@ type op1 struct {
Files []repository.Hash `json:"files"`
}
-func newOp1(author identity.Interface, field1 string, files ...repository.Hash) *op1 {
+func newOp1(author entity.Identity, field1 string, files ...repository.Hash) *op1 {
return &op1{OpBase: NewOpBase(Op1, author, 0), Field1: field1, Files: files}
}
@@ -49,7 +49,7 @@ type op2 struct {
Field2 string `json:"field_2"`
}
-func newOp2(author identity.Interface, field2 string) *op2 {
+func newOp2(author entity.Identity, field2 string) *op2 {
return &op2{OpBase: NewOpBase(Op2, author, 0), Field2: field2}
}
@@ -103,13 +103,13 @@ func wrapper(e *Entity) *Foo {
Identities + repo + definition
*/
-func makeTestContext() (repository.ClockedRepo, identity.Interface, identity.Interface, entity.Resolvers, Definition) {
+func makeTestContext() (repository.ClockedRepo, entity.Identity, entity.Identity, entity.Resolvers, Definition) {
repo := repository.NewMockRepo()
id1, id2, resolvers, def := makeTestContextInternal(repo)
return repo, id1, id2, resolvers, def
}
-func makeTestContextRemote(t *testing.T) (repository.ClockedRepo, repository.ClockedRepo, repository.ClockedRepo, identity.Interface, identity.Interface, entity.Resolvers, Definition) {
+func makeTestContextRemote(t *testing.T) (repository.ClockedRepo, repository.ClockedRepo, repository.ClockedRepo, entity.Identity, entity.Identity, entity.Resolvers, Definition) {
repoA := repository.CreateGoGitTestRepo(t, false)
repoB := repository.CreateGoGitTestRepo(t, false)
remote := repository.CreateGoGitTestRepo(t, true)
@@ -134,7 +134,7 @@ func makeTestContextRemote(t *testing.T) (repository.ClockedRepo, repository.Clo
return repoA, repoB, remote, id1, id2, resolver, def
}
-func makeTestContextInternal(repo repository.ClockedRepo) (identity.Interface, identity.Interface, entity.Resolvers, Definition) {
+func makeTestContextInternal(repo repository.ClockedRepo) (entity.Identity, entity.Identity, entity.Resolvers, Definition) {
id1, err := identity.NewIdentity(repo, "name1", "email1")
if err != nil {
panic(err)
diff --git a/entity/dag/entity.go b/entity/dag/entity.go
index 7c5c4d3c..65dae504 100644
--- a/entity/dag/entity.go
+++ b/entity/dag/entity.go
@@ -9,7 +9,6 @@ import (
"github.com/pkg/errors"
- "github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/entity"
bootstrap "github.com/MichaelMure/git-bug/entity/boostrap"
"github.com/MichaelMure/git-bug/repository"
@@ -455,7 +454,7 @@ func (e *Entity) Commit(repo repository.ClockedRepo) error {
}
for len(e.staging) > 0 {
- var author identity.Interface
+ var author entity.Identity
var toCommit []Operation
// Split into chunks with the same author
diff --git a/entity/dag/entity_actions.go b/entity/dag/entity_actions.go
index 3c3f819f..5afca124 100644
--- a/entity/dag/entity_actions.go
+++ b/entity/dag/entity_actions.go
@@ -5,7 +5,6 @@ import (
"github.com/pkg/errors"
- "github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/entity"
"github.com/MichaelMure/git-bug/repository"
)
@@ -32,7 +31,7 @@ func Push(def Definition, repo repository.Repo, remote string) (string, error) {
// Pull will do a Fetch + MergeAll
// Contrary to MergeAll, this function will return an error if a merge fail.
-func Pull[EntityT entity.Bare](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers, remote string, author identity.Interface) error {
+func Pull[EntityT entity.Bare](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers, remote string, author entity.Identity) error {
_, err := Fetch(def, repo, remote)
if err != nil {
return err
@@ -68,7 +67,7 @@ func Pull[EntityT entity.Bare](def Definition, wrapper func(e *Entity) EntityT,
//
// Note: an author is necessary for the case where a merge commit is created, as this commit will
// have an author and may be signed if a signing key is available.
-func MergeAll[EntityT entity.Bare](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers, remote string, author identity.Interface) <-chan entity.MergeResult {
+func MergeAll[EntityT entity.Bare](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers, remote string, author entity.Identity) <-chan entity.MergeResult {
out := make(chan entity.MergeResult)
go func() {
@@ -91,7 +90,7 @@ func MergeAll[EntityT entity.Bare](def Definition, wrapper func(e *Entity) Entit
// merge perform a merge to make sure a local Entity is up-to-date.
// See MergeAll for more details.
-func merge[EntityT entity.Bare](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers, remoteRef string, author identity.Interface) entity.MergeResult {
+func merge[EntityT entity.Bare](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers, remoteRef string, author entity.Identity) entity.MergeResult {
id := entity.RefToId(remoteRef)
if err := id.Validate(); err != nil {
diff --git a/entity/dag/example_test.go b/entity/dag/example_test.go
index 3a12db5f..d56f74a3 100644
--- a/entity/dag/example_test.go
+++ b/entity/dag/example_test.go
@@ -30,13 +30,13 @@ import (
// Snapshot is the compiled view of a ProjectConfig
type Snapshot struct {
// Administrator is the set of users with the higher level of access
- Administrator map[identity.Interface]struct{}
+ Administrator map[entity.Identity]struct{}
// SignatureRequired indicate that all git commit need to be signed
SignatureRequired bool
}
// HasAdministrator returns true if the given identity is included in the administrator.
-func (snap *Snapshot) HasAdministrator(i identity.Interface) bool {
+func (snap *Snapshot) HasAdministrator(i entity.Identity) bool {
for admin, _ := range snap.Administrator {
if admin.Id() == i.Id() {
return true
@@ -78,7 +78,7 @@ type SetSignatureRequired struct {
Value bool `json:"value"`
}
-func NewSetSignatureRequired(author identity.Interface, value bool) *SetSignatureRequired {
+func NewSetSignatureRequired(author entity.Identity, value bool) *SetSignatureRequired {
return &SetSignatureRequired{
OpBase: dag.NewOpBase(SetSignatureRequiredOp, author, time.Now().Unix()),
Value: value,
@@ -106,10 +106,10 @@ func (ssr *SetSignatureRequired) Apply(snapshot *Snapshot) {
// AddAdministrator is an operation to add a new administrator in the set
type AddAdministrator struct {
dag.OpBase
- ToAdd []identity.Interface `json:"to_add"`
+ ToAdd []entity.Identity `json:"to_add"`
}
-func NewAddAdministratorOp(author identity.Interface, toAdd ...identity.Interface) *AddAdministrator {
+func NewAddAdministratorOp(author entity.Identity, toAdd ...entity.Identity) *AddAdministrator {
return &AddAdministrator{
OpBase: dag.NewOpBase(AddAdministratorOp, author, time.Now().Unix()),
ToAdd: toAdd,
@@ -143,10 +143,10 @@ func (aa *AddAdministrator) Apply(snapshot *Snapshot) {
// RemoveAdministrator is an operation to remove an administrator from the set
type RemoveAdministrator struct {
dag.OpBase
- ToRemove []identity.Interface `json:"to_remove"`
+ ToRemove []entity.Identity `json:"to_remove"`
}
-func NewRemoveAdministratorOp(author identity.Interface, toRemove ...identity.Interface) *RemoveAdministrator {
+func NewRemoveAdministratorOp(author entity.Identity, toRemove ...entity.Identity) *RemoveAdministrator {
return &RemoveAdministrator{
OpBase: dag.NewOpBase(RemoveAdministratorOp, author, time.Now().Unix()),
ToRemove: toRemove,
@@ -249,7 +249,7 @@ func operationUnmarshaler(raw json.RawMessage, resolvers entity.Resolvers) (dag.
case *AddAdministrator:
// We need to resolve identities
for i, stub := range op.ToAdd {
- iden, err := entity.Resolve[identity.Interface](resolvers, stub.Id())
+ iden, err := entity.Resolve[entity.Identity](resolvers, stub.Id())
if err != nil {
return nil, err
}
@@ -258,7 +258,7 @@ func operationUnmarshaler(raw json.RawMessage, resolvers entity.Resolvers) (dag.
case *RemoveAdministrator:
// We need to resolve identities
for i, stub := range op.ToRemove {
- iden, err := entity.Resolve[identity.Interface](resolvers, stub.Id())
+ iden, err := entity.Resolve[entity.Identity](resolvers, stub.Id())
if err != nil {
return nil, err
}
@@ -275,7 +275,7 @@ func (pc ProjectConfig) Compile() *Snapshot {
// Note: this would benefit from caching, but it's a simple example
snap := &Snapshot{
// default value
- Administrator: make(map[identity.Interface]struct{}),
+ Administrator: make(map[entity.Identity]struct{}),
SignatureRequired: false,
}
for _, op := range pc.Operations() {
diff --git a/entity/dag/op_noop.go b/entity/dag/op_noop.go
index d8a2a05a..1b600ee0 100644
--- a/entity/dag/op_noop.go
+++ b/entity/dag/op_noop.go
@@ -1,7 +1,6 @@
package dag
import (
- "github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/entity"
)
@@ -15,7 +14,7 @@ type NoOpOperation[SnapT entity.Snapshot] struct {
OpBase
}
-func NewNoOpOp[SnapT entity.Snapshot](opType entity.OperationType, author identity.Interface, unixTime int64) *NoOpOperation[SnapT] {
+func NewNoOpOp[SnapT entity.Snapshot](opType entity.OperationType, author entity.Identity, unixTime int64) *NoOpOperation[SnapT] {
return &NoOpOperation[SnapT]{
OpBase: NewOpBase(opType, author, unixTime),
}
diff --git a/entity/dag/op_noop_test.go b/entity/dag/op_noop_test.go
index 61497b5b..4ce2d194 100644
--- a/entity/dag/op_noop_test.go
+++ b/entity/dag/op_noop_test.go
@@ -4,7 +4,6 @@ import (
"encoding/json"
"testing"
- "github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/entity"
)
@@ -13,7 +12,7 @@ func TestNoopSerialize(t *testing.T) {
var op NoOpOperation[*snapshotMock]
err := json.Unmarshal(raw, &op)
return &op, err
- }, func(author identity.Interface, unixTime int64) (*NoOpOperation[*snapshotMock], entity.Resolvers) {
+ }, func(author entity.Identity, unixTime int64) (*NoOpOperation[*snapshotMock], entity.Resolvers) {
return NewNoOpOp[*snapshotMock](1, author, unixTime), nil
})
}
diff --git a/entity/dag/op_set_metadata.go b/entity/dag/op_set_metadata.go
index 19176183..7b79a5bf 100644
--- a/entity/dag/op_set_metadata.go
+++ b/entity/dag/op_set_metadata.go
@@ -5,7 +5,6 @@ import (
"github.com/pkg/errors"
- "github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/entity"
"github.com/MichaelMure/git-bug/util/text"
)
@@ -19,7 +18,7 @@ type SetMetadataOperation[SnapT entity.Snapshot] struct {
NewMetadata map[string]string `json:"new_metadata"`
}
-func NewSetMetadataOp[SnapT entity.Snapshot](opType entity.OperationType, author identity.Interface, unixTime int64, target entity.Id, newMetadata map[string]string) *SetMetadataOperation[SnapT] {
+func NewSetMetadataOp[SnapT entity.Snapshot](opType entity.OperationType, author entity.Identity, unixTime int64, target entity.Id, newMetadata map[string]string) *SetMetadataOperation[SnapT] {
return &SetMetadataOperation[SnapT]{
OpBase: NewOpBase(opType, author, unixTime),
Target: target,
@@ -33,13 +32,16 @@ func (op *SetMetadataOperation[SnapT]) Id() entity.Id {
func (op *SetMetadataOperation[SnapT]) Apply(snapshot SnapT) {
for _, target := range snapshot.AllOperations() {
- if target.Id() == op.Target {
- // Apply the metadata in an immutable way: if a metadata already
- // exist, it's not possible to override it.
- for key, value := range op.NewMetadata {
- target.setExtraMetadataImmutable(key, value)
+ // cast to dag.Operation to have the private methods
+ if target, ok := target.(Operation); ok {
+ if target.Id() == op.Target {
+ // Apply the metadata in an immutable way: if a metadata already
+ // exist, it's not possible to override it.
+ for key, value := range op.NewMetadata {
+ target.setExtraMetadataImmutable(key, value)
+ }
+ return
}
- return
}
}
}
diff --git a/entity/dag/op_set_metadata_test.go b/entity/dag/op_set_metadata_test.go
index 591ce9b2..5019d838 100644
--- a/entity/dag/op_set_metadata_test.go
+++ b/entity/dag/op_set_metadata_test.go
@@ -109,7 +109,7 @@ func TestSetMetadataSerialize(t *testing.T) {
var op SetMetadataOperation[*snapshotMock]
err := json.Unmarshal(raw, &op)
return &op, err
- }, func(author identity.Interface, unixTime int64) (*SetMetadataOperation[*snapshotMock], entity.Resolvers) {
+ }, func(author entity.Identity, unixTime int64) (*SetMetadataOperation[*snapshotMock], entity.Resolvers) {
return NewSetMetadataOp[*snapshotMock](1, author, unixTime, "message", map[string]string{
"key1": "value1",
"key2": "value2",
diff --git a/entity/dag/operation.go b/entity/dag/operation.go
index 40bd7da8..216788c4 100644
--- a/entity/dag/operation.go
+++ b/entity/dag/operation.go
@@ -8,7 +8,6 @@ import (
"github.com/pkg/errors"
- "github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/entity"
)
@@ -19,7 +18,7 @@ type Operation interface {
// setId allow to set the Id, used when unmarshalling only
setId(id entity.Id)
// setAuthor allow to set the author, used when unmarshalling only
- setAuthor(author identity.Interface)
+ setAuthor(author entity.Identity)
// setExtraMetadataImmutable add a metadata not carried by the operation itself on the operation
setExtraMetadataImmutable(key string, value string)
}
@@ -36,7 +35,7 @@ type OpBase struct {
// Not serialized. Store the op's id in memory.
id entity.Id
// Not serialized
- author identity.Interface
+ author entity.Identity
OperationType entity.OperationType `json:"type"`
UnixTime int64 `json:"timestamp"`
@@ -52,7 +51,7 @@ type OpBase struct {
extraMetadata map[string]string
}
-func NewOpBase(opType entity.OperationType, author identity.Interface, unixTime int64) OpBase {
+func NewOpBase(opType entity.OperationType, author entity.Identity, unixTime int64) OpBase {
return OpBase{
OperationType: opType,
author: author,
@@ -144,7 +143,7 @@ func (base *OpBase) Validate(op entity.Operation, opType entity.OperationType) e
func (base *OpBase) IsAuthored() {}
// Author return author identity
-func (base *OpBase) Author() identity.Interface {
+func (base *OpBase) Author() entity.Identity {
return base.author
}
@@ -204,7 +203,7 @@ func (base *OpBase) setId(id entity.Id) {
}
// setAuthor allow to set the author, used when unmarshalling only
-func (base *OpBase) setAuthor(author identity.Interface) {
+func (base *OpBase) setAuthor(author entity.Identity) {
base.author = author
}
diff --git a/entity/dag/operation_pack.go b/entity/dag/operation_pack.go
index 85cceb4f..aaffa03b 100644
--- a/entity/dag/operation_pack.go
+++ b/entity/dag/operation_pack.go
@@ -12,6 +12,7 @@ import (
"github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/entity"
+ bootstrap "github.com/MichaelMure/git-bug/entity/boostrap"
"github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util/lamport"
)
@@ -29,7 +30,7 @@ type operationPack struct {
id entity.Id
// The author of the Operations. Must be the same author for all the Operations.
- Author identity.Interface
+ Author entity.Identity
// The list of Operation stored in the operationPack
Operations []Operation
// Encode the entity's logical time of creation across all entities of the same type.
@@ -58,8 +59,8 @@ func (opp *operationPack) Id() entity.Id {
func (opp *operationPack) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
- Author identity.Interface `json:"author"`
- Operations []Operation `json:"ops"`
+ Author entity.Identity `json:"author"`
+ Operations []Operation `json:"ops"`
}{
Author: opp.Author,
Operations: opp.Operations,
@@ -235,7 +236,7 @@ func readOperationPack(def Definition, repo repository.RepoData, resolvers entit
}
var id entity.Id
- var author identity.Interface
+ var author entity.Identity
var ops []Operation
var createTime lamport.Time
var editTime lamport.Time
@@ -323,7 +324,7 @@ func readOperationPackClock(repo repository.RepoData, commit repository.Commit)
// unmarshallPack delegate the unmarshalling of the Operation's JSON to the decoding
// function provided by the concrete entity. This gives access to the concrete type of each
// Operation.
-func unmarshallPack(def Definition, resolvers entity.Resolvers, data []byte) ([]Operation, identity.Interface, error) {
+func unmarshallPack(def Definition, resolvers entity.Resolvers, data []byte) ([]Operation, entity.Identity, error) {
aux := struct {
Author identity.IdentityStub `json:"author"`
Operations []json.RawMessage `json:"ops"`
@@ -337,7 +338,7 @@ func unmarshallPack(def Definition, resolvers entity.Resolvers, data []byte) ([]
return nil, nil, fmt.Errorf("missing author")
}
- author, err := entity.Resolve[identity.Interface](resolvers, aux.Author.Id())
+ author, err := entity.Resolve[entity.Identity](resolvers, aux.Author.Id())
if err != nil {
return nil, nil, err
}
@@ -364,7 +365,7 @@ func unmarshallPack(def Definition, resolvers entity.Resolvers, data []byte) ([]
var _ openpgp.KeyRing = &PGPKeyring{}
// PGPKeyring implement a openpgp.KeyRing from an slice of Key
-type PGPKeyring []*identity.Key
+type PGPKeyring []bootstrap.Key
func (pk PGPKeyring) KeysById(id uint64) []openpgp.Key {
var result []openpgp.Key
diff --git a/entity/dag/operation_testing.go b/entity/dag/operation_testing.go
index 0ca47d4b..fd4d2343 100644
--- a/entity/dag/operation_testing.go
+++ b/entity/dag/operation_testing.go
@@ -17,7 +17,7 @@ import (
func SerializeRoundTripTest[OpT Operation](
t *testing.T,
unmarshaler OperationUnmarshaler,
- maker func(author identity.Interface, unixTime int64) (OpT, entity.Resolvers),
+ maker func(author entity.Identity, unixTime int64) (OpT, entity.Resolvers),
) {
repo := repository.NewMockRepo()
diff --git a/entity/identity.go b/entity/identity.go
index 71e0a6e8..2523e1f3 100644
--- a/entity/identity.go
+++ b/entity/identity.go
@@ -1,73 +1,9 @@
package entity
-//
-// import (
-// "github.com/ProtonMail/go-crypto/openpgp"
-// "github.com/ProtonMail/go-crypto/openpgp/packet"
-//
-// "github.com/MichaelMure/git-bug/repository"
-// "github.com/MichaelMure/git-bug/util/lamport"
-// "github.com/MichaelMure/git-bug/util/timestamp"
-// )
-//
-// type Key interface {
-// Public() *packet.PublicKey
-// Private() *packet.PrivateKey
-// Validate() error
-// Clone() Key
-// PGPEntity() *openpgp.Entity
-// }
-//
-// type Identity interface {
-// Bare
-//
-// // Name return the last version of the name
-// // Can be empty.
-// Name() string
-//
-// // DisplayName return a non-empty string to display, representing the
-// // identity, based on the non-empty values.
-// DisplayName() string
-//
-// // Email return the last version of the email
-// // Can be empty.
-// Email() string
-//
-// // Login return the last version of the login
-// // Can be empty.
-// // Warning: this login can be defined when importing from a bridge but should *not* be
-// // used to identify an identity as multiple bridge with different login can map to the same
-// // identity. Use the metadata system for that usage instead.
-// Login() string
-//
-// // AvatarUrl return the last version of the Avatar URL
-// // Can be empty.
-// AvatarUrl() string
-//
-// // Keys return the last version of the valid keys
-// // Can be empty.
-// Keys() []Key
-//
-// // SigningKey return the key that should be used to sign new messages. If no key is available, return nil.
-// SigningKey(repo repository.RepoKeyring) (Key, error)
-//
-// // ValidKeysAtTime return the set of keys valid at a given lamport time for a given clock of another entity
-// // Can be empty.
-// ValidKeysAtTime(clockName string, time lamport.Time) []Key
-//
-// // LastModification return the timestamp at which the last version of the identity became valid.
-// LastModification() timestamp.Timestamp
-//
-// // LastModificationLamports return the lamport times at which the last version of the identity became valid.
-// LastModificationLamports() map[string]lamport.Time
-//
-// // IsProtected return true if the chain of git commits started to be signed.
-// // If that's the case, only signed commit with a valid key for this identity can be added.
-// IsProtected() bool
-//
-// // Validate check if the Identity data is valid
-// Validate() error
-//
-// // NeedCommit indicate that the in-memory state changed and need to be committed in the repository
-// NeedCommit() bool
-// }
+import bootstrap "github.com/MichaelMure/git-bug/entity/boostrap"
+
+var ErrNoPrivateKey = bootstrap.ErrNoPrivateKey
+
+type Key = bootstrap.Key
+
+type Identity = bootstrap.Identity
diff --git a/entity/operations.go b/entity/operations.go
index fd88f033..4280cf63 100644
--- a/entity/operations.go
+++ b/entity/operations.go
@@ -3,7 +3,6 @@ package entity
import (
"time"
- "github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/repository"
)
@@ -38,7 +37,7 @@ type Operation interface {
// Validate check if the Operation data is valid
Validate() error
// Author returns the author of this operation
- Author() identity.Interface
+ Author() Identity
// Time return the time when the operation was added
Time() time.Time