aboutsummaryrefslogtreecommitdiffstats
path: root/identity
diff options
context:
space:
mode:
Diffstat (limited to 'identity')
-rw-r--r--identity/bare.go55
-rw-r--r--identity/bare_test.go13
-rw-r--r--identity/common.go53
-rw-r--r--identity/identity.go16
-rw-r--r--identity/interface.go5
5 files changed, 117 insertions, 25 deletions
diff --git a/identity/bare.go b/identity/bare.go
index 24f30f9f..729dc2e0 100644
--- a/identity/bare.go
+++ b/identity/bare.go
@@ -1,20 +1,25 @@
package identity
import (
+ "crypto/sha256"
"encoding/json"
"fmt"
"strings"
+ "github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util/lamport"
"github.com/MichaelMure/git-bug/util/text"
)
+var _ Interface = &Bare{}
+
// Bare is a very minimal identity, designed to be fully embedded directly along
// other data.
//
// in particular, this identity is designed to be compatible with the handling of
// identities in the early version of git-bug.
type Bare struct {
+ id string
name string
email string
login string
@@ -36,7 +41,7 @@ type bareIdentityJson struct {
AvatarUrl string `json:"avatar_url,omitempty"`
}
-func (i Bare) MarshalJSON() ([]byte, error) {
+func (i *Bare) MarshalJSON() ([]byte, error) {
return json.Marshal(bareIdentityJson{
Name: i.name,
Email: i.email,
@@ -45,7 +50,7 @@ func (i Bare) MarshalJSON() ([]byte, error) {
})
}
-func (i Bare) UnmarshalJSON(data []byte) error {
+func (i *Bare) UnmarshalJSON(data []byte) error {
aux := bareIdentityJson{}
if err := json.Unmarshal(data, &aux); err != nil {
@@ -60,35 +65,54 @@ func (i Bare) UnmarshalJSON(data []byte) error {
return nil
}
-func (i Bare) Name() string {
+func (i *Bare) Id() string {
+ // We don't have a proper ID at hand, so let's hash all the data to get one.
+ // Hopefully the
+
+ if i.id != "" {
+ return i.id
+ }
+
+ data, err := json.Marshal(i)
+ if err != nil {
+ panic(err)
+ }
+
+ h := fmt.Sprintf("%x", sha256.New().Sum(data)[:16])
+ i.id = string(h)
+
+ return i.id
+}
+
+func (i *Bare) Name() string {
return i.name
}
-func (i Bare) Email() string {
+func (i *Bare) Email() string {
return i.email
}
-func (i Bare) Login() string {
+func (i *Bare) Login() string {
return i.login
}
-func (i Bare) AvatarUrl() string {
+func (i *Bare) AvatarUrl() string {
return i.avatarUrl
}
// Keys return the last version of the valid keys
-func (i Bare) Keys() []Key {
+func (i *Bare) Keys() []Key {
return []Key{}
}
// ValidKeysAtTime return the set of keys valid at a given lamport time
-func (i Bare) ValidKeysAtTime(time lamport.Time) []Key {
+func (i *Bare) ValidKeysAtTime(time lamport.Time) []Key {
return []Key{}
}
// DisplayName return a non-empty string to display, representing the
// identity, based on the non-empty values.
-func (i Bare) DisplayName() string {
+func (i *Bare) DisplayName() string {
switch {
case i.name == "" && i.login != "":
return i.login
@@ -102,7 +126,7 @@ func (i Bare) DisplayName() string {
}
// Match tell is the Person match the given query string
-func (i Bare) Match(query string) bool {
+func (i *Bare) Match(query string) bool {
query = strings.ToLower(query)
return strings.Contains(strings.ToLower(i.name), query) ||
@@ -110,7 +134,7 @@ func (i Bare) Match(query string) bool {
}
// Validate check if the Identity data is valid
-func (i Bare) Validate() error {
+func (i *Bare) Validate() error {
if text.Empty(i.name) && text.Empty(i.login) {
return fmt.Errorf("either name or login should be set")
}
@@ -146,8 +170,15 @@ func (i Bare) Validate() error {
return nil
}
+// Write the identity into the Repository. In particular, this ensure that
+// the Id is properly set.
+func (i *Bare) Commit(repo repository.Repo) error {
+ // Nothing to do, everything is directly embedded
+ return nil
+}
+
// 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.
-func (i Bare) IsProtected() bool {
+func (i *Bare) IsProtected() bool {
return false
}
diff --git a/identity/bare_test.go b/identity/bare_test.go
new file mode 100644
index 00000000..1458107a
--- /dev/null
+++ b/identity/bare_test.go
@@ -0,0 +1,13 @@
+package identity
+
+import (
+ "testing"
+
+ "github.com/magiconair/properties/assert"
+)
+
+func TestBare_Id(t *testing.T) {
+ i := NewBare("name", "email")
+ id := i.Id()
+ assert.Equal(t, "7b226e616d65223a226e616d65222c22", id)
+}
diff --git a/identity/common.go b/identity/common.go
new file mode 100644
index 00000000..32dd3d9e
--- /dev/null
+++ b/identity/common.go
@@ -0,0 +1,53 @@
+package identity
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "strings"
+)
+
+var ErrIdentityNotExist = errors.New("identity doesn't exist")
+
+type ErrMultipleMatch struct {
+ Matching []string
+}
+
+func (e ErrMultipleMatch) Error() string {
+ return fmt.Sprintf("Multiple matching identities found:\n%s", strings.Join(e.Matching, "\n"))
+}
+
+// Custom unmarshaling function to allow package user to delegate
+// the decoding of an Identity and distinguish between an Identity
+// and a Bare.
+//
+// If the given message has a "id" field, it's considered being a proper Identity.
+func UnmarshalJSON(raw json.RawMessage) (Interface, error) {
+ // First try to decode as a normal Identity
+ var i Identity
+
+ err := json.Unmarshal(raw, &i)
+ if err == nil && i.id != "" {
+ return &i, nil
+ }
+
+ // abort if we have an error other than the wrong type
+ if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
+ return nil, err
+ }
+
+ // Fallback on a legacy Bare identity
+ var b Bare
+
+ err = json.Unmarshal(raw, &b)
+ if err == nil && (b.name != "" || b.login != "") {
+ return &b, nil
+ }
+
+ // abort if we have an error other than the wrong type
+ if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
+ return nil, err
+ }
+
+ return nil, fmt.Errorf("unknown identity type")
+}
diff --git a/identity/identity.go b/identity/identity.go
index 313e3fd7..38729e37 100644
--- a/identity/identity.go
+++ b/identity/identity.go
@@ -16,16 +16,6 @@ const identityRefPattern = "refs/identities/"
const versionEntryName = "version"
const identityConfigKey = "git-bug.identity"
-var ErrIdentityNotExist = errors.New("identity doesn't exist")
-
-type ErrMultipleMatch struct {
- Matching []string
-}
-
-func (e ErrMultipleMatch) Error() string {
- return fmt.Sprintf("Multiple matching identities found:\n%s", strings.Join(e.Matching, "\n"))
-}
-
var _ Interface = &Identity{}
type Identity struct {
@@ -85,8 +75,6 @@ func (i *Identity) UnmarshalJSON(data []byte) error {
return nil
}
-// TODO: load/write from OpBase
-
// Read load an Identity from the identities data available in git
func Read(repo repository.Repo, id string) (*Identity, error) {
i := &Identity{
@@ -230,7 +218,9 @@ func (i *Identity) AddVersion(version *Version) {
i.Versions = append(i.Versions, version)
}
-func (i *Identity) Commit(repo repository.ClockedRepo) error {
+// Write the identity into the Repository. In particular, this ensure that
+// the Id is properly set.
+func (i *Identity) Commit(repo repository.Repo) error {
// Todo: check for mismatch between memory and commited data
var lastCommit git.Hash = ""
diff --git a/identity/interface.go b/identity/interface.go
index 6489efbe..c784a7a6 100644
--- a/identity/interface.go
+++ b/identity/interface.go
@@ -1,6 +1,7 @@
package identity
import (
+ "github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util/lamport"
)
@@ -28,6 +29,10 @@ type Interface interface {
// Validate check if the Identity data is valid
Validate() error
+ // Write the identity into the Repository. In particular, this ensure that
+ // the Id is properly set.
+ Commit(repo repository.Repo) error
+
// 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