commit ace452bce3e6caa62ad6d5c4e3348b17c051836f Author: Farhan Khan Date: Sat Mar 28 16:01:07 2026 -0400 Working through authentication diff --git a/auth.go b/auth.go new file mode 100644 index 0000000..ebedba3 --- /dev/null +++ b/auth.go @@ -0,0 +1,154 @@ +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "log" + "net/http" + "os" +) + +/* +func authMain(args []string) { + authCmd := flag.NewFlagSet("auth", flag.ExitOnError) + token := authCmd.String("t", "", "Auth token") + verbose := authCmd.Bool("v", false, "Verbose output") + + authCmd.Parse(args) + + fmt.Println("Auth command") + fmt.Println("Token:", *token) + fmt.Println("Verbose:", *verbose) +} +*/ + +var authCmd *flag.FlagSet + +type AuthenticateRequest struct { + Accountid string `json:"accountid"` + Username string `json:"username"` + Password string `json:"password"` +} + +func authLocalGetToken() { + +} + +func authLocalAuthenticate(args []string) { + + var authSource string + var authUsername string + var authPassword string + var authAccountid string + var outputFormat string + + authCmd.StringVar(&authSource, "s", "", "Source (required)") + authCmd.StringVar(&authSource, "source", "", "Source (required)") + authCmd.StringVar(&authUsername, "u", "", "Username (required)") + authCmd.StringVar(&authUsername, "username", "", "Username (required)") + authCmd.StringVar(&authPassword, "p", "", "Password (required)") + authCmd.StringVar(&authPassword, "password", "", "Password (required)") + authCmd.StringVar(&authAccountid, "a", "", "Account ID (required)") + authCmd.StringVar(&authAccountid, "account", "", "Account ID (required)") + authCmd.StringVar(&outputFormat, "o", "text", "Output format (text or json)") + + // verbose := authCmd.Bool("v", false, "Verbose output") + + outputFormat = "text" + + authCmd.Parse(args) + + if authSource == "" { + fmt.Println("Error: either -s or --source is required") + //authCmd.Usage() + os.Exit(1) + } + + // Enforce required flag + if authSource == "" { + fmt.Println("Error: either -s or --source is required") + //authCmd.Usage() + os.Exit(1) + } + + if authSource != "local" { + fmt.Println("Error: invalid source. Allowed values: local") + //authCmd.Usage() + os.Exit(1) + } + + if authAccountid == "" { + fmt.Print("Account ID: ") + fmt.Scanln(&authAccountid) + } + + if authUsername == "" { + fmt.Print("Username: ") + fmt.Scanln(&authUsername) + } + if authPassword == "" { + fmt.Print("Password: ") + fmt.Scanln(&authPassword) + } + + var authenticaterequest AuthenticateRequest + + authenticaterequest.Accountid = authAccountid + authenticaterequest.Username = authUsername + authenticaterequest.Password = authPassword + + authenticaterequestpostdata, err := json.Marshal(authenticaterequest) + if err != nil { + fmt.Println("Error encoding JSON:", err) + os.Exit(1) + } + + url := endpoint + "/identity/authenticate" + req, err := http.NewRequest("POST", url, bytes.NewBuffer(authenticaterequestpostdata)) + if err != nil { + log.Fatal("Error creating request:", err) + } + + // Set headers + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Fatal("Error making request:", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + log.Fatal("Authentication failed with status:", resp.Status) + } + + var result map[string]interface{} + err = json.NewDecoder(resp.Body).Decode(&result) + if err != nil { + log.Fatal("Error decoding response:", err) + } + + if outputFormat == "json" { + jsonOutput, err := json.MarshalIndent(result, "", " ") + if err != nil { + log.Fatal("Error encoding JSON output:", err) + } + fmt.Println(string(jsonOutput)) + return + } else { + for key, value := range result { + fmt.Printf("%s: %v\n", key, value) + } + } + +} + +func authenticateMain(args []string) { + authCmd = flag.NewFlagSet("auth", flag.ExitOnError) + + authLocalAuthenticate(args) + //fmt.Println("Verbose:", *verbose) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..701260f --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module upc + +go 1.25.0 diff --git a/main.go b/main.go new file mode 100644 index 0000000..3691c6e --- /dev/null +++ b/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "fmt" + "os" + "strings" +) + +var endpoint string = "http://127.0.0.1:8080" + +type Command struct { + Names []string // aliases: short + long + Description string + Handler func(args []string) +} + +var commands = []Command{ + { + Names: []string{"login", "l"}, + Description: "Log into the system", + Handler: func(args []string) { + fmt.Println("Executing login with args:", args) + }, + }, + { + Names: []string{"auth", "authenticate"}, + Description: "Authenticate with a token", + Handler: authenticateMain, + }, +} + +func printMainUsage() { + fmt.Println("Usage:") + fmt.Println(" upc [options]") + fmt.Println("\nAvailable commands:") + + for _, cmd := range commands { + fmt.Printf(" %-20s %s\n", formatNames(cmd.Names), cmd.Description) + } +} + +func formatNames(names []string) string { + return strings.Join(names, ", ") +} + +func findCommand(name string) *Command { + for _, cmd := range commands { + for _, n := range cmd.Names { + if n == name { + return &cmd + } + } + } + return nil +} + +func main() { + + if len(os.Args) < 2 { + fmt.Println("Error: missing subcommand") + printMainUsage() + os.Exit(1) + } + + subcommand := os.Args[1] + + cmd := findCommand(subcommand) + if cmd == nil { + fmt.Println("Error: unknown command:", subcommand) + printMainUsage() + os.Exit(1) + } + + cmd.Handler(os.Args[2:]) +}