class Mongo::Auth::Aws::Conversation

Defines behavior around a single MONGODB-AWS conversation between the client and server.

@see github.com/mongodb/specifications/blob/master/source/auth/auth.rst#mongodb-aws

@api private

Attributes

conversation_id[R]

Get the id of the conversation.

@return [ Integer ] The conversation id.

server_nonce[R]

@return [ String ] The server nonce.

Public Instance Methods

continue(reply_document, connection) click to toggle source

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

@param [ BSON::Document ] reply_document The reply document of the

previous message.

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

authenticated.

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

# File lib/mongo/auth/aws/conversation.rb, line 40
def continue(reply_document, connection)
  @conversation_id = reply_document[:conversationId]
  payload = reply_document[:payload].data
  payload = BSON::Document.from_bson(BSON::ByteBuffer.new(payload))
  @server_nonce = payload[:s].data
  validate_server_nonce!
  @sts_host = payload[:h]
  unless (1..255).include?(@sts_host.bytesize)
    raise Error::InvalidServerAuthConfiguration, "STS host name length is not in 1..255 bytes range: #{@sts_host}"
  end

  selector = CLIENT_CONTINUE_MESSAGE.merge(
    payload: BSON::Binary.new(client_final_payload),
    conversationId: conversation_id,
  )
  build_message(connection, user.auth_source, selector)
end

Private Instance Methods

client_final_payload() click to toggle source
# File lib/mongo/auth/aws/conversation.rb, line 87
def client_final_payload
  credentials = CredentialsRetriever.new(user).credentials
  request = Request.new(
    access_key_id: credentials.access_key_id,
    secret_access_key: credentials.secret_access_key,
    session_token: credentials.session_token,
    host: @sts_host,
    server_nonce: server_nonce,
  )

  # Uncomment this line to validate obtained credentials on the
  # client side prior to sending them to the server.
  # This generally produces informative diagnostics as to why
  # the credentials are not valid (e.g., they could be expired)
  # whereas the server normally does not elaborate on why
  # authentication failed (but the reason usually is logged into
  # the server logs).
  #
  # Note that credential validation requires that the client is
  # able to access AWS STS. If this is not permitted by firewall
  # rules, validation will fail but credentials may be perfectly OK
  # and the server may be able to authenticate using them just fine
  # (provided the server is allowed to communicate with STS).
  #request.validate!

  payload = {
    a: request.authorization,
    d: request.formatted_time,
  }
  if credentials.session_token
    payload[:t] = credentials.session_token
  end
  payload.to_bson.to_s
end
client_first_data() click to toggle source
# File lib/mongo/auth/aws/conversation.rb, line 68
def client_first_data
  {
    r: BSON::Binary.new(client_nonce),
    p: 110,
  }
end
client_first_payload() click to toggle source
# File lib/mongo/auth/aws/conversation.rb, line 75
def client_first_payload
  client_first_data.to_bson.to_s
end
client_nonce() click to toggle source
# File lib/mongo/auth/aws/conversation.rb, line 83
def client_nonce
  @client_nonce ||= SecureRandom.random_bytes(32)
end
wrap_data(data) click to toggle source
# File lib/mongo/auth/aws/conversation.rb, line 79
def wrap_data(data)
  BSON::Binary.new(data.to_bson.to_s)
end