# Copyright (C) 2014-2017 MongoDB Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require 'mongo/auth/user/view' module Mongo module Auth # Represents a user in MongoDB. # # @since 2.0.0 class User # @return [ String ] The authorization source, either a database or # external name. attr_reader :auth_source # @return [ String ] The database the user is created in. attr_reader :database # @return [ Hash ] The authentication mechanism properties. attr_reader :auth_mech_properties # @return [ Symbol ] The authorization mechanism. attr_reader :mechanism # @return [ String ] The username. attr_reader :name # @return [ String ] The cleartext password. attr_reader :password # @return [ Array ] roles The user roles. attr_reader :roles # Determine if this user is equal to another. # # @example Check user equality. # user == other # # @param [ Object ] other The object to compare against. # # @return [ true, false ] If the objects are equal. # # @since 2.0.0 def ==(other) return false unless other.is_a?(User) name == other.name && database == other.database && password == other.password end # Get an authentication key for the user based on a nonce from the # server. # # @example Get the authentication key. # user.auth_key(nonce) # # @param [ String ] nonce The response from the server. # # @return [ String ] The authentication key. # # @since 2.0.0 def auth_key(nonce) Digest::MD5.hexdigest("#{nonce}#{name}#{hashed_password}") end # Get the UTF-8 encoded name with escaped special characters for use with # SCRAM authorization. # # @example Get the encoded name. # user.encoded_name # # @return [ String ] The encoded user name. # # @since 2.0.0 def encoded_name name.encode(BSON::UTF8).gsub('=','=3D').gsub(',','=2C') end # Get the hash key for the user. # # @example Get the hash key. # user.hash # # @return [ String ] The user hash key. # # @since 2.0.0 def hash [ name, database, password ].hash end # Get the user's hashed password. # # @example Get the user's hashed password. # user.hashed_password # # @return [ String ] The hashed password. # # @since 2.0.0 def hashed_password @hashed_password ||= Digest::MD5.hexdigest("#{name}:mongo:#{password}").encode(BSON::UTF8) end # Create the new user. # # @example Create a new user. # Mongo::Auth::User.new(options) # # @param [ Hash ] options The options to create the user from. # # @option options [ String ] :auth_source The authorization database or # external source. # @option options [ String ] :database The database the user is # authorized for. # @option options [ String ] :user The user name. # @option options [ String ] :password The user's password. # @option options [ Symbol ] :auth_mech The authorization mechanism. # @option options [ Array, Array ] roles The user roles. # @option options [ String ] :client_key The user's client key cached from a previous # authentication on the same connection. # # @since 2.0.0 def initialize(options) @database = options[:database] || Database::ADMIN @auth_source = options[:auth_source] || @database @name = options[:user] @password = options[:password] || options[:pwd] @mechanism = options[:auth_mech] || :mongodb_cr @auth_mech_properties = options[:auth_mech_properties] || {} @roles = options[:roles] || [] @client_key = options[:client_key] end # Get the specification for the user, used in creation. # # @example Get the user's specification. # user.spec # # @return [ Hash ] The user spec. # # @since 2.0.0 def spec { pwd: hashed_password, roles: roles } end private # The client key for the user. # # @return [ String ] The client key for the user. attr_reader :client_key end end end