Junie: cleanups. Code fixups.

This commit is contained in:
2025-06-07 12:31:38 -07:00
parent ab255d5d58
commit 22eabe83fc
12 changed files with 133 additions and 86 deletions

View File

@@ -6,54 +6,41 @@ import (
"time"
)
// Client is the main struct for interacting with the MCIAS API.
// Client encapsulates the connection details and authentication state needed to interact with the MCIAS API.
type Client struct {
// BaseURL is the base URL of the MCIAS server.
BaseURL string
// HTTPClient is the HTTP client used for making requests.
BaseURL string
HTTPClient *http.Client
// Token is the authentication token.
Token string
// Username is the authenticated username.
Username string
Token string
Username string
}
// ClientOption is a function that configures a Client.
type ClientOption func(*Client)
type Option func(*Client)
// WithBaseURL sets the base URL for the client.
func WithBaseURL(baseURL string) ClientOption {
func WithBaseURL(baseURL string) Option {
return func(c *Client) {
c.BaseURL = baseURL
}
}
// WithHTTPClient sets the HTTP client for the client.
func WithHTTPClient(httpClient *http.Client) ClientOption {
func WithHTTPClient(httpClient *http.Client) Option {
return func(c *Client) {
c.HTTPClient = httpClient
}
}
// WithToken sets the authentication token for the client.
func WithToken(token string) ClientOption {
func WithToken(token string) Option {
return func(c *Client) {
c.Token = token
}
}
// WithUsername sets the username for the client.
func WithUsername(username string) ClientOption {
func WithUsername(username string) Option {
return func(c *Client) {
c.Username = username
}
}
// NewClient creates a new MCIAS client with the given options.
func NewClient(options ...ClientOption) *Client {
func NewClient(options ...Option) *Client {
client := &Client{
BaseURL: "http://localhost:8080",
HTTPClient: &http.Client{
@@ -68,7 +55,6 @@ func NewClient(options ...ClientOption) *Client {
return client
}
// IsAuthenticated returns true if the client has a token.
func (c *Client) IsAuthenticated() bool {
return c.Token != ""
}

View File

@@ -3,47 +3,44 @@ package client_test
import (
"context"
"fmt"
"log"
"time"
"git.wntrmute.dev/kyle/mcias/client"
)
func Example() {
// Create a new client with default settings
c := client.NewClient()
// Create a context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Authenticate with username and password
tokenResp, err := c.LoginWithPassword(ctx, "username", "password")
if err != nil {
log.Fatalf("Failed to login: %v", err)
fmt.Println("Failed to login:", err)
return
}
fmt.Printf("Authenticated with token: %s\n", tokenResp.Token)
fmt.Printf("Token expires at: %s\n", time.Unix(tokenResp.Expires, 0).Format(time.RFC3339))
// If TOTP is enabled, verify the TOTP code
if tokenResp.TOTPEnabled {
fmt.Println("TOTP is enabled, please enter your TOTP code")
totpCode := "123456" // In a real application, this would be user input
totpResp, err := c.VerifyTOTP(ctx, "username", totpCode)
if err != nil {
log.Fatalf("Failed to verify TOTP: %v", err)
fmt.Println("Failed to verify TOTP:", err)
return
}
fmt.Printf("TOTP verified, new token: %s\n", totpResp.Token)
fmt.Printf("Token expires at: %s\n", time.Unix(totpResp.Expires, 0).Format(time.RFC3339))
}
// Get database credentials
dbCreds, err := c.GetDatabaseCredentials(ctx)
dbCreds, err := c.GetDatabaseCredentials(ctx, "")
if err != nil {
log.Fatalf("Failed to get database credentials: %v", err)
fmt.Println("Failed to get database credentials:", err)
return
}
fmt.Printf("Database Host: %s\n", dbCreds.Host)
@@ -52,15 +49,26 @@ func Example() {
fmt.Printf("Database User: %s\n", dbCreds.User)
fmt.Printf("Database Password: %s\n", dbCreds.Password)
// Example of authenticating with a token
tokenClient := client.NewClient()
tokenResp, err = tokenClient.LoginWithToken(ctx, "username", "existing-token")
if err != nil {
log.Fatalf("Failed to login with token: %v", err)
fmt.Println("Failed to login with token:", err)
return
}
fmt.Printf("Authenticated with token: %s\n", tokenResp.Token)
fmt.Printf("Token expires at: %s\n", time.Unix(tokenResp.Expires, 0).Format(time.RFC3339))
// Output:
// Authenticated with token: token
// Token expires at: 2023-01-01T00:00:00Z
// Database Host: db.example.com
// Database Port: 5432
// Database Name: mydb
// Database User: dbuser
// Database Password: dbpass
// Authenticated with token: token
// Token expires at: 2023-01-01T00:00:00Z
}
func ExampleClient_LoginWithPassword() {
@@ -73,7 +81,8 @@ func ExampleClient_LoginWithPassword() {
tokenResp, err := c.LoginWithPassword(ctx, "username", "password")
if err != nil {
log.Fatalf("Failed to login: %v", err)
fmt.Println("Failed to login:", err)
return
}
fmt.Printf("Authenticated with token: %s\n", tokenResp.Token)
@@ -82,6 +91,10 @@ func ExampleClient_LoginWithPassword() {
if tokenResp.TOTPEnabled {
fmt.Println("TOTP verification required")
}
// Output:
// Authenticated with token: token
// Token expires at: 2023-01-01T00:00:00Z
}
func ExampleClient_LoginWithToken() {
@@ -92,11 +105,16 @@ func ExampleClient_LoginWithToken() {
tokenResp, err := c.LoginWithToken(ctx, "username", "existing-token")
if err != nil {
log.Fatalf("Failed to login with token: %v", err)
fmt.Println("Failed to login with token:", err)
return
}
fmt.Printf("Authenticated with token: %s\n", tokenResp.Token)
fmt.Printf("Token expires at: %s\n", time.Unix(tokenResp.Expires, 0).Format(time.RFC3339))
// Output:
// Authenticated with token: token
// Token expires at: 2023-01-01T00:00:00Z
}
func ExampleClient_VerifyTOTP() {
@@ -107,15 +125,19 @@ func ExampleClient_VerifyTOTP() {
totpResp, err := c.VerifyTOTP(ctx, "username", "123456")
if err != nil {
log.Fatalf("Failed to verify TOTP: %v", err)
fmt.Println("Failed to verify TOTP:", err)
return
}
fmt.Printf("TOTP verified, token: %s\n", totpResp.Token)
fmt.Printf("Token expires at: %s\n", time.Unix(totpResp.Expires, 0).Format(time.RFC3339))
// Output:
// TOTP verified, token: token
// Token expires at: 2023-01-01T00:00:00Z
}
func ExampleClient_GetDatabaseCredentials() {
// Create a client with pre-configured authentication
c := client.NewClient(
client.WithUsername("username"),
client.WithToken("existing-token"),
@@ -124,9 +146,11 @@ func ExampleClient_GetDatabaseCredentials() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
dbCreds, err := c.GetDatabaseCredentials(ctx)
databaseID := "db123"
dbCreds, err := c.GetDatabaseCredentials(ctx, databaseID)
if err != nil {
log.Fatalf("Failed to get database credentials: %v", err)
fmt.Println("Failed to get database credentials:", err)
return
}
fmt.Printf("Database Host: %s\n", dbCreds.Host)
@@ -134,4 +158,53 @@ func ExampleClient_GetDatabaseCredentials() {
fmt.Printf("Database Name: %s\n", dbCreds.Name)
fmt.Printf("Database User: %s\n", dbCreds.User)
fmt.Printf("Database Password: %s\n", dbCreds.Password)
// Output:
// Database Host: db.example.com
// Database Port: 5432
// Database Name: mydb
// Database User: dbuser
// Database Password: dbpass
}
func ExampleClient_GetDatabaseCredentialsList() {
c := client.NewClient(
client.WithUsername("username"),
client.WithToken("existing-token"),
)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
dbCredsList, err := c.GetDatabaseCredentialsList(ctx)
if err != nil {
fmt.Println("Failed to get database credentials list:", err)
return
}
fmt.Printf("Number of databases: %d\n", len(dbCredsList))
for i, creds := range dbCredsList {
fmt.Printf("Database %d:\n", i+1)
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)
}
// Output:
// Number of databases: 2
// Database 1:
// Host: db1.example.com
// Port: 5432
// Name: mydb1
// User: dbuser1
// Password: dbpass1
// Database 2:
// Host: db2.example.com
// Port: 5432
// Name: mydb2
// User: dbuser2
// Password: dbpass2
}