Class: Mongo::Auth::SCRAM::Conversation Private

Inherits:
Object
  • Object
show all
Defined in:
lib/mongo/auth/scram/conversation.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Defines behavior around a single SCRAM-SHA-1/256 conversation between the client and server.

Since:

  • 2.0.0

Constant Summary collapse

CLIENT_CONTINUE_MESSAGE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The base client continue message.

Since:

  • 2.0.0

{ saslContinue: 1 }.freeze
CLIENT_FIRST_MESSAGE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The base client first message.

Since:

  • 2.0.0

{ saslStart: 1, autoAuthorize: 1 }.freeze
CLIENT_KEY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Deprecated.

The client key string.

Since:

  • 2.0.0

'Client Key'.freeze
DONE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The key for the done field in the responses.

Since:

  • 2.0.0

'done'.freeze
ID =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The conversation id field.

Since:

  • 2.0.0

'conversationId'.freeze
ITERATIONS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The iterations key in the responses.

Since:

  • 2.0.0

/i=(\d+)/.freeze
MIN_ITER_COUNT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The minimum iteration count for SCRAM-SHA-256.

Since:

  • 2.6.0

4096
PAYLOAD =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The payload field.

Since:

  • 2.0.0

'payload'.freeze
RNONCE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The rnonce key in the responses.

Since:

  • 2.0.0

/r=([^,]*)/.freeze
SALT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The salt key in the responses.

Since:

  • 2.0.0

/s=([^,]*)/.freeze
SERVER_KEY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Deprecated.

The server key string.

Since:

  • 2.0.0

'Server Key'.freeze
VERIFIER =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The server signature verifier in the response.

Since:

  • 2.0.0

/v=([^,]*)/.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(user, mechanism) ⇒ Conversation

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create the new conversation.

Examples:

Create the new conversation.

Conversation.new(user, mechanism)

Since:

  • 2.0.0



226
227
228
229
230
231
232
233
234
# File 'lib/mongo/auth/scram/conversation.rb', line 226

def initialize(user, mechanism)
  unless [:scram, :scram256].include?(mechanism)
    raise InvalidMechanism.new(mechanism)
  end

  @user = user
  @nonce = SecureRandom.base64
  @mechanism = mechanism
end

Instance Attribute Details

#nonceString (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns nonce The initial user nonce.

Since:

  • 2.0.0



91
92
93
# File 'lib/mongo/auth/scram/conversation.rb', line 91

def nonce
  @nonce
end

#replyProtocol::Message (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns reply The current reply in the conversation.

Since:

  • 2.0.0



95
96
97
# File 'lib/mongo/auth/scram/conversation.rb', line 95

def reply
  @reply
end

#userUser (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns user The user for the conversation.

Since:

  • 2.0.0



98
99
100
# File 'lib/mongo/auth/scram/conversation.rb', line 98

def user
  @user
end

Instance Method Details

#continue(reply, connection) ⇒ Protocol::Message

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Examples:

Continue the conversation.

conversation.continue(reply)

Since:

  • 2.0.0



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/mongo/auth/scram/conversation.rb', line 115

def continue(reply, connection)
  validate_first_message!(reply, connection.server)

  if connection && connection.features.op_msg_enabled?
    selector = CLIENT_CONTINUE_MESSAGE.merge(
      payload: client_final_message,
      conversationId: id,
    )
    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,
      CLIENT_CONTINUE_MESSAGE.merge(
        payload: client_final_message,
        conversationId: id,
      ),
      limit: -1,
    )
  end
end

#finalize(reply, connection) ⇒ Protocol::Query

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Since:

  • 2.0.0



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/mongo/auth/scram/conversation.rb', line 150

def finalize(reply, connection)
  validate_final_message!(reply, connection.server)
  if connection && connection.features.op_msg_enabled?
    selector = CLIENT_CONTINUE_MESSAGE.merge(
      payload: client_empty_message,
      conversationId: id,
    )
    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,
      CLIENT_CONTINUE_MESSAGE.merge(
        payload: client_empty_message,
        conversationId: id,
      ),
      limit: -1,
    )
  end
end

#full_mechanismObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 2.0.0



201
202
203
# File 'lib/mongo/auth/scram/conversation.rb', line 201

def full_mechanism
  MECHANISMS[@mechanism]
end

#idInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the id of the conversation.

Examples:

Get the id of the conversation.

conversation.id

Since:

  • 2.0.0



213
214
215
# File 'lib/mongo/auth/scram/conversation.rb', line 213

def id
  reply.documents[0][ID]
end

#start(connection) ⇒ Protocol::Query

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Since:

  • 2.0.0



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/mongo/auth/scram/conversation.rb', line 182

def start(connection)
  if connection && connection.features.op_msg_enabled?
    selector = CLIENT_FIRST_MESSAGE.merge(
      payload: client_first_message, mechanism: full_mechanism)
    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,
      CLIENT_FIRST_MESSAGE.merge(
        payload: client_first_message, mechanism: full_mechanism),
      limit: -1,
    )
  end
end