Junie: TOTP flow update and db migrations.
This commit is contained in:
137
cmd/mcias-client/database.go
Normal file
137
cmd/mcias-client/database.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type DatabaseCredentials struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Name string `json:"name"`
|
||||
User string `json:"user"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
var (
|
||||
dbUsername string
|
||||
dbToken string
|
||||
useStored bool
|
||||
)
|
||||
|
||||
var databaseCmd = &cobra.Command{
|
||||
Use: "database",
|
||||
Short: "Manage database credentials",
|
||||
Long: `Commands for managing database credentials in the MCIAS system.`,
|
||||
}
|
||||
|
||||
var getCredentialsCmd = &cobra.Command{
|
||||
Use: "credentials",
|
||||
Short: "Get database credentials",
|
||||
Long: `Retrieve database credentials from the MCIAS system.
|
||||
This command requires authentication with a username and token.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
getCredentials()
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(databaseCmd)
|
||||
databaseCmd.AddCommand(getCredentialsCmd)
|
||||
|
||||
getCredentialsCmd.Flags().StringVarP(&dbUsername, "username", "u", "", "Username for authentication")
|
||||
getCredentialsCmd.Flags().StringVarP(&dbToken, "token", "t", "", "Authentication token")
|
||||
getCredentialsCmd.Flags().BoolVarP(&useStored, "use-stored", "s", false, "Use stored token from previous login")
|
||||
|
||||
// Make username required only if not using stored token
|
||||
getCredentialsCmd.MarkFlagsMutuallyExclusive("token", "use-stored")
|
||||
}
|
||||
|
||||
func getCredentials() {
|
||||
// If using stored token, load it from the token file
|
||||
if useStored {
|
||||
tokenInfo, err := loadToken()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error loading token: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
dbUsername = tokenInfo.Username
|
||||
dbToken = tokenInfo.Token
|
||||
}
|
||||
|
||||
// Validate required parameters
|
||||
if dbUsername == "" {
|
||||
fmt.Fprintf(os.Stderr, "Error: username is required\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if dbToken == "" {
|
||||
fmt.Fprintf(os.Stderr, "Error: token is required (either provide --token or use --use-stored)\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
serverAddr := viper.GetString("server")
|
||||
if serverAddr == "" {
|
||||
serverAddr = "http://localhost:8080"
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/v1/database/credentials?username=%s", serverAddr, dbUsername)
|
||||
|
||||
// Create a context with timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to create request: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", dbToken))
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to send request: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to read response: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
var errResp ErrorResponse
|
||||
if unmarshalErr := json.Unmarshal(body, &errResp); unmarshalErr == nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %s\n", errResp.Error)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "Error: %s\n", resp.Status)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var creds DatabaseCredentials
|
||||
if unmarshalErr := json.Unmarshal(body, &creds); unmarshalErr != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to parse response: %v\n", unmarshalErr)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Database Credentials:")
|
||||
fmt.Printf("Host: %s\n", creds.Host)
|
||||
fmt.Printf("Port: %d\n", creds.Port)
|
||||
fmt.Printf("Name: %s\n", creds.Name)
|
||||
fmt.Printf("User: %s\n", creds.User)
|
||||
fmt.Printf("Password: %s\n", creds.Password)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user