Skip to content

Commit

Permalink
add UserInfoHandler for dynamically fetching username+password
Browse files Browse the repository at this point in the history
Signed-off-by: btoews <benjamin.toews@gmail.com>
  • Loading branch information
btoews committed Apr 2, 2024
1 parent 33316cd commit 3b4812b
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions nats.go
Expand Up @@ -131,6 +131,7 @@ var (
ErrNkeysNotSupported = errors.New("nats: nkeys not supported by the server")
ErrStaleConnection = errors.New("nats: " + STALE_CONNECTION)
ErrTokenAlreadySet = errors.New("nats: token and token handler both set")
ErrUserInfoAlreadySet = errors.New("nats: user info and user info handler both set")
ErrMsgNotBound = errors.New("nats: message is not bound to subscription/connection")
ErrMsgNoReply = errors.New("nats: message does not have a reply")
ErrClientIPNotSupported = errors.New("nats: client IP not supported by this server")
Expand Down Expand Up @@ -230,6 +231,9 @@ type SignatureHandler func([]byte) ([]byte, error)
// AuthTokenHandler is used to generate a new token.
type AuthTokenHandler func() string

// AuthUserInfoHandler is used to fetch username and password.
type AuthUserInfoHandler func() (string, string)

// ReconnectDelayHandler is used to get from the user the desired
// delay the library should pause before attempting to reconnect
// again. Note that this is invoked after the library tried the
Expand Down Expand Up @@ -443,6 +447,10 @@ type Options struct {
// Password sets the password to be used when connecting to a server.
Password string

// UserInfoHandler designates the function used to fetch the username and
// password to be used when connecting to a server.
UserInfoHandler AuthUserInfoHandler

// Token sets the token to be used when connecting to a server.
Token string

Expand Down Expand Up @@ -1166,6 +1174,15 @@ func UserInfo(user, password string) Option {
}
}

// UserInfoHandler is an Option to set the user info handler to use when a
// username and password is not otherwise specified.
func UserInfoHandler(cb AuthUserInfoHandler) Option {
return func(o *Options) error {
o.UserInfoHandler = cb
return nil
}
}

// Token is an Option to set the token to use
// when a token is not included directly in the URLs
// and when a token handler is not provided.
Expand Down Expand Up @@ -2557,6 +2574,13 @@ func (nc *Conn) connectProto() (string, error) {
token = nc.Opts.TokenHandler()
}

if nc.Opts.UserInfoHandler != nil {
if user != _EMPTY_ || pass != _EMPTY_ {
return _EMPTY_, ErrUserInfoAlreadySet
}
user, pass = nc.Opts.UserInfoHandler()
}

// If our server does not support headers then we can't do them or no responders.
hdrs := nc.info.Headers
cinfo := connectInfo{o.Verbose, o.Pedantic, ujwt, nkey, sig, user, pass, token,
Expand Down

0 comments on commit 3b4812b

Please sign in to comment.