1package identity
2
3import (
4 "encoding/json"
5 "fmt"
6 "strings"
7
8 "github.com/MichaelMure/git-bug/util/lamport"
9 "github.com/MichaelMure/git-bug/util/text"
10)
11
12// Bare is a very minimal identity, designed to be fully embedded directly along
13// other data.
14//
15// in particular, this identity is designed to be compatible with the handling of
16// identities in the early version of git-bug.
17type Bare struct {
18 name string
19 email string
20 login string
21 avatarUrl string
22}
23
24func NewBare(name string, email string) *Bare {
25 return &Bare{name: name, email: email}
26}
27
28func NewBareFull(name string, email string, login string, avatarUrl string) *Bare {
29 return &Bare{name: name, email: email, login: login, avatarUrl: avatarUrl}
30}
31
32type bareIdentityJson struct {
33 Name string `json:"name,omitempty"`
34 Email string `json:"email,omitempty"`
35 Login string `json:"login,omitempty"`
36 AvatarUrl string `json:"avatar_url,omitempty"`
37}
38
39func (i Bare) MarshalJSON() ([]byte, error) {
40 return json.Marshal(bareIdentityJson{
41 Name: i.name,
42 Email: i.email,
43 Login: i.login,
44 AvatarUrl: i.avatarUrl,
45 })
46}
47
48func (i Bare) UnmarshalJSON(data []byte) error {
49 aux := bareIdentityJson{}
50
51 if err := json.Unmarshal(data, &aux); err != nil {
52 return err
53 }
54
55 i.name = aux.Name
56 i.email = aux.Email
57 i.login = aux.Login
58 i.avatarUrl = aux.AvatarUrl
59
60 return nil
61}
62
63func (i Bare) Name() string {
64 return i.name
65}
66
67func (i Bare) Email() string {
68 return i.email
69}
70
71func (i Bare) Login() string {
72 return i.login
73}
74
75func (i Bare) AvatarUrl() string {
76 return i.avatarUrl
77}
78
79// Keys return the last version of the valid keys
80func (i Bare) Keys() []Key {
81 return []Key{}
82}
83
84// ValidKeysAtTime return the set of keys valid at a given lamport time
85func (i Bare) ValidKeysAtTime(time lamport.Time) []Key {
86 return []Key{}
87}
88
89// DisplayName return a non-empty string to display, representing the
90// identity, based on the non-empty values.
91func (i Bare) DisplayName() string {
92 switch {
93 case i.name == "" && i.login != "":
94 return i.login
95 case i.name != "" && i.login == "":
96 return i.name
97 case i.name != "" && i.login != "":
98 return fmt.Sprintf("%s (%s)", i.name, i.login)
99 }
100
101 panic("invalid person data")
102}
103
104// Match tell is the Person match the given query string
105func (i Bare) Match(query string) bool {
106 query = strings.ToLower(query)
107
108 return strings.Contains(strings.ToLower(i.name), query) ||
109 strings.Contains(strings.ToLower(i.login), query)
110}
111
112// Validate check if the Identity data is valid
113func (i Bare) Validate() error {
114 if text.Empty(i.name) && text.Empty(i.login) {
115 return fmt.Errorf("either name or login should be set")
116 }
117
118 if strings.Contains(i.name, "\n") {
119 return fmt.Errorf("name should be a single line")
120 }
121
122 if !text.Safe(i.name) {
123 return fmt.Errorf("name is not fully printable")
124 }
125
126 if strings.Contains(i.login, "\n") {
127 return fmt.Errorf("login should be a single line")
128 }
129
130 if !text.Safe(i.login) {
131 return fmt.Errorf("login is not fully printable")
132 }
133
134 if strings.Contains(i.email, "\n") {
135 return fmt.Errorf("email should be a single line")
136 }
137
138 if !text.Safe(i.email) {
139 return fmt.Errorf("email is not fully printable")
140 }
141
142 if i.avatarUrl != "" && !text.ValidUrl(i.avatarUrl) {
143 return fmt.Errorf("avatarUrl is not a valid URL")
144 }
145
146 return nil
147}
148
149// IsProtected return true if the chain of git commits started to be signed.
150// If that's the case, only signed commit with a valid key for this identity can be added.
151func (i Bare) IsProtected() bool {
152 return false
153}