| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- package cmd
- import (
- "context"
- "encoding/json"
- "fmt"
- "gogs.dmsc.dev/arp/arp_cli/client"
- "gogs.dmsc.dev/arp/arp_cli/config"
- "github.com/AlecAivazis/survey/v2"
- "github.com/urfave/cli/v3"
- )
- // LoginCommand returns the login command
- func LoginCommand() *cli.Command {
- return &cli.Command{
- Name: "login",
- Usage: "Authenticate with the ARP server",
- Description: `Login to an ARP server using email and password.
- This command will store the authentication token in ~/.arp_cli/config.json
- for use by subsequent commands.
- Examples:
- # Login with URL and email specified
- arp_cli login --url http://localhost:8080/query --email user@example.com
- # Login interactively (will prompt for all fields)
- arp_cli login`,
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "url",
- Aliases: []string{"u"},
- Usage: "ARP server URL",
- Sources: cli.EnvVars("ARP_URL"),
- },
- &cli.StringFlag{
- Name: "email",
- Aliases: []string{"e"},
- Usage: "User email address",
- },
- &cli.StringFlag{
- Name: "password",
- Aliases: []string{"p"},
- Usage: "User password (will prompt if not provided)",
- },
- },
- Action: doLogin,
- }
- }
- func doLogin(ctx context.Context, cmd *cli.Command) error {
- // Get URL
- serverURL := cmd.String("url")
- if serverURL == "" {
- cfg, err := config.Load()
- if err != nil {
- return fmt.Errorf("failed to load config: %w", err)
- }
- serverURL = cfg.ServerURL
- }
- // Prompt for URL if still empty
- if serverURL == "" {
- prompt := &survey.Input{
- Message: "Server URL",
- Help: "The GraphQL endpoint URL (e.g., http://localhost:8080/query)",
- }
- if err := survey.AskOne(prompt, &serverURL, survey.WithValidator(survey.Required)); err != nil {
- return err
- }
- }
- // Get email
- email := cmd.String("email")
- if email == "" {
- prompt := &survey.Input{
- Message: "Email",
- Help: "Your user account email address",
- }
- if err := survey.AskOne(prompt, &email, survey.WithValidator(survey.Required)); err != nil {
- return err
- }
- }
- // Get password
- password := cmd.String("password")
- if password == "" {
- prompt := &survey.Password{
- Message: "Password",
- Help: "Your user account password",
- }
- if err := survey.AskOne(prompt, &password, survey.WithValidator(survey.Required)); err != nil {
- return err
- }
- }
- // Perform login
- c := client.New(serverURL)
- query := `
- mutation Login($email: String!, $password: String!) {
- login(email: $email, password: $password) {
- token
- user {
- id
- email
- roles {
- id
- name
- }
- }
- }
- }`
- variables := map[string]interface{}{
- "email": email,
- "password": password,
- }
- resp, err := c.Mutation(query, variables)
- if err != nil {
- return fmt.Errorf("login failed: %w", err)
- }
- // Parse response
- var loginResp struct {
- Login struct {
- Token string `json:"token"`
- User struct {
- ID string `json:"id"`
- Email string `json:"email"`
- Roles []struct {
- ID string `json:"id"`
- Name string `json:"name"`
- } `json:"roles"`
- } `json:"user"`
- } `json:"login"`
- }
- if err := json.Unmarshal(resp.Data, &loginResp); err != nil {
- return fmt.Errorf("failed to parse response: %w", err)
- }
- // Save config
- cfg, err := config.Load()
- if err != nil {
- return fmt.Errorf("failed to load config: %w", err)
- }
- cfg.ServerURL = serverURL
- cfg.Token = loginResp.Login.Token
- cfg.UserEmail = loginResp.Login.User.Email
- if err := config.Save(cfg); err != nil {
- return fmt.Errorf("failed to save config: %w", err)
- }
- fmt.Printf("Logged in as %s\n", loginResp.Login.User.Email)
- if len(loginResp.Login.User.Roles) > 0 {
- fmt.Print("Roles: ")
- for i, role := range loginResp.Login.User.Roles {
- if i > 0 {
- fmt.Print(", ")
- }
- fmt.Print(role.Name)
- }
- fmt.Println()
- }
- return nil
- }
|