-
Type: Task
-
Resolution: Unresolved
-
Priority: Unknown
-
Affects Version/s: None
-
Component/s: None
-
None
-
Go Drivers
Context
The authentication registry is fairly confusing and unnecessarily complicated. We should remove it in favor of a more idiomatic approach that doesn't require returning interfaces from functions. That is, create a single constructor that commits to the "returning interfaces" antipattern to clean up interface pollution concerning auth.Authenticator. Authenticator implementor constructors should return a concrete type.
Definition of done
What must be done to consider the task complete?
First we should replace the registry with a global struct of constructors:
type AuthFactory[T Authenticator] func(*Cred, *http.Client) (T, error) var Authenticators = struct { ScramSHA1 AuthFactory[*ScramAuthenticator] // ... }{ ScramSHA1: newScramSHA1Authenticator, // ... }
Update the constructors to return a concrete type:
func newScramSHA1Authenticator(cred *Cred, _ *http.Client) (*ScramAuthenticator, error) {}
Rename auth.CreateAuthenticator to auth.NewAuthenticator:
func NewAuthenticator(name string, cred *Cred, httpClient *http.Client) (Authenticator, error) { switch name { case SCRAMSHA1: return Authenticators.ScramSHA1(cred, httpClient) } return nil, nil }
The usage would look like this:
authCreds := topology.ConvertCreds(clientOpt.Auth) client.authenticator, err = auth.CreateAuthenticator(clientOpt.Auth.AuthMechanism, authCreds, clientOpt.HTTPClient)
Pitfalls
In the suggested pattern auth.NewAuthenticator should be the only function that returns the auth.Authenticator interface. AFAICT there is no obvious way to totally avoid this pattern, other than trivially wrapping Authenticator in a struct. However, that seems like an obfuscation:
type Authenticator struct { IAuthenticator }
- related to
-
GODRIVER-3215 (options.ClientOptions).SetAuth with MONGODB-AWS does not set default $external AuthSource
- Closed