feat: initial version of the project
This commit is contained in:
commit
5b67d39aba
13 changed files with 1538 additions and 0 deletions
123
cmd/auth.go
Normal file
123
cmd/auth.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"codeberg.org/romaintb/fgj/internal/api"
|
||||
"codeberg.org/romaintb/fgj/internal/config"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
var authCmd = &cobra.Command{
|
||||
Use: "auth",
|
||||
Short: "Authenticate fgj with a Forgejo instance",
|
||||
Long: "Manage authentication state for Forgejo instances.",
|
||||
}
|
||||
|
||||
var authLoginCmd = &cobra.Command{
|
||||
Use: "login",
|
||||
Short: "Authenticate with a Forgejo instance",
|
||||
Long: "Authenticate with a Forgejo instance using a personal access token.",
|
||||
RunE: runAuthLogin,
|
||||
}
|
||||
|
||||
var authStatusCmd = &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "View authentication status",
|
||||
Long: "Display the authentication status for configured Forgejo instances.",
|
||||
RunE: runAuthStatus,
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(authCmd)
|
||||
authCmd.AddCommand(authLoginCmd)
|
||||
authCmd.AddCommand(authStatusCmd)
|
||||
|
||||
authLoginCmd.Flags().String("hostname", "", "Forgejo instance hostname (e.g., codeberg.org)")
|
||||
authLoginCmd.Flags().StringP("token", "t", "", "Personal access token")
|
||||
}
|
||||
|
||||
func runAuthLogin(cmd *cobra.Command, args []string) error {
|
||||
hostname, _ := cmd.Flags().GetString("hostname")
|
||||
token, _ := cmd.Flags().GetString("token")
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
if hostname == "" {
|
||||
fmt.Print("Forgejo instance hostname (default: codeberg.org): ")
|
||||
input, _ := reader.ReadString('\n')
|
||||
hostname = strings.TrimSpace(input)
|
||||
if hostname == "" {
|
||||
hostname = "codeberg.org"
|
||||
}
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
fmt.Print("Personal access token: ")
|
||||
tokenBytes, err := term.ReadPassword(int(syscall.Stdin))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read token: %w", err)
|
||||
}
|
||||
fmt.Println()
|
||||
token = strings.TrimSpace(string(tokenBytes))
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
return fmt.Errorf("token is required")
|
||||
}
|
||||
|
||||
client, err := api.NewClient(hostname, token)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create client: %w", err)
|
||||
}
|
||||
|
||||
user, _, err := client.GetMyUserInfo()
|
||||
if err != nil {
|
||||
return fmt.Errorf("authentication failed: %w", err)
|
||||
}
|
||||
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load config: %w", err)
|
||||
}
|
||||
|
||||
cfg.SetHost(hostname, config.HostConfig{
|
||||
Hostname: hostname,
|
||||
Token: token,
|
||||
User: user.UserName,
|
||||
GitProtocol: "https",
|
||||
})
|
||||
|
||||
if err := cfg.Save(); err != nil {
|
||||
return fmt.Errorf("failed to save config: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("✓ Authenticated as %s on %s\n", user.UserName, hostname)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runAuthStatus(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load config: %w", err)
|
||||
}
|
||||
|
||||
if len(cfg.Hosts) == 0 {
|
||||
fmt.Println("Not authenticated with any Forgejo instances")
|
||||
fmt.Println("Run 'fgj auth login' to authenticate")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("Authenticated instances:")
|
||||
for hostname, host := range cfg.Hosts {
|
||||
fmt.Printf(" • %s (user: %s)\n", hostname, host.User)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue