/
keyring.go
118 lines (95 loc) · 1.93 KB
/
keyring.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package mau
import (
"fmt"
"os"
"path"
)
type Keyring struct {
Path string
Friends []*Friend
SubKeyrings []*Keyring
}
func (k *Keyring) Name() string {
return path.Base(k.Path)
}
func (k *Keyring) FriendsSet() []*Friend {
friends := map[Fingerprint]*Friend{}
for _, f := range k.Friends {
friends[f.Fingerprint()] = f
}
for _, sk := range k.SubKeyrings {
for _, f := range sk.FriendsSet() {
friends[f.Fingerprint()] = f
}
}
set := []*Friend{}
for _, f := range friends {
set = append(set, f)
}
return set
}
func (k *Keyring) FindByFingerprint(fingerprint Fingerprint) *Friend {
for _, friend := range k.Friends {
if friend.Fingerprint() == fingerprint {
return friend
}
}
for _, keyring := range k.SubKeyrings {
friend := keyring.FindByFingerprint(fingerprint)
if friend != nil {
return friend
}
}
return nil
}
func (k *Keyring) FriendById(id uint64) *Friend {
for _, f := range k.Friends {
if f.entity.PrimaryKey.KeyId == id {
return f
}
for _, sk := range f.entity.Subkeys {
if sk.PublicKey.KeyId == id {
return f
}
}
}
for _, sk := range k.SubKeyrings {
f := sk.FriendById(id)
if f != nil {
return f
}
}
return nil
}
func (k *Keyring) read(account *Account) error {
files, err := os.ReadDir(k.Path)
if err != nil {
return fmt.Errorf("Can't read dir: %w", err)
}
for _, file := range files {
if file.Name() == accountKeyFilename {
continue
}
filePath := path.Join(k.Path, file.Name())
if file.IsDir() {
keyring := Keyring{Path: filePath}
err := keyring.read(account)
if err != nil {
return err
}
k.SubKeyrings = append(k.SubKeyrings, &keyring)
continue
}
reader, err := os.Open(filePath)
if err != nil {
return err
}
friend, err := readFriend(account, reader)
reader.Close()
if err != nil {
return fmt.Errorf("Error reading friend: %w", err)
}
k.Friends = append(k.Friends, friend)
}
return nil
}