-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
435 lines (380 loc) · 20.5 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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"github.com/DataManager-Go/DataManagerCLI/commands"
libdm "github.com/DataManager-Go/libdatamanager"
dmConfig "github.com/DataManager-Go/libdatamanager/config"
"github.com/JojiiOfficial/gaw"
kingpin "github.com/alecthomas/kingpin"
"github.com/fatih/color"
_ "github.com/mattn/go-sqlite3"
)
const (
appName = "manager"
version = "1.4.5"
)
// ...
const (
// EnVarPrefix prefix for env vars
EnVarPrefix = "MANAGER"
// EnVarPrefix prefix of all used env vars
EnVarLogLevel = "LOG_LEVEL"
EnVarNoColor = "NO_COLOR"
EnVarNoEmojis = "NO_EMOJIS"
EnVarConfigFile = "CONFIG"
)
// Return the variable using the server prefix
func getEnVar(name string) string {
return fmt.Sprintf("%s_%s", EnVarPrefix, name)
}
// App commands
var (
app = kingpin.New(appName, "A DataManager")
// Global flags
appYes = app.Flag("yes", "Skip confirmations").Short('y').Bool()
appCfgFile = app.Flag("config", "the configuration file for the app").Envar(getEnVar(EnVarConfigFile)).Short('c').String()
// File related flags
appTags = app.Flag("tag", "Specify tags to use").Short('t').Strings()
appGroups = app.Flag("group", "Specify groups to use").Short('g').Strings()
appNamespace = app.Flag("namespace", "Specify the namespace to use").Default("default").Short('n').HintAction(hintListNamespaces).String()
appAll = app.Flag("all", "Do action for all found files").Short('a').Bool()
appVerify = app.Flag("verify", "Verify a file using a checksum to prevent errors").Bool()
appNoDecrypt = app.Flag("no-decrypt", "Don't decrypt files").Bool()
appForce = app.Flag("force", "Forces an action").Short('f').Bool()
appFileEncryption = app.Flag("encryption", "Encrypt/Decrypt the file").Short('e').HintOptions([]string{"age", "aes"}...).String()
appDisableCompression = appUpload.Flag("compressed", "Compress files while uploading").Bool()
appDecompress = fileDownloadCmd.Flag("extract", "Extract a gzipped file while downloading").Bool()
// Output related flags
appDetails = app.Flag("details", "Print more details of something").Short('d').Counter()
appQuiet = app.Flag("quiet", "Less verbose output").Short('q').Bool()
appOutputJSON = app.Flag("json", "Print output as json").Bool()
appNoRedaction = app.Flag("no-redact", "Don't redact secrets").Bool()
appNoColor = app.Flag("no-color", "Disable colors").Envar(getEnVar(EnVarNoColor)).Bool()
appNoEmojis = app.Flag("no-emojis", "Don't decrypt files").Envar(getEnVar(EnVarNoEmojis)).Bool()
// Encryptionkey related flags
appFileEncrRandKey = app.Flag("gen-key", "Generate Encryption key").Short('r').HintOptions("16", "24", "32").Int()
appFileEncrKey = app.Flag("key", "Encryption/Decryption key").Short('k').String()
appFileEncrPassKey = app.Flag("read-key", "Read encryption/decryption key as password").Short('p').Bool()
appFileEncrKeyFromStdin = app.Flag("key-from-stdin", "Read encryption/decryption key from stdin").Bool()
appFileEncrKeyFile = app.Flag("keyfile", "File containing a Encryption/Decryption key").HintAction(hintListKeyFiles).String()
appParallelism = app.Flag("parallelism", "Upload/Download n files at the same time").Default("1").Int()
//
// ---------> Ping --------------------------------------
appPing = app.Command("ping", "pings the server and checks connectivity").Alias("p")
//
// ---------> UserCommands --------------------------------------
// -- Login
loginCmd = app.Command("login", "Login")
loginCmdUser = loginCmd.Flag("username", "Your username").String()
// -- Logout
logoutCmd = app.Command("logout", "logout from a session")
logoutCmdUser = logoutCmd.Arg("username", "Delete sessiondata assigned to a different username than the current one").String()
// -- Register
registerCmd = app.Command("register", "Create an account").FullCommand()
// -- Setup
setupCmd = app.Command("setup", "Setup your client to get started")
setupCmdHost = setupCmd.Arg("host", "The host of the server you want to use").String()
setupCmdHostFlag = setupCmd.Flag("host", "The host of the server you want to use").String()
setupCmdIgnoreCert = setupCmd.Flag("Ignore-cert", "Ignore server certificate (unsafe)").Bool()
setupCmdServerOnly = setupCmd.Flag("server-only", "Setup the server connection only. No login").Bool()
setupCmdRegister = setupCmd.Flag("register", "Register after logging in").Bool()
setupCmdNoLogin = setupCmd.Flag("no-login", "Don't login after setting up").Bool()
setupCmdToken = setupCmd.Flag("token", "Use token").String()
setupCmdUsername = setupCmd.Flag("user", "The Username. Required if --token is set").String()
// -- Stats
statsCmd = app.Command("stats", "Show user statstics").FullCommand()
//
// ---------> Config commands --------------------------------------
configCMD = app.Command("config", "Commands for working with the config")
// -- Use
configUse = configCMD.Command("use", "Use something")
configUseTarget = configUse.Arg("target", "Use different namespace as default").HintOptions(commands.UseTargets...).Required().String()
configUseTargetValue = configUse.Arg("value", "the value of the new target").HintOptions("default").Strings()
// -- View
configView = configCMD.Command("view", "View config")
configViewTokenBase = configView.Flag("base64", "Encode the sessiontoken as base64").Default("false").Bool()
//
// ---------> File commands --------------------------------------
// -- Upload
appUpload = app.Command("upload", "Upload the given file").Alias("up").Alias("push")
fileUploadPaths = appUpload.Arg("filePath", "Path to the file you want to upload").HintAction(hintListFiles).Strings()
fileUploadFromStdin = appUpload.Flag("from-stdin", "Read file from stdin and upload it").Bool()
fileUploadName = appUpload.Flag("name", "Specify the name of the file").String()
fileUploadPublic = appUpload.Flag("public", "Make uploaded file publci").Bool()
fileUploadPublicName = appUpload.Flag("public-name", "Specify the public filename").String()
fileUploadReplace = appUpload.Flag("replace-file", "Replace a file").Uint()
fileUploadReplaceSameName = appUpload.Flag("replace-same-name", "Replace file with same name in selected namespace").Bool()
fileUploadDeletInvaid = app.Flag("delete-invaid", "Deletes a file if it's checksum is invalid").Bool()
fileUploadSetClipboard = app.Flag("set-clip", "Set clipboard to pubilc url").Bool()
fileUploadNoArchiving = app.Flag("no-archive", "Don't archive folder, upload all files in a given folder separately").Bool()
// -- List
appFileCmd = app.Command("file", "Do something with a file").Alias("f")
appFilesCmd = app.Command("files", "List files").Alias("fs").Alias("ls").Alias("dir")
appFilesCmdNamespace = appFilesCmd.Arg("namespace", "List files in a specific namespace").HintAction(hintListNamespaces).String()
appFilesOrder = appFilesCmd.Flag("order", "Order the output").Short('o').HintOptions(commands.AvailableOrders...).String()
// -- Create
fileCreateCmd = appFileCmd.Command("create", "create a file").Alias("c").Alias("cr")
filecreateCmdName = fileCreateCmd.Arg("name", "The name of file to create").String()
// -- Edit
fileEditCmd = appFileCmd.Command("edit", "Edit a file").Alias("e")
fileEditName = fileEditCmd.Arg("name", "The file name").Required().String()
fileEditID = fileEditCmd.Arg("ID", "The file ID").Uint()
fileEditEditor = fileEditCmd.Flag("editor", "Use a custom editor to edit the given file").HintOptions("libreoffice", "vim", "nano", "emacs", "vi").String()
// -- Tree
appFileTree = app.Command("tree", "Show your files like the unix file tree")
appFileTreeOrder = appFileTree.Flag("order", "Order the output").Short('o').HintOptions(commands.AvailableOrders...).String()
appFileTreeNamespace = appFileTree.Arg("namespace", "View only a namespace").HintAction(hintListNamespaces).String()
// -- Delete file -> rm
fileRmCmd = app.Command("rm", "Delete a file")
fileRmName = fileRmCmd.Arg("fileName", "Name of the file that should be removed").String()
fileRmID = fileRmCmd.Arg("fileID", "FileID of file. Only required if mulitple files with same name are available").Uint()
// -- Delete -> file delete/rm
fileDeleteCmd = appFileCmd.Command("delete", "Delete a file").Alias("rm").Alias("del")
fileDeleteName = fileDeleteCmd.Arg("fileName", "Name of the file that should be removed").String()
fileDeleteID = fileDeleteCmd.Arg("fileID", "FileID of file. Only required if mulitple files with same name are available").Uint()
// -- List
fileListCmd = appFileCmd.Command("list", "List files").Alias("ls")
fileListName = fileListCmd.Arg("fileName", "Show files with this name").String()
fileListID = fileListCmd.Arg("fileID", "The fileID").Uint()
fileListOrder = fileListCmd.Flag("order", "Order the output").Short('o').HintOptions(commands.AvailableOrders...).String()
// -- Update
fileUpdateCmd = appFileCmd.Command("update", "Update a file").Alias("u")
fileUpdateName = fileUpdateCmd.Arg("fileName", "Name of the file that should be updated").Required().String()
fileUpdateID = fileUpdateCmd.Arg("fileID", "FileID of file. Only required if mulitple files with same name are available").Uint()
fileUpdateSetPublic = fileUpdateCmd.Flag("set-public", "Sets a file public").Bool()
fileUpdateSetPrivate = fileUpdateCmd.Flag("set-private", "Sets a file private").Bool()
fileUpdateNewName = fileUpdateCmd.Flag("new-name", "Change the name of a file").String()
fileUpdateNewNamespace = fileUpdateCmd.Flag("new-namespace", "Change the namespace of a file").HintAction(hintListNamespaces).String()
fileUpdateAddTags = fileUpdateCmd.Flag("add-tags", "Add tags to a file").Strings()
fileUpdateRemoveTags = fileUpdateCmd.Flag("remove-tags", "Remove tags from a file").Strings()
fileUpdateAddGroups = fileUpdateCmd.Flag("add-groups", "Add groups to a file").Strings()
fileUpdateRemoveGroups = fileUpdateCmd.Flag("remove-groups", "Remove groups from a file").Strings()
// -- Move
fileMoveCmd = app.Command("mv", "Move a file into a new namespace")
fileMoveFile = fileMoveCmd.Arg("file", "The file to move").Required().String()
fileMoveNewNs = fileMoveCmd.Arg("newNamespace", "The namespace to move the given file to").Required().HintAction(hintListNamespaces).String()
// -- Download
fileDownloadCmd = app.Command("download", "Download a file from the server").Alias("dl")
fileDownloadName = fileDownloadCmd.Arg("fileName", "Download files with this name").String()
fileDownloadID = fileDownloadCmd.Arg("fileId", "Specify the fileID").Uint()
fileDownloadPath = fileDownloadCmd.Flag("output", "Where to store the file").Default("./").Short('o').String()
fileDownloadPreview = fileDownloadCmd.Flag("preview", "Whether you want to open the file after downloading it").Bool()
// -- Publish
filePublishCmd = app.Command("publish", "publish a file").Alias("pub").Alias("p")
filePublishName = filePublishCmd.Arg("fileName", "Name of the file that should be published").Required().String()
filePublishID = filePublishCmd.Arg("fileID", "FileID of specified file. Only required if mulitple files with same name are available").Uint()
publishPublicName = filePublishCmd.Flag("public-name", "Specify the public filename").String()
// -- UnPublish
fileUnPublishCmd = app.Command("unpublish", "unpublish a file").Alias("unpub")
fileUnPublishName = fileUnPublishCmd.Arg("fileName", "Name of the file that should be unpublished").Required().String()
fileUnPublishID = fileUnPublishCmd.Arg("fileID", "FileID of specified file. Only required if mulitple files with same name are available").Uint()
// -- View
viewCmd = appFileCmd.Command("view", "View something").Alias("v")
viewFileName = viewCmd.Arg("fileName", "filename of file to view").Required().String()
viewFileID = viewCmd.Arg("fileID", "fileID of file to view").Uint()
viewNoPreview = viewCmd.Flag("no-preview", "Disable preview for command").Bool()
viewPreview = viewCmd.Flag("preview", "Show preview for command").Bool()
// -- Cat
catCmd = app.Command("cat", "View something").Alias("v")
catFileName = catCmd.Arg("fileName", "filename of file to view").Required().String()
catFileID = catCmd.Arg("fileID", "fileID of file to view").Uint()
//
// ---------> Tag commands --------------------------------------
tagCmd = app.Command("tag", "Do something with tags").Alias("t")
// -- List
tagListCmd = app.Command("tags", "List existing tags").Alias("ts")
// -- Delete
tagDeleteCmd = tagCmd.Command("delete", "Delete a tag").Alias("rm").Alias("del")
tagDeleteName = tagDeleteCmd.Arg("tagName", "Name of tag to delete").Required().String()
// -- Update
tagUpdateCmd = tagCmd.Command("update", "Update a tag").Alias("u")
tagUpdateName = tagUpdateCmd.Arg("tagname", "Name of the tag that should be updated").Required().String()
tagUpdateNewName = tagUpdateCmd.Flag("new-name", "New name of a tag").String()
//
// ---------> Group commands --------------------------------------
groupCmd = app.Command("group", "Do something with groups").Alias("g").Alias("gr")
// -- List
groupListCmd = app.Command("groups", "List existing groups").Alias("gs")
// -- Delete
groupDeleteCmd = groupCmd.Command("delete", "Delete a group").Alias("rm").Alias("del")
groupDeleteName = groupDeleteCmd.Arg("groupName", "Name of group to delete").Required().String()
// -- Update
groupUpdateCmd = groupCmd.Command("update", "Update a group").Alias("u")
groupUpdateName = groupUpdateCmd.Arg("groupName", "Name of the group that should be updated").Required().String()
groupUpdateNewName = groupUpdateCmd.Flag("new-name", "Rename a group").String()
//
// ---------> Namespace commands --------------------------------------
namespaceCmd = app.Command("namespace", "Do something with namespaces").Alias("ns").Alias("n")
namespacesCmd = app.Command("namespaces", "List your namespaces").Alias("nss")
// -- Create
namespaceCreateCmd = namespaceCmd.Command("create", "Create a namespace").Alias("c").Alias("cr")
namespaceCreateName = namespaceCreateCmd.Arg("namespaceName", "Name of namespace").Required().String()
namespaceCreateCustom = namespaceCreateCmd.Flag("custom", "Create a custom namespace (no username prefix)").Bool()
// -- Update
namespaceUpdateCmd = namespaceCmd.Command("update", "Update a namespace").Alias("u")
namespaceUpdateName = namespaceUpdateCmd.Arg("namespaceName", "Name of the namespace that should be updated").Required().String()
namespaceUpdateNewName = namespaceUpdateCmd.Flag("new-name", "Rename a namespace").String()
// -- Delete
namespaceDeleteCmd = namespaceCmd.Command("delete", "Delete a namespace").Alias("rm").Alias("del")
namespaceDeleteName = namespaceDeleteCmd.Arg("namespaceName", "Name of namespace to delete").Required().String()
// -- List
namespaceListCmd = namespaceCmd.Command("list", "List your namespaces").Alias("ls")
// -- Download
namespaceDownloadCmd = namespaceCmd.Command("download", "Download all files in a namespace").Alias("dl")
namespaceDownloadNs = namespaceDownloadCmd.Arg("namespace", "The namespace to download the files from").HintAction(hintListNamespaces).Required().String()
namespaceDownloadExcludeGroups = namespaceDownloadCmd.Flag("exclude-groups", "Exclude files in specified group(s) from getting downloaded").Strings()
namespaceDownloadExcludeTags = namespaceDownloadCmd.Flag("exclude-tags", "Exclude files having specified tags(s) from getting downloaded").Strings()
namespaceDownloadExcludeFiles = namespaceDownloadCmd.Flag("exclude-files", "Exclude files by ID").Strings()
namespaceDownloadOutputDir = namespaceDownloadCmd.Flag("output", "Save namespace in a custom directory than the namespacename").Short('o').Default("./").String()
//
// ---------> Keystore commands --------------------------------------
keystoreCmd = app.Command("keystore", "Save keys to assigned to files and store them into a specific directory").Alias("ks")
// -- Create
keystoreCreateCmd = keystoreCmd.Command("create", "Create a keystore").Alias("c").Alias("cr")
keystoreCreateCmdPath = keystoreCreateCmd.Arg("path", "The path to store the keys in").Required().String()
keystoreCreateCmdOverwrite = keystoreCreateCmd.Flag("overwrite", "Overwrite an existing keystore setting").Short('o').Bool()
// -- Info
keystoreInfoCmd = keystoreCmd.Command("info", "Show information to your keystore")
// -- Delete
keystoreDeleteCmd = keystoreCmd.Command("delete", "Delete a keystore")
keystoreDeleteCmdShredCount = keystoreDeleteCmd.Flag("shredder", "Overwrite your keys").Default("6").Uint()
// -- CleanUp
keystoreCleanupCmd = keystoreCmd.Command("cleanup", "Cleans up unassigned keys").Alias("c").Alias("clean")
keystoreCleanupCmdShredCount = keystoreCleanupCmd.Flag("shredder", "Overwrite your keys").Default("6").Uint()
// -- AddKey
keystoreAddKeyCmd = keystoreCmd.Command("add", "Adds a Key to a file to the keystore").Alias("a")
keystoreAddKeyCmdFileID = keystoreAddKeyCmd.Arg("fileID", "The file id where the key should be assigned to").Required().Uint()
keystoreAddKeyCmdKey = keystoreAddKeyCmd.Arg("keyfile", "The filename of the keyfile. Must be located in the keystore path").HintAction(hintListKeyFiles).Required().String()
// -- RemoveKey
keystoreRemoveKeyCmd = keystoreCmd.Command("remove", "Removes a key from keystore by it's assigned fileid").Alias("rm")
keystoreRemoveKeyCmdID = keystoreRemoveKeyCmd.Arg("fileID", "The fileID to delete the key from ").Required().Uint()
)
var (
config *dmConfig.Config
appTrimName int
unmodifiedNS string
)
func main() {
app.HelpFlag.Short('h')
app.Version(version)
// Init random seed from gaw
gaw.Init()
// Prase cli flags
parsed := kingpin.MustParse(app.Parse(os.Args[1:]))
// Init config
if !initConfig(parsed) {
return
}
unmodifiedNS = *appNamespace
// Process params: make t1,t2 -> [t1 t2]
commands.ProcesStrSliceParams(appTags, appGroups)
initDefaults()
if *appNoColor {
color.NoColor = true
}
// Bulid commandData
commandData := buildCData(parsed, appTrimName)
if commandData == nil {
return
}
defer commandData.CloseKeystore()
// Run desired command
runCommand(parsed, commandData)
}
// Load and init config. Return false on error
func initConfig(parsed string) bool {
// Init config
var err error
config, err = dmConfig.InitConfig(dmConfig.GetDefaultConfigFile(), *appCfgFile)
if err != nil {
log.Fatalln(err)
}
if config == nil {
fmt.Println("New config created")
if parsed != setupCmd.FullCommand() {
return false
}
}
return true
}
// Init default values from config
func initDefaults() {
// Config is nil if a new configfile
// was created and setup command is running
if config != nil {
// Use config default values if not set
if len(*appNamespace) == 0 || (*appNamespace) == "default" {
*appNamespace = config.Default.Namespace
}
if len(*appTags) == 0 {
*appTags = config.Default.Tags
}
if len(*appGroups) == 0 {
*appGroups = config.Default.Groups
}
if *appDetails == 0 {
*appDetails = config.Client.Defaults.DefaultDetails
}
if len(*appFilesOrder) == 0 {
*appFilesOrder = config.GetDefaultOrder()
}
if !*appVerify && config.User.ForceVerify {
*appVerify = true
}
if !*fileUploadDeletInvaid && config.User.DeleteInvaildFiles {
*fileUploadDeletInvaid = true
}
appTrimName = config.Client.TrimNameAfter
}
}
// ---- CLI Hint funcs ------
// Returns a slice containing all files in current folder
func hintListFiles() []string {
fileInfos, err := ioutil.ReadDir(".")
if err != nil {
return []string{err.Error()}
}
var files []string
for _, fi := range fileInfos {
files = append(files, fi.Name())
}
return files
}
// Returns a slice containing all files in current folder
// except the keystore DB file
func hintListKeyFiles() []string {
files := hintListFiles()
retFiles := []string{}
for i := range files {
if files[i] != libdm.KeystoreDBFile {
retFiles = append(retFiles, files[i])
}
}
return retFiles
}
// Return a slice containing all available namespaces
func hintListNamespaces() []string {
if !initConfig("") {
return []string{}
}
// Init config
config, err := config.ToRequestConfig()
if err != nil {
return []string{}
}
libDM := libdm.NewLibDM(config)
// Get namespaces
namespaces, err := libDM.GetNamespaces()
if err != nil {
return []string{}
}
// Remove user prefix
for i := range namespaces.Slice {
namespaces.Slice[i] = namespaces.Slice[i][strings.Index(namespaces.Slice[i], "_")+1:]
}
return namespaces.Slice
}