mirror of
https://github.com/int128/kubelogin.git
synced 2026-02-14 16:39:51 +00:00
117 lines
5.1 KiB
Go
117 lines
5.1 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/int128/kubelogin/pkg/usecases/authentication"
|
|
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
|
|
"github.com/int128/kubelogin/pkg/usecases/authentication/devicecode"
|
|
"github.com/int128/kubelogin/pkg/usecases/authentication/ropc"
|
|
"github.com/spf13/pflag"
|
|
)
|
|
|
|
const oobRedirectURI = "urn:ietf:wg:oauth:2.0:oob"
|
|
|
|
type authenticationOptions struct {
|
|
GrantType string
|
|
ListenAddress []string
|
|
ListenPort []int // deprecated
|
|
AuthenticationTimeoutSec int
|
|
SkipOpenBrowser bool
|
|
BrowserCommand string
|
|
LocalServerCertFile string
|
|
LocalServerKeyFile string
|
|
OpenURLAfterAuthentication string
|
|
RedirectURLHostname string
|
|
RedirectURLAuthCodeKeyboard string
|
|
AuthRequestExtraParams map[string]string
|
|
Username string
|
|
Password string
|
|
}
|
|
|
|
// determineListenAddress returns the addresses from the flags.
|
|
// Note that --listen-address is always given due to the default value.
|
|
// If --listen-port is not set, it returns --listen-address.
|
|
// If --listen-port is set, it returns the strings of --listen-port.
|
|
func (o *authenticationOptions) determineListenAddress() []string {
|
|
if len(o.ListenPort) == 0 {
|
|
return o.ListenAddress
|
|
}
|
|
var a []string
|
|
for _, p := range o.ListenPort {
|
|
a = append(a, fmt.Sprintf("127.0.0.1:%d", p))
|
|
}
|
|
return a
|
|
}
|
|
|
|
var allGrantType = strings.Join([]string{
|
|
"auto",
|
|
"authcode",
|
|
"authcode-keyboard",
|
|
"password",
|
|
"device-code",
|
|
}, "|")
|
|
|
|
func (o *authenticationOptions) addFlags(f *pflag.FlagSet) {
|
|
f.StringVar(&o.GrantType, "grant-type", "auto", fmt.Sprintf("Authorization grant type to use. One of (%s)", allGrantType))
|
|
f.StringSliceVar(&o.ListenAddress, "listen-address", defaultListenAddress, "[authcode] Address to bind to the local server. If multiple addresses are set, it will try binding in order")
|
|
//TODO: remove the deprecated flag
|
|
f.IntSliceVar(&o.ListenPort, "listen-port", nil, "[authcode] deprecated: port to bind to the local server")
|
|
if err := f.MarkDeprecated("listen-port", "use --listen-address instead"); err != nil {
|
|
panic(err)
|
|
}
|
|
f.BoolVar(&o.SkipOpenBrowser, "skip-open-browser", false, "[authcode] Do not open the browser automatically")
|
|
f.StringVar(&o.BrowserCommand, "browser-command", "", "[authcode] Command to open the browser")
|
|
f.IntVar(&o.AuthenticationTimeoutSec, "authentication-timeout-sec", defaultAuthenticationTimeoutSec, "[authcode] Timeout of authentication in seconds")
|
|
f.StringVar(&o.LocalServerCertFile, "local-server-cert", "", "[authcode] Certificate path for the local server")
|
|
f.StringVar(&o.LocalServerKeyFile, "local-server-key", "", "[authcode] Certificate key path for the local server")
|
|
f.StringVar(&o.OpenURLAfterAuthentication, "open-url-after-authentication", "", "[authcode] If set, open the URL in the browser after authentication")
|
|
f.StringVar(&o.RedirectURLHostname, "oidc-redirect-url-hostname", "localhost", "[authcode] Hostname of the redirect URL")
|
|
f.StringVar(&o.RedirectURLAuthCodeKeyboard, "oidc-redirect-url-authcode-keyboard", oobRedirectURI, "[authcode-keyboard] Redirect URL")
|
|
f.StringToStringVar(&o.AuthRequestExtraParams, "oidc-auth-request-extra-params", nil, "[authcode, authcode-keyboard] Extra query parameters to send with an authentication request")
|
|
f.StringVar(&o.Username, "username", "", "[password] Username for resource owner password credentials grant")
|
|
f.StringVar(&o.Password, "password", "", "[password] Password for resource owner password credentials grant")
|
|
}
|
|
|
|
func (o *authenticationOptions) expandHomedir() {
|
|
o.LocalServerCertFile = expandHomedir(o.LocalServerCertFile)
|
|
o.LocalServerKeyFile = expandHomedir(o.LocalServerKeyFile)
|
|
}
|
|
|
|
func (o *authenticationOptions) grantOptionSet() (s authentication.GrantOptionSet, err error) {
|
|
switch {
|
|
case o.GrantType == "authcode" || (o.GrantType == "auto" && o.Username == ""):
|
|
s.AuthCodeBrowserOption = &authcode.BrowserOption{
|
|
BindAddress: o.determineListenAddress(),
|
|
SkipOpenBrowser: o.SkipOpenBrowser,
|
|
BrowserCommand: o.BrowserCommand,
|
|
AuthenticationTimeout: time.Duration(o.AuthenticationTimeoutSec) * time.Second,
|
|
LocalServerCertFile: o.LocalServerCertFile,
|
|
LocalServerKeyFile: o.LocalServerKeyFile,
|
|
OpenURLAfterAuthentication: o.OpenURLAfterAuthentication,
|
|
RedirectURLHostname: o.RedirectURLHostname,
|
|
AuthRequestExtraParams: o.AuthRequestExtraParams,
|
|
}
|
|
case o.GrantType == "authcode-keyboard":
|
|
s.AuthCodeKeyboardOption = &authcode.KeyboardOption{
|
|
AuthRequestExtraParams: o.AuthRequestExtraParams,
|
|
RedirectURL: o.RedirectURLAuthCodeKeyboard,
|
|
}
|
|
case o.GrantType == "password" || (o.GrantType == "auto" && o.Username != ""):
|
|
s.ROPCOption = &ropc.Option{
|
|
Username: o.Username,
|
|
Password: o.Password,
|
|
}
|
|
case o.GrantType == "device-code":
|
|
s.DeviceCodeOption = &devicecode.Option{
|
|
SkipOpenBrowser: o.SkipOpenBrowser,
|
|
BrowserCommand: o.BrowserCommand,
|
|
}
|
|
default:
|
|
err = fmt.Errorf("grant-type must be one of (%s)", allGrantType)
|
|
}
|
|
return
|
|
}
|