git-bug/identity/bare.go

190 lines
4.9 KiB
Go
Raw Normal View History

2018-11-21 20:56:12 +03:00
package identity
import (
2019-01-19 21:23:31 +03:00
"crypto/sha256"
2018-11-21 20:56:12 +03:00
"encoding/json"
"fmt"
"strings"
"github.com/MichaelMure/git-bug/entity"
2019-01-19 21:23:31 +03:00
"github.com/MichaelMure/git-bug/repository"
2018-11-21 20:56:12 +03:00
"github.com/MichaelMure/git-bug/util/lamport"
"github.com/MichaelMure/git-bug/util/text"
"github.com/MichaelMure/git-bug/util/timestamp"
2018-11-21 20:56:12 +03:00
)
2019-01-19 21:23:31 +03:00
var _ Interface = &Bare{}
var _ entity.Interface = &Bare{}
2019-01-19 21:23:31 +03:00
// 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.
// Deprecated: legacy identity for compat, might make sense to ditch entirely for
// simplicity but that would be a breaking change.
2018-11-21 20:56:12 +03:00
type Bare struct {
id entity.Id
2018-11-21 20:56:12 +03:00
name string
email string
avatarUrl string
}
func NewBare(name string, email string) *Bare {
return &Bare{id: entity.UnsetId, name: name, email: email}
2018-11-21 20:56:12 +03:00
}
2020-01-21 20:49:33 +03:00
func NewBareFull(name string, email string, avatarUrl string) *Bare {
return &Bare{id: entity.UnsetId, name: name, email: email, avatarUrl: avatarUrl}
}
func deriveId(data []byte) entity.Id {
sum := sha256.Sum256(data)
return entity.Id(fmt.Sprintf("%x", sum))
2018-11-21 20:56:12 +03:00
}
type bareIdentityJSON struct {
2018-11-21 20:56:12 +03:00
Name string `json:"name,omitempty"`
Email string `json:"email,omitempty"`
2020-01-21 20:49:33 +03:00
Login string `json:"login,omitempty"` // Deprecated, only kept to have the same ID when reading an old value
2018-11-21 20:56:12 +03:00
AvatarUrl string `json:"avatar_url,omitempty"`
}
2019-01-19 21:23:31 +03:00
func (i *Bare) MarshalJSON() ([]byte, error) {
return json.Marshal(bareIdentityJSON{
2018-11-21 20:56:12 +03:00
Name: i.name,
Email: i.email,
AvatarUrl: i.avatarUrl,
})
}
2019-01-19 21:23:31 +03:00
func (i *Bare) UnmarshalJSON(data []byte) error {
// Compute the Id when loading the op from disk.
i.id = deriveId(data)
aux := bareIdentityJSON{}
2018-11-21 20:56:12 +03:00
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
i.name = aux.Name
i.email = aux.Email
i.avatarUrl = aux.AvatarUrl
return nil
}
2019-02-19 02:19:27 +03:00
// Id return the Identity identifier
func (i *Bare) Id() entity.Id {
// We don't have a proper Id at hand, so let's hash all the data to get one.
2019-01-19 21:23:31 +03:00
if i.id == "" {
// something went really wrong
panic("identity's id not set")
2019-01-19 21:23:31 +03:00
}
if i.id == entity.UnsetId {
// This means we are trying to get the identity identifier *before* it has been stored
// As the Id is computed based on the actual bytes written on the disk, we are going to predict
// those and then get the Id. This is safe as it will be the exact same code writing on disk later.
2019-01-19 21:23:31 +03:00
data, err := json.Marshal(i)
if err != nil {
panic(err)
}
2019-01-19 21:23:31 +03:00
i.id = deriveId(data)
}
2019-01-19 21:23:31 +03:00
return i.id
}
2019-02-19 02:19:27 +03:00
// Name return the last version of the name
2019-01-19 21:23:31 +03:00
func (i *Bare) Name() string {
2018-11-21 20:56:12 +03:00
return i.name
}
2019-02-19 02:19:27 +03:00
// Email return the last version of the email
2019-01-19 21:23:31 +03:00
func (i *Bare) Email() string {
2018-11-21 20:56:12 +03:00
return i.email
}
2019-02-19 02:19:27 +03:00
// AvatarUrl return the last version of the Avatar URL
2019-01-19 21:23:31 +03:00
func (i *Bare) AvatarUrl() string {
2018-11-21 20:56:12 +03:00
return i.avatarUrl
}
// Keys return the last version of the valid keys
2020-01-24 02:30:13 +03:00
func (i *Bare) Keys() []*Key {
return nil
2018-11-21 20:56:12 +03:00
}
// ValidKeysAtTime return the set of keys valid at a given lamport time
2020-01-24 02:30:13 +03:00
func (i *Bare) ValidKeysAtTime(_ lamport.Time) []*Key {
return nil
2018-11-21 20:56:12 +03:00
}
// DisplayName return a non-empty string to display, representing the
// identity, based on the non-empty values.
2019-01-19 21:23:31 +03:00
func (i *Bare) DisplayName() string {
2020-01-21 20:49:33 +03:00
return i.name
2018-11-21 20:56:12 +03:00
}
// Validate check if the Identity data is valid
2019-01-19 21:23:31 +03:00
func (i *Bare) Validate() error {
2020-01-21 20:49:33 +03:00
if text.Empty(i.name) {
return fmt.Errorf("name is not set")
2018-11-21 20:56:12 +03:00
}
if strings.Contains(i.name, "\n") {
return fmt.Errorf("name should be a single line")
}
if !text.Safe(i.name) {
return fmt.Errorf("name is not fully printable")
}
if strings.Contains(i.email, "\n") {
return fmt.Errorf("email should be a single line")
}
if !text.Safe(i.email) {
return fmt.Errorf("email is not fully printable")
}
if i.avatarUrl != "" && !text.ValidUrl(i.avatarUrl) {
return fmt.Errorf("avatarUrl is not a valid URL")
}
return nil
}
2019-01-19 21:23:31 +03:00
// Write the identity into the Repository. In particular, this ensure that
// the Id is properly set.
2019-02-19 02:19:27 +03:00
func (i *Bare) Commit(repo repository.ClockedRepo) error {
2019-01-19 21:23:31 +03:00
// Nothing to do, everything is directly embedded
return nil
}
2019-02-19 02:19:27 +03:00
// If needed, write the identity into the Repository. In particular, this
// ensure that the Id is properly set.
func (i *Bare) CommitAsNeeded(repo repository.ClockedRepo) error {
2019-02-16 19:32:30 +03:00
// 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.
2019-01-19 21:23:31 +03:00
func (i *Bare) IsProtected() bool {
2018-11-21 20:56:12 +03:00
return false
}
// LastModificationLamportTime return the Lamport time at which the last version of the identity became valid.
func (i *Bare) LastModificationLamport() lamport.Time {
return 0
}
// LastModification return the timestamp at which the last version of the identity became valid.
func (i *Bare) LastModification() timestamp.Timestamp {
return 0
}