generated from nvti/template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
254 lines (219 loc) · 5.48 KB
/
main.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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
package main
import (
"encoding/json"
"errors"
"flag"
"fmt"
"io/ioutil"
"math/rand"
"net/url"
"os"
"path/filepath"
"strings"
"sync"
"time"
"github.com/mattermost/mattermost-server/v5/model"
"gopkg.in/yaml.v2"
)
// mattermost client
var client *model.Client4
// waitgroup for wait all go routine
var wg sync.WaitGroup
// user structure for parse user data from file
type user struct {
Email string `json:"email"`
Pass string `json:"pass"`
}
func main() {
// Create command line argument parser
email := flag.String("email", "", "Mattermost login email")
password := flag.String("pass", "", "Mattermost login password")
file := flag.String("file", "", "File contain mattermost login email and password. Support json and yaml type")
var num int
flag.IntVar(&num, "n", 20, "Number of reaction you want to add. Set 0 to use max supported emoji")
flag.Usage = usage
flag.Parse()
// Check post link is exist
if flag.NArg() != 1 {
println("Missing post link")
flag.Usage()
os.Exit(1)
}
post := flag.Args()[0]
// Check cert file or email+pass is exist
if *file == "" && (*email == "" || *password == "") {
println("Missing certificate file or email/pass parametter")
flag.Usage()
os.Exit(1)
}
// Parse cert file if listed
if *file != "" {
var u user
if filepath.Ext(*file) == ".json" {
u = parseJson(*file)
} else if filepath.Ext(*file) == ".yaml" || filepath.Ext(*file) == ".yml" {
u = parseYaml(*file)
} else {
println("Un-support file type ", filepath.Ext(*file))
flag.Usage()
os.Exit(1)
}
email = &u.Email
password = &u.Pass
}
// Parse mattermost server url and post id from post link
u, err := url.Parse(post)
if err != nil {
println("Wrong post link")
os.Exit(1)
}
mattermost_server := u.Scheme + "://" + u.Host
params := strings.Split(u.Path, "/")
if len(params) == 0 {
println("Wrong post link")
os.Exit(1)
}
postID := params[len(params)-1]
// Check number of emoji
if num == 0 {
num = len(support_emojis)
}
// If number of emoji is too big, display a comfirmation
if num > 50 {
print("WARNING: ", num, " is a large number of emoji, are you sure? y/[n]) ")
var comfirm string
fmt.Scanln(&comfirm)
if comfirm != "y" {
os.Exit(0)
}
}
// Connect and login
client = model.NewAPIv4Client(mattermost_server)
pingServer()
userID := login(*email, *password)
// Add reaction
if num == len(support_emojis) {
// get list of supported emoji and add reaction
getAllEmoji()
reactAll(userID, postID)
} else {
react(userID, postID, num)
}
// Wait all go routine
wg.Wait()
println("Done")
}
// Custom usage function
func usage() {
println("Usage: ", os.Args[0], "[options] post_link")
println("post_link: Link of post you want to spam reaction =))")
println("Options:")
flag.PrintDefaults()
println("Login using certificate file or email+pass")
}
// Parse json file
func parseJson(file string) (u user) {
jsonFile, err := os.Open(file)
if err != nil {
println("Can't open file: ", err.Error())
os.Exit(1)
}
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
if err != nil {
println("Can't open file: ", err.Error())
os.Exit(1)
}
err = json.Unmarshal(byteValue, &u)
if err != nil {
println("Can't parse json file: ", err.Error())
os.Exit(1)
}
return
}
// Parse yaml file
func parseYaml(file string) (u user) {
yamlFile, err := os.Open(file)
if err != nil {
println("Can't open file: ", err.Error())
os.Exit(1)
}
// defer the closing of our yamlFile so that we can parse it later on
defer yamlFile.Close()
byteValue, err := ioutil.ReadAll(yamlFile)
if err != nil {
println("Can't open file: ", err.Error())
os.Exit(1)
}
err = yaml.Unmarshal(byteValue, &u)
if err != nil {
println("Can't parse json file: ", err.Error())
os.Exit(1)
}
return
}
// Check server is running
func pingServer() {
if _, resp := client.GetOldClientConfig(""); resp.Error != nil {
println("There was a problem pinging the Mattermost server.")
os.Exit(1)
}
}
// Login to server with email+pass
func login(email string, pass string) string {
user, resp := client.Login(email, pass)
if resp.Error != nil {
println("There was a problem logging into the Mattermost server.")
os.Exit(1)
}
return user.Id
}
// Get all emoji
func getAllEmoji() {
support_emojis = append(support_emojis, getCustomEmoji()...)
}
// Get list of custom emoji in the server
func getCustomEmoji() (emojis []string) {
emoji, resp := client.GetEmojiList(0, 60)
if resp.Error != nil {
return
}
for _, e := range emoji {
emojis = append(emojis, e.Name)
}
return
}
// add all emoji to the post
func reactAll(userID string, postID string) {
for _, emoji := range support_emojis {
wg.Add(1)
go reactOne(userID, postID, emoji)
}
}
// add a number of emoji to the post
func react(userID string, postID string, num int) {
// initialize global pseudo random generator
rand.Seed(time.Now().Unix())
// Get random num emoji from support_emojis list
res := rand.Perm(len(support_emojis))
for _, i := range res[:num] {
wg.Add(1)
go reactOne(userID, postID, support_emojis[i])
}
}
// add one emoji to the post
func reactOne(userID string, postID string, emoji string) error {
defer wg.Done()
react := &model.Reaction{
UserId: userID,
PostId: postID,
EmojiName: emoji,
}
react.PreSave()
_, resp := client.SaveReaction(react)
if resp.Error != nil || resp.StatusCode < 200 || resp.StatusCode >= 300 {
return errors.New("")
}
return nil
}