M README.md => README.md +1 -3
@@ 2,7 2,7 @@
Fork of theboxmage's [discord-cli](https://github.com/theboxmage/discordcli)
-JSON config is in `$home/lib/disco.cfg` for setting password, should be made automatically after first run.
+NDB config is in `$home/lib/disco.ndb` for setting password, should be made automatically after first run.
## Install
@@ 15,8 15,6 @@ go get bitbucket.org/henesy/disco
## Problems
-* JSON
-
* PM's are temporarily disabled
* Does not create accounts for you, this still needs to be done in a browser/app
M TODO => TODO +2 -4
@@ 8,13 8,11 @@ Commands:
Features:
-* remove JSON config
-
* read $home/lib/discord.face for profile picture (or just face?)
-* delete disco.cfg on failure to log in for 400 bad request: password does not match
+* delete disco.ndb on failure to log in for 400 bad request: password does not match
-* verify proper permissions -rw------- 0600 for discord.cfg
+* runtime verify proper permissions -rw------- 0600 for discord.ndb
* [done] if ``` entered, allow multi-line message (composition)
M config.go => config.go +106 -40
@@ 2,29 2,67 @@ package main
import (
"bufio"
- "encoding/json"
"fmt"
"log"
"os"
"os/user"
- // "golang.org/x/crypto/ssh/terminal"
+sc "strconv"
+ "strings"
"bitbucket.org/mischief/libauth"
+ "github.com/mischief/ndb"
+)
+
+// Types of auth we can do add handling for new modes to atoam()
+type AuthModes int
+const (
+ Pass AuthModes = iota
+ Factotum
+ Unknown // Placeholder
)
//Configuration is a struct that contains all configuration fields
type Configuration struct {
- Username string `json:"username"`
- MessageDefault bool `json:"messagedefault"`
- Messages int `json:"messages"`
- CompletionChar string `json:"completionchar"`
- TimeCompChar string `json:"timecompchar"`
- password string
+ AuthMode AuthModes
+ Username string
+ LoadBacklog bool
+ Messages int
+ PromptChar string
+ TimestampChar string
+ password string
}
// Config is the global configuration of discord-cli
var Config Configuration
-//GetConfig retrieves configuration file from $home/lib/disco.cfg, if it doesn't exist it calls CreateConfig()
+var ConfigPath string = "/lib/disco.ndb"
+
+// Convert a string such as "true" into true
+func atob(s string) bool {
+ s = strings.ToLower(s)
+
+ if s == "true" {
+ return true
+ }
+
+ return false
+}
+
+// Convert a string such as "factotum" into factotum
+func atoam(s string) AuthModes {
+ s = strings.ToLower(s)
+
+ if s == "pass" {
+ return Pass
+ }
+
+ if s == "factotum" {
+ return Factotum
+ }
+
+ return Unknown
+}
+
+//GetConfig retrieves configuration file from $home/lib/disco.ndb, if it doesn't exist it calls CreateConfig()
func GetConfig() {
//Get User
Start:
@@ 33,59 71,66 @@ Start:
log.Fatal(err)
}
- //Get File
- file, err := os.Open(usr.HomeDir + "/lib/disco.cfg")
+ // Get File
+ file, err := os.Open(usr.HomeDir + ConfigPath)
+
if err != nil {
log.Println("Creating new config file")
CreateConfig()
goto Start
}
- //Decode File
- decoder := json.NewDecoder(file)
- err = decoder.Decode(&Config)
+ file.Close()
+
+ // Decode File
+ ndb, err := ndb.Open(usr.HomeDir + ConfigPath)
if err != nil {
- log.Println("Failed to decode configuration file")
- log.Fatalf("Error: %s", err)
+ log.Fatal("error: Could not ")
}
+
+ Config.Username = ndb.Search("username", "").Search("username")
+ Config.AuthMode = atoam(ndb.Search("auth", "").Search("auth"))
+
+ if Config.AuthMode == Pass {
+ Config.password = ndb.Search("username", "").Search("password")
+ }
+
+ Config.LoadBacklog = atob(ndb.Search("loadbacklog", "").Search("loadbacklog"))
+ Config.Messages, _ = sc.Atoi(ndb.Search("messages", "").Search("messages"))
+ Config.PromptChar = ndb.Search("promptchar", "").Search("promptchar")
+ Config.TimestampChar = ndb.Search("timestampchar", "").Search("timestampchar")
+
}
//CreateConfig creates folder inside $home and makes a new empty configuration file
func CreateConfig() {
- //Get User
+ // Get User
usr, err := user.Current()
if err != nil {
log.Fatal(err)
}
- var EmptyStruct Configuration
- //Set Default values
+ // Set Default values
fmt.Print("Input your email: ")
scan := bufio.NewScanner(os.Stdin)
scan.Scan()
- EmptyStruct.Username = scan.Text()
- EmptyStruct.Messages = 10
- EmptyStruct.MessageDefault = true
- EmptyStruct.CompletionChar = ">"
- EmptyStruct.TimeCompChar = ">"
+ raw := fmt.Sprintf("auth=pass\nloadbacklog=true\nmessages=10\npromptchar=→\ntimestampchar=>\n\nusername=%s password=\n", scan.Text())
- //Create File
- os.Mkdir(usr.HomeDir+"/lib", 0775)
- file, err := os.Create(usr.HomeDir + "/lib/disco.cfg")
+ // Create File
+ os.Mkdir(usr.HomeDir + "/lib", 0775)
+
+ file, err := os.Create(usr.HomeDir + ConfigPath)
+
if err != nil {
log.Fatalln(err)
}
+
file.Chmod(0600)
- //Marshall EmptyStruct
- raw, err := json.Marshal(EmptyStruct)
- if err != nil {
- log.Fatalln(err)
- }
+ // PrintToFile
+ _, err = file.Write([]byte(raw))
- //PrintToFile
- _, err = file.Write(raw)
if err != nil {
log.Fatalln(err)
}
@@ 93,20 138,41 @@ func CreateConfig() {
file.Close()
}
-//CheckState checks the current state for essential missing information, errors will fail the program
+// CheckState checks the current state for essential missing information, errors will fail the program
func CheckState() {
//Get User
usr, err := user.Current()
+
if err != nil {
log.Fatal(err)
}
if Config.Username == "" {
- log.Fatalln("No Username Specified, please edit " + usr.HomeDir + "/lib/disco.cfg")
+ log.Fatalln("Error: No Username Specified, please edit " + usr.HomeDir + ConfigPath)
}
- userPwd, err := libauth.Getuserpasswd("proto=pass service=discord user=%s server=discordapp.com", Config.Username)
- if err != nil {
- log.Fatal(err)
+
+ // Check and handle password loading
+ switch(Config.AuthMode){
+ case Factotum:
+ // Acquire password from factotum
+ userPwd, err := libauth.Getuserpasswd("proto=pass service=discord user=%s server=discordapp.com", Config.Username)
+
+ if err != nil {
+ // Factotum didn't get anything
+ fmt.Fprintln(os.Stderr, "Warning: No success getting key from factotum, consider disabling it in ndb.")
+ fmt.Fprintln(os.Stderr, "Libauth gave: ", err)
+ } else {
+ Config.password = userPwd.Password
+ }
+
+ case Unknown:
+ log.Fatalln("Error: incorrect, or no, authmode specified via auth= config tuple. Consider: auth=(pass factotum).")
+
+ default:
+ // Password is already loaded in auth=pass mode
+ }
+
+ if(Config.password == "") {
+ log.Fatalln("Error: No password loaded, cannot auth. Are you missing a factotum key or password= tuple?")
}
- Config.password = userPwd.Password
}
M helper.go => helper.go +2 -2
@@ 133,11 133,11 @@ func MessagePrint(Time, Username, Content string) {
//var Color color.Attribute
log.SetFlags(0)
if *hideTimeStamp {
- log.Printf("%s %s %s\n", Username, Config.CompletionChar, content)
+ log.Printf("%s %s %s\n", Username, Config.PromptChar, content)
} else {
TimeStamp, _ := time.Parse(time.RFC3339, Time)
LocalTime := TimeStamp.Local().Format("2006/01/02 15:04:05")
- log.Printf("%s %s %s %s %s\n", LocalTime, Config.TimeCompChar, Username, Config.CompletionChar, content)
+ log.Printf("%s %s %s %s %s\n", LocalTime, Config.TimestampChar, Username, Config.PromptChar, content)
}
log.SetFlags(log.LstdFlags)
M main.go => main.go +1 -1
@@ 139,7 139,7 @@ func InitWindow() {
//ShowContent shows default Channel content
func ShowContent() {
Header()
- if Config.MessageDefault {
+ if Config.LoadBacklog {
State.RetrieveMessages(Config.Messages)
PrintMessages(Config.Messages)
}