class Mongo::Auth::CR::Conversation

Defines behavior 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) 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 61
def continue(reply, connection)
  validate!(reply, connection.server)
  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([], {}, 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) click to toggle source

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

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

message.

@param [ 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 90
def finalize(reply, connection)
  validate!(reply, connection.server)
end
start(connection) click to toggle source

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

@param [ Server::Connection ] connection The connection being

authenticated.

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

@since 2.0.0

# File lib/mongo/auth/cr/conversation.rb, line 103
def start(connection)
  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([], {}, selector)
  else
    Protocol::Query.new(
      user.auth_source,
      Database::COMMAND,
      Auth::GET_NONCE,
      limit: -1)
  end
end

Private Instance Methods

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