Uploaded image for project: 'Go Driver'
  1. Go Driver
  2. GODRIVER-3316

Remove Authentication Registry

    • Type: Icon: Task Task
    • Resolution: Unresolved
    • Priority: Icon: Unknown Unknown
    • 2.1.0
    • Affects Version/s: None
    • Component/s: None
    • None
    • Go Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      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
      } 
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            preston.vasquez@mongodb.com Preston Vasquez
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: