class Mongo::Auth::CR::Conversation

Defines behaviour around a single MONGODB-CR conversation between the client and server.

@since 2.0.0 @deprecated MONGODB-CR authentication mechanism is deprecated

as of MongoDB 3.6. Support for it in the Ruby driver will be
removed in driver version 3.0. Please use SCRAM instead.

Constants

LOGIN

The login message base.

@since 2.0.0

Attributes

database[R]

@return [ String ] database The database to authenticate against.

nonce[R]

@return [ String ] nonce The initial auth nonce.

reply[R]

@return [ Protocol::Message ] reply The current reply in the

conversation.
user[R]

@return [ User ] user The user for the conversation.

Public Class Methods

new(user) click to toggle source

Create the new conversation.

@example Create the new conversation.

Conversation.new(user, "admin")

@param [ Auth::User ] user The user to converse about.

@since 2.0.0

# File lib/mongo/auth/cr/conversation.rb, line 126
def initialize(user)
  @user = user
end

Public Instance Methods

continue(reply, connection = nil) click to toggle source

Continue the CR conversation. This sends the client final message to the server after setting the reply from the previous server communication.

@example Continue the conversation.

conversation.continue(reply)

@param [ Protocol::Message ] reply The reply of the previous

message.

@param [ Mongo::Server::Connection ] connection The connection being authenticated.

@return [ Protocol::Query ] The next message to send.

@since 2.0.0

# File lib/mongo/auth/cr/conversation.rb, line 60
def continue(reply, connection = nil)
  validate!(reply)
  if connection && connection.features.op_msg_enabled?
    selector = LOGIN.merge(user: user.name, nonce: nonce, key: user.auth_key(nonce))
    selector[Protocol::Msg::DATABASE_IDENTIFIER] = user.auth_source
    cluster_time = connection.mongos? && connection.cluster_time
    selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
    Protocol::Msg.new([:none], {}, selector)
  else
    Protocol::Query.new(
      user.auth_source,
      Database::COMMAND,
      LOGIN.merge(user: user.name, nonce: nonce, key: user.auth_key(nonce)),
      limit: -1
    )
  end
end
finalize(reply, connection = nil) click to toggle source

Finalize the CR conversation. This is meant to be iterated until the provided reply indicates the conversation is finished.

@example Finalize the conversation.

conversation.finalize(reply)

@param [ Protocol::Message ] reply The reply of the previous

message.

@return [ Protocol::Query ] The next message to send.

@since 2.0.0

# File lib/mongo/auth/cr/conversation.rb, line 90
def finalize(reply, connection = nil)
  validate!(reply)
end
start(connection = nil) click to toggle source

Start the CR conversation. This returns the first message that needs to be send to the server.

@example Start the conversation.

conversation.start

@return [ Protocol::Query ] The first CR conversation message.

@since 2.0.0

# File lib/mongo/auth/cr/conversation.rb, line 103
def start(connection = nil)
  if connection && connection.features.op_msg_enabled?
    selector = Auth::GET_NONCE.merge(Protocol::Msg::DATABASE_IDENTIFIER => user.auth_source)
    cluster_time = connection.mongos? && connection.cluster_time
    selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
    Protocol::Msg.new([:none], {}, selector)
  else
    Protocol::Query.new(
      user.auth_source,
      Database::COMMAND,
      Auth::GET_NONCE,
      limit: -1)
  end
end

Private Instance Methods

validate!(reply) click to toggle source
# File lib/mongo/auth/cr/conversation.rb, line 132
def validate!(reply)
  raise Unauthorized.new(user) if reply.documents[0][Operation::Result::OK] != 1
  @nonce = reply.documents[0][Auth::NONCE]
  @reply = reply
end