Browse Source

Add configuration file support

master
Jaeha Choi 2 months ago
parent
commit
2782eb0904
Signed by: Jaeha.Choi GPG Key ID: FC8A150CF6C09314
  1. 6
      .gitignore
  2. 68
      cmd/coconut_desktop/main.go
  3. 3
      config/config.yml
  4. 58
      internal/client/client.go
  5. 2
      internal/client/client_test.go
  6. 26
      internal/client/ui.go

6
.gitignore

@ -1,3 +1,9 @@
### Project specific
*.priv
*.pub
coverage.txt
/cmd/coconut_desktop/coconut_desktop
### Linux template
*~

68
cmd/coconut_desktop/main.go

@ -2,12 +2,78 @@ package main
import (
//_ "embed"
"flag"
"github.com/jaeha-choi/Proj_Coconut_Desktop/internal/client"
"github.com/jaeha-choi/Proj_Coconut_Utility/log"
"github.com/jaeha-choi/Proj_Coconut_Utility/util"
"os"
)
//var uiString []byte
func main() {
client.Start("./data/ui/UI.glade")
// Command line arguments (flags) overrides configuration file, if exist
// Double dash arguments (e.g. --config-path) is not possible with "flag" package it seems like. Consider
// Using "getopt" package.
confPath := flag.String("config-path", "./config/config.yml", "Configuration file path")
logLevelArg := flag.String("log-level", "warning", "Logging level")
serverHostFlag := flag.String("host", "", "Server address")
serverPortFlag := flag.Int("port", 0, "Server port")
keyPathFlag := flag.String("cert-path", "", "Key pair path")
flag.Parse()
// Setup logger
var logLevel log.LoggingMode
switch *logLevelArg {
case "debug":
logLevel = log.DEBUG
case "info":
logLevel = log.INFO
case "warning":
logLevel = log.WARNING
case "error":
logLevel = log.ERROR
case "fatal":
logLevel = log.FATAL
default:
logLevel = log.WARNING
}
log.Init(os.Stdout, logLevel)
var cli *client.Client
var err error
// Read configurations
if cli, err = client.ReadConfig(*confPath); err != nil {
log.Warning("Could not read config, trying default config")
if cli, err = client.InitConfig(); err != nil {
log.Debug(err)
log.Fatal("Could not load default config")
os.Exit(1)
}
if err := util.WriteConfig(*confPath, cli); err != nil {
log.Debug(err)
log.Warning("Could not save config")
}
}
// Override configurations if arguments are provided
if *serverHostFlag != "" {
cli.ServerHost = *serverHostFlag
}
if *keyPathFlag != "" {
cli.KeyPath = *keyPathFlag
}
if 0 < *serverPortFlag && *serverPortFlag < 65536 {
cli.ServerPort = uint16(*serverPortFlag)
} else if *serverPortFlag != 0 {
log.Fatal("Provided port out of range")
os.Exit(1)
}
client.Start("./data/ui/UI.glade", cli)
//client.Start(string(uiString))
}

3
config/config.yml

@ -0,0 +1,3 @@
server_host: coconut-demo.jaeha.dev
server_port: 9129
key_path: ./

58
internal/client/client.go

