/
account.go
188 lines (162 loc) · 3.55 KB
/
account.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package cmd
import (
"encoding/json"
"io"
"os"
"path/filepath"
"sort"
"strings"
)
var (
// accountsFile is the json file that contains all accounts
accountsFile = "accounts.json"
// accounts contains all active accounts
accounts = make(map[int]*account)
)
// account stores account information
type account struct {
ID int
Protocol string
User string
Password string
client *mattermost
}
// splitAccountUser extracts username and server address from the account user
func (a *account) splitAccountUser() (username, server string) {
username = strings.Split(a.User, "@")[0]
server = strings.Split(a.User, "@")[1]
return
}
// start starts the client for this account
func (a *account) start() {
// skip non-mattermost accounts
if a.Protocol != "mattermost" {
return
}
// extract server and username from account user
user, server := a.splitAccountUser()
// start client
logInfo("Starting account", a.ID)
a.client = newClient(conf, a.ID, server, user, a.Password)
go a.client.run()
}
// stop shuts down the client for this account
func (a *account) stop() {
if a.client != nil {
logInfo("Stopping account", a.ID)
a.client.stop()
}
}
// getAccount returns account with account ID
func getAccount(id int) *account {
return accounts[id]
}
// getAccounts returns all accounts sorted by account ID
func getAccounts() []*account {
// sort account ids
ids := make([]int, len(accounts))
i := 0
for id := range accounts {
ids[i] = id
i++
}
sort.Ints(ids)
// construct sorted slice of accounts
accs := make([]*account, len(accounts))
for i, id := range ids {
accs[i] = accounts[id]
}
return accs
}
// getFreeAccountID returns the first free account ID
func getFreeAccountID() int {
for i := 0; i < len(accounts); i++ {
if accounts[i] == nil {
return i
}
}
return len(accounts)
}
// addAccount adds a new account with protocol, user and password and returns
// the new account's ID
func addAccount(protocol, user, password string) int {
a := account{
ID: getFreeAccountID(),
Protocol: protocol,
User: user,
Password: password,
}
accounts[a.ID] = &a
writeAccountsToFile()
a.start()
return a.ID
}
// delAccount removes the existing account with id
func delAccount(id int) bool {
if accounts[id] != nil {
accounts[id].stop()
delete(accounts, id)
writeAccountsToFile()
return true
}
return false
}
// readAccountsFromFile reads accounts from file
func readAccountsFromFile() {
file := filepath.Join(conf.Dir, accountsFile)
// open file for reading
f, err := os.Open(file)
if err != nil {
logError(err)
return
}
// read accounts from file
dec := json.NewDecoder(f)
for {
var a account
err := dec.Decode(&a)
if err == io.EOF {
break
}
if err != nil {
logFatal(err)
}
accounts[a.ID] = &a
}
}
// writeAccountsToFile writes all accounts to file
func writeAccountsToFile() {
file := filepath.Join(conf.Dir, accountsFile)
// open file for writing
f, err := os.Create(file)
if err != nil {
logFatal(err)
}
// make sure file is only readable and writable by the current user
err = os.Chmod(file, 0600)
if err != nil {
logFatal(err)
}
// write accounts to file
enc := json.NewEncoder(f)
for _, a := range accounts {
err := enc.Encode(&a)
if err != nil {
logFatal(err)
}
}
}
// startAccounts initializes all accounts and starts their clients
func startAccounts() {
// read accounts
readAccountsFromFile()
for _, a := range accounts {
a.start()
}
}
// stopAccounts stops all accounts and their clients
func stopAccounts() {
for _, a := range accounts {
a.stop()
}
}