github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runners/auth/auth.go (about)

     1  package auth
     2  
     3  import (
     4  	"github.com/ActiveState/cli/internal/keypairs"
     5  	"github.com/ActiveState/cli/internal/locale"
     6  	"github.com/ActiveState/cli/internal/output"
     7  	"github.com/ActiveState/cli/internal/primer"
     8  	"github.com/ActiveState/cli/internal/prompt"
     9  	"github.com/ActiveState/cli/internal/runbits/auth"
    10  	"github.com/ActiveState/cli/pkg/platform/authentication"
    11  )
    12  
    13  type Auth struct {
    14  	output.Outputer
    15  	*authentication.Auth
    16  	prompt.Prompter
    17  	Cfg keypairs.Configurable
    18  }
    19  
    20  type primeable interface {
    21  	primer.Outputer
    22  	primer.Auther
    23  	primer.Prompter
    24  	primer.Configurer
    25  }
    26  
    27  func NewAuth(prime primeable) *Auth {
    28  	return &Auth{prime.Output(), prime.Auth(), prime.Prompt(), prime.Config()}
    29  }
    30  
    31  type AuthParams struct {
    32  	Token          string
    33  	Username       string
    34  	Password       string
    35  	Totp           string
    36  	Prompt         bool
    37  	NonInteractive bool
    38  }
    39  
    40  func (p AuthParams) verify() error {
    41  	if p.Username != "" && p.Password == "" {
    42  		return locale.NewInputError("err_auth_invalid_username_param", "[ACTIONABLE]--username[/RESET] flag requires [ACTIONABLE]--password[/RESET] flag")
    43  	}
    44  
    45  	if p.Username == "" && p.Password != "" {
    46  		return locale.NewInputError("err_auth_invalid_password_param", "[ACTIONABLE]--password[/RESET] flag requires [ACTIONABLE]--username[/RESET] flag")
    47  	}
    48  
    49  	if p.Totp != "" && (p.Username == "" || p.Password == "") {
    50  		return locale.NewInputError("err_auth_invalid_totp_param", "[ACTIONABLE]--totp[/RESET] flag requires both [ACTIONABLE]--username[/RESET] and [ACTIONABLE]--password[/RESET] flags")
    51  	}
    52  
    53  	return nil
    54  }
    55  
    56  // Run runs our command
    57  func (a *Auth) Run(params *AuthParams) error {
    58  	if !a.Authenticated() {
    59  		if err := params.verify(); err != nil {
    60  			return locale.WrapError(err, "err_auth_params", "Invalid authentication params")
    61  		}
    62  
    63  		if err := a.authenticate(params); err != nil {
    64  			return locale.WrapError(err, "err_auth_authenticate", "Could not authenticate.")
    65  		}
    66  
    67  		if err := a.verifyAuthentication(); err != nil {
    68  			return locale.WrapError(err, "err_auth_verify", "Could not verify authentication")
    69  		}
    70  	}
    71  
    72  	username := a.Auth.WhoAmI()
    73  	a.Outputer.Print(output.Prepare(
    74  		locale.T("logged_in_as", map[string]string{"Name": username}),
    75  		&struct {
    76  			Username string `json:"username"`
    77  		}{
    78  			username,
    79  		},
    80  	))
    81  
    82  	return nil
    83  }
    84  
    85  func (a *Auth) authenticate(params *AuthParams) error {
    86  	if params.Prompt || params.Username != "" {
    87  		return auth.AuthenticateWithInput(params.Username, params.Password, params.Totp, params.NonInteractive, a.Cfg, a.Outputer, a.Prompter, a.Auth)
    88  	}
    89  
    90  	if params.Token != "" {
    91  		return auth.AuthenticateWithToken(params.Token, a.Auth)
    92  	}
    93  
    94  	if params.NonInteractive {
    95  		return locale.NewInputError("err_auth_needinput")
    96  	}
    97  
    98  	return auth.AuthenticateWithBrowser(a.Outputer, a.Auth, a.Prompter, a.Cfg)
    99  }
   100  
   101  func (a *Auth) verifyAuthentication() error {
   102  	if !a.Auth.Authenticated() {
   103  		return locale.NewInputError("login_err_auth")
   104  	}
   105  
   106  	a.Outputer.Notice(output.Title(locale.Tl("authentication_title", "Authentication")))
   107  	a.Outputer.Notice(locale.T("login_success_welcome_back", map[string]string{
   108  		"Name": a.Auth.WhoAmI(),
   109  	}))
   110  
   111  	return nil
   112  }