module SimpleTelnetServer::HasLogin

Adds functionality for simple authentication and authorization.

By default, login credentials are defined right in the class definition using {ClassMethods::has_login}. If something more dynamic is needed, just override {#authenticate}.

After authentication, {#entered_username}, {#entered_password}, and {#authorized_role} are set.

Attributes

authorized_role[R]

@return [Symbol] the associated role of the valid login credentials

entered_password[R]

@return [String] the password username

entered_username[R]

@return [String] the entered username @note This doesn’t necessarily mean the user is logged in. Use

{#authorized?} to check for that.

Public Class Methods

included(klass) click to toggle source

Extends klass with {ClassMethods}.

# File lib/em-simple_telnet_server/has_login.rb, line 11
def self.included(klass)
  klass.extend ClassMethods
end

Public Instance Methods

authenticate(user, pass) click to toggle source

Checks user and pass against all known login credentials.

@param user [String] entered username @param pass [String] entered password @return [Symbol] associated role, if credentials are known @return [nil] if credentials are not known

# File lib/em-simple_telnet_server/has_login.rb, line 134
def authenticate(user, pass)
  self.class.login_credentials.each do |role, credentials|
    return role if credentials == [ user, pass ]
  end
  return nil
end
initiate_authentication() click to toggle source

Initiates authentication. This means setting the connection state to waiting_for_username and sending the login prompt.

# File lib/em-simple_telnet_server/has_login.rb, line 50
def initiate_authentication
  @connection_state = :waiting_for_username
  send_login_prompt
end
needs_authentication?() click to toggle source

@return [true] true, as this module is about authentication

# File lib/em-simple_telnet_server/has_login.rb, line 44
def needs_authentication?
  true
end
process_buffer() click to toggle source

If the user was requested to enter his username, the username is read. If the user was requested to enter his password, the password is read.

Otherwise, the normal (super) behavior proceeds.

In all cases, it ensures that the buffer is cleared at the end.

Calls superclass method
# File lib/em-simple_telnet_server/has_login.rb, line 62
def process_buffer
  if waiting_for_username?
    read_username_from_buffer

  elsif waiting_for_password?
    read_password_from_buffer

  else
    super
  end
ensure
  @buffer.clear
end
read_password_from_buffer() click to toggle source

Reads the password from buffer and authorizes the user if he can be authenticated. Otherwise the connection state is set back to :waiting_for_username and the login prompt is sent.

# File lib/em-simple_telnet_server/has_login.rb, line 100
def read_password_from_buffer
  @entered_password = @buffer.chomp
  if role = authenticate(@entered_username, @entered_password)
    @authorized_role = role
    authorize
  else
    @connection_state = :waiting_for_username
    @entered_username = @entered_password = nil
    send_login_failed
    send_login_prompt
  end
end
read_username_from_buffer() click to toggle source

Reads the username from buffer. Sends the password prompt afterwards ({#send_password_prompt}) and sets the connection state to :waiting_for_password.

# File lib/em-simple_telnet_server/has_login.rb, line 116
def read_username_from_buffer
  @entered_username = @buffer.strip
  send_password_prompt
  @connection_state = :waiting_for_password
end
send_login_failed() click to toggle source

Sends the message “Sorry, please try again.” and the login prompt.

# File lib/em-simple_telnet_server/has_login.rb, line 123
def send_login_failed
  send_data "Sorry, please try again.\n"
end
send_login_prompt() click to toggle source

Sends the login prompt.

# File lib/em-simple_telnet_server/has_login.rb, line 77
def send_login_prompt
  send_data options[:login_prompt]
end
send_password_prompt() click to toggle source

Sends the password prompt.

# File lib/em-simple_telnet_server/has_login.rb, line 82
def send_password_prompt
  send_data options[:password_prompt]
end
waiting_for_password?() click to toggle source

@return [Boolean] whether we are waiting for the user to enter the password

# File lib/em-simple_telnet_server/has_login.rb, line 92
def waiting_for_password?
  @connection_state == :waiting_for_password
end
waiting_for_username?() click to toggle source

@return [Boolean] whether we are waiting for the user to enter the username

# File lib/em-simple_telnet_server/has_login.rb, line 87
def waiting_for_username?
  @connection_state == :waiting_for_username
end