@ -8,8 +8,9 @@ import (
"github.com/jaeha-choi/Proj_Coconut_Utility/cryptography"
"github.com/jaeha-choi/Proj_Coconut_Utility/log"
"github.com/jaeha-choi/Proj_Coconut_Utility/util"
"gopkg.in/yaml.v3"
"io/ioutil"
"net"
"os"
"strconv"
)
@ -18,8 +19,9 @@ const (
)
type Client struct {
ServerIp string `yaml:"server_ip"`
ServerHost string `yaml:"server_host"`
ServerPort uint16 `yaml:"server_port"`
KeyPath string `yaml:"key_path"`
tlsConfig *tls.Config
privKey *rsa.PrivateKey
pubKeyBlock *pem.Block
@ -27,37 +29,51 @@ type Client struct {
addCode string
}
func init() {
log.Init(os.Stdout, log.DEBUG)
// InitConfig initializes Client struct.
func InitConfig() (client *Client, err error) {
client = &Client{
//ServerHost: "127.0.0.1",
ServerHost: "coconut-demo.jaeha.dev",
ServerPort: 9129,
tlsConfig: &tls.Config{InsecureSkipVerify: true}, // TODO: Update after using trusted cert
privKey: nil,
pubKeyBlock: nil,
conn: nil,
addCode: "",
KeyPath: keyPath,
}
return client, nil
}
func NewClient() (client *Client, err error) {
// Open RSA Keys
pubBlock, privBlock, err := cryptography.OpenKeys(keyPath)
// ReadConfig reads a config from a yaml file
func ReadConfig(fileName string) (client *Client, err error) {
client, err = InitConfig()
if err != nil {
log.Debug(err)
return nil, err
}
privK, err := cryptography.PemToKeys(privBlock)
file, err := ioutil.ReadFile(fileName)
if err != nil {
log.Debug(err)
return nil, err
}
client = &Client{
//ServerIp: "coconut-demo.jaeha.dev",
ServerIp: "127.0.0.1",
ServerPort: 9129,
tlsConfig: &tls.Config{InsecureSkipVerify: true}, // TODO: Update after using trusted cert
privKey: privK,
pubKeyBlock: pubBlock,
conn: nil,
err = yaml.Unmarshal(file, &client)
if err != nil {
log.Debug(err)
log.Error("Error while parsing config.yml")
return nil, err
}
return client, nil
}
func (client *Client) HandleGetPubKey() {
func (client *Client) HandleGetPubKey(conn net.Conn) (err error) {
if _, err = util.WriteBytes(conn, client.pubKeyBlock.Bytes); err != nil {
log.Debug(err)
log.Error("Error while sending public key")
return err
}
// TODO: Write error code to conn?
return nil
}
func (client *Client) doInit() (err error) {
@ -148,14 +164,14 @@ func (client *Client) Connect() (err error) {
return common.ExistingConnError
}
log.Debug("Connecting...")
dial, err := tls.Dial("tcp", client.ServerIp+":"+strconv.Itoa(int(client.ServerPort)), client.tlsConfig)
client.conn, err = tls.Dial("tcp", client.ServerHost+":"+strconv.Itoa(int(client.ServerPort)), client.tlsConfig)
if err != nil {
log.Debug(err)
log.Error("Error while connecting to the server")
return err
}
client.conn = dial
log.Info(client.conn.LocalAddr().String())
return client.doInit()
}

2
internal/client/client_test.go

@ -12,7 +12,7 @@ func init() {
//TODO: Test with demo server
func TestConnect(t *testing.T) {
_, err := NewClient()
_, err := InitConfig()
if err != nil {
t.Error(err)
}

26
internal/client/ui.go

@ -5,6 +5,7 @@ import (
"github.com/gotk3/gotk3/gdk"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
"github.com/jaeha-choi/Proj_Coconut_Utility/cryptography"
"github.com/jaeha-choi/Proj_Coconut_Utility/log"
"os"
"path/filepath"
@ -67,7 +68,7 @@ func initUIStatus() (stat *UIStatus) {
}
// Start initializes all configurations and starts main UI
func Start(uiGladePath string) {
func Start(uiGladePath string, client *Client) {
var stat *UIStatus
// Create a new application.
@ -82,20 +83,25 @@ func Start(uiGladePath string) {
application.Connect("startup", func() {
log.Debug("Application starting up...")
var err error
stat = initUIStatus()
// TODO: NewClient can take a while, perhaps some sort of popup indicating a program is being executed would be helpful
stat.client, err = NewClient()
if err != nil {
log.Debug(err)
log.Error("Error while initializing client configuration")
return
}
stat.client = client
})
// Connect function to application activate event
application.Connect("activate", func() {
var err error
// Open RSA Keys
pubBlock, privBlock, err := cryptography.OpenKeys(client.KeyPath)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
stat.client.pubKeyBlock = pubBlock
stat.client.privKey, err = cryptography.PemToKeys(privBlock)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
// Get the GtkBuilder ui definition in the glade file.
stat.builder, err = gtk.BuilderNewFromFile(uiGladePath)
@ -145,7 +151,7 @@ func Start(uiGladePath string) {
})
// Launch the application
os.Exit(application.Run(os.Args))
os.Exit(application.Run(nil))
}
func (ui *UIStatus) handleSwitchPage() {

Loading…
Cancel
Save