github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/x/mongo/driver/auth/default.go (about)

     1  // Copyright (C) MongoDB, Inc. 2017-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package auth
     8  
     9  import (
    10  	"context"
    11  	"fmt"
    12  
    13  	"go.mongodb.org/mongo-driver/mongo/description"
    14  )
    15  
    16  func newDefaultAuthenticator(cred *Cred) (Authenticator, error) {
    17  	scram, err := newScramSHA256Authenticator(cred)
    18  	if err != nil {
    19  		return nil, newAuthError("failed to create internal authenticator", err)
    20  	}
    21  	speculative, ok := scram.(SpeculativeAuthenticator)
    22  	if !ok {
    23  		typeErr := fmt.Errorf("expected SCRAM authenticator to be SpeculativeAuthenticator but got %T", scram)
    24  		return nil, newAuthError("failed to create internal authenticator", typeErr)
    25  	}
    26  
    27  	return &DefaultAuthenticator{
    28  		Cred:                     cred,
    29  		speculativeAuthenticator: speculative,
    30  	}, nil
    31  }
    32  
    33  // DefaultAuthenticator uses SCRAM-SHA-1 or MONGODB-CR depending
    34  // on the server version.
    35  type DefaultAuthenticator struct {
    36  	Cred *Cred
    37  
    38  	// The authenticator to use for speculative authentication. Because the correct auth mechanism is unknown when doing
    39  	// the initial hello, SCRAM-SHA-256 is used for the speculative attempt.
    40  	speculativeAuthenticator SpeculativeAuthenticator
    41  }
    42  
    43  var _ SpeculativeAuthenticator = (*DefaultAuthenticator)(nil)
    44  
    45  // CreateSpeculativeConversation creates a speculative conversation for SCRAM authentication.
    46  func (a *DefaultAuthenticator) CreateSpeculativeConversation() (SpeculativeConversation, error) {
    47  	return a.speculativeAuthenticator.CreateSpeculativeConversation()
    48  }
    49  
    50  // Auth authenticates the connection.
    51  func (a *DefaultAuthenticator) Auth(ctx context.Context, cfg *Config) error {
    52  	var actual Authenticator
    53  	var err error
    54  
    55  	switch chooseAuthMechanism(cfg) {
    56  	case SCRAMSHA256:
    57  		actual, err = newScramSHA256Authenticator(a.Cred)
    58  	case SCRAMSHA1:
    59  		actual, err = newScramSHA1Authenticator(a.Cred)
    60  	default:
    61  		actual, err = newMongoDBCRAuthenticator(a.Cred)
    62  	}
    63  
    64  	if err != nil {
    65  		return newAuthError("error creating authenticator", err)
    66  	}
    67  
    68  	return actual.Auth(ctx, cfg)
    69  }
    70  
    71  // If a server provides a list of supported mechanisms, we choose
    72  // SCRAM-SHA-256 if it exists or else MUST use SCRAM-SHA-1.
    73  // Otherwise, we decide based on what is supported.
    74  func chooseAuthMechanism(cfg *Config) string {
    75  	if saslSupportedMechs := cfg.HandshakeInfo.SaslSupportedMechs; saslSupportedMechs != nil {
    76  		for _, v := range saslSupportedMechs {
    77  			if v == SCRAMSHA256 {
    78  				return v
    79  			}
    80  		}
    81  		return SCRAMSHA1
    82  	}
    83  
    84  	if err := scramSHA1Supported(cfg.HandshakeInfo.Description.WireVersion); err == nil {
    85  		return SCRAMSHA1
    86  	}
    87  
    88  	return MONGODBCR
    89  }
    90  
    91  // scramSHA1Supported returns an error if the given server version does not support scram-sha-1.
    92  func scramSHA1Supported(wireVersion *description.VersionRange) error {
    93  	if wireVersion != nil && wireVersion.Max < 3 {
    94  		return fmt.Errorf("SCRAM-SHA-1 is only supported for servers 3.0 or newer")
    95  	}
    96  
    97  	return nil
    98  }